Module:Navbox

-- -- -- Implements --

local p = {} local tnavbar = require( 'Module:Tnavbar' ) local yesno = require( 'Module:Yesno' ) local onmain = require('Module:Mainonly').on_main local hc = require('Module:Paramtest').has_content local page_title = mw.title.getCurrentTitle.fullText -- -- Helper for inserting a new row into the navbox -- -- @param tbl {mw.html table} -- @return tbl {mw.html table} -- local function insertRow( tbl ) return tbl:tag( 'tr' ) end

-- -- Creates the navbox table -- -- @param args {table} -- @return tbl {mw.html table} -- local function createTbl( args )

local tbl = mw.html.create( 'table' )

tbl :addClass( yesno( args.subgroup ) and 'navbox-subgroup' or 'navbox' ) :addClass( 'nowraplinks' )

if not yesno( args.subgroup ) and ( args.state == 'collapsed' or		 args.state == 'uncollapsed' or		  args.state == 'autocollapse' or		  -- defaults to autocollapse		  args.state == nil ) then tbl:addClass( 'mw-collapsible' )

if args.state == 'collapsed' then tbl:addClass( 'mw-collapsed' ) elseif args.state == 'uncollapsed' then tbl:addClass('navbox-uncollapsed') end end

if yesno( args.collapsible ) then tbl:addClass( 'navbox-collapsible' ) end

if args.style then tbl:cssText( args.style ) end

-- manually set collapse/expand messages -- bug causing the default database messages to be used tbl :attr( {			['data-expandtext'] = 'show',			['data-collapsetext'] = 'hide'		} )

return tbl end

-- -- Wrapper for Module:Tnavbar -- -- @param args {table} -- @return {string} -- local function navbar( args ) return tnavbar._collapsible( { [1] = args.title, [2] = args.name } ) end

-- -- Creates the header (what you see when the navbox is collapsed) -- -- @param tbl {mw.html table} -- @param args {table} -- @return {mw.html table} -- local function header( tbl, args ) local div = insertRow( tbl ) :tag( 'th' ) :attr( 'colspan', '2' ) :addClass( 'navbox-title' ) :attr( 'id', 'navbox-title' ) :tag( 'div' )

-- @todo move this to site css so we can simplify this (hook off a class) -- to something like div:wikitext( args.name and navbar( args ) or args.title ) -- which can be appended to the above and returned straight away if args.name then div :css( 'padding-right', args.state == 'plain' and '6em' or '0' ) :wikitext( navbar( args ) ) else div :css( 'padding-left', args.state == 'plain' and '0' or '6em' ) :wikitext( args.title ) end

return div:allDone end

-- -- Inserts a row into the navbox -- -- @param tbl {mw.html table} -- @param gtitle {string} -- @param group {string} -- @param gtype {string} -- @param style {string} -- @return {mw.html table} -- local function row( tbl, gtitle, group, gtype, style, _name, subgroup ) local tr = insertRow( tbl ) local td

if gtitle then td = tr			:addClass( 'navbox-group' ) :tag( 'td' ) :addClass( 'navbox-group-title' ) :wikitext( gtitle ) :done :tag( 'td' ) else td = tr			:addClass( 'navbox-group' ) :addClass( 'navbox-group-split' ) :tag( 'td' ) :addClass( 'navbox-group-title-hidden' ) :attr( 'colspan', '0' ) :css( 'display', 'none' ) :done :tag( 'td' ) :attr( 'colspan', '2' ) end

-- group3 =	  * 	   * 	   * if mw.ustring.match( group, '^%s*%*' ) then td:newline

-- trim whitespace on bullets local spl = mw.text.split( group, '\n' )

for i = 1, #spl do			spl[i] = mw.text.trim( spl[i] ) end

group = '\n' .. table.concat( spl, '\n' ) end

--local group2 = group --local group3 = group2 -- analytics

