開啟主選單

求真百科

變更

模块:Navbox

增加 649 位元組, 4 年前
per tper
--
-- This module will implement implements {{Navbox}}
--
local p = {}
local navbar = require('Module:Navbar')._navbar
local getArgs -- lazily initialized
local args
local tableRowAdded = false
local border
local listnums local ODD_EVEN_MARKER = {}'\127_ODDEVEN_\127'local RESTART_MARKER = '\127_ODDEVEN0_\127'local REGEX_MARKER = '\127_ODDEVEN(%d?)_\127'
local function trimstriped(swikitext) -- 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 (mwcode) if code == '0' then -- Current occurrence is for a group before a nested table.ustring -- 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(s'([%[%]])', "^'%s*%%1') return (wikitext:gsub(.-regex, '')%s*$":gsub(REGEX_MARKER, "%1"changer)) -- ()omits gsub count
end
local function addNewlineprocessItem(sitem, nowrapitems) if sitem:matchsub('^[*:;#]'1, 2) or s:match(== '^{|') then -- Applying nowrap to lines in a table does not make sense. -- Add newlines to compensate for trim of x in |parm=x in a template. return '\n' .. s item ..'\n' else return s end end local function addTableRow(tbl) -- If any other rows have already been added, then we add a 2px gutter row. if tableRowAdded nowrapitems == 'yes' then tbl local lines = {} :tag for line in (item .. 'tr\n') :cssgmatch('height([^\n]*)\n') do local prefix, content = line:match('2px^([*:;#]+)%s*(.*)') if prefix and not content:tagmatch('td^<span class="nowrap">')then :attr( line = prefix .. '<span class="nowrap">' .. content .. 'colspan</span>' end table.insert(lines, 3line) end tableRowAdded item = truetable.concat(lines, '\n') end return tbl if item:tagmatch('tr^[*:;#]')then return '\n' .. item ..'\n' end return item
end
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 -- No navbar, and client wants no spacer, i.e. wants the title to be shifted to the left. If there's -- also no show/hide link, then we need a spacer on the right to achieve the left shift. if args.state == 'plain' then spacerSide = 'right' end elseif args.navbar =~= 'plain' or and not (not args.name and mw.getCurrentFrame():getParent():getTitle() == 'Template:Navbox' and gsub(border == 'subgroup/sandbox$' or border == , 'child' or border ) == 'noneTemplate:Navbox')) then -- No titleCell:wikitext(navbar. Need a spacer on the left to balance out the width of the show/hide link.{ if args.state ~name, mini = 'plain' then spacerSide 1, fontstyle = (args.basestyle or 'left' 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 == titlestyle or 'plain' then spacerSide = ) .. 'right;background:none transparent;border:none;-moz-box-shadow:none;-webkit-box-shadow:none;box-shadow:none; padding:0;' }) 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', '8em')
:css('font-size', '80%')
:css('margin-' .. (spacerSide == 'left' and 'right' or 'left'), '0.5em')
:wikitext('&nbsp;')
end
end
--
local function renderTitleRow(tbl)
if not args.title then return end local titleRow = addTableRowtbl:tag(tbl'tr') 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') :addClass(args.titleclass) :attr('colspan', titleColspan) renderNavBar(titleCell)
titleCell :tag('div') -- id for aria-labelledby attribute :attr('id', mw.uri.anchorEncode(args.title)) :addClass(args.titleclass) :css('font-size', '110114%') :css('margin', '0 4em') :wikitext(addNewlineprocessItem(args.title))
end
local function getAboveBelowColspan()
local ret = 2 if args.imageleft then ret = ret + 1 end if args.image then ret = ret + 1 end return ret
end
local function renderAboveRow(tbl)
if not args.above then return end
addTableRow tbl:tag(tbl'tr') :tag('td') :addClass('navbox-abovebelow') :addClass(args.aboveclass) :cssText(args.basestyle) :cssText(args.abovestyle) :attr('colspan', getAboveBelowColspan()) :tag('div') -- id for aria-labelledby attribute, if no title :attr('id', args.title and nil or mw.uri.anchorEncode(args.above)) :wikitext(addNewlineprocessItem(args.above, args.nowrapitems))
end
local function renderBelowRow(tbl)
if not args.below then return end
addTableRow tbl:tag(tbl'tr') :tag('td') :addClass('navbox-abovebelow') :addClass(args.belowclass) :cssText(args.basestyle) :cssText(args.belowstyle) :attr('colspan', getAboveBelowColspan()) :tag('div') :wikitext(addNewlineprocessItem(args.below, args.nowrapitems))
end
--
-- List rows
--
local function renderListRow(tbl, index, listnum) local row = addTableRowtbl:tag(tbl'tr') if listnum index == 1 and args.imageleft then row :tag('td') :addClass('navbox-image') :addClass(args.imageclass) :css('width', '0%1px') -- Minimize width :css('padding', '0px 2px 0px 0px') :cssText(args.imageleftstyle) :attr('rowspan', 2 * #listnums - 1) :tag('div') :wikitext(addNewlineprocessItem(args.imageleft)) end if args['group' .. listnum] then local groupCell = row:tag('th') -- id for aria-labelledby attribute, if lone group with no title or above if listnum == 1 and not (args.title or args.above or args.group2) then groupCell :attr('id', mw.uri.anchorEncode(args.group1)) end  groupCell :attr('scope', 'row') :addClass('navbox-group') :addClass(args.groupclass) :cssText(args.basestyle) if args.groupwidth then groupCell :css('width', args.groupwidthor '1%')-- If groupwidth not specified, minimize width 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( if not args.liststyle)groupwidth then :cssText(rowstyle) :cssText(args['list' .. listnum .. 'style']) :addClass('navbox-list') :addClass('navbox-' .. evenOdd) :addClass(args.listclass) :tag('div') listCell:css('paddingwidth', (listnum == 1 and args.list1padding) or args.listpadding or '0em 0.25em100%') :wikitext(addNewline(args['list' .. listnum])) end
local rowstyle -- usually nil so cssText(rowstyle) usually adds nothing if index % 2 == 1 then rowstyle = args.oddstyle else rowstyle = args.evenstyle end  local listText = args['list' .. listnum ] local oddEven = ODD_EVEN_MARKER if listText:sub(1, 12) == '</div><table' then -- Assume list text is for a subgroup navbox so no automatic striping for this row. oddEven = listText:find('<th[^>]*"navbox%-title"') and RESTART_MARKER or 'odd' 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))  if index == 1 and args.image then row :tag('td') :addClass('navbox-image') :addClass(args.imageclass) :css('width', '0%1px') -- Minimize width :css('padding', '0px 0px 0px 2px') :cssText(args.imagestyle) :attr('rowspan', 2 * #listnums - 1) :tag('div') :wikitext(addNewlineprocessItem(args.image)) end
end
local function needsHorizontalLists()
if border == 'child' or 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, } for i, cls in ipairs return not (listClasses) do if [args.listclass == cls ] or listClasses[args.bodyclass == cls then return false end]) end
local function hasBackgroundColors() for _, key in ipairs({'titlestyle', 'groupstyle', 'basestyle', 'abovestyle', 'belowstyle'}) do if tostring(args[key]):find('background', 1, true) then return true end end
end
local function hasBackgroundColorshasBorders() return mw.ustring.match for _, key in ipairs(args.titlestyle or {'groupstyle','backgroundbasestyle') or mw.ustring.match(args.groupstyle or , 'abovestyle','backgroundbelowstyle'}) or mw.ustring.matchdo if tostring(args.basestyle or [key]):find('border','background'1, true)then return true end end
end
local function argNameAndRealTitleAreDifferentisIllegible() if border =local styleratio = require('childModule:Color contrast' or border == 'subgroup' or args).tracking == 'no' then return false end_styleratio
for key, style in pairs(args) do if tostring(key):match("style$") then if args.name ~= styleratio{mw.titletext.getCurrentTitleunstripNoWiki(style)} < 4.text 5 then return true end end
end
return false
local function getTrackingCategories()
local cats = {} if needsHorizontalLists() then table.insert(cats, ' 没有使用水平列表的导航框Navigational boxes without horizontal lists') end if hasBackgroundColors() then table.insert(cats, ' 使用背景颜色的导航框Navboxes using background colours') end if argNameAndRealTitleAreDifferentisIllegible() then table.insert(cats, 'name參數和實際不同的導航框Potentially illegible navboxes') end if hasBorders() then table.insert(cats, 'Navboxes using borders') end return cats
end
local function renderTrackingCategories(builder)
local title = mw.title.getCurrentTitle() if title.namespace ~= 10 then return end -- not in template space local subpage = title.subpageText if subpage == 'doc' or subpage == 'sandbox' or subpage == 'testcases' then return end for i_, cat in ipairs(getTrackingCategories()) do builder:wikitext('[[Category:' .. cat .. ']]') end
end
--
local function renderMainTable()
local tbl = mw.html.create('table') :attr('cellspacing', 0) :addClass('nowraplinks') :addClass(args.bodyclass) if args.title and (args.state ~= 'plain' and args.state ~= 'off') then if args.state == 'collapsed' then args.state = 'mw-collapsed' end tbl :addClass('mw-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 navbox - 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) for i, listnum in ipairs(listnums) do renderListRow(tbl, i, listnum) end renderBelowRow(tbl) return tbl
end
function p._navbox(navboxArgs)
args = navboxArgs listnums = {} for k, v _ 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) border = mw.text.trim(args.border or args[1] or '') if border == 'child' then border = 'subgroup' end
-- render the main body of the navbox local tbl = renderMainTable()
-- 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) elseif border == -- aria-labelledby title, otherwise above, otherwise lone group if args.title or args.above or (args.group1 and not args.group2) then nav:attr('subgrouparia-labelledby' , mw.uri.anchorEncode(args.title or args.above or args.group1)) else nav:attr('aria-label', 'Navbox') end elseif border == 'childsubgroup' 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>') -- mw.html 未支持 unclosed :node(tbl) :wikitext('<div>') -- mw.html 未支持 unclosed else local nav = res :tag('tablediv') :attr('cellspacingrole', 0'navigation') :addClass('navbox') :cssaddClass('border-spacing', 0args.navboxclass) :cssText(args.bodystyle) :cssText(args.style) :tagcss('trpadding', '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:tagattr('tdaria-labelledby', mw.uri.anchorEncode(args.title or args.above or args.group1)) else nav:cssattr('paddingaria-label', '2pxNavbox') end end  if (args.nocat or 'false'):nodelower(tbl)== 'false' then end renderTrackingCategories(res) end return striped(tostring(res))
end
function p.navbox(frame)
if not getArgs then getArgs = require('Module:Arguments').getArgs end args = getArgs(frame, {wrappers = {'Template:Navbox', 'Template:Navboxsubgroup'}}) 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. local _ _ = args.title _ = args.above for i = 1, 35 20 do _ = args["group" .. tostring(i)] _ = args["list" .. tostring(i)] end _ = args.below
return p._navbox(args)
end
return p
匿名用戶