---- This module will implement {{Navbox}}--localp={}localHtmlBuilder=require('Module:HtmlBuilder')localNavbar=require('Module:Navbar')localargslocalframelocaltableRowAdded=falselocalborderlocallistnums={}functiontrim(s)return(mw.ustring.gsub(s,"^%s*(.-)%s*$","%1"))endfunctionaddTableRow(tbl)-- If any other rows have already been added, then we add a 2px gutter row.iftableRowAddedthentbl.tag('tr').css('height','2px').tag('td')endtableRowAdded=truereturntbl.tag('tr')end---- Title row--functionrenderTitleRow(tbl)ifnotargs.titlethenreturnendlocaltitleRow=addTableRow(tbl)ifargs.titlegroupthentitleRow.tag('th').attr('scope','row').addClass('navbox-group').addClass(args.titlegroupclass).cssText(args.basestyle).cssText(args.groupstyle).cssText(args.titlegroupstyle).wikitext(args.titlegroup)endlocaltitleCell=titleRow.tag('th').attr('scope','col')ifargs.titlegroupthentitleCell.css('border-left','2px solid #fdfdfd').css('width','100%')endlocaltitleColspan=2ifargs.imageleftthentitleColspan=titleColspan+1endifargs.imagethentitleColspan=titleColspan+1endifargs.titlegroupthentitleColspan=titleColspan-1endtitleCell.cssText(args.basestyle).cssText(args.titlestyle).addClass('navbox-title').attr('colspan',titleColspan)renderNavBar(titleCell)titleCell.tag('div').addClass(args.titleclass).css('font-size','110%').newline().wikitext(args.title)endfunctionrenderNavBar(titleCell)-- Depending on the presence of the navbar and/or show/hide link, we may need to add a spacer div on the left-- or right to keep the title centered.localspacerSide=nilifargs.navbar=='off'then-- No navbar, and client wants no spacer, i.e. wants the title to be shifted to the left. If there's-- also no show/hide link, then we need a spacer on the right to achieve the left shift.ifargs.state=='plain'thenspacerSide='right'endelseifargs.navbar=='plain'orargs.navbar=='off'or(notargs.nameand(border=='subgroup'orborder=='child'orborder=='none'))then-- No navbar. Need a spacer on the left to balance out the width of the show/hide link.ifargs.state~='plain'thenspacerSide='left'endelse-- Will render navbar (or error message). If there's no show/hide link, need a spacer on the right-- to balance out the width of the navbar.ifargs.state=='plain'thenspacerSide='right'endtitleCell.wikitext(Navbar.navbar({args.name,mini=1,fontstyle=(args.basestyleor'')..';'..(args.titlestyleor'')..';background:none transparent;border:none;'}))end-- Render the spacer div.ifspacerSidethentitleCell.tag('span').css('float',spacerSide).css('width','6em').wikitext('&nbsp;')endend---- Above/Below rows--functionrenderAboveRow(tbl)ifnotargs.abovethenreturnendaddTableRow(tbl).tag('td').addClass('navbox-abovebelow').addClass(args.aboveclass).cssText(args.basestyle).cssText(args.abovestyle).attr('colspan',getAboveBelowColspan()).tag('div').newline().wikitext(args.above)endfunctionrenderBelowRow(tbl)ifnotargs.belowthenreturnendaddTableRow(tbl).tag('td').addClass('navbox-abovebelow').addClass(args.belowclass).cssText(args.basestyle).cssText(args.belowstyle).attr('colspan',getAboveBelowColspan()).tag('div').newline().wikitext(args.below)endfunctiongetAboveBelowColspan()localret=2ifargs.imageleftthenret=ret+1endifargs.imagethenret=ret+1endreturnretend---- List rows--functionrenderListRow(tbl,listnum)localrow=addTableRow(tbl)iflistnum==1andargs.imageleftthenrow.tag('td').addClass('navbox-image').addClass(args.imageclass).css('width','0%').css('padding','0px 2px 0px 0px').cssText(args.imageleftstyle).attr('rowspan',2*#listnums-1).tag('div').newline().wikitext(args.imageleft)endifargs['group'..listnum]thenlocalgroupCell=row.tag('th')groupCell.attr('scope','row').addClass('navbox-group').addClass(args.groupclass).cssText(args.basestyle)ifargs.groupwidththengroupCell.css('width',args.groupwidth)endgroupCell.cssText(args.groupstyle).cssText(args['group'..listnum..'style']).wikitext(args['group'..listnum])endlocallistCell=row.tag('td')ifargs['group'..listnum]thenlistCell.css('text-align','left').css('border-left-width','2px').css('border-left-style','solid')elselistCell.attr('colspan',2)endifnotargs.groupwidththenlistCell.css('width','100%')endlocalisOdd=(listnum%2)==1localrowstyle=args.evenstyleifisOddthenrowstyle=args.oddstyleendlocalevenOddifargs.evenodd=='swap'thenifisOddthenevenOdd='even'elseevenOdd='odd'endelseifisOddthenevenOdd=args.evenoddor'odd'elseevenOdd=args.evenoddor'even'endendlistCell.css('padding','0px').cssText(args.liststyle).cssText(rowstyle).cssText(args['list'..listnum..'style']).addClass('navbox-list').addClass('navbox-'..evenOdd).addClass(args.listclass).tag('div').css('padding',(listnum==1andargs.list1padding)orargs.listpaddingor'0em 0.25em').newline().wikitext(args['list'..listnum])iflistnum==1andargs.imagethenrow.tag('td').addClass('navbox-image').addClass(args.imageclass).css('width','0%').css('padding','0px 0px 0px 2px').cssText(args.imagestyle).attr('rowspan',2*#listnums-1).tag('div').newline().wikitext(args.image)endend---- Tracking categories--functionrenderTrackingCategories(builder)localframe=mw.getCurrentFrame()ifnotframethenreturnendlocals=frame:preprocess('{{#ifeq:{{NAMESPACE}}|{{ns:10}}|1|0}}{{SUBPAGENAME}}')ifmw.ustring.sub(s,1,1)=='0'thenreturnend-- not in template spacelocalsubpage=mw.ustring.lower(mw.ustring.sub(s,2))ifsubpage=='doc'orsubpage=='sandbox'orsubpage=='testcases'thenreturnendfori,catinipairs(getTrackingCategories())dobuilder.wikitext('[[Category:'..cat..']]')endendfunctiongetTrackingCategories()localcats={}ifneedsHorizontalLists()thentable.insert(cats,'Navigational boxes without horizontal lists')endifhasCustomListSpacing()thentable.insert(cats,'Navigational boxes with custom list spacing')endifhasBackgroundColors()thentable.insert(cats,'Navboxes using background colours')endreturncatsendfunctionneedsHorizontalLists()ifborder=='child'orborder=='subgroup'orargs.tracking=='no'thenreturnfalseendlocallistClasses={'plainlist','hlist','hlist hnum','hlist vcard','vcard hlist'}fori,clsinipairs(listClasses)doifargs.listclass==clsorargs.bodyclass==clsthenreturnfalseendendreturntrueendfunctionhasCustomListSpacing()returnargs.liststyle=='padding: 0.25em 0; line-height: 1.3em;'orargs.liststyle=='padding:0.25em 0; line-height:1.4em; width:auto;'orargs.liststyle=='padding:0.4em 0; line-height:1.4em;'endfunctionhasBackgroundColors()returnargs.titlestyleorargs.groupstyleend---- Main navbox tables--functionrenderMainTable()localtbl=HtmlBuilder.create('table').attr('cellspacing',0).addClass('nowraplinks').addClass(args.bodyclass)ifargs.titleand(args.state~='plain'andargs.state~='off')thentbl.addClass('collapsible').addClass(args.stateor'autocollapse')endtbl.css('border-spacing',0)ifborder=='subgroup'orborder=='child'orborder=='none'thentbl.addClass('navbox-subgroup').cssText(args.bodystyle).cssText(args.style)else-- regular navobx - bodystyle and style will be applied to the wrapper tabletbl.addClass('navbox-inner').css('background','transparent').css('color','inherit')endtbl.cssText(args.innerstyle)renderTitleRow(tbl)renderAboveRow(tbl)fori,listnuminipairs(listnums)dorenderListRow(tbl,listnum)endrenderBelowRow(tbl)returntblendfunctionp._navbox(navboxArgs)args=navboxArgsfork,vinpairs(args)dolocallistnum=(''..k):match('^list(%d+)$')iflistnumthentable.insert(listnums,tonumber(listnum))endendtable.sort(listnums)border=trim(args.borderorargs[1]or'')-- render the main body of the navboxlocaltbl=renderMainTable()-- render the appropriate wrapper around the navbox, depending on the border paramlocalres=HtmlBuilder.create()ifborder=='none'thenres.node(tbl)elseifborder=='subgroup'orborder=='child'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.tag('/div',{unclosed=true}).done().node(tbl).tag('div',{unclosed=true})elseres.tag('table').attr('cellspacing',0).addClass('navbox').css('border-spacing',0).cssText(args.bodystyle).cssText(args.style).tag('tr').tag('td').css('padding','2px').node(tbl)endrenderTrackingCategories(res)returntostring(res)endfunctionp.navbox(frame)-- ParserFunctions considers the empty string to be false, so to preserve the previous -- behavior of {{navbox}}, change any empty arguments to nil, so Lua will consider-- them false too.localargs={}localparent_args=frame:getParent().args;-- Out of order parsing bug.localtemp;temp=parent_args.title;temp=parent_args.above;fori=1,35dotemp=parent_args["group"..tostring(i)];temp=parent_args["list"..tostring(i)];endtemp=parent_args.below;fork,vinpairs(parent_args)doifv~=''thenargs[k]=vendendreturnp._navbox(args)endreturnp