打开/关闭搜索
搜索
打开/关闭菜单
10
29
3
584
大天使虫洞百科
导航
首页
加入EVE Online
资助甲虫
最近更改
随机页面
特殊页面
上传文件
外部链接
zKillboard
大天使对外频道(QQ)
大天使边境要塞(Discord)
打开/关闭外观设置菜单
通知
打开/关闭个人菜单
未登录
未登录用户的IP地址会在进行任意编辑后公开展示。
user-interface-preferences
个人工具
创建账号
登录
查看“︁Module:NavboxV2”︁的源代码
来自大天使虫洞百科
查看
阅读
查看源代码
查看历史
associated-pages
模块
讨论
更多操作
←
Module:NavboxV2
因为以下原因,您没有权限编辑该页面:
您请求的操作仅限属于该用户组的用户执行:
用户
您可以查看和复制此页面的源代码。
-- -- This module implements {{NavboxV2}} -- local p = {} local NavboxContext = require('Module:NavboxV2/NavboxContext') local EvenoddContext = require('Module:NavboxV2/EvenoddContext') local getArgs -- lazily initialized local DEBUG = false --p.NavboxContext = NavboxContext -- 全局性参数锚 local args -- 常量定义 (Constant Define) local Limit = { vertical = 35, horizontal = {col = 20, list = 10}, --原Navbox with columns为6个list,放宽至10 vertical_collapsible = 20, child = 10 } -- 模板类型名 local NavType = { V = "vertical" -- 垂直,list , H = "horizontal" -- 水平,col , VC = "vertical_collapsible" -- 折叠垂直 } -- 模板名,用于参数获得的限定 local MainTemplateName = 'Template:NavboxV2' -- Navbar存在标记 local haveNavBarMarker = false -- 部分判断样式的参数 local listsCheck = { plainlist_t = { patterns = { '^plainlist$', '%splainlist$', '^plainlist%s', '%splainlist%s' }, found = false, styles = 'Plainlist/styles.css' }, hlist_t = { patterns = { '^hlist$', '%shlist$', '^hlist%s', '%shlist%s' }, found = false, styles = 'Hlist/styles.css' } } --------------------------------------------------------------- -- -- 工具箱方法 (Util Function) -- local addNewline = function(s) if mw.ustring.match(s,'^[*:;#]') or mw.ustring.match(s,'^{|') then return '\n' .. s .. '\n' else return s end end ---数组除重 local removeDump = function(arr) local _t1, _t2 = {}, {} for _, val in pairs(arr) do _t1[val] = true end for key, _ in pairs(_t1) do table.insert(_t2, key) end return _t2 end function tableToString(_table) local outputs = {} if _table == nil then table.insert(outputs, '<nil>') elseif type(_table) == 'table' then for k, v in pairs(_table) do local output if type(v) == 'table' then output = tableToString(v) else output = tostring(v) end table.insert(outputs, tostring(k) .. "=" .. output) end end return '{' .. table.concat(outputs, ",") .. '}' end function debugLog(prefix , ...) if not DEBUG then return end if #arg == 0 then mw.log(prefix) else for k, v in pairs(arg) do local pass = false or tostring(k) == 'n' if not pass then local _v = v if type(v) == 'table' then _v = tableToString(v) end mw.log(prefix,tostring(_v)) end end end end --------------------------------------------------------------- -- -- 功能性方法 (Functional Function) -- ---获得有效的类型 local getValidType = function(input, defVal) --[[ if input == 'with columns' then input = NavType.H elseif input == 'with collapsible groups' then input = NavType.VC end]] return (NavType.V == input or NavType.H == input or NavType.VC == input) and input or defVal end ---检查border判断是不是子Navbox local borderIsChild = function(border) return (border == 'subgroup' or border == 'child') end --- 前缀生成 local makePrefix = function(oldPrefix, thisLevel) return oldPrefix == "" and thisLevel or (oldPrefix .. '-' .. thisLevel) end --[[ 获得参数 _prefix 只有1个参数时为直接取模板参数对应参数名值,否则是作为子Navbox体的前缀名,无结尾"-" _argKey 作为子Navbox体的具体参数名 defVal 默认值 context Navbox层级的上下文,注入时如果存在_argKey对应参数值则取上下文的存入值 _contextKey 代替_argKey作为上下文的参数名 ]] local getArg = function(_prefix, _argKey, defVal, context, _contextKey) local contextKey = _contextKey or _argKey if context and contextKey and context[contextKey] then -- debugLog('getArg By Context',contextKey) return context[contextKey] else local prefix = _prefix ~= nil and _prefix or "" local key = (_argKey == nil and _prefix ~= nil) and _prefix or _argKey local argsKey = makePrefix(prefix, key) -- debugLog('getArg By InputArg',argsKey) return args[argsKey] or defVal end end ---子Navbox参数组判断 local checkHaveChild = function(prefix, valuekey) return ( getValidType(getArg(prefix, valuekey .. '-type'), nil) and borderIsChild(getArg(prefix, valuekey .. '-border')) ) == true end local getListnumMakeKey = function(prefix) prefix = mw.ustring.gsub(prefix,'(-)', '%%-') local middle = (prefix == "" and "" or "%-") local listKeyMatch , contentKeyMatch= '^' .. prefix .. middle .. 'list(%d+)', '^' .. prefix .. middle .. 'content(%d+)' return listKeyMatch .. '$' , listKeyMatch .. '%-' , contentKeyMatch .. '$' , contentKeyMatch .. '%-' end ---获得listnum local getListnum = function(prefix, limit, contentEqList) debugLog("getListnum", {['prefix'] = prefix, ['limit'] = limit}) local listKeyMatchEnd, listKeyMatchSub, contentKeyMatchEnd, contentKeyMatchSub = getListnumMakeKey(prefix) local listnums = {} for k, v in pairs(args) do k = '' .. k -- debugLog("getListnum,k=",k) local listnum = ( mw.ustring.match(k, listKeyMatchEnd) or mw.ustring.match(k, listKeyMatchSub) ) or ( contentEqList and ( -- VerticalCollapsibleTable 的 Content适配 mw.ustring.match(k, contentKeyMatchEnd) or mw.ustring.match(k, contentKeyMatchSub) ) or nil ) if listnum and tonumber(listnum) <= limit then listnum = tonumber(listnum) table.insert(listnums, listnum) end end listnums = removeDump(listnums) table.sort(listnums) debugLog('getListnum End',{['listnums']=tableToString(listnums)}) return listnums end ---参数检查和摇匀 function p.shakeArgs(prefix, level, _type) local _ local list_limit = 0 _type = _type or getArg(prefix, "type") _ = getArg(prefix, "title") _ = getArg(prefix, "above") if _type == NavType.H then list_limit = Limit.horizontal.list for i = 1, Limit.horizontal.col do _ = getArg(prefix, "col" .. tostring(i) .. "header") --[[if checkHaveChild(prefix, "col" .. tostring(i) .. "header") then p.shakeArgs(makePrefix(prefix,"col" .. tostring(i) .. "header" ), level + 1) end ]] _ = getArg(prefix, "col" .. tostring(i)) if checkHaveChild(prefix, "col" .. tostring(i)) then p.shakeArgs(makePrefix(prefix, "col" .. tostring(i)), level + 1) end _ = getArg(prefix, "col" .. tostring(i) .. "footer") --[[if checkHaveChild(prefix, "col" .. tostring(i) .. "footer") then p.shakeArgs(makePrefix(prefix, "col" .. tostring(i) .."footer" ), level + 1) end ]] end elseif _type == NavType.V then list_limit = Limit.vertical elseif _type == NavType.VC then list_limit = Limit.vertical_collapsible end for i = 1, list_limit do _ = getArg(prefix, "group" .. tostring(i)) _ = getArg(prefix, "list" .. tostring(i)) if checkHaveChild(prefix, "list" .. tostring(i)) then p.shakeArgs(makePrefix(prefix, "list" .. tostring(i)), level + 1) end if checkHaveChild(prefix, "content" .. tostring(i)) then p.shakeArgs(makePrefix(prefix, "content" .. tostring(i)), level + 1) end end _ = getArg(prefix, "below") end -- 检查是否关闭展开折叠按钮 local hasCollapsibleToggle = function(context) local prefix = context.prefix local state = getArg(prefix, "state", nil, context) return not (state == 'off' or state == 'plain') end -- 检查是否使用过Navbar local hasNavBar = function(context,pass) if pass then return haveNavBarMarker end local prefix = context.prefix local navbar, name = getArg(prefix, "navbar", nil, context), getArg(prefix, "name") local parentTitle = mw.getCurrentFrame():getParent():getTitle():gsub('/sandbox$', '') local titleCheck = false if type(MainTemplateName) == 'table' then for _ , v in pairs(MainTemplateName) do if parentTitle == MainTemplateName then titleCheck = true break end end else titleCheck = (parentTitle == MainTemplateName) end if navbar == 'off' or navbar == 'plain' or ((not name) and titleCheck ) then return false else haveNavBarMarker = true --用来启动模版样式标记 return true end end -- 从CSS中提取出颜色 local extractColor = function(cssstr) -- return nil because navbar takes its argument into mw.html which handles -- nil gracefully, removing the associated style attribute return mw.ustring.match(';' .. cssstr .. ';', '.*;%s*([Cc][Oo][Ll][Oo][Rr]%s*:%s*.-)%s*;') or nil end -- 检测class是否存在需要list local has_list_class = function(args_to_check) debugLog('has_list_class',args_to_check) for _, list in pairs(listsCheck) do if not list.found then for _, arg in pairs(args_to_check) do for _, pattern in ipairs(list.patterns) do if mw.ustring.find(arg or '', pattern) then list.found = true break end end if list.found then break end end end end end local childEvenOddContextInject = function(childType,context,childContext) if getArg(childType,'evenodd','') ~= '' then childContext.oddevenContext = EvenoddContext.new(context,getArg) else childContext.oddevenContext = context.oddevenContext end if childType == NavType.H then childContext.noEvenOdd = true end end --------------------------------------------------------------- -- -- 元素渲染方法 (Element Render) -- ---创建表头 local function createNavTableHeader(context) debugLog('render TableHeader', context) local prefix = context.prefix local state, title, border = getArg(prefix, "state", nil, context), getArg(prefix, "title", nil, context), getArg(prefix, "border", nil, context) debugLog('render TableHeader args', { ['prefix'] = prefix, ['state'] = state, ['title'] = title, ['border'] = border }) local bodyclass = getArg(prefix, "bodyclass", nil, context) has_list_class({bodyclass}) local rootTable = mw.html.create('table') :attr('cellspacing', 0) :addClass('nowraplinks') :addClass(bodyclass) :css('border-spacing', 0) if title and hasCollapsibleToggle(context) then if state == 'collapsed' then state = 'mw-collapsed' end -- mw-collapsible 对应 展开模式 rootTable :addClass('mw-collapsible') :addClass(state or 'autocollapse') end if borderIsChild(border) or border == 'none' then rootTable :addClass('navbox-subgroup') :cssText(getArg(prefix,"bodystyle", nil,context)) :cssText(getArg(prefix, "style", nil, context)) else -- regular navobx - bodystyle and style will be applied to the wrapper table rootTable :addClass('navbox-inner') :css('background', 'transparent') :css('color', 'inherit') end rootTable:cssText(getArg(prefix, "innerstyle")) debugLog('render TableHeader End') return rootTable end ---创建三键导航 local function renderNavBar(titleCell, context) local prefix = context.prefix local name = getArg(prefix, "name") debugLog('render Navbar',{['name']=name}) if hasNavBar(context) then local navbarFunc = require('Module:Navbar')._navbar titleCell :wikitext(navbarFunc { name, mini = 1, fontstyle = extractColor( table.concat({ getArg(prefix, 'basestyle', nil, context) or '', getArg(prefix, 'titlestyle', nil, context) or '' }, ';') ) }) end debugLog('render Navbar End') end ---标题行 local function renderTitleRow(rootTable, context) local prefix = context.prefix local title, titleclass = getArg(prefix, "title", nil, context), getArg(prefix, "titleclass", nil, context) if not title then return end has_list_class({titleclass}) debugLog('render TitleRow', { ['prefix'] = prefix, ['title'] = title },context) local basestyle = getArg(prefix, "basestyle", nil, context) local titleRow = rootTable:tag('tr') local titleCell = titleRow:tag('th'):attr('scope', 'col') local titleColspan = context.totalColspan if hasCollapsibleToggle(context) then titleCell:addClass('collapsible-title') end --[[ 如果是水平式,层级大于1(作为子Navbox),border是子类型, 有奇偶上下文的话, 轮空一次 ]] do local border, type = getArg(prefix, "border", nil, context), getValidType(context.type, nil) if type == NavType.V and context.level > 1 and borderIsChild(border) and context.oddevenContext ~= nil then debugLog("oddevenContext passed") context.oddevenContext:next() end end titleCell :cssText(basestyle) :cssText(getArg(prefix, "titlestyle", nil, context)) :addClass('navbox-title') :attr('colspan',titleColspan) renderNavBar(titleCell, context) titleCell :tag('div') :addClass(titleclass) :css('font-size', '110%') :css('margin', '0 5em') :wikitext(addNewline(title)) debugLog('render TitleRow End') end ---上行 local function renderAboveRow(rootTable, context) local prefix = context.prefix local above, aboveclass = getArg(prefix, "above"), getArg(prefix,"aboveclass") if not above then return end has_list_class({aboveclass}) debugLog('render AboveRow', {['prefix'] = prefix}, context) local Colspan = context.totalColspan local AboveRow = rootTable:tag('tr') AboveRow :tag('td') :addClass('navbox-abovebelow') :addClass(aboveclass) :cssText(getArg(prefix, "basestyle")) :cssText(getArg(prefix,"abovestyle")) :attr('colspan', Colspan) :tag('div') :wikitext(addNewline(above)) debugLog('render AboveRow End') end ---下行 local function renderBelowRow(rootTable, context) local prefix = context.prefix local below, belowclass = getArg(prefix, "below"), getArg(prefix,"belowclass") if not below then return end has_list_class({belowclass}) debugLog('render BelowRow', {['prefix'] = prefix}, context) local Colspan = context.totalColspan local BelowRow = rootTable:tag('tr') BelowRow :tag('td') :addClass('navbox-abovebelow') :addClass(belowclass) :cssText(getArg(prefix, "basestyle")) :cssText(getArg(prefix,"belowstyle")) :attr('colspan', Colspan) :tag('div') :wikitext(addNewline(below)) debugLog('render BelowRow End') end --------------------------------------------------------------- -- 数据列的方法生成器 local function _renderColRow_FunctionBuilder(rootTable, context, nodeFunc) debugLog("_renderColRow_FunctionBuilder builded", {['context'] = context}) return function(listCellDivToWrite, divNotClose) debugLog("FunctionInrenderColRow", {['traceback']=debug.traceback(),['context'] = context, ['divNotClose'] = divNotClose}) if not divNotClose then listCellDivToWrite:done() -- div end :node(rootTable and nodeFunc(rootTable, context) or nodeFunc(context) ) :tag('div'):done() else listCellDivToWrite:node(nodeFunc(rootTable, context)) end end end ---数据行,统一的实现 local function _renderListRow(rootTable, context, OtherListFunction) local prefix, level = context.prefix, context.level local listnum = context.listnum or 1 local index = context.listindex or listnum --local isFirst, isOdd = (listnum == 1), (listnum % 2) == 1 local isFirst, isOdd = (listnum == 1), (index % 2) == 1 local ImageRowspan = context.totalRowspan + (context.imageCellCompensate or 0) local notNeedImage, notNeedGroup = context.notNeedImage, context.notNeedGroup debugLog('ValueRow Implement', { ['prefix'] = prefix, ['listnum'] = listnum, ['index'] = index, ['ImageRowspan'] = ImageRowspan, ['HaveOtherListFunction'] = tostring(not not OtherListFunction), ['notNeedImage'] = notNeedImage, ['notNeedGroup'] = notNeedGroup, ['context'] = context }) local listRow = rootTable:tag('tr') local groupCell, listCell -- image local imageLeft, image, imageclass, insertImage = getArg(prefix, "imageleft", nil, context), getArg(prefix, "image", nil, context), getArg(prefix, "imageclass", nil, context), false -- CollapsibleListRow 适配 if context.notImageLeftCell then imageLeft = nil end if context.notImageCell then image = nil end if isFirst and (not notNeedImage) then if imageLeft then has_list_class({imageclass}) debugLog('imageLeftRow', {['imageLeft'] = imageLeft}) listRow :tag('td') :addClass('noviewer') :addClass('navbox-image') :addClass(imageclass) :css('width', '1px') -- Minimize width :css('padding', '0px 2px 0px 0px') :cssText(getArg(prefix,"imageleftstyle",nil, context)) :attr('rowspan', ImageRowspan) :tag('div') :wikitext(addNewline(imageLeft)) :done() -- div done :done() -- td done end if image then insertImage = true end end -- group start local needGroup, haveGroupWidth = false, false do local group, groupclass, groupwidth = getArg(prefix,"group" ..listnum,nil,context), getArg(prefix, "groupclass", nil, context), nil if group and not notNeedGroup then needGroup = true end if group then groupwidth = getArg(prefix,"groupwidth") end if groupwidth then haveGroupWidth = true end --debugLog("_renderListRow().group_part",{['group']=group,['groupwidth']=groupwidth}) if needGroup then has_list_class({groupclass}) debugLog('groupTh', {['group'] = group}) groupCell = listRow :tag('th') :attr('scope', 'row') :addClass('navbox-group') :addClass(groupclass) :cssText(getArg(prefix, "basestyle")) :css('width', groupwidth or "1%" ) -- If groupwidth not specified, minimize width :cssText(getArg(prefix, "groupstyle")) :cssText(getArg(prefix,'group' ..listnum ..'style')) :wikitext(group) end end -- group end -- list start do local listHaveChild = checkHaveChild(prefix, 'list' .. listnum) local contentHaveChild = context.contentEqList and checkHaveChild(prefix, 'content' .. listnum) listCell = listRow:tag('td') if needGroup then listCell:addClass('navbox-list-with-group') else listCell:attr('colspan', 2) end if not haveGroupWidth then listCell:css('width', '100%') end -- list奇偶控制 start local evenOdd , evenOddNavBoxClass , evenOddStyle if not (listHaveChild or contentHaveChild) then --有子Navbox则不生成奇偶 if context.oddevenContext ~= nil then --基于上下文的奇偶控制 local _evenOdd , _evenOddNavBoxClass , _evenOddStyle , _ _evenOddStyle = (isOdd and getArg(prefix, "oddstyle", "", context)) or getArg(prefix, "evenstyle", "", context) if (context.noEvenOdd or false) then -- 除list外部分停止使用奇偶交替 _evenOdd , _evenOddNavBoxClass = "odd", "navbox-odd" debugLog("evenoddContext.noEvenOdd",{_evenOdd , _evenOddNavBoxClass , _evenOddStyle }) else _evenOdd , _evenOddNavBoxClass = context.oddevenContext:next(); debugLog("evenoddContext",{_evenOdd , _evenOddNavBoxClass , _evenOddStyle }) end if context.lockEvenOdd then -- CollapsibleListRow 适配 _evenOdd = "odd" _evenOddNavBoxClass = 'navbox-' .. _evenOdd end if context.noEvenOddStyle then -- CollapsibleListRow 适配 _evenOddStyle = "" end debugLog("evenoddContext.final",{_evenOdd , _evenOddNavBoxClass , _evenOddStyle }) evenOdd , evenOddNavBoxClass , evenOddStyle = _evenOdd , _evenOddNavBoxClass , _evenOddStyle else -- 原有基于参数的奇偶模式 local no_evenOddStyle = false evenOdd = getArg(prefix, "evenodd", "") if evenOdd == "off" then no_evenOddStyle = true elseif evenOdd == "odd" or evenOdd == "even" then --isOdd = (evenOdd == "odd") elseif evenOdd == "swap" then isOdd = not isOdd end if (context.noEvenOdd or false) then -- 除list外部分停止使用奇偶交替 no_evenOddStyle = true end if context.lockEvenOdd then -- CollapsibleListRow 适配 evenOdd, isOdd = 'odd', true end if context.noEvenOddStyle then -- CollapsibleListRow 适配 no_evenOddStyle = true end evenOdd = no_evenOddStyle and "odd" or (isOdd and "odd" or "even") evenOddStyle = no_evenOddStyle and "" or ((isOdd and getArg(prefix, "oddstyle", "", context)) or getArg(prefix, "evenstyle", "", context)) evenOddNavBoxClass = 'navbox-' .. evenOdd debugLog("evenodd.old",{evenOdd , evenOddNavBoxClass , evenOddStyle }) end else evenOdd , evenOddNavBoxClass , evenOddStyle = "odd", "navbox-odd" , "" end -- list奇偶控制 end local list1padding = (notNeedGroup) and getArg(prefix, "list1padding", nil, context) or '0em 0.25em' local listNpadding = (isFirst and list1padding) or (getArg(prefix, "listpadding", nil, context) or '0em 0.25em') local listNstyle = (isFirst and getArg(prefix, 'list1style', '', context)) or getArg(prefix, 'list' .. listnum .. 'style', '') local liststyle = getArg(prefix, "liststyle", '', context) local listclass = getArg(prefix, "listclass", nil , context) local listNclass = getArg(prefix, "list".. listnum .."class", nil , context) has_list_class({listclass, listNclass}) listCell :css('padding', '0px') :cssText(liststyle) :cssText(evenOddStyle) :cssText(listNstyle) :addClass('navbox-list') :addClass(evenOddNavBoxClass) :addClass(listclass) :addClass(listNclass) local tempdiv = listCell:tag('div'):css('padding', listNpadding) if OtherListFunction then debugLog('ValueRow OtherListFunction', { ['otherListFunctionDivNotClose'] = context.otherListFunctionDivNotClose }) OtherListFunction(tempdiv, context.otherListFunctionDivNotClose) elseif (listHaveChild or contentHaveChild) and level <= Limit.child then local listKeyName = contentHaveChild and 'content' or 'list' local childPrefix= makePrefix(prefix, listKeyName ..listnum) local childType = getValidType(getArg(childPrefix,'type'), NavType.V) local childContext = NavboxContext.new( childPrefix, level + 1, childType ) childEvenOddContextInject(childType,context,childContext) debugLog('ValueRow NewChild', childContext) tempdiv :done() -- div end :node(p.renderNavTable(childContext)) :tag('div'):done() else local list_str = getArg(prefix, 'list' .. listnum, '') local content_str = getArg(prefix, 'content' .. listnum, '') -- VerticalCollapsibleTable 的 Content适配 if not context.contentEqList then content_str = '' end debugLog('ValueRow listnum', {['listnum'] = listnum}) tempdiv:wikitext(addNewline(table.concat({list_str,content_str}))) end end -- list end if insertImage then has_list_class({imageclass}) debugLog('imageRow', {['image'] = image}) listRow :tag('td') :addClass('noviewer') :addClass('navbox-image') :addClass(imageclass) :css('width', '1px') -- Minimize width :css('padding', '0px 0px 0px 2px') :cssText(getArg(prefix, "imagestyle", nil, context)) :attr('rowspan',ImageRowspan) :tag('div') :wikitext(addNewline(image)) end debugLog('ValueRow Implement End') end ---数据行,垂直式的具体实现 local function renderListRow(rootTable, context) debugLog('render ListRow', context) _renderListRow(rootTable, context) debugLog('render ListRow End') end --------------------------------------------------------------- ---数据列,水平式的具体实现 (ColRow) local function _renderColRow(rootTable, context) local prefix, level = context.prefix, context.level local fullwidth = getArg(prefix, "fullwidth") local col1header, col1, col1footer = getArg(prefix, 'col1header'), getArg(prefix, 'col1'), getArg(prefix, 'col1footer') debugLog('ColRow Implement', {['prefix'] = prefix}, context) -- new table root rootTable = mw.html.create('table') rootTable :addClass("navbox-columns-table") :css('border-spacing', '0px') :css('text-align', 'left') :cssText((col1header or fullwidth) and "width:100%;" or "width:auto;margin-left:auto;margin-right:auto;") :cssText(getArg(prefix,"coltablestyle")) local headerTR, colbodyTR, footerTR = nil, nil, nil -- header if col1header then debugLog('ColRow Header', {}) headerTR = rootTable:tag('tr') for colnum = 1, Limit.horizontal.col do debugLog('ColRow Header', colnum) local isFirst, isOdd = colnum == 1, (colnum % 2) == 1 local colheaderkey = 'col' .. colnum .. 'header' local colNheader = isFirst and col1header or getArg(prefix, colheaderkey) if headerTR and colNheader then debugLog('ColRow Herder Cell', {['colnum'] = colnum}) local headerNCell = headerTR:tag('td') headerNCell :addClass('navbox-abovebelow') :css('font-weight', 'bold') :cssText(isFirst and "" or "border-left:2px solid #fdfdfd;") :cssText(getArg(prefix, "colheaderstyle")) :cssText(getArg(prefix,colheaderkey ..'style')) :attr((colnum ~= Limit.horizontal.col and {['colspan'] = getArg(prefix, colheaderkey .. 'colspan', 1)}) or {}) --[[ if checkHaveChild(prefix,colheaderkey) and level<= Limit.child then local childContext=NavboxContext.new(colheaderkey ,level+1 ,NavType.H,context) debugLog('ColRow Herder NewChild',childContext) headerNCell:node(p.renderNavTable(childContext):allDone()) else]] -- debugLog('ColRow Herder Cell',{['colnum']=colnum}) headerNCell:wikitext(addNewline(colNheader)) -- end end end debugLog('ColRow Header End', {['colnum'] = colnum}) end -- col local col1havechild = checkHaveChild(prefix, "col1") if col1 or col1havechild then debugLog('ColRow Body', {['col1havechild'] = col1havechild}) colbodyTR = rootTable:tag('tr'):cssText('vertical-align:top;') if not (col1header or col1footer or fullwidth) then local padding, test0 = getArg(prefix, "padding"), nil if padding then padding = mw.text.trim(padding) test0 = mw.ustring.find(padding,'^0[%%%a]?[%a]?[;]?$') end if test0 ~= nil or padding == 'off' then else colbodyTR :tag('td') :css("width", padding or '5em') :wikitext(' ') :done() end end for colnum = 1, Limit.horizontal.col do local isFirst, isOdd = colnum == 1, (colnum % 2) == 1 local colkey = 'col' .. colnum local colN = isFirst and col1 or getArg(prefix, colkey) local colNhavechild = isFirst and col1havechild or checkHaveChild(prefix, colkey) debugLog('ColRow Body', {['prefix']=prefix,['colnum']=colnum,['colkey']=colkey}) if colN or colNhavechild then local oddevenstyle = getArg(prefix, isOdd and 'oddcolstyle' or'evencolstyle') local colNCell = colbodyTR :tag('td') :addClass('navbox-list') :css("padding", "0px") :cssText(((not isFirst) and "border-left:2px solid #fdfdfd;") or '') :cssText(getArg(prefix, 'colstyle')) :cssText(oddevenstyle) :cssText(getArg(prefix, colkey .. 'style')) :css('width', (getArg(prefix, colkey .. 'width') or getArg(prefix, 'colwidth')) or '10em') if checkHaveChild(prefix, colkey) and level <= Limit.child then local newPrefix = makePrefix(prefix , colkey) local childType = getValidType(getArg(newPrefix, 'type'), NavType.H) local childContext = NavboxContext.new( newPrefix, level + 1, childType ) childEvenOddContextInject(childType,context,childContext) debugLog('ColRow Body NewChild', childContext) colNCell :tag('div'):done() :node(p.renderNavTable(childContext):allDone()) :tag('div'):done() else debugLog('ColRow Body Cell', {['colnum'] = colnum}) colNCell:tag('div'):wikitext(addNewline('\n'..colN..'\n')) end end debugLog('ColRow Body End', {['colnum'] = colnum}) end end -- footer if col1footer then debugLog('ColRow footer', {}) footerTR = rootTable:tag('tr') for colnum = 1, Limit.horizontal.col do debugLog('ColRow footer', colnum) local isFirst, isOdd = colnum == 1, (colnum % 2) == 1 local colfooterkey = 'col' .. colnum .. 'footer' local colNfooter = isFirst and col1footer or getArg(prefix, colfooterkey) if colNfooter then debugLog('ColRow footer Cell', {['colnum'] = colnum}) local footerNCell = footerTR:tag('td') footerNCell :addClass('navbox-abovebelow') :css('font-weight', 'bold') :cssText(isFirst and "" or "border-left:2px solid #fdfdfd;") :cssText(getArg(prefix, "colfooterstyle")) :cssText(getArg(prefix, colfooterkey ..'style')) :attr((colnum ~= Limit.horizontal.col and {['colspan'] = getArg(prefix,colfooterkey .. 'colspan', 1)}) or {}) --[[ if checkHaveChild(prefix,colfooterkey) and level<= Limit.child then local childContext=NavboxContext.new(colfooterkey ,level+1 ,NavType.H,context) debugLog('ColRow footer NewChild',childContext) footerNCell:node(p.renderNavTable(childContext):allDone()) else]] -- debugLog('ColRow footer Cell',{['colnum']=colnum}) footerNCell:wikitext(addNewline(colNfooter)) -- end end end debugLog('ColRow footer End', {['colnum'] = colnum}) end debugLog('ColRow Implement End') return rootTable:allDone() end -- 数据列,具体实现 local function renderColRow(rootTable, context) debugLog('renderColRow', {['context'] = context}) context['notNeedGroup'] = true context['list1padding'] = '0px' context['list1style'] = "background:transparent;color:inherit;" context['otherListFunctionDivNotClose'] = true context['imageCellCompensate'] = 1 _renderListRow( rootTable, context, _renderColRow_FunctionBuilder(rootTable,context,_renderColRow) ) -- clean up context['notNeedGroup'] = nil context['list1padding'] = nil context['list1style'] = nil context['otherListFunctionDivNotClose'] = nil context['imageCellCompensate'] = nil debugLog('renderColRow End') end --------------------------------------------------------------- -- 折叠行式的子Nabox local function _renderSmallNavboxInCollapsibleListRow(rootTable, context) local prefix, level = context.prefix, context.level debugLog('_renderSmallNavboxInCollapsibleListRow', {['prefix'] = prefix}, {['context'] = context}) local listnum = context.listnum -- 部分需要压制传入的样式 context.bodyclass = '' context.titleclass = '' context.groupclass = '' context.imageclass = '' context.bodystyle = '' context.style = '' context.basestyle = '' context.imagestyle = '' context.imageleftstyle = '' -- 传入本级奇偶样式 do local oddstyle , evenstyle = getArg(prefix, 'oddstyle', ''), getArg(prefix, 'evenstyle', '') if oddstyle ~= '' then context.oddstyle = oddstyle end if evenstyle ~= '' then context.evenstyle = evenstyle end end -- 传入renderNavBar,renderTitleRow context.navbar = 'plain' context.border = 'child' local selected, abbrN, state = getArg(prefix, 'selected'), getArg(prefix, 'abbr' .. listnum), 'expanded' if selected ~= nil and selected == abbrN then state = 'expanded' else state = getArg(prefix, 'state' .. listnum, 'collapsed') end context.state = state -- 传入renderTitleRow -- context.titleEqGroup=true context.titlestyle = table.concat({ (getArg(prefix, 'basestyle', '')), (getArg(prefix, 'groupstyle', '')), (getArg(prefix, 'secttitlestyle', '')), (getArg(prefix, 'group' .. listnum .. 'style', '')), (getArg(prefix, 'sect' .. listnum .. 'titlestyle', '')) }, ';') context.title = (getArg(prefix, 'group' .. listnum, '')) .. (getArg(prefix, 'sect' .. listnum, '')) .. (getArg(prefix, 'section' .. listnum, '')) -- 传入renderListRow context.contentEqList = true context.notNeedGroup = true context.liststyle = table.concat({ (getArg(prefix, 'liststyle', '')), (getArg(prefix, 'contentstyle', '')), (getArg(prefix, 'list' .. listnum .. 'style', '')), (getArg(prefix, 'content' .. listnum .. 'style', '')) }, ';') local totalColspan = 2 -- title,above,below local totalRowspan = 1 -- image,imageleft -- 传入image local imageLeft, image = getArg(prefix, "imageleft" .. listnum, nil,context, 'imageleft'), getArg(prefix,"image" ..listnum,nil, context,'image') if imageLeft then totalColspan = totalColspan + 1 context.imageleft = imageLeft else context.notImageLeftCell = true -- CollapsibleListRow 适配 end if image then totalColspan = totalColspan + 1 context.image = image else context.notImageCell = true -- CollapsibleListRow 适配 end context.totalColspan = totalColspan context.totalRowspan = totalRowspan context.lockEvenOdd = true -- CollapsibleListRow 适配 debugLog( 'SmallNavboxInCollapsibleListRow Implement', 'listnum=' .. listnum, context) -- start local rootTable2 = createNavTableHeader(context) renderTitleRow(rootTable2, context) -- only 1 list local otherListFunction local listHaveChild = checkHaveChild(prefix, 'list' .. listnum) local contentHaveChild = context.contentEqList and checkHaveChild(prefix, 'content' .. listnum) if (listHaveChild or contentHaveChild) and level <= Limit.child then local listKeyName = 'list' if contentHaveChild then listKeyName = 'content' end local childPrefix = makePrefix(prefix , listKeyName .. listnum) local childContext = NavboxContext.new( childPrefix, level + 1, getValidType(getArg(childPrefix, 'type'),NavType.V) ) childContext.oddevenContext = context.oddevenContext debugLog('SmallNavboxInCollapsibleListRow NewChild', childContext) otherListFunction = _renderColRow_FunctionBuilder( nil, childContext, p.renderNavTable) end context.noEvenOddStyle = true _renderListRow(rootTable2, context, otherListFunction) context.noEvenOddStyle = nil debugLog('_renderSmallNavboxInCollapsibleListRow End') return rootTable2:allDone() end ---折叠行具体实现 local function renderCollapsibleListRow(rootTable, context) local prefix, level = context.prefix, context.level debugLog('renderCollapsibleListRow', { ['prefix'] = prefix, ['context'] = context}) context.notNeedGroup = true local listnum = context.listnum local context_function local title = getArg(prefix, 'group' .. listnum, '') .. getArg(prefix, 'sect' .. listnum, '' ) .. getArg(prefix, 'section' .. listnum, '') if title ~= '' then local grandChild_context = NavboxContext.new(prefix, level) grandChild_context.notNeedGroup = true grandChild_context.listpadding = getArg(prefix, 'listpadding') grandChild_context.listnum = listnum grandChild_context.listindex = context.listindex grandChild_context.oddevenContext = context.oddevenContext grandChild_context.title = title context_function = _renderColRow_FunctionBuilder( rootTable, grandChild_context, _renderSmallNavboxInCollapsibleListRow) debugLog('renderCollapsibleListRow function generate', { ['context'] = context, ['grandChild_context'] = grandChild_context }) end context.noEvenOddStyle = true context.contentEqList = true debugLog('renderCollapsibleListRow renderListRow', {['context'] = context}) _renderListRow(rootTable, context, context_function) context.noEvenOddStyle = nil context.contentEqList = nil debugLog('renderCollapsibleListRow End') end --------------------------------------------------------------- -- -- Tracking categories -- -- 没有使用水平列表的导航框 local function needsHorizontalLists(context) local prefix = context.prefix local border, tracking = context.border or getArg(prefix, 'border'), getArg(prefix, 'tracking') debugLog('needsHorizontalLists', {['border']=border,['tracking']=tracking}) if borderIsChild(border) or tracking == 'no' then return false end return not listsCheck.hlist_t.found and not listsCheck.plainlist_t.found end -- 使用背景颜色的导航框 local function hasBackgroundColors(context) local prefix = context.prefix for _, key in ipairs({'titlestyle', 'groupstyle', 'basestyle'}) do local style=context[key] or getArg(prefix, key) or '' if tostring(style):find('background', 1, true) then return true end end return false end -- name參數和實際不同的導航框 local function argNameAndRealTitleAreDifferent(context) local prefix = context.prefix local border, name, tracking = getArg(prefix, 'border', nil, context), getArg(prefix, 'name', nil, context), getArg(prefix, 'tracking') debugLog('argNameAndRealTitleAreDifferent', {['border']=border,['name']=name,['tracking']=tracking}) if borderIsChild(border) or tracking == 'no' or not hasNavBar(context) then return false end if name ~= mw.title.getCurrentTitle().text then return true end return false end local catCheckList = { ['needsHorizontalLists'] = { ['catkey'] = 'needsHorizontalLists', ['catCheckFunc'] = needsHorizontalLists, ['catName'] = '没有使用水平列表的导航框' }, ['hasBackgroundColors'] = { ['catkey'] = 'hasBackgroundColors', ['catCheckFunc'] = hasBackgroundColors, ['catName'] = '使用背景颜色的导航框' }, ['argNameAndRealTitleAreDifferent'] = { ['catkey'] = 'argNameAndRealTitleAreDifferent', ['catCheckFunc'] = argNameAndRealTitleAreDifferent, ['catName'] = 'name參數和實際不同的導航框' } } -- 检查并获得需要的分类 local function getTrackingCategories(context) local cats = _G['globalCatList'] or {} for catkey, checkObj in pairs(catCheckList) do if checkObj['catCheckFunc'](context) then table.insert(cats, checkObj['catkey']) end end debugLog('getTrackingCategories',{['level']=context.level,['catList']=cats}) _G['globalCatList'] = cats end -- 生成分类 local function renderTrackingCategories(builder, context) local title = mw.title.getCurrentTitle() if DEBUG == false then 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 -- end getTrackingCategories(context) debugLog('renderTrackingCategories',{['level']=context.level}) if context.level ==1 then local catList=_G['globalCatList'] or {} catList = removeDump(catList) for i, cat in ipairs(catList) do builder:wikitext('[[Category:' .. catCheckList[cat]['catName'] ..']]') end end end --------------------------------------------------------------- -- -- 模板样式的调整 -- -- work around [[phab:T303378]] -- for each arg: find all the templatestyles strip markers, insert them into a -- table. then remove all templatestyles markers from the arg local function move_hiding_templatestyles(args) local gfind = string.gfind local gsub = string.gsub local templatestyles_markers = {} local strip_marker_pattern = '(\127[^\127]*UNIQ%-%-templatestyles%-%x+%-QINU[^\127]*\127)' for k, arg in pairs(args) do for marker in gfind(arg, strip_marker_pattern) do table.insert(templatestyles_markers, marker) end args[k] = gsub(arg, strip_marker_pattern, '') end return templatestyles_markers end -- -- Load the templatestyles for the navbox -- local function loadTemplateStyles(hiding_templatestyles) local frame = mw.getCurrentFrame() local templateStyles = {} -- 提前注入,到时清空 templateStyles[1] = frame:extensionTag{ name = 'templatestyles', args = { src = listsCheck.hlist_t.styles } } templateStyles[2] = frame:extensionTag{ name = 'templatestyles', args = { src = listsCheck.plainlist_t.styles } } --[[ if listsCheck.hlist_t.found then hlist_templatestyles = frame:extensionTag{ name = 'templatestyles', args = { src = listsCheck.hlist_t.styles } } else templateStyles[1] = '' end ]] --[[ -- a second workaround for phab:T303378 -- when that issue is fixed, we can actually use has_navbar not to emit the -- tag here if we want]] --[[ if hasNavBar(nil,true) and hlist_templatestyles == '' then hlist_templatestyles = frame:extensionTag{ name = 'templatestyles', args = { src = listsCheck.hlist_t.styles } } templateStyles[1] = hlist_templatestyles end]] --[[ if listsCheck.plainlist_t.found then templateStyles[2] = frame:extensionTag{ name = 'templatestyles', args = { src = listsCheck.plainlist_t.styles } } else templateStyles[2] = '' end ]] templateStyles[3] = frame:extensionTag{ name = 'templatestyles', args = { src = 'Module:Navbox/styles.css' } } local base_templatestyles = getArg("","templatestyles","") if base_templatestyles~= '' then templateStyles[4] = frame:extensionTag{ name = 'templatestyles', args = { src = base_templatestyles } } else templateStyles[4] = '' end local child_templatestyles = getArg("","child templatestyles","") if child_templatestyles~= '' then templateStyles[5] = frame:extensionTag{ name = 'templatestyles', args = { src = child_templatestyles } } else templateStyles[5] = '' end -- 其他 for _ , v in pairs(hiding_templatestyles) do templateStyles[#templateStyles+1] = v end return templateStyles end --------------------------------------------------------------- -- -- SubType Implement -- ---水平式 (col) local function renderHorizontalTable(context) debugLog('render Horizontal NavTable', context) local prefix, level = context.prefix, context.level local rootTable = createNavTableHeader(context) local listnums = getListnum(prefix, Limit.horizontal.list) local totalColspan = 2 -- title,above,below local totalRowspan = #listnums -- image,imageleft if getArg(prefix, "imageleft", nil, context) then totalColspan = totalColspan + 1 end if getArg(prefix, "image", nil, context) then totalColspan = totalColspan + 1 end context.totalColspan = totalColspan context.totalRowspan = totalRowspan renderTitleRow(rootTable, context) renderAboveRow(rootTable, context) if listnums == nil or #listnums == 0 then -- 没有list的话,只有col debugLog('render Horizontal NavTable,no list', {listnums}) context.listnum = 1 renderColRow(rootTable, context) -- context.notNeedImage=true else debugLog('render Horizontal NavTable,have list with col', {listnums}) if getArg(prefix, "evenOdd", "") == "" and context.oddevenContext == nil then context.oddevenContext = EvenoddContext.new(context,getArg) end for i, listnum in ipairs(listnums) do context.listnum = listnum if listnum == 1 then -- 一行Col context.noEvenOdd = true renderColRow(rootTable, context) context.notNeedImage = true -- clear context.noEvenOdd = nil else context.notNeedImage = nil end context.listindex = i _renderListRow(rootTable, context) end end renderBelowRow(rootTable, context) if (getArg("nocat") or 'false'):lower() == 'false' then renderTrackingCategories(rootTable, context) end debugLog('render Horizontal NavTable End') return rootTable end ---垂直式 (list) local function renderVerticalTable(context) debugLog('render Vertical NavTable', context) local prefix, level = context.prefix, context.level local rootTable = createNavTableHeader(context) local listnums = getListnum(prefix, Limit.vertical) local totalColspan = 2 -- title,above,below local totalRowspan = #listnums -- image,imageleft if getArg(prefix, "imageleft", nil, context) then totalColspan = totalColspan + 1 end if getArg(prefix, "image", nil, context) then totalColspan = totalColspan + 1 end context.totalColspan = totalColspan context.totalRowspan = totalRowspan renderTitleRow(rootTable, context) renderAboveRow(rootTable, context) if getArg(prefix, "evenOdd", "") == "" and context.oddevenContext == nil then context.oddevenContext = EvenoddContext.new(context,getArg) end for i, listnum in ipairs(listnums) do context.listnum = listnum context.listindex = i renderListRow(rootTable, context) end renderBelowRow(rootTable, context) if (getArg("nocat") or 'false'):lower() == 'false' then renderTrackingCategories(rootTable, context) end debugLog('render Vertical NavTable End') return rootTable end ---垂直折叠式(Collapsible, list/content ) local function renderVerticalCollapsibleTable(context) debugLog('render VerticalCollapsible NavTable', context) local prefix, level = context.prefix, context.level local rootTable = createNavTableHeader(context) local listnums = getListnum(prefix, Limit.vertical, ( --[[context.contentEqList or ]] true) -- VerticalCollapsibleTable 的 Content适配 ) local totalColspan = 2 -- title,above,below local totalRowspan = #listnums -- image,imageleft if getArg(prefix, "imageleft", nil, context) then totalColspan = totalColspan + 1 end if getArg(prefix, "image", nil, context) then totalColspan = totalColspan + 1 end context.totalColspan = totalColspan context.totalRowspan = totalRowspan renderTitleRow(rootTable, context) renderAboveRow(rootTable, context) if getArg(prefix, "evenOdd", "") == "" and context.oddevenContext == nil then context.oddevenContext = EvenoddContext.new(context,getArg) end for i, listnum in ipairs(listnums) do context.listnum = listnum context.listindex = i renderCollapsibleListRow(rootTable, context) end renderBelowRow(rootTable, context) if (getArg("nocat") or 'false'):lower() == 'false' then renderTrackingCategories(rootTable, context) end debugLog('render VerticalCollapsible NavTable End') return rootTable end -- Type Selector function p.renderNavTable(context) local navtype = context.type debugLog('render NavTable') debugLog('Type=' .. navtype) local result if navtype == NavType.H then result = renderHorizontalTable(context) elseif navtype == NavType.VC then result = renderVerticalCollapsibleTable(context) else result = renderVerticalTable(context) end debugLog('render NavTable End') return result end -- Main Funtion function p._navbox(templateArgs, context) args = templateArgs -- 转移模板入参 debugLog('Navbox mainfuntion', context) local prefix, level = context.prefix, context.level local navboxclass = getArg(prefix, "navboxclass") local hiding_templatestyles = move_hiding_templatestyles(args) local rootTable --[[ 适配list内再嵌套单独Navbox的情况,部分Navbox可以单独或者再嵌入使用 原生的Navbox的各种实现机制就是Navbox嵌套 ]] local border = mw.text.trim(getArg(prefix, 'border') or getArg(prefix, '1') or '') debugLog("_Navbox.border", border) local templateStylesArr={} if border == 'none' then templateStylesArr=loadTemplateStyles(hiding_templatestyles) rootTable = p.renderNavTable(context):allDone() if not (listsCheck.hlist_t.found or hasNavBar(nil,true)) then templateStylesArr[1] = "" --清空掉 end if not listsCheck.plainlist_t.found then templateStylesArr[2] = "" --清空掉 end elseif borderIsChild(border) then -- Navbox的值段直接嵌套单独Navbox的情况 rootTable = mw.html.create() rootTable :wikitext('</div>') :node(p.renderNavTable(context):allDone()) :wikitext('<div>') else templateStylesArr=loadTemplateStyles(hiding_templatestyles) has_list_class({navboxclass}) rootTable = mw.html.create('table') rootTable :attr('cellspacing', 0) :addClass('navbox') :addClass(navboxclass) :css('border-spacing', 0) :cssText(getArg(prefix, 'bodystyle')) :cssText(getArg(prefix, 'style')) :tag('tr') :tag('td') :css('padding', '2px') :node(p.renderNavTable(context):allDone()) if not (listsCheck.hlist_t.found or hasNavBar(nil,true)) then templateStylesArr[1] = "" --清空掉 end if not listsCheck.plainlist_t.found then templateStylesArr[2] = "" --清空掉 end end local tsNode = mw.html.create('div') :addClass("navbox-styles") :wikitext(table.concat(templateStylesArr)) debugLog('Navbox mainfuntion End') return tsNode:allDone() , rootTable:allDone() end -- Level 0 enter function function p._L0navbox(templateArgs,moduleArgsType) args = templateArgs -- 转移模板入参 local prefix, level = "", 1 local navType = getValidType( getArg(prefix, 'type') or moduleArgsType, NavType.V) -- Read the arguments in the order they'll be output in, to make references number in the right order. p.shakeArgs(prefix, level, navType) local L0Context = NavboxContext.new(prefix, level, navType) return p._navbox(templateArgs,L0Context) end -- template enter function function p.navbox(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end local moduleArgs = getArgs(frame, {frameOnly = true}) DEBUG = (moduleArgs['DEBUG']=='true') or DEBUG MainTemplateName = moduleArgs['MainTemplateName'] or MainTemplateName if mw.ustring.find(MainTemplateName,",") then MainTemplateName = mw.text.split(MainTemplateName,",") end local templateArgs = getArgs(frame, {wrappers = MainTemplateName, trim = true}) DEBUG = (templateArgs['DEBUG']=='true') or DEBUG debugLog('Navbox start') local tsNode , rootNode = p._L0navbox(templateArgs,moduleArgs['type']) debugLog('rootnode build done, Navbox end') return table.concat({tostring(tsNode) , tostring(rootNode)}) end return p
返回
Module:NavboxV2
。
查看“︁Module:NavboxV2”︁的源代码
来自大天使虫洞百科