Module:Accordion

From Coral Island Wiki
Jump to navigation Jump to search

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

local getArgs = require('Dev:Arguments').getArgs
local p = {}
function p.main(frame)
    local args = getArgs(frame)
    local types = {
        text = 'text',
        links = 'links',
    }
    local hasTypeMismatch = false
    local accordionsType = types[args.type] or 'text'
    local wrapper = mw.html.create('div'):addClass('accordions__wrapper'):attr({
        ['data-accordions-type'] = accordionsType,
        ['data-animation-duration'] = tonumber(args['animation-duration'])
    })
    local accordions = {}
    local patterns = {
        'accordion%-(%d+)%-(title)',
        'accordion%-(%d+)%-(contents)',
        'accordion%-(%d+)%-(link)%-(%d+)',
    }
    for k, v in pairs(args) do
        local index, thing, subIndex
        for _, pattern in ipairs(patterns) do
            index, thing, subIndex = k:match(pattern)
            if index then break end -- found the pattern
        end
        -- Ensure indices are numeric.
        index = tonumber(index)
        subIndex = tonumber(subIndex)
        if index then
            if (
                accordionsType == 'links' and thing == 'contents' or
                accordionsType == 'text' and thing == 'link'
            ) then
                hasTypeMismatch = true
            end
            accordions[index] = accordions[index] or {}
            if subIndex then
                accordions[index][thing] = accordions[index][thing] or {}
                accordions[index][thing][subIndex] = v
            else
                accordions[index][thing] = v
            end
        end
    end
    -- TODO: Maybe log the indices of accordions with mismatched type?
    if hasTypeMismatch then
        mw.log('Warning: Accordion contains mixed types. Mismatched types will be ignored.')
    end
    for i, v in ipairs(accordions) do
        local title = v.title
        local contents = v.contents
        local links = v.link
        -- BUG: Expanded argument doesn't work.
        local expanded = v.expanded or 'false'
        if title or contents or links then
            local accordion = wrapper:tag('div')
                :addClass('accordion')
            accordion:tag('div')
                :addClass('accordion--header')
                :attr('data-aria-expanded', expanded)
                :wikitext(title)
            local contentsDiv = accordion:tag('div')
                :addClass('accordion--panel')
            if accordionsType == 'links' and links then
                contentsDiv:addClass('accordion__links--panel')
                local ul = contentsDiv:tag('ul')
                for _, link in ipairs(links) do
                    ul:tag('li')
                        :wikitext(link)
                end
            elseif accordionsType == 'text' and contents then
                contentsDiv:wikitext(contents)
            end
        end
    end
    return tostring(wrapper)
end
return p