跳转到内容
打开/关闭菜单
  • 450 条目
  • 804 文件
  • 22 用户
  • 9046 编辑
Blockland Wiki
打开/关闭外观设置菜单
打开/关闭个人菜单
未登录
未登录用户的IP地址会在进行任意编辑后公开展示。

模块:Navbox:修订间差异

来自Blockland Wiki
创建页面,内容为“-- -- This module implements {{Navbox}} -- local p = {} local navbar = require('Module:Navbar')._navbar local getArgs -- lazily initialized local args 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 striped(wikitext) -- Return wikitext with markers replaced for odd/even striping. -- Child (subgroup) navboxes are flagged with a c…”
 
无编辑摘要
 
(未显示同一用户的2个中间版本)
第1行: 第1行:
--
--
-- This module implements {{Navbox}}
-- 此版本移除了 Navbar (VDE) 功能,其余逻辑保留。
--
--


local p = {}
local p = {}


local navbar = require('Module:Navbar')._navbar
local getArgs -- lazily initialized
local getArgs -- lazily initialized


第16行: 第15行:


local function striped(wikitext)
local function striped(wikitext)
-- Return wikitext with markers replaced for odd/even striping.
    local orphanCat = '[[Category:Navbox orphans]]'
-- Child (subgroup) navboxes are flagged with a category that is removed
    if border == 'subgroup' and args.orphan ~= 'yes' then
-- by parent navboxes. The result is that the category shows all pages
        return wikitext .. orphanCat
-- where a child navbox is not contained in a parent navbox.
    end
local orphanCat = '[[Category:Navbox orphans]]'
    local first, second = 'odd', 'even'
if border == 'subgroup' and args.orphan ~= 'yes' then
    if args.evenodd then
-- No change; striping occurs in outermost navbox.
        if args.evenodd == 'swap' then
return wikitext .. orphanCat
            first, second = second, first
end
        else
local first, second = 'odd', 'even'
            first = args.evenodd
if args.evenodd then
            second = first
if args.evenodd == 'swap' then
        end
first, second = second, first
    end
else
    local changer
first = args.evenodd
    if first == second then
second = first
        changer = first
end
    else
end
        local index = 0
local changer
        changer = function (code)
if first == second then
            if code == '0' then
changer = first
                index = 0
else
                return first
local index = 0
            end
changer = function (code)
            index = index + 1
if code == '0' then
            return index % 2 == 1 and first or second
-- Current occurrence is for a group before a nested table.
        end
-- Set it to first as a valid although pointless class.
    end
-- The next occurrence will be the first row after a title
    local regex = orphanCat:gsub('([%[%]])', '%%%1')
-- in a subgroup and will also be first.
    return (wikitext:gsub(regex, ''):gsub(REGEX_MARKER, changer))
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 processItem(item, nowrapitems)
local function processItem(item, nowrapitems)
if item:sub(1, 2) == '{|' then
    if not item then return nil end
-- Applying nowrap to lines in a table does not make sense.
    if item:sub(1, 2) == '{|' then
-- Add newlines to compensate for trim of x in |parm=x in a template.
        return '\n' .. item ..'\n'
return '\n' .. item ..'\n'
    end
end
    if nowrapitems == 'yes' then
if nowrapitems == 'yes' then
        local lines = {}
local lines = {}
        for line in (item .. '\n'):gmatch('([^\n]*)\n') do
for line in (item .. '\n'):gmatch('([^\n]*)\n') do
            local prefix, content = line:match('^([*:;#]+)%s*(.*)')
local prefix, content = line:match('^([*:;#]+)%s*(.*)')
            if prefix and not content:match('^<span class="nowrap">') then
if prefix and not content:match('^<span class="nowrap">') then
                line = prefix .. '<span class="nowrap">' .. content .. '</span>'
line = prefix .. '<span class="nowrap">' .. content .. '</span>'
            end
end
            table.insert(lines, line)
table.insert(lines, line)
        end
end
        item = table.concat(lines, '\n')
item = table.concat(lines, '\n')
    end
