Module:Navbox

-- Navbox Module -- -- * Supports unlimited rows -- -- Originally written by User:Tjcool007 from layton.fandom.com -- Taken and modified from dev.fandom.com -- Modified to function more closely to the existing Template:Navibox

local p = {}

local args = {} -- Arguments passed to template local navbox -- Actual navbox

--local working = {} local rownums = {} local activeSection, sections local colspan, rowspan

local showText, hideText = 'Expand', 'Collapse'

Applies the colorscheme or back/text colors to an HTML element -- -- @param html The html element where the colors should be applied local function applyCS( html ) html:addClass('cs '..(args.colorscheme or '')) if not args.colorscheme and args.backcolor then html:cssText('background:#'..args.backcolor..';') end if not args.colorscheme and args.textcolor then html:cssText('color:#'..args.textcolor..';') end end

-- Title

--- Processes the VDE links in the title -- -- @param titlecell The table cell of the title local function processVeq( titlecell ) if not args.template then return end local between = ' · '

local vde = mw.html.create('div'):cssText('position:absolute; left:50px; font-size:80%;') vde:wikitext('&#91; v ') -- V   vde:wikitext(between) vde:wikitext('args.template:gsub(' ', '_') ..'?action=edit e') -- E   vde:wikitext(between) vde:wikitext('? &#93;') -- ?

titlecell:node(vde) end

--- Processes the main title row local function processTitle local titlerow = mw.html.create('tr') local titlecell = mw.html.create('th'):attr('colspan',colspan):attr('scope','col') applyCS(titlerow)

processVeq(titlecell)

local titlediv = mw.html.create('div'):cssText('margin: 0 7em;') titlediv:wikitext(args.title or '')

titlecell:node(titlediv)

-- Padding local hasTemplate = args.template ~= nil local hasState = not args.state or args.state ~= 'plain' -- may need to be flipped?

titlerow:node(titlecell) navbox:node(titlerow) end

-- Main Rows

--- Closes the currently active section (if any) local function _closeCurrentSection if not activeSection then return end

local row = mw.html.create('tr') local cell = mw.html.create('td'):attr('colspan',2)

cell:node(sections[activeSection]) row:node(cell)

navbox:node(row) rowspan = rowspan + 1

activeSection = false end

--- Process a single Header "row" -- -- @param num Number of the row to be processed local function processHeader(num) if not args['header'..num] then return end

_closeCurrentSection

local table_attrs = { align='center', border='0', cellpadding='1', cellspacing='1' } local subtable = mw.html.create('table'):addClass('collapsible'):attr(table_attrs):cssText('clear: both; text-align: center; width: 100%;') local headerrow = mw.html.create('tr') local header = mw.html.create('th'):attr('colspan',2):attr('scope','col'):wikitext( args['header'..num] ):attr('align', 'center') applyCS(header)

local collapseme = args['state'..num] or false local state = false

if collapseme then -- Look at this one if collapseme ~= 'plain' then state = collapseme == 'expanded' and 'expanded' or 'collapsed' end else -- Look at default local collapseall = args.defaultstate or false if collapseall then state = collapseall == 'expanded' and 'expanded' or 'collapsed' end end

if state then subtable:addClass('mw-collapsible'):attr('data-expandtext',args['expandtext'..num] or args['defaultexpandtext'] or showText):attr('data-collapsetext',args['collapsetext'..num] or args['defaultcollapsetext'] or hideText) if state == 'collapsed' then subtable:addClass('mw-collapsed') end header:addClass('navbox-header-collapsible')   -- may need to be taken out end

headerrow:node(header) subtable:node(headerrow)

sections[num] = subtable activeSection = num end

--- Processes a single list row -- -- @param num Number of the row to be processed local function processList(num) if not args['list'..num] then return end

local row = mw.html.create('tr'):addClass('navbox-row')

local listcell = mw.html.create('td') local hlistcell = listcell:tag('div'):addClass('hlist'):attr('align', 'left') --maybe switch to span ? local data = args['list'..num] if data:sub(1,1) == '*' then -- Add newlines to support lists properly hlistcell :newline :wikitext( data ) :newline else hlistcell:wikitext( data ) end

if args['group'..num] then local groupcell = mw.html.create('th'):attr('scope','row'):wikitext( args['group'..num]..':' ) groupcell:attr('align', 'center'):attr('width', '15%') applyCS(groupcell) row:node( groupcell ) else listcell:attr('colspan',2):addClass('no-group') end

row:node( listcell )

if activeSection then local parent = sections[activeSection] parent:node(row) else navbox:node( row ) rowspan = rowspan + 1 end end

--- Processes all rows local function processRows sections = {} for i=1,#rownums do		local num = rownums[i] processHeader(num) processList(num) end _closeCurrentSection end

-- ARGUMENTS PREPROCESSOR -- * Extracts arguments from frame and stores them in args table -- * At the same time, checks for valid row numbers

--- Preprocessor for the arguments. -- Will fill up the args table with the parameters from the frame grouped by their type. -- -- @param frame The frame passed to the Module. local function preProcessArgs(frame) local tmp = {}

if frame == mw.getCurrentFrame then tmp = frame:getParent.args else tmp = frame end

-- Storage tables local nums = {}

-- Loop over all the args for k,v in pairs(tmp) do		-- Skip empty args, which are useless if v ~= '' then local cat,num = tostring(k):match('^(%a+)([1-9]%d*)$')

if cat == 'header' or cat == 'list' then nums[num] = true end

args[k] = v -- Simple copy end end

colspan = 2 rowspan = 0

for k, v in pairs(nums) do		rownums[#rownums+1] = tonumber(k) end

table.sort(rownums) end

-- MAIN FUNCTIONS

--- Processes the arguments to create the navbox. -- -- @return A string with HTML that is the navbox. local function _navbox -- Create the root HTML element navbox = mw.html.create('table'):addClass('navbox'):addClass('toccolours') navbox:addClass('mw-collapsible'):attr('align', 'center'):attr('width', '95%') navbox:cssText('border:1px solid #FFF0B3; margin-bottom:5px;'):attr('title', args.template or '') -- no idea if will work -- Template:Navibox seems to put collapsible one level down, though Module:Navbox doesn't; see what works if args.state ~= 'plain' then navbox:addClass('mw-collapsed') end

processTitle processRows return tostring(navbox) end

--- Main module entry point. -- To be called with or directly from another module. -- -- @param frame The frame passed to the module via the #invoke. If called from another --             module directly, this should be a table with the parameter definition. function p.main(frame) -- Save the arguments in a local variable so other functions can use them. preProcessArgs(frame) return _navbox end

return p