FANDOM


-- <nowiki>
--------------------------------------------------------------------------------
-- Creates the Navbox metatemplate.
--------------------------------------------------------------------------------
local Navbox = {}
 
local getArgs = require('Dev:Arguments').getArgs
local lseq = require('Module:HF').lettersequence
local expT = require('Module:HF').expandTemplate
 
-- Helper function that creates metatables in Lua that will be output as HTML
-- tables.
function Navbox.parse(args)
    local nav = {}
 
    nav.nested = not not (args[1] and args[1]:find('nested'))
    nav.editlink = args.editlink
    nav.above = args.above and {text = args.above} or false
    nav.below = args.below and {text = args.below} or false
    nav.position = args.position or 'bottom'
    nav.width = args.width or (nav.position == 'bottom' and '100%' or '200px')
    nav.class = args.class or 'series'
    nav.collapsible = true
    nav.collapsed = nav.position == 'bottom'
 
    -- Creates inheritance metatables allowing multiple styles and classes to
    -- pass to each Navbox element. Applies to entire Navbox.
    do
        nav.inherit = {}
        nav.inherit.__index = nav.inherit
 
        if args['meta class'] then
            nav.inherit.class = args['meta class'] or ''
        end
 
        nav.inherit.style = args['meta style'] or ''
        nav.inherit.block = {}
        nav.inherit.block.__index = nav.inherit.block
        setmetatable(nav.inherit.block, nav.inherit)
 
        if args['blocks class'] then
            nav.inherit.block.class = args['blocks class']
        end
 
        if args['blocks style'] then
            nav.inherit.block.style = nav.inherit.block.style .. ';' .. args['blocks style']
        end
 
        nav.inherit.block.collapsible = true
        nav.inherit.block.collapsed = false
        nav.inherit.block.columns = false
        nav.inherit.block.wraplinks = false
        nav.inherit.block.normallists = false
        nav.inherit.content = {}
        nav.inherit.content.__index = nav.inherit.content
        setmetatable(nav.inherit.content, nav.inherit)
 
        if args['contents class'] then
            nav.inherit.content.class = args['contents class']
        end
 
        if args['contents style'] then
            nav.inherit.content.style = nav.inherit.content.style .. ';' .. args['contents style']
        end
 
        nav.inherit.group = {}
        nav.inherit.group.__index = nav.inherit.group
        setmetatable(nav.inherit.group, nav.inherit)
 
        if args['groups class'] then
            nav.inherit.group.class = args['groups class']
        end
 
        if args['groups style'] then
            nav.inherit.group.style = nav.inherit.group.style .. ';' .. args['groups style']
        end
 
        nav.inherit.header = {}
        nav.inherit.header.__index = nav.inherit.header
        setmetatable(nav.inherit.header, nav.inherit)
 
        if args['headers class'] then
            nav.inherit.header.class = args['headers class']
        end
 
        if args['headers style'] then
            nav.inherit.header.style = nav.inherit.header.style .. ';' .. args['headers style']
        end
 
        nav.title = {}
        setmetatable(nav.title, nav.inherit)
        mw.log(nav.title.style)
        nav.title.text = args.title or 'Title?'
 
        if args['title class'] then
            nav.title.class = args['title class']
        end
 
        if args['title style'] then
            nav.title.style = nav.title.style .. ';' .. args['title style']
        end
 
        if nav.above then
            setmetatable(nav.above, nav.inherit)
            if args['above class'] then
                nav.above.class = args['above class']
            end
 
            if args['above style'] then
                nav.above.style = nav.above.style .. ';' .. args['above style']
            end
        end
 
        if nav.below then
            setmetatable(nav.below, nav.inherit)
            if args['below class'] then
                nav.below.class = args['below class']
            end
 
            if args['below style'] then
                nav.below.style = nav.below.block.style .. ';' .. args['below style']
            end
        end
    end
 
    -- Creates an options parameter. Options are:
    --     collapsible (collapsed and collapsible by default)
    --     collapsible groups (collapsible and uncollapsed by default)
    --     columns (false by default)
    --     list types
    do
        local opt = ',' .. string.gsub(args.options or '', ' ', '') .. ','
 
        if string.find(opt, ',nocollapse,') then
            nav.collapsible = false
            nav.collapsed = false
        elseif string.find(opt, ',collapsed,') then
            nav.collapsed = true
        elseif string.find(opt, ',uncollapsed,') then
            nav.collapsed = false
        end
 
        if string.find(opt, ',uncollapsiblegroups,') then
            nav.inherit.block.collapsible = false
            nav.inherit.block.collapsed = false
        elseif string.find(opt, ',collapsedgroups,') then
            nav.inherit.block.collapsed = true
        end
 
        if string.find(opt, ',columns,') then
            nav.inherit.block.columns = true
        end
 
        if string.find(opt, ',normallists,') then
            nav.inherit.block.normallists = true
        end
 
        if string.find(opt, ',wraplinks,') then
            nav.inherit.block.wraplinks = true
        end
    end
 
    -- Creates an array for blocks.
    nav.blocks = {}
    i = 1
 
    while true do
        local l = lseq(i)
 
        if not (args['content' .. l .. '1'] or args['nested' .. l] or args['nestedplain' .. l]) then
            break
        end
 
        local blk = {}
 
        -- Creating inheritance metatables for block content. Applies only to
        -- that block.
        blk.header = args['block' .. l] and {text = args['block' .. l]} or false
        blk.title = args['header' .. l] and {text = args['header' .. l]} or false
        setmetatable(blk, nav.inherit.block)
        blk.inherit = {}
        blk.inherit.__index = blk.inherit
        setmetatable(blk.inherit, nav.inherit.block)
 
        if args[l .. ' class'] then
            blk.inherit.class = args['contents' .. l .. ' class']
        end
 
        if args[l .. ' style'] then
            blk.inherit.style = blk.inherit.style .. ';' .. args['contents' .. l .. ' style']
        end
 
        blk.inherit.content = {}
        blk.inherit.content.__index = blk.inherit.content
        setmetatable(blk.inherit.content, nav.inherit.content)
 
        if args['contents' .. l .. ' class'] then
            blk.inherit.content.class = args['contents' .. l .. ' class']
        end
 
        if args['contents' .. l .. ' style'] then
            blk.inherit.content.style = blk.inherit.content.style .. ';' .. args['contents' .. l .. ' style']
        end
 
        blk.inherit.group = {}
        blk.inherit.group.__index = blk.inherit.group
        setmetatable(blk.inherit.group, nav.inherit.group)
 
        if args['groups' .. l .. ' class'] then
            blk.inherit.group.class = args['groups' .. l .. ' class']
        end
 
        if args['groups' .. l .. ' style'] then
            blk.inherit.group.style = nav.inherit.group.style .. ';' .. args['groups' .. l .. ' style']
        end
 
        if blk.title then
            setmetatable(blk.title, nav.inherit.header)
 
            if args['header' .. l .. ' class'] then
                blk.title.class = args['header' .. l .. ' class']
            end
 
            if args['header' .. l .. ' style'] then
                blk.title.style = blk.title.style .. ';' .. args['header' .. l .. ' style']
            end
        end
 
        if blk.header then
            setmetatable(blk.header, nav.inherit.header)
 
            if args['block' .. l .. ' class'] then
                blk.header.class = args['block' .. l .. ' class']
            end
 
            if args['block' .. l .. ' style'] then
                blk.header.style = blk.header.style .. ';' .. args['block' .. l .. ' style']
            end
        end
 
        blk.nest = args['nested' .. l] and frame:expandTemplate({title = args['nested' .. l], args =  {'nested'}}) or (args['nestedplain' .. l] or false)
 
        do
            local opt = ',' .. string.gsub(args['options' .. l] or '', ' ', '') .. ','
 
            if string.find(opt, ',nocollapse,') then
                blk.collapsible = false
                blk.collapsed = false
            elseif string.find(opt, ',collapsed,') then
                blk.collapsed = true
            elseif string.find(opt, ',uncollapsed,') then
                blk.collapsed = false
            end
 
            if string.find(opt, ',columns,') then
                blk.columns = true
            end
 
            if string.find(opt, ',normallists,') then
                blk.normallists = true
            end
 
            if string.find(opt, ',wraplinks,') then
                blk.wraplinks = true
            end
        end
 
        -- Creates inheritance for and defines groups and their contents within
        -- Navbox blocks. Applies only to the groups.
        blk.groups = {}
 
        local j = 1
 
        while true do
            local k = l .. j
 
            if not args['content' .. k] then
                break
            end
 
            grp = {}
            setmetatable(grp, nav.inherit.group)
            grp.header = args['group' .. k] and {text = args['group' .. k]} or false
 
            if grp.header then
                setmetatable(grp.header, blk.inherit.group)
            end
 
            if args['group' .. k .. ' class'] then
                grp.header.class = args['group' .. k .. ' class']
            end
 
            if args['group' .. k .. ' style'] then
                grp.header.style = grp.header.style .. ';' .. args['group' .. k .. ' style']
            end
 
            grp.content = args['content' .. k] and {text = args['content' .. k]} or false
 
            if grp.content then
                setmetatable(grp.content, blk.inherit.content)
            end
 
            if args['content' .. k .. ' class'] then
                grp.content.class = args['content' .. k .. ' class']
            end
 
            if args['content' .. k .. ' style'] then
                grp.content.style = grp.content.style .. ';' .. args['content' .. k .. ' style']
            end
 
            table.insert(blk.groups, grp)
            j = j + 1
        end
 
        table.insert(nav.blocks, blk)
        i = i + 1
    end
 
    return nav
