Line 9: |
Line 9: |
| | | |
| local args | | local args |
− | local tableRowAdded = false
| |
| local border | | local border |
− | local listnums = {} | + | local listnums |
| + | local ODD_EVEN_MARKER = '\127_ODDEVEN_\127' |
| + | local RESTART_MARKER = '\127_ODDEVEN0_\127' |
| + | local REGEX_MARKER = '\127_ODDEVEN(%d?)_\127' |
| | | |
− | local function trim(s) | + | local function striped(wikitext) |
− | return (mw.ustring.gsub(s, "^%s*(.-)%s*$", "%1"))
| + | -- Return wikitext with markers replaced for odd/even striping. |
| + | -- Child (subgroup) navboxes are flagged with a category that is removed |
| + | -- by parent navboxes. The result is that the category shows all pages |
| + | -- where a child navbox is not contained in a parent navbox. |
| + | local orphanCat = '[[Category:Navbox orphans]]' |
| + | if border == 'subgroup' and args.orphan ~= 'yes' then |
| + | -- No change; striping occurs in outermost navbox. |
| + | return wikitext .. orphanCat |
| + | end |
| + | local first, second = 'odd', 'even' |
| + | if args.evenodd then |
| + | if args.evenodd == 'swap' then |
| + | first, second = second, first |
| + | else |
| + | first = args.evenodd |
| + | second = first |
| + | end |
| + | end |
| + | local changer |
| + | if first == second then |
| + | changer = first |
| + | else |
| + | local index = 0 |
| + | changer = function (code) |
| + | if code == '0' then |
| + | -- Current occurrence is for a group before a nested table. |
| + | -- Set it to first as a valid although pointless class. |
| + | -- The next occurrence will be the first row after a title |
| + | -- in a subgroup and will also be first. |
| + | index = 0 |
| + | return first |
| + | end |
| + | index = index + 1 |
| + | return index % 2 == 1 and first or second |
| + | end |
| + | end |
| + | local regex = orphanCat:gsub('([%[%]])', '%%%1') |
| + | return (wikitext:gsub(regex, ''):gsub(REGEX_MARKER, changer)) -- () omits gsub count |
| end | | end |
| | | |
− | local function addNewline(s) | + | local function processItem(item, nowrapitems) |
− | if s:match('^[*:;#]') or s:match('^{|') then
| + | if item:sub(1, 2) == '{|' then |
− | return '\n' .. s ..'\n'
| + | -- Applying nowrap to lines in a table does not make sense. |
− | else
| + | -- Add newlines to compensate for trim of x in |parm=x in a template. |
− | return s
| + | return '\n' .. item ..'\n' |
− | end
| + | end |
− | end
| + | if nowrapitems == 'yes' then |
− | | + | local lines = {} |
− | local function addTableRow(tbl)
| + | for line in (item .. '\n'):gmatch('([^\n]*)\n') do |
− | -- If any other rows have already been added, then we add a 2px gutter row.
| + | local prefix, content = line:match('^([*:;#]+)%s*(.*)') |
− | if tableRowAdded then
| + | if prefix and not content:match('^<span class="nowrap">') then |
− | tbl
| + | line = prefix .. '<span class="nowrap">' .. content .. '</span>' |
− | :tag('tr')
| + | end |
− | :css('height', '2px')
| + | table.insert(lines, line) |
− | :tag('td')
| + | end |
− | :attr('colspan',2)
| + | item = table.concat(lines, '\n') |
− | end
| + | end |
− | | + | if item:match('^[*:;#]') then |
− | tableRowAdded = true
| + | return '\n' .. item ..'\n' |
− | | + | end |
− | return tbl:tag('tr')
| + | return item |
| end | | end |
| | | |
| local function renderNavBar(titleCell) | | local function renderNavBar(titleCell) |
− | -- Depending on the presence of the navbar and/or show/hide link, we may need to add a spacer div on the left
| |
− | -- or right to keep the title centered.
| |
− | local spacerSide = nil
| |
| | | |
− | if args.navbar == 'off' then
| + | if args.navbar ~= 'off' and args.navbar ~= 'plain' and not (not args.name and mw.getCurrentFrame():getParent():getTitle():gsub('/sandbox$', '') == 'Template:Navbox') then |
− | -- No navbar, and client wants no spacer, i.e. wants the title to be shifted to the left. If there's
| + | titleCell:wikitext(navbar{ |
− | -- also no show/hide link, then we need a spacer on the right to achieve the left shift.
| + | args.name, |
− | if args.state == 'plain' then spacerSide = 'right' end
| + | mini = 1, |
− | elseif args.navbar == 'plain' or (not args.name and mw.getCurrentFrame():getParent():getTitle():gsub('/sandbox$', '') == 'Template:Navbox') then
| + | fontstyle = (args.basestyle or '') .. ';' .. (args.titlestyle or '') .. ';background:none transparent;border:none;-moz-box-shadow:none;-webkit-box-shadow:none;box-shadow:none; padding:0;' |
− | -- No navbar. Need a spacer on the left to balance out the width of the show/hide link.
| + | }) |
− | if args.state ~= 'plain' then spacerSide = 'left' end
| + | end |
− | else
| |
− | -- Will render navbar (or error message). If there's no show/hide link, need a spacer on the right
| |
− | -- to balance out the width of the navbar.
| |
− | if args.state == 'plain' then spacerSide = 'right' end
| |
| | | |
− | titleCell:wikitext(navbar{
| |
− | args.name,
| |
− | mini = 1,
| |
− | fontstyle = (args.basestyle or '') .. ';' .. (args.titlestyle or '') .. ';background:none transparent;border:none;'
| |
− | })
| |
− | end
| |
− |
| |
− | -- Render the spacer div.
| |
− | if spacerSide then
| |
− | titleCell
| |
− | :tag('span')
| |
− | :css('float', spacerSide)
| |
− | :css('width', '6em')
| |
− | :wikitext(' ')
| |
− | end
| |
| end | | end |
| | | |
Line 78: |
Line 95: |
| -- | | -- |
| local function renderTitleRow(tbl) | | local function renderTitleRow(tbl) |
− | if not args.title then return end
| + | if not args.title then return end |
| | | |
− | local titleRow = addTableRow(tbl)
| + | local titleRow = tbl:tag('tr') |
| | | |
− | if args.titlegroup then
| + | if args.titlegroup then |
− | titleRow
| + | titleRow |
− | :tag('th')
| + | :tag('th') |
− | :attr('scope', 'row')
| + | :attr('scope', 'row') |
− | :addClass('navbox-group')
| + | :addClass('navbox-group') |
− | :addClass(args.titlegroupclass)
| + | :addClass(args.titlegroupclass) |
− | :cssText(args.basestyle)
| + | :cssText(args.basestyle) |
− | :cssText(args.groupstyle)
| + | :cssText(args.groupstyle) |
− | :cssText(args.titlegroupstyle)
| + | :cssText(args.titlegroupstyle) |
− | :wikitext(args.titlegroup)
| + | :wikitext(args.titlegroup) |
− | end
| + | end |
| | | |
− | local titleCell = titleRow:tag('th'):attr('scope', 'col')
| + | local titleCell = titleRow:tag('th'):attr('scope', 'col') |
| | | |
− | if args.titlegroup then
| + | if args.titlegroup then |
− | titleCell
| + | titleCell |
− | :css('border-left', '2px solid #fdfdfd')
| + | :css('border-left', '2px solid #fdfdfd') |
− | :css('width', '100%')
| + | :css('width', '100%') |
− | end
| + | end |
| | | |
− | local titleColspan = 2
| + | local titleColspan = 2 |
− | if args.imageleft then titleColspan = titleColspan + 1 end
| + | if args.imageleft then titleColspan = titleColspan + 1 end |
− | if args.image then titleColspan = titleColspan + 1 end
| + | if args.image then titleColspan = titleColspan + 1 end |
− | if args.titlegroup then titleColspan = titleColspan - 1 end
| + | if args.titlegroup then titleColspan = titleColspan - 1 end |
| | | |
− | titleCell
| + | titleCell |
− | :cssText(args.basestyle)
| + | :cssText(args.basestyle) |
− | :cssText(args.titlestyle)
| + | :cssText(args.titlestyle) |
− | :addClass('navbox-title')
| + | :addClass('navbox-title') |
− | :attr('colspan', titleColspan)
| + | :attr('colspan', titleColspan) |
| | | |
− | renderNavBar(titleCell)
| + | renderNavBar(titleCell) |
| | | |
− | titleCell
| + | titleCell |
− | :tag('div')
| + | :tag('div') |
− | :addClass(args.titleclass)
| + | -- id for aria-labelledby attribute |
− | :css('font-size', '114%')
| + | :attr('id', mw.uri.anchorEncode(args.title)) |
− | :wikitext(addNewline(args.title))
| + | :addClass(args.titleclass) |
| + | :css('font-size', '114%') |
| + | :css('margin', '0 4em') |
| + | :wikitext(processItem(args.title)) |
| end | | end |
| | | |
Line 127: |
Line 147: |
| | | |
| local function getAboveBelowColspan() | | local function getAboveBelowColspan() |
− | local ret = 2
| + | local ret = 2 |
− | if args.imageleft then ret = ret + 1 end
| + | if args.imageleft then ret = ret + 1 end |
− | if args.image then ret = ret + 1 end
| + | if args.image then ret = ret + 1 end |
− | return ret
| + | return ret |
| end | | end |
| | | |
| local function renderAboveRow(tbl) | | local function renderAboveRow(tbl) |
− | if not args.above then return end
| + | if not args.above then return end |
| | | |
− | addTableRow(tbl)
| + | tbl:tag('tr') |
− | :tag('td')
| + | :tag('td') |
− | :addClass('navbox-abovebelow')
| + | :addClass('navbox-abovebelow') |
− | :addClass(args.aboveclass)
| + | :addClass(args.aboveclass) |
− | :cssText(args.basestyle)
| + | :cssText(args.basestyle) |
− | :cssText(args.abovestyle)
| + | :cssText(args.abovestyle) |
− | :attr('colspan', getAboveBelowColspan())
| + | :attr('colspan', getAboveBelowColspan()) |
− | :tag('div')
| + | :tag('div') |
− | :wikitext(addNewline(args.above))
| + | -- id for aria-labelledby attribute, if no title |
| + | :attr('id', args.title and nil or mw.uri.anchorEncode(args.above)) |
| + | :wikitext(processItem(args.above, args.nowrapitems)) |
| end | | end |
| | | |
| local function renderBelowRow(tbl) | | local function renderBelowRow(tbl) |
− | if not args.below then return end
| + | if not args.below then return end |
| | | |
− | addTableRow(tbl)
| + | tbl:tag('tr') |
− | :tag('td')
| + | :tag('td') |
− | :addClass('navbox-abovebelow')
| + | :addClass('navbox-abovebelow') |
− | :addClass(args.belowclass)
| + | :addClass(args.belowclass) |
− | :cssText(args.basestyle)
| + | :cssText(args.basestyle) |
− | :cssText(args.belowstyle)
| + | :cssText(args.belowstyle) |
− | :attr('colspan', getAboveBelowColspan())
| + | :attr('colspan', getAboveBelowColspan()) |
− | :tag('div')
| + | :tag('div') |
− | :wikitext(addNewline(args.below))
| + | :wikitext(processItem(args.below, args.nowrapitems)) |
| end | | end |
| | | |
Line 164: |
Line 186: |
| -- List rows | | -- List rows |
| -- | | -- |
− | local function renderListRow(tbl, listnum) | + | local function renderListRow(tbl, index, listnum) |
− | local row = addTableRow(tbl)
| + | local row = tbl:tag('tr') |
| | | |
− | if listnum == 1 and args.imageleft then
| + | if index == 1 and args.imageleft then |
− | row
| + | row |
− | :tag('td')
| + | :tag('td') |
− | :addClass('navbox-image')
| + | :addClass('navbox-image') |
− | :addClass(args.imageclass)
| + | :addClass(args.imageclass) |
− | :css('width', '0%')
| + | :css('width', '1px') -- Minimize width |
− | :css('padding', '0px 2px 0px 0px')
| + | :css('padding', '0px 2px 0px 0px') |
− | :cssText(args.imageleftstyle)
| + | :cssText(args.imageleftstyle) |
− | :attr('rowspan', 2 * #listnums - 1)
| + | :attr('rowspan', #listnums) |
− | :tag('div')
| + | :tag('div') |
− | :wikitext(addNewline(args.imageleft))
| + | :wikitext(processItem(args.imageleft)) |
− | end
| + | end |
| | | |
− | if args['group' .. listnum] then
| + | if args['group' .. listnum] then |
− | local groupCell = row:tag('th')
| + | local groupCell = row:tag('th') |
| | | |
− | groupCell
| + | -- id for aria-labelledby attribute, if lone group with no title or above |
− | :attr('scope', 'row')
| + | if listnum == 1 and not (args.title or args.above or args.group2) then |
− | :addClass('navbox-group')
| + | groupCell |
− | :addClass(args.groupclass)
| + | :attr('id', mw.uri.anchorEncode(args.group1)) |
− | :cssText(args.basestyle)
| + | end |
| | | |
− | if args.groupwidth then
| + | groupCell |
− | groupCell:css('width', args.groupwidth)
| + | :attr('scope', 'row') |
− | end
| + | :addClass('navbox-group') |
| + | :addClass(args.groupclass) |
| + | :cssText(args.basestyle) |
| + | :css('width', args.groupwidth or '1%') -- If groupwidth not specified, minimize width |
| | | |
− | groupCell
| + | groupCell |
− | :cssText(args.groupstyle)
| + | :cssText(args.groupstyle) |
− | :cssText(args['group' .. listnum .. 'style'])
| + | :cssText(args['group' .. listnum .. 'style']) |
− | :wikitext(args['group' .. listnum])
| + | :wikitext(args['group' .. listnum]) |
− | end
| + | end |
| | | |
− | local listCell = row:tag('td')
| + | local listCell = row:tag('td') |
| | | |
− | if args['group' .. listnum] then
| + | if args['group' .. listnum] then |
− | listCell
| + | listCell |
− | :css('text-align', 'left')
| + | :css('text-align', 'left') |
− | :css('border-left-width', '2px')
| + | :css('border-left-width', '2px') |
− | :css('border-left-style', 'solid')
| + | :css('border-left-style', 'solid') |
− | else
| + | else |
− | listCell:attr('colspan', 2)
| + | listCell:attr('colspan', 2) |
− | end
| + | end |
| | | |
− | if not args.groupwidth then
| + | if not args.groupwidth then |
− | listCell:css('width', '100%')
| + | listCell:css('width', '100%') |
− | end
| + | end |
| | | |
− | local isOdd = (listnum % 2) == 1
| + | local rowstyle -- usually nil so cssText(rowstyle) usually adds nothing |
− | local rowstyle = args.evenstyle
| + | if index % 2 == 1 then |
− | if isOdd then rowstyle = args.oddstyle end
| + | rowstyle = args.oddstyle |
| + | else |
| + | rowstyle = args.evenstyle |
| + | end |
| | | |
− | local evenOdd
| + | local listText = args['list' .. listnum] |
− | if args.evenodd == 'swap' then
| + | local oddEven = ODD_EVEN_MARKER |
− | if isOdd then evenOdd = 'even' else evenOdd = 'odd' end
| + | if listText:sub(1, 12) == '</div><table' then |
− | else
| + | -- Assume list text is for a subgroup navbox so no automatic striping for this row. |
− | if isOdd then evenOdd = args.evenodd or 'odd' else evenOdd = args.evenodd or 'even' end
| + | oddEven = listText:find('<th[^>]*"navbox%-title"') and RESTART_MARKER or 'odd' |
− | end
| + | end |
| + | listCell |
| + | :css('padding', '0px') |
| + | :cssText(args.liststyle) |
| + | :cssText(rowstyle) |
| + | :cssText(args['list' .. listnum .. 'style']) |
| + | :addClass('navbox-list') |
| + | :addClass('navbox-' .. oddEven) |
| + | :addClass(args.listclass) |
| + | :addClass(args['list' .. listnum .. 'class']) |
| + | :tag('div') |
| + | :css('padding', (index == 1 and args.list1padding) or args.listpadding or '0em 0.25em') |
| + | :wikitext(processItem(listText, args.nowrapitems)) |
| | | |
− | listCell
| + | if index == 1 and args.image then |
− | :css('padding', '0px')
| + | row |
− | :cssText(args.liststyle)
| + | :tag('td') |
− | :cssText(rowstyle)
| + | :addClass('navbox-image') |
− | :cssText(args['list' .. listnum .. 'style'])
| + | :addClass(args.imageclass) |
− | :addClass('navbox-list')
| + | :css('width', '1px') -- Minimize width |
− | :addClass('navbox-' .. evenOdd)
| + | :css('padding', '0px 0px 0px 2px') |
− | :addClass(args.listclass)
| + | :cssText(args.imagestyle) |
− | :tag('div')
| + | :attr('rowspan', #listnums) |
− | :css('padding', (listnum == 1 and args.list1padding) or args.listpadding or '0em 0.25em')
| + | :tag('div') |
− | :wikitext(addNewline(args['list' .. listnum]))
| + | :wikitext(processItem(args.image)) |
− | | + | end |
− | if listnum == 1 and args.image then
| |
− | row
| |
− | :tag('td')
| |
− | :addClass('navbox-image')
| |
− | :addClass(args.imageclass)
| |
− | :css('width', '0%')
| |
− | :css('padding', '0px 0px 0px 2px')
| |
− | :cssText(args.imagestyle)
| |
− | :attr('rowspan', 2 * #listnums - 1)
| |
− | :tag('div')
| |
− | :wikitext(addNewline(args.image))
| |
− | end
| |
| end | | end |
| | | |
Line 257: |
Line 285: |
| | | |
| local function needsHorizontalLists() | | local function needsHorizontalLists() |
− | if border == 'child' or border == 'subgroup' or args.tracking == 'no' then return false end
| + | if border == 'subgroup' or args.tracking == 'no' then |
| + | return false |
| + | end |
| + | local listClasses = { |
| + | ['plainlist'] = true, ['hlist'] = true, ['hlist hnum'] = true, |
| + | ['hlist hwrap'] = true, ['hlist vcard'] = true, ['vcard hlist'] = true, |
| + | ['hlist vevent'] = true, |
| + | } |
| + | return not (listClasses[args.listclass] or listClasses[args.bodyclass]) |
| + | end |
| | | |
− | local listClasses = {'plainlist', 'hlist', 'hlist hnum', 'hlist hwrap', 'hlist vcard', 'vcard hlist', 'hlist vevent'}
| + | local function hasBackgroundColors() |
− | for i, cls in ipairs(listClasses) do
| + | for _, key in ipairs({'titlestyle', 'groupstyle', 'basestyle', 'abovestyle', 'belowstyle'}) do |
− | if args.listclass == cls or args.bodyclass == cls then
| + | if tostring(args[key]):find('background', 1, true) then |
− | return false
| + | return true |
− | end
| + | end |
− | end
| + | end |
− | | |
− | return true
| |
| end | | end |
| | | |
− | local function hasBackgroundColors() | + | local function hasBorders() |
− | return mw.ustring.match(args.titlestyle or '','background') or mw.ustring.match(args.groupstyle or '','background') or mw.ustring.match(args.basestyle or '','background')
| + | for _, key in ipairs({'groupstyle', 'basestyle', 'abovestyle', 'belowstyle'}) do |
| + | if tostring(args[key]):find('border', 1, true) then |
| + | return true |
| + | end |
| + | end |
| end | | end |
| | | |
| local function isIllegible() | | local function isIllegible() |
− | local styleratio = require('Module:Color contrast')._styleratio
| + | local styleratio = require('Module:Color contrast')._styleratio |
| | | |
− | for key, style in pairs(args) do
| + | for key, style in pairs(args) do |
− | if tostring(key):match("style$") then
| + | if tostring(key):match("style$") then |
− | if styleratio{mw.text.unstripNoWiki(style)} < 4.5 then
| + | if styleratio{mw.text.unstripNoWiki(style)} < 4.5 then |
− | return true
| + | return true |
− | end
| + | end |
− | end
| + | end |
− | end
| + | end |
− | return false
| + | return false |
| end | | end |
| | | |
| local function getTrackingCategories() | | local function getTrackingCategories() |
− | local cats = {}
| + | local cats = {} |
− | if needsHorizontalLists() then table.insert(cats, 'Navigational boxes without horizontal lists') end
| + | if needsHorizontalLists() then table.insert(cats, 'Navigational boxes without horizontal lists') end |
− | if hasBackgroundColors() then table.insert(cats, 'Navboxes using background colours') end
| + | if hasBackgroundColors() then table.insert(cats, 'Navboxes using background colours') end |
− | if isIllegible() then table.insert(cats, 'Potentially illegible navboxes') end
| + | if isIllegible() then table.insert(cats, 'Potentially illegible navboxes') end |
− | return cats
| + | if hasBorders() then table.insert(cats, 'Navboxes using borders') end |
| + | return cats |
| end | | end |
| | | |
| local function renderTrackingCategories(builder) | | local function renderTrackingCategories(builder) |
− | local title = mw.title.getCurrentTitle()
| + | local title = mw.title.getCurrentTitle() |
− | if title.namespace ~= 10 then return end -- not in template space
| + | if title.namespace ~= 10 then return end -- not in template space |
− | local subpage = title.subpageText
| + | local subpage = title.subpageText |
− | if subpage == 'doc' or subpage == 'sandbox' or subpage == 'testcases' then return end
| + | if subpage == 'doc' or subpage == 'sandbox' or subpage == 'testcases' then return end |
| | | |
− | for i, cat in ipairs(getTrackingCategories()) do
| + | for _, cat in ipairs(getTrackingCategories()) do |
− | builder:wikitext('[[Category:' .. cat .. ']]')
| + | builder:wikitext('[[Category:' .. cat .. ']]') |
− | end
| + | end |
| end | | end |
| | | |
Line 309: |
Line 349: |
| -- | | -- |
| local function renderMainTable() | | local function renderMainTable() |
− | local tbl = mw.html.create('table')
| + | local tbl = mw.html.create('table') |
− | :addClass('nowraplinks')
| + | :addClass('nowraplinks') |
− | :addClass(args.bodyclass)
| + | :addClass(args.bodyclass) |
| | | |
− | if args.title and (args.state ~= 'plain' and args.state ~= 'off') then
| + | if args.title and (args.state ~= 'plain' and args.state ~= 'off') then |
− | tbl
| + | tbl |
− | :addClass('collapsible')
| + | :addClass('collapsible') |
− | :addClass(args.state or 'autocollapse')
| + | :addClass(args.state or 'autocollapse') |
− | end
| + | end |
| | | |
− | tbl:css('border-spacing', 0)
| + | tbl:css('border-spacing', 0) |
− | if border == 'subgroup' or border == 'child' or border == 'none' then
| + | if border == 'subgroup' or border == 'none' then |
− | tbl
| + | tbl |
− | :addClass('navbox-subgroup')
| + | :addClass('navbox-subgroup') |
− | :cssText(args.bodystyle)
| + | :cssText(args.bodystyle) |
− | :cssText(args.style)
| + | :cssText(args.style) |
− | else -- regular navobx - bodystyle and style will be applied to the wrapper table
| + | else -- regular navbox - bodystyle and style will be applied to the wrapper table |
− | tbl
| + | tbl |
− | :addClass('navbox-inner')
| + | :addClass('navbox-inner') |
− | :css('background', 'transparent')
| + | :css('background', 'transparent') |
− | :css('color', 'inherit')
| + | :css('color', 'inherit') |
− | end
| + | end |
− | tbl:cssText(args.innerstyle)
| + | tbl:cssText(args.innerstyle) |
| | | |
− | renderTitleRow(tbl)
| + | renderTitleRow(tbl) |
− | renderAboveRow(tbl)
| + | renderAboveRow(tbl) |
− | for i, listnum in ipairs(listnums) do
| + | for i, listnum in ipairs(listnums) do |
− | renderListRow(tbl, listnum)
| + | renderListRow(tbl, i, listnum) |
− | end
| + | end |
− | renderBelowRow(tbl)
| + | renderBelowRow(tbl) |
| | | |
− | return tbl
| + | return tbl |
| end | | end |
| | | |
| function p._navbox(navboxArgs) | | function p._navbox(navboxArgs) |
− | args = navboxArgs
| + | args = navboxArgs |
− | | + | listnums = {} |
− | 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)
| |
| | | |
− | border = trim(args.border or args[1] or '')
| + | for k, _ in pairs(args) do |
| + | if type(k) == 'string' then |
| + | local listnum = k:match('^list(%d+)$') |
| + | if listnum then table.insert(listnums, tonumber(listnum)) end |
| + | end |
| + | end |
| + | table.sort(listnums) |
| | | |
− | -- render the main body of the navbox
| + | border = mw.text.trim(args.border or args[1] or '') |
− | local tbl = renderMainTable()
| + | if border == 'child' then |
| + | border = 'subgroup' |
| + | end |
| | | |
− | -- render the appropriate wrapper around the navbox, depending on the border param
| + | -- render the main body of the navbox |
− | local res = mw.html.create()
| + | local tbl = renderMainTable() |
− | if border == 'none' then
| |
− | res:node(tbl)
| |
− | elseif border == 'subgroup' or border == 'child' then
| |
− | -- We assume that this navbox is being rendered in a list cell of a parent navbox, and is
| |
− | -- therefore inside a div with padding:0em 0.25em. We start with a </div> to avoid the
| |
− | -- padding being applied, and at the end add a <div> to balance out the parent's </div>
| |
− | res
| |
− | :wikitext('</div>') -- XXX: hack due to lack of unclosed support in mw.html.
| |
− | :node(tbl)
| |
− | :wikitext('<div>') -- XXX: hack due to lack of unclosed support in mw.html.
| |
− | else
| |
− | res
| |
− | :tag('table')
| |
− | :addClass('navbox')
| |
− | :css('border-spacing', 0)
| |
− | :cssText(args.bodystyle)
| |
− | :cssText(args.style)
| |
− | :tag('tr')
| |
− | :tag('td')
| |
− | :css('padding', '2px')
| |
− | :node(tbl)
| |
− | end
| |
| | | |
− | renderTrackingCategories(res)
| + | -- render the appropriate wrapper around the navbox, depending on the border param |
| + | local res = mw.html.create() |
| + | if border == 'none' then |
| + | local nav = res:tag('div') |
| + | :attr('role', 'navigation') |
| + | :node(tbl) |
| + | -- aria-labelledby title, otherwise above, otherwise lone group |
| + | if args.title or args.above or (args.group1 and not args.group2) then |
| + | nav:attr('aria-labelledby', mw.uri.anchorEncode(args.title or args.above or args.group1)) |
| + | else |
| + | nav:attr('aria-label', 'Navbox') |
| + | end |
| + | elseif border == 'subgroup' then |
| + | -- We assume that this navbox is being rendered in a list cell of a parent navbox, and is |
| + | -- therefore inside a div with padding:0em 0.25em. We start with a </div> to avoid the |
| + | -- padding being applied, and at the end add a <div> to balance out the parent's </div> |
| + | res |
| + | :wikitext('</div>') |
| + | :node(tbl) |
| + | :wikitext('<div>') |
| + | else |
| + | local nav = res:tag('div') |
| + | :attr('role', 'navigation') |
| + | :addClass('navbox') |
| + | :cssText(args.bodystyle) |
| + | :cssText(args.style) |
| + | :css('padding', '3px') |
| + | :node(tbl) |
| + | -- aria-labelledby title, otherwise above, otherwise lone group |
| + | if args.title or args.above or (args.group1 and not args.group2) then |
| + | nav:attr('aria-labelledby', mw.uri.anchorEncode(args.title or args.above or args.group1)) |
| + | else |
| + | nav:attr('aria-label', 'Navbox') |
| + | end |
| + | end |
| | | |
− | return tostring(res)
| + | if (args.nocat or 'false'):lower() == 'false' then |
| + | renderTrackingCategories(res) |
| + | end |
| + | return striped(tostring(res)) |
| end | | end |
| | | |
| function p.navbox(frame) | | function p.navbox(frame) |
− | if not getArgs then
| + | if not getArgs then |
− | getArgs = require('Module:Arguments').getArgs
| + | getArgs = require('Module:Arguments').getArgs |
− | end
| + | end |
− | args = getArgs(frame, {wrappers = 'Template:Navbox'})
| + | args = getArgs(frame, {wrappers = {'Template:Navbox', 'Template:Navbox subgroup'}}) |
| + | if frame.args.border then |
| + | -- This allows Template:Navbox_subgroup to use {{#invoke:Navbox|navbox|border=...}}. |
| + | args.border = frame.args.border |
| + | end |
| | | |
− | -- Read the arguments in the order they'll be output in, to make references number in the right order.
| + | -- Read the arguments in the order they'll be output in, to make references number in the right order. |
− | local _
| + | local _ |
− | _ = args.title
| + | _ = args.title |
− | _ = args.above
| + | _ = args.above |
− | for i = 1, 20 do
| + | for i = 1, 20 do |
− | _ = args["group" .. tostring(i)]
| + | _ = args["group" .. tostring(i)] |
− | _ = args["list" .. tostring(i)]
| + | _ = args["list" .. tostring(i)] |
− | end
| + | end |
− | _ = args.below
| + | _ = args.below |
| | | |
− | return p._navbox(args)
| + | return p._navbox(args) |
| end | | end |
| | | |
| return p | | return p |