--if _name then --	local name = mw.ustring.gsub(_name,' ','_') --	for v in mw.ustring.gmatch(group,'%[%^%+%]%]') do	--		if mw.ustring.match(v,'%[%[File:.+|link=') then --			local link = mw.ustring.match(v,'|link=([^%]|]+)') --			if link then --				local linkrep = mw.ustring.gsub(link,'([%%%]%[%-^$*+?])','%%%1') --				local _link = mw.ustring.gsub(link,' ','_') --				local newfile = mw.ustring.gsub(v,'|link='..linkrep,string.format('|link=https://oldschool.runescape.wiki/w/%s?f=%s',_link,name)) --				local w = mw.ustring.gsub(v,'([%%%]%[%-^$*+?])','%%%1') --				group2 = mw.ustring.gsub(group2,w,newfile) --			end --		elseif mw.ustring.match(v,'%[%[Category:') then -- nothing --		else --			local link = mw.ustring.match(v,'%[%[([^%]|]+)') --			local txt = mw.ustring.match(v,'%|([^%]|]+)') or link

--			local newlink = ''

-- black links if current page --			if link == page_title then --				newlink = string.format('%s',txt) --			else --				local _link = mw.ustring.gsub(link or '',' ','_') --				newlink = string.format('%s',_link,name,txt) --			end --			local w = mw.ustring.gsub(v,'([%%%]%[%-^$*+?])','%%%1') --			group2 = mw.ustring.gsub(group2,w,newlink) --		end --	end

--[==[			fix these kinds of links post analytics parse ]==]	--	group3 = group2

--	for v in mw.ustring.gmatch(group2,'%]-%]%a') do	--		local rep = mw.ustring.gsub(v,'%]','') --		rep = rep..']' --		local w = mw.ustring.gsub(v,'([%%%]%[%-^$*+?])','%%%1')

--		group3 = mw.ustring.gsub(group2,w,rep) --	end --end

local subgroups if gtype and mw.ustring.lower( gtype ) == 'subgroup' then td :addClass( 'navbox-parent' ) :css( {				padding = '0',				['border-bottom'] = '0'			} ) subgroups = mw.ustring.match(group, '@@JSON@@(.-)@@NOSJ@@') group = mw.ustring.gsub(group, '@@JSON@@.-@@NOSJ@@', '') end td :addClass( 'navbox-list' ) :wikitext( group ) --group3

if style then td:cssText( style ) end if yesno(subgroup) then td	--:tag('span') --	:css('display','none'):addClass('hidden') :wikitext('@@JSON@@') :wikitext(_dumpGroup(gtitle, gtype, group, subgroups)) :wikitext('@@NOSJ@@') end

return td:allDone end

-- -- Inserts a footer into the navbox -- -- @param tbl {mw.html table} -- @param args {table} -- @return {mw.html table} -- local function footer( tbl, args ) local th = insertRow( tbl ) :tag( 'th' ) :attr( 'colspan', '2' ) :addClass( 'navbox-footer' )

if args.fstyle then th:cssText( args.fstyle ) end

if mw.ustring.match( args.footer, '^%s*%*' ) then th:newline

-- trim whitespace on bullets local spl = mw.text.split( args.footer, '\n' )

for i = 1, #spl do			spl[i] = mw.text.trim( spl[i] ) end

args.footer = table.concat( spl, '\n' )

th:addClass( 'navbox-list' ) end

th:wikitext( args.footer )

return th:allDone end

-- -- Adds to navbox template pages -- -- @return {string} -- local function categories local title = mw.title.getCurrentTitle local page = title.text local ns = title.nsText

if ns == 'Template' then -- sort in category by pagename return '' else return '' end

end

-- -- Adds Template:Navbox/doc to navbox template pages -- -- @param args {table} -- @return {string} -- local function docs( args ) local frame = mw.getCurrentFrame local title = mw.title.getCurrentTitle local base = title.baseText local ns = title.nsText

