Module:Navbox

    From Nonbinary Wiki
    Revision as of 21:15, 25 February 2013 by m>Toohool (fix errors)

    Documentation for this module may be created at Module:Navbox/doc

    --
    -- This module will implement {{Navbox}}
    --
    
    local p = {}
    
    local gutterRow = '<tr style="height:2px;"><td></td></tr>'
    local listnums = {}
    local ret = {}
    
    function add(...)
        local args = {...}
        for i = 1, #args do
            if args[i] then
                table.insert(ret, args[i])
            end
        end
    end
    
    function renderTitleRow(args)
        if not args.title then return end
        
        add('<tr>')
        if args.titlegroup then
            add('<th scope="row" class="navbox-group ', args.titlegroupclass, '" style="', args.basestyle, ';', args.groupstyle, ';', args.titlegroupstyle, '">', args.titlegroup, '</th><th scope="col" style="border-left:2px solid #fdfdfd;width:100%;')
        else
            add('<th scope="col" style="')
        end
        local colspan = 2
        if args.imageleft then colspan = colspan + 1 end
        if args.image then colspan = colspan + 1 end
        if args.titlegroup then colspan = colspan - 1 end
        add(args.basestyle, ';', args.titlestyle, '" class="navbox-title" colspan=', colspan, '>')
    
        local stateLinkPlaceholder = '<span style="float:right;width:6em;">&nbsp;</span>'
        if args.navbar == 'plain' or args.navbar == 'off' or (not args.name and (border == 'subgroup' or border == 'child' or border == 'none')) then
            if args.navbar == 'off' then
                if args.state == 'plain' then add(stateLinkPlaceholder) end
            else
                if args.state ~= 'plain' then add(stateLinkPlaceholder) end
            end
        else
            if args.name then
                add(mw.getCurrentFrame():expandTemplate{ title = 'navbar', args = { 
                    args.name, 
                    mini = 1, 
                    fontstyle = (args.basestyle or '') .. ';' .. (args.titlestyle or '') ..  ';background:none transparent;border:none;'
                }})
            else
                add('<span class="error" style="float:left;white-space:nowrap;">Error: No name provided</span>')
                if args.state == 'plain' then add(stateLinkPlaceholder) end
            end
        end
    
        add('<div class="', args.titleclass, '" style="font-size:110%;">')
        add(args.title)
        add('</div></th></tr>')
    end
    
    function renderAboveRow(args)
        if not args.above then return end
        
        if args.title then add(gutterRow) end
        add('<tr><td class="navbox-abovebelow ', args.aboveclass, '" style="', args.basestyle, ';', args.abovestyle, '" colspan="', getAboveBelowColspan(args), '">')
        add('<div>', args.above, '</div></td></tr>')
    end
    function renderBelowRow(args)
        if args.below then
            if args.title or args.above or #listnums > 0 then add(gutterRow) end
            add('<tr><td class="navbox-abovebelow ', args.belowclass, '" style="', args.basestyle, ';', args.belowstyle, '"  colspan="', getAboveBelowColspan(args), '">')
            add('<div>', args.below, '</div></td></tr>')
        end
    end
    function getAboveBelowColspan(args)
        local ret = 2
        if args.imageleft then ret = ret + 1 end
        if args.image then ret = ret + 1 end
        return ret
    end
    
    function renderFirstListRow(args)
        if not args.list1 then return end
        
        if args.title or args.above then add(gutterRow) end
        add('<tr>')
        if args.imageleft then
            add('<td class="navbox-image ', args.imageclass, '" style="width:0%;padding:0px 2px 0px 0px;', args.imageleftstyle, '"')
            add(' rowspan=', (2 * #listnums - 1), '><div>', args.imageleft, '</div></td>')
        end
    
        if args.group1 then
            add('<th scope="row" class="navbox-group ', args.groupclass, '" style="', args.basestyle, ';')
            if args.groupwidth then add('width:', args.groupwidth, ';') end
            add(args.groupstyle, ';', args.group1style, '">')
            add(args.group1, '</th>')
            add('<td style="text-align:left;border-left-width:2px;border-left-style:solid;')
        else
            add('<td colspan=2 style="')
        end
        if not args.groupwidth then add('width:100%;') end
        add('padding:0px;', args.liststyle, ';', args.oddstyle, ';', args.list1style, '" class="navbox-list navbox-')
        if args.evenodd == 'swap' then
            add('even')
        else
            add(args.evenodd or 'odd')
        end
        add(' ', args.listclass, '">')
        add('<div style="padding:', args.list1padding or args.listpadding or '0em 0.25em', '">')
        add(args.list1)
        add('</div></td>')
    
        if args.image then
            add('<td class="navbox-image ', args.imageclass, '" style="width:0%;padding:0px 0px 0px 2px;', args.imagestyle, '" ')
            add(' rowspan=', (2 * #listnums - 1), '>')
            add('<div>', args.image, '</div></td>')
        end
        
        add('</tr>')
    end
    
    function renderNthListRow(args, listnum)
        if args.title or args.above or args.list1 then
            add(gutterRow)
        end
        add('<tr>')
        if args['group' .. listnum] then
            add('<th scope="row" class="navbox-group ', args.groupclass, '" style="', args.basestyle, ';')
            if args.groupwidth then add('width:', args.groupwidth, ';') end
            add(args.groupstyle, ';', args['group' .. listnum .. 'style'], '">')
            add(args['group' .. listnum])
            add('</th><td style="text-align:left;border-left-width:2px;border-left-style:solid;')
        else
            add('<td colspan=2 style="')
        end
        if not args.groupwidth then add('width:100%;') end
        
        local isOdd = (listnum % 2) == 1
        local rowstyle = args.evenstyle
        if isOdd then rowstyle = args.oddstyle end
            
        add('padding:0px;', args.liststyle, ';', rowstyle, ';', args['list' .. listnum .. 'style'], '" ')
        add('class="navbox-list navbox-')
        if args.evenodd == 'swap' then
            if isOdd then add('even') else add('odd') end
        else
            if isOdd then add(args.evenodd or 'odd') else add(args.evenodd or 'even') end
        end
        add(' ', args.listclass, '">')
        
        add('<div style="padding:', args.listpadding or '0em 0.25em', '">', args['list' .. listnum], '</div></td></tr>')
    end
    
    function p._navbox(args)
        for k, v in pairs(args) do
            local listnum = ('' .. k):match('^list(%d+)$')
            if listnum then table.insert(listnums, tonumber(listnum)) end
        end
        table.sort(listnums)
        
        local border = args.border or args[1]
        if border == 'subgroup' or border == 'child' then
            add('</div>')
        elseif border ~= 'none' then
            add('<table cellspacing="0" class="navbox" style="border-spacing:0;', args.bodystyle, ';', args.style, '"><tr><td style="padding:2px;">')
        end
        
        add('<table cellspacing="0" class="nowraplinks ', args.bodyclass, ' ')
        
        if args.title and (args.state ~= 'plain' and args.state ~= 'off') then
            add('collapsible ', args.state or 'autocollapse', ' ')
        end
        
        if border == 'subgroup' or border == 'child' or border == 'none' then
            add('navbox-subgroup" style="border-spacing:0;', args.bodystyle, ';', args.style)
        else
            add('navbox-inner" style="border-spacing:0;background:transparent;color:inherit')
        end
        add(';', args.innerstyle, ';">')
        
        renderTitleRow(args)
        renderAboveRow(args)
        renderFirstListRow(args)
    
        -- render lists 2 through N
        for i, listnum in ipairs(listnums) do
            if listnum > 1 then
                renderNthListRow(args, listnum) 
            end
        end
    
        renderBelowRow(args)
    
        add('</table>')
        
        if border == 'subgroup' or border == 'child' then
            add('<div>')
        elseif border ~= 'none' then
            add('</td></tr></table>')
        end
    
        -- TODO: add tracking categories
        
        return table.concat(ret, '')
    end
    
    function p.navbox(frame)
        return p._navbox(frame:getParent().args)
    end
    
    return p