Module:Navboxdl

From Guild of Archivists
Revision as of 18:48, 12 October 2020 by Alahmnat (talk | contribs) (Add newline after lists so that MW generates ul tags properly, hopefully fixing styling issues with nested lists in rows after the first row)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

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

-- <nowiki>
-- Implements {{navboxdl}}
-- Taken from http://camtest.wikia.com/wiki/Module:Navbox
--
--

--
-- - Things to implement -                                  || - Done (✗/✓) -
-- * name                                                       ✓
-- * state  [autocollapse, collapsed, expanded, plain, off]     ✓
-- * navbar [plain, off]                                        ✓
-- * border [child, subgroup, none(?)]                          ✓
-- * title                                                      ✓
-- * above                                                      ✗
-- * group(n)                                                   ✓
-- * list(n)                                                    ✓
-- * image                                                      ✗
-- * imageleft                                                  ✗
-- * below                                                      ✗
-- * bodystyle                                                  ✗
-- * basestyle                                                  ✗
-- * titlestyle                                                 ✗
-- * groupstyle                                                 ✗
-- * group(n)style                                              ✗
-- * groupwidth                                                 ✗
-- * liststyle                                                  ✗
-- * listnstyle                                                 ✗
-- * listpadding                                                ✗
-- * oddstyle                                                   ✗
-- * evenstyle                                                  ✗
-- * evenodd [swap, even, odd, off]                             ✗
-- * bodyclass                                                  ✗
-- * aboveclass                                                 ✗
-- * groupclass                                                 ✗
-- * listclass                                                  ✓
-- * belowclass                                                 ✗
-- * titlegroup                                                 ✗
-- * titlegroupstyle                                            ✗
-- * innerstyle                                                 ✗
-- * bodyclass                                                  ✓
-- * titleclass                                                 ✓

local p = {}
local args
local navbar = require('Module:Navbar')._navbar

-- set default expand/collapse messages
--
-- these aren't hardcoded in so it can be changed if it was imported as a global module
-- @example local n = require('Module:Navbox')
--          n.collapsetext = 'foo'
--          return n
p.collapsetext = 'hide'
p.expandtext = 'show'

--
-- <docs>
--
local function navbody(args)
    local body = mw.html.create('dl'):addClass('nav-def-list')
    local list, group, desc, rows, parent, term
    local j = 0

    if args.border ~= 'child' then
        body
            :addClass('mw-collapsible-content')
            -- <http://www.w3.org/TR/wai-aria/roles#navigation>
            :attr('role', 'navigation')
    else
        body:addClass('nav-subgroup')
    end

    -- @todo check if this limit be increased
    for i = 1, 20 do
        list = args['list' .. i]
        group = args['group' .. i]

        if not list then
            break
        end

        -- track number of rows
        j = j + 1

        if string.find(list, 'nav%-subgroup') then
            parent = true
            rows = tonumber(string.match(list, 'data%-rows="(%d+)"'))
        else
            parent = false
        end

        if group then
            term = body
                :tag('dt')
                    :addClass('nav-term')
                    :tag('span')
                        :addClass('nav-term-inner')
                        :wikitext(group)
                        :done()

            if parent == true then
                term
                    :addClass('nav-subgroup-parent-term')
            end

            body = term:done()
        end

        desc = body
            :tag('dd')
                :addClass('nav-desc')
                :addClass(args.listclass)

        -- add a class for CSS to hook off for full width
        if not group then
            desc:addClass('no-term')
        end

        -- If the list text is a MediaWiki list,
        -- add a newline before and after the text,
        -- so that the list is correctly recognized by the MediaWiki parser.
        -- only support url and ol at the moment
        -- add ; and : when CSS supports it
        local isList = string.find(list, '^[%*#]')
        if isList then
            desc:newline()
        end

        if parent == true then
            desc:addClass('nav-subgroup-parent-desc')
        end

        desc:wikitext(list)

        if isList then
            desc:newline()
        end

        body = desc:done()
    end

    return body
        -- store number of rows
        :attr('data-rows', tostring(j))
        :done()
end

local function renderNavBar(titleCell)

	if args.navbar ~= 'off' and args.navbar ~= 'plain' and not (not args.name and mw.getCurrentFrame():getParent():getTitle():gsub('/sandbox$', '') == 'Template:Navbox') then
		titleCell:wikitext(navbar{
			args.name,
			mini = 1,
			fontstyle = (args.basestyle or '') .. ';' .. (args.titlestyle or '') .. ';background:none transparent;border:none;-moz-box-shadow:none;-webkit-box-shadow:none;box-shadow:none;'
		})
	end

end

-- export for testing
p.navbody = navbody

-- {{navbox subgroup}}
-- {{navbox|border=child}}
-- 
function p.subgroup(frame)
    local args = frame:getParent().args
    args.border = 'child'
    return navbody(args)
end

--
-- {{navbox}}
--
function p.main(frame)
    args = frame:getParent().args
    local child_borders = {
        child = true,
        border = true
    }

    -- subgroup handling
    if
        child_borders[args.border] or
        -- unnamed args keep whitespace (or is it the other way around?)
        child_borders[mw.text.trim(args[1] or '')]
    then
        return p.subgroup(frame)
    end

    -- create initial navbox container
    local navbox = mw.html.create('div')
        :addClass('navbox')
        -- @todo remove once mw.html accepts nil args
        :addClass(args.bodyclass or '')
    -- define states that collapse here
    -- can't be created on the fly within a conditonal for some reason
    local collapse_states = {
        autocollapse = true,
        collapsed = true,
        exanded = true
    }
        
    if collapse_states[args.state] then
        navbox
            :addClass('mw-collapsible')
            :attr({
                ['data-collapsetext'] = p.collapsetext,
                ['data-expandtext'] = p.expandtext
            })
        
        if args.state == 'collapsed' then
            navbox:addClass('mw-collapsed')
        end
        
        if args.state == 'autocollapse' then
            navbox:addClass('autocollapse')
        end
    -- class to hook off
    elseif state == 'off' then
        navbox:addClass('off')
    end

    -- insert header
    local header = mw.html.create('div')
        :addClass('nav-header-wrap')
        :done()

    renderNavBar(header)

    header
        :tag('div')
            :addClass('nav-header')
            -- @todo remove once mw.html accepts nil args
            :addClass(args.titleclass or '')
            :wikitext(args.title or '{{{title}}}')
            :done()

    navbox
        :node(header)
        :done()

    navbox
        :node(navbody(args))
        :allDone()

    return tostring( navbox )
end

return p