-- not if a subpage of Template:Navbox if base ~= 'Navbox' and -- in template ns		ns == 'Template' and -- not a navbox group within a navbox not yesno( args.subgroup ) and -- not a collapsible navbox within a navbox not yesno( args.collapsible ) and -- not if the doc argument is set to "no" ( args.doc == nil or yesno( args.doc ) ) then return frame:expandTemplate{ title = 'Navbox/doc' } else return '' end

end

function _dumpGroup(gtitle, gtype, group, subgroups) local jsg, json = pcall(mw.text.jsonEncode, _jsonGroup(gtitle, gtype, group, subgroups)) if jsg then return mw.text.nowiki(json) end return '' end function _jsonGroup(gtitle, gtype, group, subgroups) local ret = { title = gtitle, type = gtype }	if hc(subgroups) then local jsg, json = pcall(mw.text.jsonDecode, mw.text.decode(subgroups)) if jsg then ret.contents = json end else local contents = {} for i,v in ipairs(mw.text.split(group, '%*')) do			if hc(v) then local item = {} local working for j in mw.ustring.gmatch(v, '%[%[(.-)%]%]') do					if not mw.ustring.find(j, 'File:', 1, true) then local _j = mw.text.split(j, '|', true) if #_j == 1 then item.link = _j[1] item.text = _j[1] else item.link = _j[1] item.text = _j[2] end break --only want 1 at the mo					end end working = mw.ustring.match(v, '%[%[File:(.-)[|%]]') if working then item.image = working end table.insert(contents, item) end end ret.contents = contents end return ret end

-- -- Tracking SMW -- -- @param _args {table} -- @return {string} -- function smw(args) if not onmain or yesno(args.subgroup) then return '' end local err = mw.html.create('div') err:addClass('hidden'):css('display','none') local haserr = false local info = '' -- more SMW here at some point local smwJSON = { name = args.name, title = args.title, groups = {} }	for i=1,20 do		if not args['group'..i] then break end table.insert(smwJSON.groups, _jsonGroup(args['gtitle'..i], args['gtype'..i], args['group'..i])) end --error(mw.dumpObject(smwJSON)) local jsongood, encsmwJSON = pcall(mw.text.jsonEncode, smwJSON) if jsongood then -- for easier debug, please do not remove encsmwJSON = mw.text.nowiki(encsmwJSON) local div = mw.html.create('div') div	:addClass('hidden navbox-data') :css('display', 'none') :wikitext('Navbox JSON: Navbox JSON::'..encsmwJSON..'') info = mw.getCurrentFrame:preprocess(tostring(div)) else haserr = true err:wikitext('Error setting SMW JSON, string:\n' .. mw.dumpObject(smwJSON)) end if not haserr then err = '' end return tostring(info) .. tostring(err) end

-- -- Navbox method to allow it to be called by other modules -- -- @param _args {table} -- @return {string} -- function p._navbox( _args ) local args = {} local wkCss = '' local wkDiv = '' local j	-- preserves parser function behaviour where an empty string is considered undefined -- or nil in lua's case for k, v in pairs( _args ) do		if v ~= '' then args[k] = v		end end

local tbl = createTbl( args )

if not yesno( args.subgroup ) then tbl = header( tbl, args ) end

-- insert up to 20 rows --	-- 20 is a limit inherited from wikipedia when we copied this over -- and we've never had a reason to extend it	for i = 1, 20 do		j = tostring( i )

if args['group' .. j] then tbl = row( tbl, args['gtitle' .. j], args['group' .. j], args['gtype' .. j], args['style' .. j], args.name, args.subgroup ) else break end end

if args.footer then tbl = footer( tbl, args ) end

tbl = tostring( tbl )

local cats = '' if not yesno(args.subgroup) and not yesno(args.hidecat) then cats = categories end local docs = docs( args ) local smw = smw(args)

return tbl .. cats .. docs .. smw end

-- -- Main navbox method accessed through #invoke -- -- @param frame {table} -- @return {string} -- function p.navbox( frame ) local args = frame:getParent.args return p._navbox( args ) end

return p --