end
    if item:match('^[*:;#]') then
if item:match('^[*:;#]') then
        return '\n' .. item ..'\n'
return '\n' .. item ..'\n'
    end
end
    return item
return item
end
 
-- Separate function so that we can evaluate properly whether hlist should
-- be added by the module
local function has_navbar()
return args.navbar ~= 'off' and args.navbar ~= 'plain' and not
(not args.name and mw.getCurrentFrame():getParent():getTitle():gsub('/sandbox$', '') == 'Template:Navbox')
end
 
local function renderNavBar(titleCell)
 
if has_navbar() then
titleCell:wikitext(navbar{
args.name,
-- we depend on this being mini = 1 when the navbox module decides
-- to add hlist templatestyles. we also depend on navbar outputting
-- a copy of the hlist templatestyles.
mini = 1,
fontstyle = (args.basestyle or '') .. ';' .. (args.titlestyle or '') .. ';background:none transparent;border:none;box-shadow:none; padding:0;'
})
end
 
end
end


--
--
--  Title row
--  Title row (已移除 Navbar 调用)
--
--
local function renderTitleRow(tbl)
local function renderTitleRow(tbl)
if not args.title then return end
    if not args.title then return end


local titleRow = tbl:tag('tr')
    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:addClass('navbox-title1')
:addClass('navbox-title1')
    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')
-- id for aria-labelledby attribute
        :attr('id', mw.uri.anchorEncode(args.title))
:attr('id', mw.uri.anchorEncode(args.title))
        :addClass(args.titleclass)
:addClass(args.titleclass)
        :css('font-size', '114%')
:css('font-size', '114%')
        :css('margin', '0') -- 移除了原本为 VDE 留出的 4em 边距,使文字完全居中
:css('margin', '0 4em')
        :wikitext(processItem(args.title))
:wikitext(processItem(args.title))
end
end


--
-- 后续 renderAboveRow, renderListRow, renderBelowRow 等函数逻辑未变,直接合并处理 --
--  Above/Below rows
--


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
 
    tbl:tag('tr'):tag('td')
tbl:tag('tr')
        :addClass('navbox-abovebelow')
:tag('td')
        :addClass(args.aboveclass)
:addClass('navbox-abovebelow')
        :cssText(args.basestyle)
:addClass(args.aboveclass)
        :cssText(args.abovestyle)
:cssText(args.basestyle)
        :attr('colspan', getAboveBelowColspan())
:cssText(args.abovestyle)
        :tag('div')
:attr('colspan', getAboveBelowColspan())
        :attr('id', args.title and nil or mw.uri.anchorEncode(args.above))
:tag('div')
        :wikitext(processItem(args.above, args.nowrapitems))
-- 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
 
    tbl:tag('tr'):tag('td')
tbl:tag('tr')
        :addClass('navbox-abovebelow')
:tag('td')
        :addClass(args.belowclass)
:addClass('navbox-abovebelow')
        :cssText(args.basestyle)
:addClass(args.belowclass)
        :cssText(args.belowstyle)
:cssText(args.basestyle)
        :attr('colspan', getAboveBelowColspan())
:cssText(args.belowstyle)
        :tag('div')
:attr('colspan', getAboveBelowColspan())
        :wikitext(processItem(args.below, args.nowrapitems))
:tag('div')
:wikitext(processItem(args.below, args.nowrapitems))
end
end


--
--  List rows
--
local function renderListRow(tbl, index, listnum)
local function renderListRow(tbl, index, listnum)
local row = tbl:tag('tr')
    local row = tbl:tag('tr')
 
    if index == 1 and args.imageleft then
