Module:Simple navbox/sandbox

From Uncyclopedia, the content-free encyclopedia
Jump to navigation Jump to search
local p = {}

-- Utilities
local ustring_lower = mw.ustring.lower
local function isNotEmpty(v)
    return v ~= nil and v ~= ''
end
local function lc(v)
    return type(v) == 'string' and ustring_lower(v) or v
end
local function getArg(args, ...)
    for i = 1, select('#', ...) do
        local k = select(i, ...)
        local v = args[k]
        if isNotEmpty(v) then return v end
    end
    return nil
end

-- Main entry point
function p.main(frame)
    local args = frame:getParent().args
    local out = {}

    -- Stylesheets
    table.insert(out, frame:extensionTag{ name = 'templatestyles', args = { src = 'Simple navbox/styles.css' } })
    table.insert(out, frame:extensionTag{ name = 'templatestyles', args = { src = 'Hlist/styles.css' } })
    if isNotEmpty(args.templatestyles) then
        table.insert(out, frame:extensionTag{ name = 'templatestyles', args = { src = args.templatestyles } })
    end

    -- Collapse logic
    local collapse = getArg(args, 'collapse', 'collapsible')
    local collapsible = not (lc(collapse) == 'no')
    local state = lc(args.state)

    -- Outer image
    local imageOuter = getArg(args, 'image-outer', 'imageouter')
    local hasOuter = isNotEmpty(imageOuter)

    -- Classes
    local bodyclass = getArg(args, 'bodyclass', 'class') or ''
    local classes = { 'simple-navbox', bodyclass, 'noprint' }
    if collapsible then
        classes[#classes+1] = 'NavFrame'
        if state == 'collapsed' then classes[#classes+1] = 'NavClosed' end
    elseif hasOuter then
        classes[#classes+1] = 'simple-outer'
    end

    -- Body style
    local bodystyle = args.bodystyle or ''
    out[#out+1] = string.format('<div class="%s" style="%s">', table.concat(classes, ' '), bodystyle)

    -- Outer image (non-collapsible)
    if not collapsible and hasOuter then
        out[#out+1] = string.format('<div class="simple-outer-image">%s</div>', imageOuter)
    end

    -- Header
    local headerstyle = getArg(args, 'headerstyle', 'titlestyle') or ''
    local headerClass = 'simple-header NavHead'
    if isNotEmpty(headerstyle) then headerClass = headerClass .. ' simple-header-modified' end
    local header = {}
    if isNotEmpty(args.name) then
        header[#header+1] = frame:expandTemplate{ title = 'simple navbar', args = { args.name } }
    end
    header[#header+1] = args.title or 'Default title: add a value for <code>title</code> in the template.'
    out[#out+1] = string.format('<div class="%s" style="%s">%s</div>', headerClass, headerstyle, table.concat(header))

    -- Nav content wrapper
    out[#out+1] = string.format('<div class="simple-navcontent NavContent" style="%s">', args.navcontentstyle or '')

    -- Above block
    if isNotEmpty(args.above) then
        out[#out+1] = string.format(
            '<div class="simple-group-above" style="%s">\n%s\n</div>',
            args.abovestyle or '',
            frame:preprocess(args.above)
        )
    end

    -- Flex container
    local imageAlign = getArg(args, 'image-align', 'imagealign')
    local flex = 'display:flex; flex-flow:row;'
    if lc(imageAlign) == 'left' then
        flex = 'display:flex; flex-flow:row-reverse; justify-content:flex-end;'
    end
    local containerstyle = args.containerstyle or ''
    out[#out+1] = string.format('<div class="simple-content-container" style="%s %s">', flex, containerstyle)

    -- Left image
    local imageLeft = getArg(args, 'image2', 'imageleft')
    local imageValign = getArg(args, 'image-valign', 'imagevalign') or 'center'
    if not hasOuter and isNotEmpty(imageLeft) then
        out[#out+1] = string.format('<div class="simple-image" style="align-self:%s">%s</div>', imageValign, imageLeft)
    end

    -- Content
    out[#out+1] = string.format('<div class="simple-content %s" style="%s">', args.listclass or '', args.contentstyle or '')

    -- Grouped mode
    if isNotEmpty(args.group1) then
        local hasGroupStyle = isNotEmpty(args.groupstyle) or isNotEmpty(args.oddgroupstyle) or isNotEmpty(args.evengroupstyle)
        local tableClass = 'simple-group-container' .. (hasGroupStyle and ' simple-group-modified' or '')
        out[#out+1] = string.format('<table class="%s" style="%s">', tableClass, args.tablestyle or '')

        -- Precompute styles once with safe defaults
        local oddGStyle, evenGStyle = '', ''
        local oddLStyle, evenLStyle = '', ''
        if isNotEmpty(args.groupstyle) or isNotEmpty(args.oddgroupstyle) or isNotEmpty(args.evengroupstyle) then
            oddGStyle = (args.groupstyle or '') .. (isNotEmpty(args.oddgroupstyle) and ';' .. args.oddgroupstyle or '')
            evenGStyle = (args.groupstyle or '') .. (isNotEmpty(args.evengroupstyle) and ';' .. args.evengroupstyle or '')
        end
        if isNotEmpty(args.liststyle) or isNotEmpty(args.oddliststyle) or isNotEmpty(args.evenliststyle) then
            oddLStyle = (args.liststyle or '') .. (isNotEmpty(args.oddliststyle) and ';' .. args.oddliststyle or '')
            evenLStyle = (args.liststyle or '') .. (isNotEmpty(args.evenliststyle) and ';' .. args.evenliststyle or '')
        end

        -- Collect non-empty lists
        local batchLists, groupIndices = {}, {}
        for i = 1, 50 do
            local group = args['group'..i]
            if isNotEmpty(group) then
                table.insert(batchLists, args['list'..i] or '')
                table.insert(groupIndices, i)
            end
        end

        -- Batch preprocess
        local preprocessedLists = {}
        if #batchLists > 0 then
            local sep = '@@SIMPLE_SEPARATOR@@'
            local concatenated = table.concat(batchLists, sep)
            local processed = frame:preprocess(concatenated)
            for part in mw.ustring.gmatch(processed, '(.-)'..sep) do
                table.insert(preprocessedLists, part)
            end
            if #preprocessedLists < #batchLists then
                table.insert(preprocessedLists, mw.ustring.match(processed, '.*'..sep..'(.*)') or batchLists[#batchLists])
            end
        end

        -- Output rows
        for idx, i in ipairs(groupIndices) do
            local group = args['group'..i]
            local listContent = preprocessedLists[idx] or ''
            local odd = (i % 2 == 1)
            local gstyle = (odd and oddGStyle or evenGStyle) .. ';' .. (args['group'..i..'style'] or '')
            local lstyle = (odd and oddLStyle or evenLStyle) .. ';' .. (args['list'..i..'style'] or '')

            out[#out+1] = string.format(
                '<tr class="simple-group-row" style="%s">'..
                '<td class="simple-group" style="%s">%s</td>'..
                '<td class="simple-list" style="%s">\n%s\n</td>'..
                '</tr>',
                args.rowstyle or '', gstyle, group, lstyle, listContent
            )
        end

        out[#out+1] = '</table>'
    else
        -- List-only mode
        local list = args.list or args.list1 or 'Error: <code>list</code> is empty!'
        if isNotEmpty(list) then list = frame:preprocess(list) end
        out[#out+1] = string.format('<div class="simple-list simple-list-only" style="%s">\n%s\n</div>', args.liststyle or '', list)
    end

    out[#out+1] = '</div>' -- simple-content

    -- Right image
    if not hasOuter and isNotEmpty(args.image) then
        out[#out+1] = string.format('<div class="simple-image" style="align-self:%s">%s</div>', imageValign, args.image)
    end

    out[#out+1] = '</div>' -- container

    -- Below block
    if isNotEmpty(args.below) then
        out[#out+1] = string.format(
            '<div class="simple-group-above simple-group-below" style="%s">\n%s\n</div>',
            args.belowstyle or args.abovestyle or '', frame:preprocess(args.below)
        )
    end

    out[#out+1] = '</div></div>'

    return table.concat(out)
end

return p