This module is subject to page protection. It is a highly visible module in use by a very large number of pages, or is substituted very frequently. Because vandalism or mistakes would affect many pages, and even trivial editing might cause substantial load on the servers, it is protected from editing.
This module depends on the following other modules:
--
-- This module will implement {{Navbox}}
--
local p = {}
local HtmlBuilder = require('Module:HtmlBuilder')
local args
local tableRowAdded = false
local border
local listnums = {}
function trim(s)
return (mw.ustring.gsub(s, "^%s*(.-)%s*$", "%1"))
end
function addTableRow(tbl)
-- If any other rows have already been added, then we add a 2px gutter row.
if tableRowAdded then
tbl
.tag('tr')
.css('height', '2px')
.tag('td')
end
tableRowAdded = true
return tbl.tag('tr')
end
--
-- Title row
--
function renderTitleRow(tbl)
if not args.title then return end
local titleRow = addTableRow(tbl)
if args.titlegroup then
titleRow
.tag('th')
.attr('scope', 'row')
.addClass('navbox-group')
.addClass(args.titlegroupclass)
.cssText(args.basestyle)
.cssText(args.groupstyle)
.cssText(args.titlegroupstyle)
.wikitext(args.titlegroup)
end
local titleCell = titleRow.tag('th').attr('scope', 'col')
if args.titlegroup then
titleCell
.css('border-left', '2px solid #fdfdfd')
.css('width', '100%')
end
local titleColspan = 2
if args.imageleft then titleColspan = titleColspan + 1 end
if args.image then titleColspan = titleColspan + 1 end
if args.titlegroup then titleColspan = titleColspan - 1 end
titleCell
.cssText(args.basestyle)
.cssText(args.titlestyle)
.addClass('navbox-title')
.attr('colspan', titleColspan)
renderNavBar(titleCell)
titleCell
.tag('div')
.addClass(args.titleclass)
.css('font-size', '110%')
.newline()
.wikitext(args.title)
end
function renderNavBar(titleCell)
local addStateLinkPlaceholder = false
if args.navbar == 'plain' or args.navbar == 'off' or (not args.name and (border == 'subgroup' or border == 'child' or border == 'none')) then
if args.navbar == 'off' then
addStateLinkPlaceholder = (args.state == 'plain')
else
addStateLinkPlaceholder = (args.state ~= 'plain')
end
else
if args.name then
titleCell.wikitext(mw.getCurrentFrame():expandTemplate{ title = 'navbar', args = {
args.name,
mini = 1,
fontstyle = (args.basestyle or '') .. ';' .. (args.titlestyle or '') .. ';background:none transparent;border:none;'
}})
else
titleCell
.tag('span')
.addClass('error')
.css('float', 'left')
.css('white-space', 'nowrap')
.wikitext('Error: No name provided')
addStateLinkPlaceholder = (args.state == 'plain')
end
end
if addStateLinkPlaceholder then
titleCell
.tag('span')
.css('float', 'right')
.css('width', '6em')
.wikitext(' ')
end
end
--
-- Above/Below rows
--
function renderAboveRow(tbl)
if not args.above then return end
addTableRow(tbl)
.tag('td')
.addClass('navbox-abovebelow')
.addClass(args.aboveclass)
.cssText(args.basestyle)
.cssText(args.abovestyle)
.attr('colspan', getAboveBelowColspan())
.tag('div')
.newline()
.wikitext(args.above)
end
function renderBelowRow(tbl)
if not args.below then return end
addTableRow(tbl)
.tag('td')
.addClass('navbox-abovebelow')
.addClass(args.belowclass)
.cssText(args.basestyle)
.cssText(args.belowstyle)
.attr('colspan', getAboveBelowColspan())
.tag('div')
.newline()
.wikitext(args.below)
end
function getAboveBelowColspan()
local ret = 2
if args.imageleft then ret = ret + 1 end
if args.image then ret = ret + 1 end
return ret
end
--
-- List rows
--
function renderFirstListRow(tbl)
if not args.list1 then return end
local row = addTableRow(tbl)
if args.imageleft then
row
.tag('td')
.addClass('navbox-image')
.addClass(args.imageclass)
.css('width', '0%')
.css('padding', '0px 2px 0px 0px')
.cssText(args.imageleftstyle)
.attr('rowspan', 2 * #listnums - 1)
.tag('div')
.newline()
.wikitext(args.imageleft)
end
if args.group1 then
local groupCell = row.tag('th')
groupCell
.attr('scope', 'row')
.addClass('navbox-group')
.addClass(args.groupclass)
.cssText(args.basestyle)
if args.groupwidth then
groupCell.css('width', args.groupwidth)
end
groupCell
.cssText(args.groupstyle)
.cssText(args.group1style)
.wikitext(args.group1)
end
local listCell = row.tag('td')
if args.group1 then
listCell
.css('text-align', 'left')
.css('border-left-width', '2px')
.css('border-left-style', 'solid')
else
listCell.attr('colspan', 2)
end
if not args.groupwidth then
listCell.css('width', '100%')
end
local evenOdd = args.evenodd or 'odd'
if args.evenodd == 'swap' then evenOdd = 'even' end
listCell
.css('padding', '0px')
.cssText(args.liststyle)
.cssText(args.oddstyle)
.cssText(args.list1style)
.addClass('navbox-list')
.addClass('navbox-' .. evenOdd)
.addClass(args.listclass)
.tag('div')
.css('padding', args.list1padding or args.listpadding or '0em 0.25em')
.newline()
.wikitext(args.list1)
if 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')
.newline()
.wikitext(args.image)
end
end
function renderNthListRow(tbl, listnum)
local row = addTableRow(tbl)
if args['group' .. listnum] then
local groupCell = row.tag('th')
groupCell
.attr('scope', 'row')
.addClass('navbox-group')
.addClass(args.groupclass)
.cssText(args.basestyle)
if args.groupwidth then
groupCell.css('width', args.groupwidth)
end
groupCell
.cssText(args.groupstyle)
.cssText(args['group' .. listnum .. 'style'])
.wikitext(args['group' .. listnum])
end
local listCell = row.tag('td')
if args['group' .. listnum] then
listCell
.css('text-align', 'left')
.css('border-left-width', '2px')
.css('border-left-style', 'solid')
else
listCell.attr('colspan', 2)
end
if not args.groupwidth then
listCell.css('width', '100%')
end
local isOdd = (listnum % 2) == 1
local rowstyle = args.evenstyle
if isOdd then rowstyle = args.oddstyle end
local evenOdd
if args.evenodd == 'swap' then
if isOdd then evenOdd = 'even' else evenOdd = 'odd' end
else
if isOdd then evenOdd = args.evenodd or 'odd' else evenOdd = args.evenodd or 'even' end
end
listCell
.css('padding', '0px')
.cssText(args.liststyle)
.cssText(rowstyle)
.cssText(args['list' .. listnum .. 'style'])
.addClass('navbox-list')
.addClass('navbox-' .. evenOdd)
.addClass(args.listclass)
.tag('div')
.css('padding', args.listpadding or '0em 0.25em')
.newline()
.wikitext(args['list' .. listnum])
end
--
-- Main navbox tables
--
function renderMainTable()
local tbl = HtmlBuilder.create('table')
.attr('cellspacing', 0)
.addClass('nowraplinks')
.addClass(args.bodyclass)
if args.title and (args.state ~= 'plain' and args.state ~= 'off') then
tbl
.addClass('collapsible')
.addClass(args.state or 'autocollapse')
end
tbl.css('border-spacing', 0)
if border == 'subgroup' or border == 'child' or border == 'none' then
tbl
.addClass('navbox-subgroup')
.cssText(args.bodyStyle)
.cssText(args.style)
else -- regular navobx - bodyStyle and style will be applied to the wrapper table
tbl
.addClass('navbox-inner')
.css('background', 'transparent')
.css('color', 'inherit')
end
tbl.cssText(args.innerstyle)
renderTitleRow(tbl)
renderAboveRow(tbl)
renderFirstListRow(tbl)
-- render lists 2 through N
for i, listnum in ipairs(listnums) do
if listnum > 1 then
renderNthListRow(tbl, listnum)
end
end
renderBelowRow(tbl)
return tbl
end
function p._navbox(navboxArgs)
args = navboxArgs
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 '')
-- render the main body of the navbox
local tbl = renderMainTable()
-- render the appropriate wrapper around the navbox, depending on the border param
local res = HtmlBuilder.create()
if border == 'subgroup' or border == 'child' then
res
.tag('/div', {unclosed = true})
.done()
.node(tbl)
.tag('div', {unclosed = true})
elseif border ~= 'none' then
res
.tag('table')
.attr('cellspacing', 0)
.addClass('navbox')
.css('border-spacing', 0)
.cssText(args.bodystyle)
.cssText(args.style)
.tag('tr')
.tag('td')
.css('padding', '2px')
.node(tbl)
end
-- TODO: add tracking categories
return tostring(res)
end
function p.navbox(frame)
return p._navbox(frame:getParent().args)
end
return p