if index == 1 and args.imageleft then
        row:tag('td'):addClass('navbox-image'):addClass(args.imageclass):css('width', '1px'):css('padding', '0 2px 0 0'):cssText(args.imageleftstyle):attr('rowspan', #listnums):tag('div'):wikitext(processItem(args.imageleft))
row
    end
:tag('td')
    if args['group' .. listnum] then
:addClass('navbox-image')
        local groupCell = row:tag('th'):attr('scope', 'row'):addClass('navbox-group'):addClass(args.groupclass):cssText(args.basestyle):css('width', args.groupwidth or '1%'):cssText(args.groupstyle):cssText(args['group' .. listnum .. 'style']):wikitext(args['group' .. listnum])
:addClass(args.imageclass)
    end
:css('width', '1px')               -- Minimize width
    local listCell = row:tag('td')
:css('padding', '0px 2px 0px 0px')
    if args['group' .. listnum] then listCell:addClass('navbox-list1') else listCell:attr('colspan', 2) end
:cssText(args.imageleftstyle)
    if not args.groupwidth then listCell:css('width', '100%') end
:attr('rowspan', #listnums)
   
:tag('div')
    local rowstyle = (index % 2 == 1) and args.oddstyle or args.evenstyle
:wikitext(processItem(args.imageleft))
local listText = args['list' .. listnum]
end
    local oddEven = ODD_EVEN_MARKER
 
    -- fix: 增加对 navbox-subgroup 样式的匹配,或者允许 listText 以 templatestyles div 开头
if args['group' .. listnum] then
    if listText:sub(1, 12) == '</div><table' or listText:find('navbox%-subgroup') then
local groupCell = row:tag('th')
        oddEven = listText:find('<th[^>]*"navbox%-title"') and RESTART_MARKER or 'odd'
 
    end
-- 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)
:css('width', args.groupwidth or '1%') -- If groupwidth not specified, minimize width
 
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
:addClass('navbox-list1')
else
listCell:attr('colspan', 2)
end
 
if not args.groupwidth then
listCell:css('width', '100%')
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', '1px')              -- Minimize width
:css('padding', '0px 0px 0px 2px')
:cssText(args.imagestyle)
:attr('rowspan', #listnums)
:tag('div')
:wikitext(processItem(args.image))
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))
--  Tracking categories
--


local function needsHorizontalLists()
    if index == 1 and args.image then
