นี่เป็นมอดูลที่ถูกป้องกันถาวรเนื่องจากมีความเสี่ยงสูง กรุณาอภิปรายการเปลี่ยนแปลงใด ๆ ทาง(หน้าคุย) คุณอาจส่งคำขอแก้ไขไปยังเพื่อให้แก้ไขได้หากเป็นการแก้ไขที่ไม่มีการคัดค้านหรือมีความเห็นพ้องสนับสนุน คุณยังสามารถขอให้เลิกป้องกันหน้าได้ |
มอดูลนี้ขึ้นอยู่กับมอดูลอื่น ๆ ดังต่อไปนี้
|
มอดูลนี้ทำให้เกิดผลต่อแม่แบบ {{}} ศึกษาวิธีการใช้งานได้ที่
หมวดหมู่ติดตาม/บำรุงรักษา
- (42)
- (873)
- (3,282)
- (536)
- (56)
คู่มือการใช้งานที่ปรากฏด้านบนนี้ดึงมาจาก (มอดูล:Navbox/doc) (แก้ | ประวัติ) ผู้เขียนสามารถทำการทดลองได้ที่(กระบะทราย) (แก้ | ดูความแตกต่าง) และชุดทดสอบ (สร้าง) ของมอดูลนี้ |
require('strict') local p = {} local navbar = require('มอดูล:Navbar')._navbar local cfg = mw.loadData('มอดูล:Navbox/configuration') local getArgs -- lazily initialized local args local format = string.format local function striped(wikitext, border) -- 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 = cfg.category.orphan if border == cfg.keyword.border_subgroup and args[cfg.arg.orphan] ~= cfg.keyword.orphan_yes then -- No change; striping occurs in outermost navbox. return wikitext .. orphanCat end local first, second = cfg.class.navbox_odd_part, cfg.class.navbox_even_part if args[cfg.arg.evenodd] then if args[cfg.arg.evenodd] == cfg.keyword.evenodd_swap then first, second = second, first else first = args[cfg.arg.evenodd] second = first end end local changer if first == second then changer = first else local index = 0 changer = function (code) if code == '0' then -- Current occurrence is for a group before a nested table. -- Set it to first as a valid although pointless class. -- The next occurrence will be the first row after a title -- in a subgroup and will also be first. index = 0 return first end index = index + 1 return index % 2 == 1 and first or second end end local regex = orphanCat:gsub('([%[%]])', '%%%1') return (wikitext:gsub(regex, ''):gsub(cfg.marker.regex, changer)) -- () omits gsub count end local function processItem(item, nowrapitems) if item:sub(1, 2) == '{|' 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' .. item ..'\n' end if nowrapitems == cfg.keyword.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(cfg.pattern.nowrap) then line = format(cfg.nowrap_item, prefix, content) end table.insert(lines, line) end item = table.concat(lines, '\n') end if item:match('^[*:;#]') then return '\n' .. item ..'\n' end return item end local function has_navbar() return args[cfg.arg.navbar] ~= cfg.keyword.navbar_off and args[cfg.arg.navbar] ~= cfg.keyword.navbar_plain and ( args[cfg.arg.name] or mw.getCurrentFrame():getParent():getTitle():gsub(cfg.pattern.sandbox, '') ~= cfg.pattern.navbox ) end local function renderNavBar(titleCell) if has_navbar() then titleCell:wikitext(navbar{ [cfg.navbar.name] = args[cfg.arg.name], [cfg.navbar.mini] = 1, [cfg.navbar.fontstyle] = (args[cfg.arg.basestyle] or '') .. ';' .. (args[cfg.arg.titlestyle] or '') .. ';background:none transparent;border:none;box-shadow:none;padding:0;' }) end end local function renderTitleRow(tbl) if not args[cfg.arg.title] then return end local titleRow = tbl:tag('tr') local titleCell = titleRow:tag('th'):attr('scope', 'col') local titleColspan = 2 if args[cfg.arg.imageleft] then titleColspan = titleColspan + 1 end if args[cfg.arg.image] then titleColspan = titleColspan + 1 end titleCell :cssText(args[cfg.arg.basestyle]) :cssText(args[cfg.arg.titlestyle]) :addClass(cfg.class.navbox_title) :attr('colspan', titleColspan) renderNavBar(titleCell) titleCell :tag('div') -- id for aria-labelledby attribute :attr('id', mw.uri.anchorEncode(args[cfg.arg.title])) :addClass(args[cfg.arg.titleclass]) :css('font-size', '114%') :css('margin', '0 4em') :wikitext(processItem(args[cfg.arg.title])) end local function getAboveBelowColspan() local ret = 2 if args[cfg.arg.imageleft] then ret = ret + 1 end if args[cfg.arg.image] then ret = ret + 1 end return ret end local function renderAboveRow(tbl) if not args[cfg.arg.above] then return end tbl:tag('tr') :tag('td') :addClass(cfg.class.navbox_abovebelow) :addClass(args[cfg.arg.aboveclass]) :cssText(args[cfg.arg.basestyle]) :cssText(args[cfg.arg.abovestyle]) :attr('colspan', getAboveBelowColspan()) :tag('div') -- id for aria-labelledby attribute, if no title :attr('id', (not args[cfg.arg.title]) and mw.uri.anchorEncode(args[cfg.arg.above]) or nil) :wikitext(processItem(args[cfg.arg.above], args[cfg.arg.nowrapitems])) end local function renderBelowRow(tbl) if not args[cfg.arg.below] then return end tbl:tag('tr') :tag('td') :addClass(cfg.class.navbox_abovebelow) :addClass(args[cfg.arg.belowclass]) :cssText(args[cfg.arg.basestyle]) :cssText(args[cfg.arg.belowstyle]) :attr('colspan', getAboveBelowColspan()) :tag('div') :wikitext(processItem(args[cfg.arg.below], args[cfg.arg.nowrapitems])) end local function renderListRow(tbl, index, listnum, listnums_size) local row = tbl:tag('tr') if index == 1 and args[cfg.arg.imageleft] then row :tag('td') :addClass(cfg.class.noviewer) :addClass(cfg.class.navbox_image) :addClass(args[cfg.arg.imageclass]) :css('width', '1px') -- Minimize width :css('padding', '0 2px 0 0') :cssText(args[cfg.arg.imageleftstyle]) :attr('rowspan', listnums_size) :tag('div') :wikitext(processItem(args[cfg.arg.imageleft])) end local group_and_num = format(cfg.arg.group_and_num, listnum) local groupstyle_and_num = format(cfg.arg.groupstyle_and_num, listnum) if args[group_and_num] 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[cfg.arg.title] or args[cfg.arg.above] or args[cfg.arg.group2]) then groupCell :attr('id', mw.uri.anchorEncode(args[cfg.arg.group1])) end groupCell :attr('scope', 'row') :addClass(cfg.class.navbox_group) :addClass(args[cfg.arg.groupclass]) :cssText(args[cfg.arg.basestyle]) -- If groupwidth not specified, minimize width :css('width', args[cfg.arg.groupwidth] or '1%') groupCell :cssText(args[cfg.arg.groupstyle]) :cssText(args[groupstyle_and_num]) :wikitext(args[group_and_num]) end local listCell = row:tag('td') if args[group_and_num] then listCell :addClass(cfg.class.navbox_list_with_group) else listCell:attr('colspan', 2) end if not args[cfg.arg.groupwidth] then listCell:css('width', '100%') end local rowstyle -- usually nil so cssText(rowstyle) usually adds nothing if index % 2 == 1 then rowstyle = args[cfg.arg.oddstyle] else rowstyle = args[cfg.arg.evenstyle] end local list_and_num = format(cfg.arg.list_and_num, listnum) local listText = args[list_and_num] local oddEven = cfg.marker.oddeven 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(cfg.pattern.navbox_title) and cfg.marker.restart or cfg.class.navbox_odd_part end local liststyle_and_num = format(cfg.arg.liststyle_and_num, listnum) local listclass_and_num = format(cfg.arg.listclass_and_num, listnum) listCell :css('padding', '0') :cssText(args[cfg.arg.liststyle]) :cssText(rowstyle) :cssText(args[liststyle_and_num]) :addClass(cfg.class.navbox_list) :addClass(cfg.class.navbox_part .. oddEven) :addClass(args[cfg.arg.listclass]) :addClass(args[listclass_and_num]) :tag('div') :css('padding', (index == 1 and args[cfg.arg.list1padding]) or args[cfg.arg.listpadding] or '0 0.25em' ) :wikitext(processItem(listText, args[cfg.arg.nowrapitems])) if index == 1 and args[cfg.arg.image] then row :tag('td') :addClass(cfg.class.noviewer) :addClass(cfg.class.navbox_image) :addClass(args[cfg.arg.imageclass]) :css('width', '1px') -- Minimize width :css('padding', '0 0 0 2px') :cssText(args[cfg.arg.imagestyle]) :attr('rowspan', listnums_size) :tag('div') :wikitext(processItem(args[cfg.arg.image])) end end local function has_list_class(htmlclass) local patterns = { '^' .. htmlclass .. '$', '%s' .. htmlclass .. '$', '^' .. htmlclass .. '%s', '%s' .. htmlclass .. '%s' } for arg, _ in pairs(args) do if type(arg) == 'string' and mw.ustring.find(arg, cfg.pattern.class) then for _, pattern in ipairs(patterns) do if mw.ustring.find(args[arg] or '', pattern) then return true end end end end return false end -- there are a lot of list classes in the wild, so we add their TemplateStyles local function add_list_styles() local frame = mw.getCurrentFrame() local function add_list_templatestyles(htmlclass, templatestyles) if has_list_class(htmlclass) then return frame:extensionTag{ name = 'templatestyles', args = { src = templatestyles } } else return '' end end local hlist_styles = add_list_templatestyles('hlist', cfg.hlist_templatestyles) local plainlist_styles = add_list_templatestyles('plainlist', cfg.plainlist_templatestyles) -- 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 has_navbar() and hlist_styles == '' then hlist_styles = frame:extensionTag{ name = 'templatestyles', args = { src = cfg.hlist_templatestyles } } end -- hlist -> plainlist is best-effort to preserve old Common.css ordering. -- this ordering is not a guarantee because most navboxes will emit only -- one of these classes [hlist_note] return hlist_styles .. plainlist_styles end local function needsHorizontalLists(border) if border == cfg.keyword.border_subgroup or args[cfg.arg.tracking] == cfg.keyword.tracking_no then return false end return not has_list_class(cfg.pattern.hlist) and not has_list_class(cfg.pattern.plainlist) end local function hasBackgroundColors() for _, key in ipairs({cfg.arg.titlestyle, cfg.arg.groupstyle, cfg.arg.basestyle, cfg.arg.abovestyle, cfg.arg.belowstyle}) do if tostring(args[key]):find('background', 1, true) then return true end end return false end local function hasBorders() for _, key in ipairs({cfg.arg.groupstyle, cfg.arg.basestyle, cfg.arg.abovestyle, cfg.arg.belowstyle}) do if tostring(args[key]):find('border', 1, true) then return true end end return false end local function isIllegible() local styleratio = require('มอดูล:Color contrast')._styleratio for key, style in pairs(args) do if tostring(key):match(cfg.pattern.style) then if styleratio{mw.text.unstripNoWiki(style)} < 4.5 then return true end end end return false end local function getTrackingCategories(border) local cats = {} if needsHorizontalLists(border) then table.insert(cats, cfg.category.horizontal_lists) end if hasBackgroundColors() then table.insert(cats, cfg.category.background_colors) end if isIllegible() then table.insert(cats, cfg.category.illegible) end if hasBorders() then table.insert(cats, cfg.category.borders) end return cats end local function renderTrackingCategories(builder, border) local title = mw.title.getCurrentTitle() if title.namespace ~= 10 then return end -- not in template space local subpage = title.subpageText if subpage == cfg.keyword.subpage_doc or subpage == cfg.keyword.subpage_sandbox or subpage == cfg.keyword.subpage_testcases then return end for _, cat in ipairs(getTrackingCategories(border)) do builder:wikitext('[[หมวดหมู่:' .. cat .. ']]') end end local function renderMainTable(border, listnums) local tbl = mw.html.create('table') :addClass(cfg.class.nowraplinks) :addClass(args[cfg.arg.bodyclass]) local state = args[cfg.arg.state] if args[cfg.arg.title] and state ~= cfg.keyword.state_plain and state ~= cfg.keyword.state_off then if state == cfg.keyword.state_collapsed then state = cfg.class.collapsed end tbl :addClass(cfg.class.collapsible) :addClass(state or cfg.class.autocollapse) end tbl:css('border-spacing', 0) if border == cfg.keyword.border_subgroup or border == cfg.keyword.border_none then tbl :addClass(cfg.class.navbox_subgroup) :cssText(args[cfg.arg.bodystyle]) :cssText(args[cfg.arg.style]) else -- regular navbox - bodystyle and style will be applied to the wrapper table tbl :addClass(cfg.class.navbox_inner) :css('background', 'transparent') :css('color', 'inherit') end tbl:cssText(args[cfg.arg.innerstyle]) renderTitleRow(tbl) renderAboveRow(tbl) local listnums_size = #listnums for i, listnum in ipairs(listnums) do renderListRow(tbl, i, listnum, listnums_size) end renderBelowRow(tbl) return tbl end local function add_navbox_styles(hiding_templatestyles) local frame = mw.getCurrentFrame() -- This is a lambda so that it doesn't need the frame as a parameter local function add_user_styles(templatestyles) if templatestyles and templatestyles ~= '' then return frame:extensionTag{ name = 'templatestyles', args = { src = templatestyles } } end return '' end -- get templatestyles. load base from config so that Lua only needs to do -- the work once of parser tag expansion local base_templatestyles = cfg.templatestyles local templatestyles = add_user_styles(args[cfg.arg.templatestyles]) local child_templatestyles = add_user_styles(args[cfg.arg.child_templatestyles]) -- The 'navbox-styles' div exists to wrap the styles to work around T200206 -- more elegantly. Instead of combinatorial rules, this ends up being linear -- number of CSS rules. return mw.html.create('div') :addClass(cfg.class.navbox_styles) :wikitext( add_list_styles() .. -- see [hlist_note] applied to 'before base_templatestyles' base_templatestyles .. templatestyles .. child_templatestyles .. table.concat(hiding_templatestyles) ) :done() 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 function p._navbox(navboxArgs) args = navboxArgs local hiding_templatestyles = move_hiding_templatestyles(args) local listnums = {} for k, _ in pairs(args) do if type(k) == 'string' then local listnum = k:match(cfg.pattern.listnum) if listnum then table.insert(listnums, tonumber(listnum)) end end end table.sort(listnums) local border = mw.text.trim(args[cfg.arg.border] or args[1] or '') if border == cfg.keyword.border_child then border = cfg.keyword.border_subgroup end -- render the main body of the navbox local tbl = renderMainTable(border, listnums) local res = mw.html.create() -- render the appropriate wrapper for the navbox, based on the border param if border == cfg.keyword.border_none then res:node(add_navbox_styles(hiding_templatestyles)) local nav = res:tag('div') :attr('role', 'navigation') :node(tbl) -- aria-labelledby title, otherwise above, otherwise lone group if args[cfg.arg.title] or args[cfg.arg.above] or (args[cfg.arg.group1] and not args[cfg.arg.group2]) then nav:attr( 'aria-labelledby', mw.uri.anchorEncode( args[cfg.arg.title] or args[cfg.arg.above] or args[cfg.arg.group1] ) ) else nav:attr('aria-label', cfg.aria_label) end elseif border == cfg.keyword.border_subgroup then -- We assume that this navbox is being rendered in a list cell of a -- parent navbox, and is therefore inside a div with padding:0em 0.25em. -- We start with a </div> to avoid the padding being applied, and at the -- end add a <div> to balance out the parent's </div> res :wikitext('</div>') :node(tbl) :wikitext('<div>') else res:node(add_navbox_styles(hiding_templatestyles)) local nav = res:tag('div') :attr('role', 'navigation') :addClass(cfg.class.navbox) :addClass(args[cfg.arg.navboxclass]) :cssText(args[cfg.arg.bodystyle]) :cssText(args[cfg.arg.style]) :css('padding', '3px') :node(tbl) -- aria-labelledby title, otherwise above, otherwise lone group if args[cfg.arg.title] or args[cfg.arg.above] or (args[cfg.arg.group1] and not args[cfg.arg.group2]) then nav:attr( 'aria-labelledby', mw.uri.anchorEncode(args[cfg.arg.title] or args[cfg.arg.above] or args[cfg.arg.group1]) ) else nav:attr('aria-label', cfg.aria_label) end end if (args[cfg.arg.nocat] or cfg.keyword.nocat_false):lower() == cfg.keyword.nocat_false then renderTrackingCategories(res, border) end return striped(tostring(res), border) end function p.navbox(frame) if not getArgs then getArgs = require('มอดูล:Arguments').getArgs end args = getArgs(frame, {wrappers = {cfg.pattern.navbox}}) -- Read the arguments in the order they'll be output in, to make references -- number in the right order. local _ _ = args[cfg.arg.title] _ = args[cfg.arg.above] -- Limit this to 20 as covering 'most' cases (that's a SWAG) and because -- iterator approach won't work here for i = 1, 20 do _ = args[format(cfg.arg.group_and_num, i)] _ = args[format(cfg.arg.list_and_num, i)] end _ = args[cfg.arg.below] return p._navbox(args) end return p
wikipedia, แบบไทย, วิกิพีเดีย, วิกิ หนังสือ, หนังสือ, ห้องสมุด, บทความ, อ่าน, ดาวน์โหลด, ฟรี, ดาวน์โหลดฟรี, mp3, วิดีโอ, mp4, 3gp, jpg, jpeg, gif, png, รูปภาพ, เพลง, เพลง, หนัง, หนังสือ, เกม, เกม, มือถือ, โทรศัพท์, Android, iOS, Apple, โทรศัพท์โมบิล, Samsung, iPhone, Xiomi, Xiaomi, Redmi, Honor, Oppo, Nokia, Sonya, MI, PC, พีซี, web, เว็บ, คอมพิวเตอร์
niepnmxdulthithukpxngknthawrenuxngcakmikhwamesiyngsung krunaxphipraykarepliynaeplngid thanghnakhuy khunxacsngkhakhxaekikh ipyngphuduaelrabbephuxihaekikhidhakepnkaraekikhthiimmikarkhdkhanhruxmikhwamehnphxngsnbsnun khunyngsamarthkhxihelikpxngknhnaidkhumuxkarichnganmxdul du aek prawti langaekhch mxdulnikhunxyukbmxdulxun dngtxipnimxdul Navbar krabathray mxdul Color contrastmxdul Arguments krabathray mxdulnithaihekidphltxaemaebb Navbox suksawithikarichnganidthi hnakhxngaemaebb hmwdhmutidtam barungrksa hmwdhmu klxngnathangkaphra 42 hmwdhmu klxngnathangthiimmiraykaraenwnxn 873 hmwdhmu klxngnathangthiichsiphunhlng 3 282 hmwdhmu klxngnathangthiichsixacxanidyak 536 hmwdhmu klxngnathangthiichesnkhxb 56 khumuxkarichnganthipraktdanbnnidungmacak mxdul Navbox doc aek prawti phuekhiynsamarththakarthdlxngidthikrabathray aek dukhwamaetktang aelachudthdsxb srang khxngmxdulni hnayxykhxngmxdulni require strict local p local navbar require mxdul Navbar navbar local cfg mw loadData mxdul Navbox configuration local getArgs lazily initialized local args local format string format local function striped wikitext border 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 cfg category orphan if border cfg keyword border subgroup and args cfg arg orphan cfg keyword orphan yes then No change striping occurs in outermost navbox return wikitext orphanCat end local first second cfg class navbox odd part cfg class navbox even part if args cfg arg evenodd then if args cfg arg evenodd cfg keyword evenodd swap then first second second first else first args cfg arg evenodd second first end end local changer if first second then changer first else local index 0 changer function code if code 0 then Current occurrence is for a group before a nested table Set it to first as a valid although pointless class The next occurrence will be the first row after a title in a subgroup and will also be first index 0 return first end index index 1 return index 2 1 and first or second end end local regex orphanCat gsub 1 return wikitext gsub regex gsub cfg marker regex changer omits gsub count end local function processItem item nowrapitems if item sub 1 2 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 item n end if nowrapitems cfg keyword 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 cfg pattern nowrap then line format cfg nowrap item prefix content end table insert lines line end item table concat lines n end if item match then return n item n end return item end local function has navbar return args cfg arg navbar cfg keyword navbar off and args cfg arg navbar cfg keyword navbar plain and args cfg arg name or mw getCurrentFrame getParent getTitle gsub cfg pattern sandbox cfg pattern navbox end local function renderNavBar titleCell if has navbar then titleCell wikitext navbar cfg navbar name args cfg arg name cfg navbar mini 1 cfg navbar fontstyle args cfg arg basestyle or args cfg arg titlestyle or background none transparent border none box shadow none padding 0 end end local function renderTitleRow tbl if not args cfg arg title then return end local titleRow tbl tag tr local titleCell titleRow tag th attr scope col local titleColspan 2 if args cfg arg imageleft then titleColspan titleColspan 1 end if args cfg arg image then titleColspan titleColspan 1 end titleCell cssText args cfg arg basestyle cssText args cfg arg titlestyle addClass cfg class navbox title attr colspan titleColspan renderNavBar titleCell titleCell tag div id for aria labelledby attribute attr id mw uri anchorEncode args cfg arg title addClass args cfg arg titleclass css font size 114 css margin 0 4em wikitext processItem args cfg arg title end local function getAboveBelowColspan local ret 2 if args cfg arg imageleft then ret ret 1 end if args cfg arg image then ret ret 1 end return ret end local function renderAboveRow tbl if not args cfg arg above then return end tbl tag tr tag td addClass cfg class navbox abovebelow addClass args cfg arg aboveclass cssText args cfg arg basestyle cssText args cfg arg abovestyle attr colspan getAboveBelowColspan tag div id for aria labelledby attribute if no title attr id not args cfg arg title and mw uri anchorEncode args cfg arg above or nil wikitext processItem args cfg arg above args cfg arg nowrapitems end local function renderBelowRow tbl if not args cfg arg below then return end tbl tag tr tag td addClass cfg class navbox abovebelow addClass args cfg arg belowclass cssText args cfg arg basestyle cssText args cfg arg belowstyle attr colspan getAboveBelowColspan tag div wikitext processItem args cfg arg below args cfg arg nowrapitems end local function renderListRow tbl index listnum listnums size local row tbl tag tr if index 1 and args cfg arg imageleft then row tag td addClass cfg class noviewer addClass cfg class navbox image addClass args cfg arg imageclass css width 1px Minimize width css padding 0 2px 0 0 cssText args cfg arg imageleftstyle attr rowspan listnums size tag div wikitext processItem args cfg arg imageleft end local group and num format cfg arg group and num listnum local groupstyle and num format cfg arg groupstyle and num listnum if args group and num 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 cfg arg title or args cfg arg above or args cfg arg group2 then groupCell attr id mw uri anchorEncode args cfg arg group1 end groupCell attr scope row addClass cfg class navbox group addClass args cfg arg groupclass cssText args cfg arg basestyle If groupwidth not specified minimize width css width args cfg arg groupwidth or 1 groupCell cssText args cfg arg groupstyle cssText args groupstyle and num wikitext args group and num end local listCell row tag td if args group and num then listCell addClass cfg class navbox list with group else listCell attr colspan 2 end if not args cfg arg groupwidth then listCell css width 100 end local rowstyle usually nil so cssText rowstyle usually adds nothing if index 2 1 then rowstyle args cfg arg oddstyle else rowstyle args cfg arg evenstyle end local list and num format cfg arg list and num listnum local listText args list and num local oddEven cfg marker oddeven if listText sub 1 12 lt div gt lt table then Assume list text is for a subgroup navbox so no automatic striping for this row oddEven listText find cfg pattern navbox title and cfg marker restart or cfg class navbox odd part end local liststyle and num format cfg arg liststyle and num listnum local listclass and num format cfg arg listclass and num listnum listCell css padding 0 cssText args cfg arg liststyle cssText rowstyle cssText args liststyle and num addClass cfg class navbox list addClass cfg class navbox part oddEven addClass args cfg arg listclass addClass args listclass and num tag div css padding index 1 and args cfg arg list1padding or args cfg arg listpadding or 0 0 25em wikitext processItem listText args cfg arg nowrapitems if index 1 and args cfg arg image then row tag td addClass cfg class noviewer addClass cfg class navbox image addClass args cfg arg imageclass css width 1px Minimize width css padding 0 0 0 2px cssText args cfg arg imagestyle attr rowspan listnums size tag div wikitext processItem args cfg arg image end end local function has list class htmlclass local patterns htmlclass s htmlclass htmlclass s s htmlclass s for arg in pairs args do if type arg string and mw ustring find arg cfg pattern class then for pattern in ipairs patterns do if mw ustring find args arg or pattern then return true end end end end return false end there are a lot of list classes in the wild so we add their TemplateStyles local function add list styles local frame mw getCurrentFrame local function add list templatestyles htmlclass templatestyles if has list class htmlclass then return frame extensionTag name templatestyles args src templatestyles else return end end local hlist styles add list templatestyles hlist cfg hlist templatestyles local plainlist styles add list templatestyles plainlist cfg plainlist templatestyles 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 has navbar and hlist styles then hlist styles frame extensionTag name templatestyles args src cfg hlist templatestyles end hlist gt plainlist is best effort to preserve old Common css ordering this ordering is not a guarantee because most navboxes will emit only one of these classes hlist note return hlist styles plainlist styles end local function needsHorizontalLists border if border cfg keyword border subgroup or args cfg arg tracking cfg keyword tracking no then return false end return not has list class cfg pattern hlist and not has list class cfg pattern plainlist end local function hasBackgroundColors for key in ipairs cfg arg titlestyle cfg arg groupstyle cfg arg basestyle cfg arg abovestyle cfg arg belowstyle do if tostring args key find background 1 true then return true end end return false end local function hasBorders for key in ipairs cfg arg groupstyle cfg arg basestyle cfg arg abovestyle cfg arg belowstyle do if tostring args key find border 1 true then return true end end return false end local function isIllegible local styleratio require mxdul Color contrast styleratio for key style in pairs args do if tostring key match cfg pattern style then if styleratio mw text unstripNoWiki style lt 4 5 then return true end end end return false end local function getTrackingCategories border local cats if needsHorizontalLists border then table insert cats cfg category horizontal lists end if hasBackgroundColors then table insert cats cfg category background colors end if isIllegible then table insert cats cfg category illegible end if hasBorders then table insert cats cfg category borders end return cats end local function renderTrackingCategories builder border local title mw title getCurrentTitle if title namespace 10 then return end not in template space local subpage title subpageText if subpage cfg keyword subpage doc or subpage cfg keyword subpage sandbox or subpage cfg keyword subpage testcases then return end for cat in ipairs getTrackingCategories border do builder wikitext hmwdhmu cat end end local function renderMainTable border listnums local tbl mw html create table addClass cfg class nowraplinks addClass args cfg arg bodyclass local state args cfg arg state if args cfg arg title and state cfg keyword state plain and state cfg keyword state off then if state cfg keyword state collapsed then state cfg class collapsed end tbl addClass cfg class collapsible addClass state or cfg class autocollapse end tbl css border spacing 0 if border cfg keyword border subgroup or border cfg keyword border none then tbl addClass cfg class navbox subgroup cssText args cfg arg bodystyle cssText args cfg arg style else regular navbox bodystyle and style will be applied to the wrapper table tbl addClass cfg class navbox inner css background transparent css color inherit end tbl cssText args cfg arg innerstyle renderTitleRow tbl renderAboveRow tbl local listnums size listnums for i listnum in ipairs listnums do renderListRow tbl i listnum listnums size end renderBelowRow tbl return tbl end local function add navbox styles hiding templatestyles local frame mw getCurrentFrame This is a lambda so that it doesn t need the frame as a parameter local function add user styles templatestyles if templatestyles and templatestyles then return frame extensionTag name templatestyles args src templatestyles end return end get templatestyles load base from config so that Lua only needs to do the work once of parser tag expansion local base templatestyles cfg templatestyles local templatestyles add user styles args cfg arg templatestyles local child templatestyles add user styles args cfg arg child templatestyles The navbox styles div exists to wrap the styles to work around T200206 more elegantly Instead of combinatorial rules this ends up being linear number of CSS rules return mw html create div addClass cfg class navbox styles wikitext add list styles see hlist note applied to before base templatestyles base templatestyles templatestyles child templatestyles table concat hiding templatestyles done 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 function p navbox navboxArgs args navboxArgs local hiding templatestyles move hiding templatestyles args local listnums for k in pairs args do if type k string then local listnum k match cfg pattern listnum if listnum then table insert listnums tonumber listnum end end end table sort listnums local border mw text trim args cfg arg border or args 1 or if border cfg keyword border child then border cfg keyword border subgroup end render the main body of the navbox local tbl renderMainTable border listnums local res mw html create render the appropriate wrapper for the navbox based on the border param if border cfg keyword border none then res node add navbox styles hiding templatestyles local nav res tag div attr role navigation node tbl aria labelledby title otherwise above otherwise lone group if args cfg arg title or args cfg arg above or args cfg arg group1 and not args cfg arg group2 then nav attr aria labelledby mw uri anchorEncode args cfg arg title or args cfg arg above or args cfg arg group1 else nav attr aria label cfg aria label end elseif border cfg keyword 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 lt div gt to avoid the padding being applied and at the end add a lt div gt to balance out the parent s lt div gt res wikitext lt div gt node tbl wikitext lt div gt else res node add navbox styles hiding templatestyles local nav res tag div attr role navigation addClass cfg class navbox addClass args cfg arg navboxclass cssText args cfg arg bodystyle cssText args cfg arg style css padding 3px node tbl aria labelledby title otherwise above otherwise lone group if args cfg arg title or args cfg arg above or args cfg arg group1 and not args cfg arg group2 then nav attr aria labelledby mw uri anchorEncode args cfg arg title or args cfg arg above or args cfg arg group1 else nav attr aria label cfg aria label end end if args cfg arg nocat or cfg keyword nocat false lower cfg keyword nocat false then renderTrackingCategories res border end return striped tostring res border end function p navbox frame if not getArgs then getArgs require mxdul Arguments getArgs end args getArgs frame wrappers cfg pattern navbox Read the arguments in the order they ll be output in to make references number in the right order local args cfg arg title args cfg arg above Limit this to 20 as covering most cases that s a SWAG and because iterator approach won t work here for i 1 20 do args format cfg arg group and num i args format cfg arg list and num i end args cfg arg below return p navbox args end return p