end
 
-- A function that converts Lua tables into HTML.
function Navbox.render(nav)
    function spaceV(col, tag)
        if tag then
            return mw.html.create(tag)
                :addClass('space-v')
        end
 
        return mw.html.create('tr')
            :addClass('space-v')
            :tag('td')
                :attr('colspan', col or 1)
                :done()
    end
 
    function spaceH(row)
        return mw.html.create('td')
            :addClass('space-h')
            :attr('rowspan', row or 1)
    end
 
    -- Converts Lua to HTML for the outer Navbox.
    local container = mw.html.create('div')
        :addClass('navbox-container')
        :css('width', nav.width)
 
    local main = container:tag('div')
        :addClass('navbox')
 
    local title = main:tag('div')
        :addClass('title')
        :addClass('header')
        :cssText(nav.title.style)
 
    local contents = main:tag('table')
 
    if ({left = true, right = true, bottom = true})[nav.position] then
        container:addClass(nav.position)
    end
 
    if nav.editlink then
        container:attr('id', nav.editlink .. '-nav')
        title:tag('div')
            :addClass('editlink')
            :wikitext(expT({title = 'tnav', args = {nav.editlink}}))
    end
 
    if nav.nested then
        main:addClass('nested')
    else
        title:addClass('maintitle')
    end
 
    if nav.collapsible then
        main
            :addClass('collapsible')
            :addClass('slide')
    end
 
    if nav.collapsed then
        main:addClass('collapsed')
    end
 
    if nav.title.class then
        title
            :addClass(nav.title.class)
            :addClass('a')
    else
        local _foo_ = nav.blocks[1] and nav.blocks[1].nest or false
        local class_suffix = (not nav.nested or _foo_) and 'a' or 'b'
 
        title
            :addClass(nav.class)
            :addClass(class_suffix)
    end
 
    title:tag('div')
        :addClass('titletext')
        :wikitext(nav.title.text)
 
    contents
        :addClass('contents')
        :attr('cellpadding', '0')
        :attr('cellspacing', '0')
 
    -- Converts Lua to HTML for above.
    if nav.above then
        contents
            :node(spaceV())
            :tag('tr')
                :tag('td')
                    :addClass('abovebelow')
                    :addClass(nav.above.class and nav.above.class or nav.class)
                    :addClass(nav.above.class and 'a' or 'b')
                    :wikitext(nav.above.text)
    end
 
    -- Converts Lua to HTML for blocks.
    local blocksarray = contents:tag('tr')
        :tag('td')
            :addClass('brickcont')
 
    for _, block in ipairs(nav.blocks) do
        blocksarray:node(spaceV(1, 'div'))
 
        if block.nest then
            blocksarray:wikitext(block.nest)
        else
            local blockcontainer = blocksarray:tag('div')
                :addClass(block.columns and 'colcont' or 'standardcont')
 
            if block.title then
                blockcontainer
                    :tag('div')
                        :addClass('navheader')
                        :addClass('header')
                        :addClass(block.title.class and block.title.class or nav.class)
                        :addClass(block.title.class and 'a' or 'b')
                        :cssText(block.title.style)
                        :tag('div')
                            :addClass('headertext')
                            :wikitext(block.title.text)
                            :done()
                        :done()
                    :node(spaceV(1, 'div'))
 
                if block.collapsible then
                    blockcontainer
                        :addClass('collapsible')
                        :addClass('slide')
                end
 
                if block.collapsed then
                    blockcontainer:addClass('collapsed')
                end
            end
 
            if not block.normallists then
                blockcontainer:addClass('formatlist')
            end
 
            if not block.wraplinks then
                blockcontainer:addClass('nowraplinks')
            end
 
            local blocktable = blockcontainer:tag('table')
                :addClass('brick')
                :attr('cellpadding', '0')
                :attr('cellspacing', '0')
 
            -- Begins a table, for which all contents of the block will be
            -- contained.
            local tbl = {rows = {}}
 
            -- If the block is a column block, makes calculations for column
            -- Navbox block rows and contents.
            local gHeadEx = false
 
            if block.header then
                tbl.header = mw.html.create('th')
                    :addClass('group')
                    :cssText(block.header.style)
                    :wikitext(block.header.text)
 
                if block.header.class then
                    tbl.header
                        :addClass(block.header.class)
                        :addClass('a')
                elseif nav.blocks.header and nav.blocks.header.class then
                    tbl.header
                        :addClass(nav.blocks.header.class)
                        :addClass('b')
                else
                    tbl.header
                        :addClass(nav.class)
                        :addClass('b')
                end
            end
 
            -- Converts Lua to HTML for groups.
            for _, group in ipairs(block.groups) do
                local row = {}
 
                if group.header then
                    gHeadEx = true
 
                    row.header = mw.html.create('th')
                        :addClass((block.columns and 'col' or (group.header and 'sub' or '')) .. 'group')
                        :cssText(group.header.style)
                        :wikitext(group.header.text)
 
                    if group.header.class then
                        row.header
                            :addClass(group.header.class)
                            :addClass('a')
                    elseif block.header and block.header.class then
                        row.header
                            :addClass(block.header.class)
                            :addClass('b')
                    elseif block.title and block.title.class then
                        row.header
                            :addClass(block.title.class)
                            :addClass('b')
                    else
                        row.header
                            :addClass(nav.class)
                            :addClass('b')
                    end
                end
 
                row.content = mw.html.create('td')
                    :addClass(block.columns and 'navcol' or 'cell')
                    :wikitext('\n' .. group.content.text)
                    :cssText(group.content.style)
 
                if group.content.class then
                    row.content
                        :addClass(group.content.class)
                        :addClass('a')
                end
 
                table.insert(tbl.rows, row)
            end
 
            if block.columns then
                local hTr = gHeadEx and mw.html.create('tr') or nil
                local cTr = mw.html.create('tr')
                local rows = hTr and 3 or 1
                local cols = #tbl.rows + (tbl.header and 1 or 0)
                local wid = math.floor(100 / cols)
 
                if hTr then
                    blocktable
                        :node(hTr)
                        :node(spaceV((cols * 2) - 1))
                end
 
                blocktable:node(cTr)
 
                if tbl.header then
                    (hTr or cTr)
                        :node(tbl.header)
                        :node(spaceH(rows))
                    tbl.header:attr('rowspan', rows)
                    tbl.header:css('width', wid .. '%')
                end
 
                for k = 1, #tbl.rows do
                    if k ~= 1 then
                        (hTr or cTr):node(spaceH(rows))
                    end
 
                    if hTr then
                        if tbl.rows[k].header then
                            hTr:node(tbl.rows[k].header)
                        else
                            hTr:tag('td')
                        end
                    end
 
                    tbl.rows[k].content:css('width', wid .. '%')
                    cTr:node(tbl.rows[k].content)
                end
            else
                local cols = 1 + (tbl.header and 1 or 0) + (gHeadEx and 1 or 0)
 
                for k = 1, #tbl.rows do
                    contentcols = 1
                    local tr = mw.html.create('tr')
 
                    if k ~= 1 then
                        blocktable:node(spaceV())
                    end
 
                    blocktable:node(tr)
 
                    if k == 1 and tbl.header then
                        tr
                            :node(tbl.header)
                            :node(spaceH((#tbl.rows * 2) - 1))
                        tbl.header:attr('rowspan', (#tbl.rows * 2) - 1)
                    end
 
                    if tbl.rows[k].header then
                        tr
                            :node(tbl.rows[k].header)
                            :node(spaceH())
                    else
                        contentcols = contentcols + 1
                    end
 
                    tr:node(tbl.rows[k].content)
                    tbl.rows[k].content
                        :attr('colspan', (contentcols * 2) - 1)
                        :addClass(((tbl.header or tbl.rows[k].header) and 'with' or 'no') .. 'groups')
                end
            end
        end
    end
 
    -- Converts Lua to HTML for below.
    if nav.below then
        contents
            :node(spaceV())
            :tag('tr')
                :tag('td')
                    :addClass('abovebelow')
                    :addClass(nav.below.class and nav.below.class or nav.class)
                    :addClass(nav.below.class and 'a' or 'b')
                    :wikitext(nav.below.text)
    end
 
    return nav.nested and tostring(main) or tostring(container)
end
 
-- Function that returns the output of all Navbox functions and ultimately
-- displays the Navbox.
function Navbox.main(frame)
    local args = getArgs(frame)
    local nav = Navbox.parse(args)
 
    return Navbox.render(nav)
end
 
return Navbox
-- </nowiki>
I contenuti della comunità sono disponibili sotto la licenza CC-BY-SA a meno che non sia diversamente specificato.