if border == 'subgroup' or args.tracking == 'no' then
        row:tag('td'):addClass('navbox-image'):addClass(args.imageclass):css('width', '1px'):css('padding', '0 0 0 2px'):cssText(args.imagestyle):attr('rowspan', #listnums):tag('div'):wikitext(processItem(args.image))
return false
    end
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
end


-- there are a lot of list classes in the wild, so we have a function to find
-- 辅助函数:列表样式加载 --
-- them and add their TemplateStyles
local function addListStyles()
local function addListStyles()
local frame = mw.getCurrentFrame()
    local frame = mw.getCurrentFrame()
-- TODO?: Should maybe take a table of classes for e.g. hnum, hwrap as above
    local function _add(htmlclass, ts)
-- I'm going to do the stupid thing first though
        local found = false
-- Also not sure hnum and hwrap are going to live in the same TemplateStyles
        for _, arg in ipairs({'bodyclass', 'listclass', 'titleclass', 'groupclass'}) do
-- as hlist
            if (args[arg] or ''):find(htmlclass) then found = true break end
local function _addListStyles(htmlclass, templatestyles)
        end
local class_args = { -- rough order of probability of use
        return found and frame:extensionTag{ name = 'templatestyles', args = { src = ts } } or ''
'bodyclass', 'listclass', 'aboveclass', 'belowclass', 'titleclass',
    end
'navboxclass', 'groupclass', 'titlegroupclass', 'imageclass'
    return _add('hlist', 'Flatlist/styles.css') .. _add('plainlist', 'Plainlist/styles.css')
}
local patterns = {
'^' .. htmlclass .. '$',
'%s' .. htmlclass .. '$',
'^' .. htmlclass .. '%s',
'%s' .. htmlclass .. '%s'
}
local found = false
for _, arg in ipairs(class_args) do
for _, pattern in ipairs(patterns) do
if mw.ustring.find(args[arg] or '', pattern) then
found = true
break
end
end
if found then break end
end
if found then
return frame:extensionTag{
name = 'templatestyles', args = { src = templatestyles }
}
else
return ''
end
end
local hlist_styles = ''
-- navbar always has mini = 1, so here (on this wiki) we can assume that
-- we don't need to output hlist styles in navbox again.
if not has_navbar() then
hlist_styles = _addListStyles('hlist', 'Flatlist/styles.css')
end
local plainlist_styles = _addListStyles('plainlist', 'Plainlist/styles.css')
return hlist_styles .. plainlist_styles
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 hasBorders()
for _, key in ipairs({'groupstyle', 'basestyle', 'abovestyle', 'belowstyle'}) do
if tostring(args[key]):find('border', 1, true) then
return true
end
end
end
 
local function isIllegible()
-- require('Module:Color contrast') absent on mediawiki.org
return false
end
 
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 isIllegible() then table.insert(cats, '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 _, cat in ipairs(getTrackingCategories()) do
builder:wikitext('[[Category:' .. cat .. ']]')
end
end
 
--
--  Main navbox tables
--
local function renderMainTable()
local tbl = mw.html.create('table')
: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 == 'none' then
tbl
:addClass('navbox-subgroup')
:cssText(args.bodystyle)
:cssText(args.style)
else  -- regular 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
end


function p._navbox(navboxArgs)
function p._navbox(navboxArgs)
args = navboxArgs
    args = navboxArgs
listnums = {}
    listnums = {}
 
    for k, _ in pairs(args) do
for k, _ in pairs(args) do
        local listnum = type(k) == 'string' and k:match('^list(%d+)$')
if type(k) == 'string' then
        if listnum then table.insert(listnums, tonumber(listnum)) end
local listnum = k:match('^list(%d+)$')
    end
if listnum then table.insert(listnums, tonumber(listnum)) end
    table.sort(listnums)
end
    border = mw.text.trim(args.border or args[1] or '')
end
    if border == 'child' then border = 'subgroup' 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 = mw.html.create('table'):addClass('nowraplinks'):addClass(args.bodyclass)
local tbl = renderMainTable()
    if args.title and (args.state ~= 'plain' and args.state ~= 'off') then
        tbl:addClass('mw-collapsible'):addClass(args.state == 'collapsed' and 'mw-collapsed' or (args.state or 'autocollapse'))
-- get templatestyles
    end
local frame = mw.getCurrentFrame()
    tbl:css('border-spacing', 0)
local base_templatestyles = frame:extensionTag{
    if border == 'subgroup' or border == 'none' then
name = 'templatestyles', args = { src = 'Module:Navbox/styles.css' }
        tbl:addClass('navbox-subgroup'):cssText(args.bodystyle):cssText(args.style)
}
    else
local templatestyles = ''
        tbl:addClass('navbox-inner'):css('background', 'transparent'):css('color', 'inherit')
if args.templatestyles and args.templatestyles ~= '' then
    end
templatestyles = frame:extensionTag{
   
name = 'templatestyles', args = { src = args.templatestyles }
    renderTitleRow(tbl)
}
    renderAboveRow(tbl)
end
    for i, listnum in ipairs(listnums) do renderListRow(tbl, i, listnum) end
    renderBelowRow(tbl)
local res = mw.html.create()
-- 'navbox-styles' exists for two reasons:
--  1. To wrap the styles to work around phab: T200206 more elegantly. Instead
--   of combinatorial rules, this ends up being linear number of CSS rules.
--  2. To allow MobileFrontend to rip the styles out with 'nomobile' such that
--    they are not dumped into the mobile view.
res:tag('div')
:addClass('navbox-styles')
:addClass('nomobile')
:wikitext(base_templatestyles .. templatestyles)
:done()
-- render the appropriate wrapper around the navbox, depending on the border param
if border == 'none' then
local nav = res:tag('div')
:attr('role', 'navigation')
:wikitext(addListStyles())
: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>')
:wikitext(addListStyles())
:node(tbl)
:wikitext('<div>')
else
local nav = res:tag('div')
:attr('role', 'navigation')
:addClass('navbox')
:addClass(args.navboxclass)
:cssText(args.bodystyle)
:cssText(args.style)
:css('padding', '3px')
:wikitext(addListStyles())
: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


if (args.nocat or 'false'):lower() == 'false' then
    local res = mw.html.create()
renderTrackingCategories(res)
    local frame = mw.getCurrentFrame()
end
    res:tag('div'):addClass('navbox-styles'):addClass('nomobile'):wikitext(frame:extensionTag{name = 'templatestyles', args = {src = 'Module:Navbox/styles.css'}}):done()
   
    if border == 'subgroup' then
        res:wikitext('</div>'):wikitext(addListStyles()):node(tbl):wikitext('<div>')
    else
        local nav = res:tag('div'):attr('role', 'navigation'):addClass(border ~= 'none' and 'navbox' or nil):addClass(args.navboxclass):cssText(args.bodystyle or args.style):wikitext(addListStyles()):node(tbl)
    end


return striped(tostring(res))
    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 end
getArgs = require('Module:Arguments').getArgs
    args = getArgs(frame, {wrappers = {'Template:Navbox', 'Template:Navbox subgroup'}})
end
    return p._navbox(args)
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.
local _
_ = args.title
_ = args.above
for i = 1, 20 do
_ = args["group" .. tostring(i)]
_ = args["list" .. tostring(i)]
end
_ = args.below
 
return p._navbox(args)
end
end


return p
return p

2026年2月12日 (四) 16:20的最新版本

此模块的文档可以在模块:Navbox/doc创建

--
-- 此版本移除了 Navbar (VDE) 功能,其余逻辑保留。
--

local p = {}

local getArgs -- lazily initialized

local args
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 striped(wikitext)
    local orphanCat = '[[Category:Navbox orphans]]'
    if border == 'subgroup' and args.orphan ~= 'yes' then
        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
                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))
end

local function processItem(item, nowrapitems)
    if not item then return nil end
    if item:sub(1, 2) == '{|' then
        return '\n' .. item ..'\n'
    end
    if nowrapitems == 'yes' then
        local lines = {}
        for line in (item .. '\n'):gmatch('([^\n]*)\n') do
            local prefix, content = line:match('^([*:;#]+)%s*(.*)')
            if prefix and not content:match('^<span class="nowrap">') then
                line = prefix .. '<span class="nowrap">' .. content .. '</span>'
            end
            table.insert(lines, line)
        end
        item = table.concat(lines, '\n')
    end
    if item:match('^[*:;#]') then
        return '\n' .. item ..'\n'
    end
    return item
end

--
--   Title row (已移除 Navbar 调用)
--
local function renderTitleRow(tbl)
    if not args.title then return end

    local titleRow = tbl:tag('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:addClass('navbox-title1')
    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')
        :attr('id', mw.uri.anchorEncode(args.title))
        :addClass(args.titleclass)
        :css('font-size', '114%')
        :css('margin', '0') -- 移除了原本为 VDE 留出的 4em 边距,使文字完全居中
        :wikitext(processItem(args.title))
end

-- 后续 renderAboveRow, renderListRow, renderBelowRow 等函数逻辑未变,直接合并处理 --

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
    tbl:tag('tr'):tag('td')
        :addClass('navbox-abovebelow')
        :addClass(args.aboveclass)
        :cssText(args.basestyle)
        :cssText(args.abovestyle)
        :attr('colspan', getAboveBelowColspan())
        :tag('div')
        :attr('id', args.title and nil or mw.uri.anchorEncode(args.above))
        :wikitext(processItem(args.above, args.nowrapitems))
end

local function renderBelowRow(tbl)
    if not args.below then return end
    tbl:tag('tr'):tag('td')
        :addClass('navbox-abovebelow')
        :addClass(args.belowclass)
        :cssText(args.basestyle)
        :cssText(args.belowstyle)
        :attr('colspan', getAboveBelowColspan())
        :tag('div')
        :wikitext(processItem(args.below, args.nowrapitems))
end

local function renderListRow(tbl, index, listnum)
    local row = tbl:tag('tr')
    if index == 1 and args.imageleft then
        row:tag('td'):addClass('navbox-image'):addClass(args.imageclass):css('width', '1px'):css('padding', '0 2px 0 0'):cssText(args.imageleftstyle):attr('rowspan', #listnums):tag('div'):wikitext(processItem(args.imageleft))
    end
    if args['group' .. listnum] then
        local groupCell = row:tag('th'):attr('scope', 'row'):addClass('navbox-group'):addClass(args.groupclass):cssText(args.basestyle):css('width', args.groupwidth or '1%'):cssText(args.groupstyle):cssText(args['group' .. listnum .. 'style']):wikitext(args['group' .. listnum])
    end
    local listCell = row:tag('td')
    if args['group' .. listnum] then listCell:addClass('navbox-list1') else listCell:attr('colspan', 2) end
    if not args.groupwidth then listCell:css('width', '100%') end
    
    local rowstyle = (index % 2 == 1) and args.oddstyle or args.evenstyle
local listText = args['list' .. listnum]
    local oddEven = ODD_EVEN_MARKER
    -- fix: 增加对 navbox-subgroup 样式的匹配,或者允许 listText 以 templatestyles div 开头
    if listText:sub(1, 12) == '</div><table' or listText:find('navbox%-subgroup') then 
        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', '1px'):css('padding', '0 0 0 2px'):cssText(args.imagestyle):attr('rowspan', #listnums):tag('div'):wikitext(processItem(args.image))
    end
end

-- 辅助函数:列表样式加载 --
local function addListStyles()
    local frame = mw.getCurrentFrame()
    local function _add(htmlclass, ts)
        local found = false
        for _, arg in ipairs({'bodyclass', 'listclass', 'titleclass', 'groupclass'}) do
            if (args[arg] or ''):find(htmlclass) then found = true break end
        end
        return found and frame:extensionTag{ name = 'templatestyles', args = { src = ts } } or ''
    end
    return _add('hlist', 'Flatlist/styles.css') .. _add('plainlist', 'Plainlist/styles.css')
end

function p._navbox(navboxArgs)
    args = navboxArgs
    listnums = {}
    for k, _ in pairs(args) do
        local listnum = type(k) == 'string' and k:match('^list(%d+)$')
        if listnum then table.insert(listnums, tonumber(listnum)) end
    end
    table.sort(listnums)
    border = mw.text.trim(args.border or args[1] or '')
    if border == 'child' then border = 'subgroup' end

    local tbl = mw.html.create('table'):addClass('nowraplinks'):addClass(args.bodyclass)
    if args.title and (args.state ~= 'plain' and args.state ~= 'off') then
        tbl:addClass('mw-collapsible'):addClass(args.state == 'collapsed' and 'mw-collapsed' or (args.state or 'autocollapse'))
    end
    tbl:css('border-spacing', 0)
    if border == 'subgroup' or border == 'none' then
        tbl:addClass('navbox-subgroup'):cssText(args.bodystyle):cssText(args.style)
    else
        tbl:addClass('navbox-inner'):css('background', 'transparent'):css('color', 'inherit')
    end
    
    renderTitleRow(tbl)
    renderAboveRow(tbl)
    for i, listnum in ipairs(listnums) do renderListRow(tbl, i, listnum) end
    renderBelowRow(tbl)

    local res = mw.html.create()
    local frame = mw.getCurrentFrame()
    res:tag('div'):addClass('navbox-styles'):addClass('nomobile'):wikitext(frame:extensionTag{name = 'templatestyles', args = {src = 'Module:Navbox/styles.css'}}):done()
    
    if border == 'subgroup' then
        res:wikitext('</div>'):wikitext(addListStyles()):node(tbl):wikitext('<div>')
    else
        local nav = res:tag('div'):attr('role', 'navigation'):addClass(border ~= 'none' and 'navbox' or nil):addClass(args.navboxclass):cssText(args.bodystyle or args.style):wikitext(addListStyles()):node(tbl)
    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:Navbox subgroup'}})
    return p._navbox(args)
end

return p