Jump to content

विभाग:Navbox

Page protected
विकिपीडिया, मुक्‍त ज्ञानकोशातून

localp={}
localnavbar=require('Module:Navbar')._navbar
localcfg=mw.loadData('Module:Navbox/configuration')
localgetArgs-- lazily initialized
localargs
localformat=string.format

localfunctionstriped(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.
localorphanCat=cfg.category.orphan
ifborder==cfg.keyword.border_subgroupandargs[cfg.arg.orphan]~=cfg.keyword.orphan_yesthen
-- No change; striping occurs in outermost navbox.
returnwikitext..orphanCat
end
localfirst,second=cfg.class.navbox_odd_part,cfg.class.navbox_even_part
ifargs[cfg.arg.evenodd]then
ifargs[cfg.arg.evenodd]==cfg.keyword.evenodd_swapthen
first,second=second,first
else
first=args[cfg.arg.evenodd]
second=first
end
end
localchanger
iffirst==secondthen
changer=first
else
localindex=0
changer=function(code)
ifcode=='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
returnfirst
end
index=index+1
returnindex%2==1andfirstorsecond
end
end
localregex=orphanCat:gsub('([%[%]])','%%%1')
return(wikitext:gsub(regex,''):gsub(cfg.marker.regex,changer))-- () omits gsub count
end

localfunctionprocessItem(item,nowrapitems)
ifitem: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
ifnowrapitems==cfg.keyword.nowrapitems_yesthen
locallines={}
forlinein(item..'\n'):gmatch('([^\n]*)\n')do
localprefix,content=line:match('^([*:;#]+)%s*(.*)')
ifprefixandnotcontent:match(cfg.pattern.nowrap)then
line=format(cfg.nowrap_item,prefix,content)
end
table.insert(lines,line)
end
item=table.concat(lines,'\n')
end
ifitem:match('^[*:;#]')then
return'\n'..item..'\n'
end
returnitem
end

-- we will want this later when we want to add tstyles for hlist/plainlist
localfunctionhas_navbar()
returnargs[cfg.arg.navbar]~=cfg.keyword.navbar_off
andargs[cfg.arg.navbar]~=cfg.keyword.navbar_plain
and(
args[cfg.arg.name]
ormw.getCurrentFrame():getParent():getTitle():gsub(cfg.pattern.sandbox,'')
~=cfg.pattern.navbox
)
end

localfunctionrenderNavBar(titleCell)
ifhas_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

localfunctionrenderTitleRow(tbl)
ifnotargs[cfg.arg.title]thenreturnend

localtitleRow=tbl:tag('tr')

localtitleCell=titleRow:tag('th'):attr('scope','col')

localtitleColspan=2
ifargs[cfg.arg.imageleft]thentitleColspan=titleColspan+1end
ifargs[cfg.arg.image]thentitleColspan=titleColspan+1end

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

localfunctiongetAboveBelowColspan()
localret=2
ifargs[cfg.arg.imageleft]thenret=ret+1end
ifargs[cfg.arg.image]thenret=ret+1end
returnret
end

localfunctionrenderAboveRow(tbl)
ifnotargs[cfg.arg.above]thenreturnend

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',args[cfg.arg.title]andnilormw.uri.anchorEncode(args[cfg.arg.above]))
:wikitext(processItem(args[cfg.arg.above],args[cfg.arg.nowrapitems]))
end

localfunctionrenderBelowRow(tbl)
ifnotargs[cfg.arg.below]thenreturnend

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

localfunctionrenderListRow(tbl,index,listnum,listnums_size)
localrow=tbl:tag('tr')

ifindex==1andargs[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

localgroup_and_num=format(cfg.arg.group_and_num,listnum)
localgroupstyle_and_num=format(cfg.arg.groupstyle_and_num,listnum)
ifargs[group_and_num]then
localgroupCell=row:tag('th')

-- id for aria-labelledby attribute, if lone group with no title or above
iflistnum==1andnot(args[cfg.arg.title]orargs[cfg.arg.above]orargs[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

locallistCell=row:tag('td')

ifargs[group_and_num]then
listCell
:addClass(cfg.class.navbox_list_with_group)
else
listCell:attr('colspan',2)
end

ifnotargs[cfg.arg.groupwidth]then
listCell:css('width','100%')
end

localrowstyle-- usually nil so cssText(rowstyle) usually adds nothing
ifindex%2==1then
rowstyle=args[cfg.arg.oddstyle]
else
rowstyle=args[cfg.arg.evenstyle]
end

locallist_and_num=format(cfg.arg.list_and_num,listnum)
locallistText=args[list_and_num]
localoddEven=cfg.marker.oddeven
iflistText: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)andcfg.marker.restartorcfg.class.navbox_odd_part
end

localliststyle_and_num=format(cfg.arg.liststyle_and_num,listnum)
locallistclass_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==1andargs[cfg.arg.list1padding])orargs[cfg.arg.listpadding]or'0 0.25em'
)
:wikitext(processItem(listText,args[cfg.arg.nowrapitems]))

ifindex==1andargs[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

-- uses this now to make the needHlistCategory correct
-- to use later for when we add list styles via navbox
localfunctionhas_list_class(htmlclass)
localclass_args={-- rough order of probability of use
cfg.arg.bodyclass,cfg.arg.listclass,cfg.arg.aboveclass,
cfg.arg.belowclass,cfg.arg.titleclass,cfg.arg.navboxclass,
cfg.arg.groupclass,cfg.arg.imageclass
}
localpatterns={
'^'..htmlclass..'$',
'%s'..htmlclass..'$',
'^'..htmlclass..'%s',
'%s'..htmlclass..'%s'
}

for_,arginipairs(class_args)do
for_,patterninipairs(patterns)do
ifmw.ustring.find(args[arg]or'',pattern)then
returntrue
end
end
end
returnfalse
end

localfunctionneedsHorizontalLists(border)
ifborder==cfg.keyword.border_subgrouporargs[cfg.arg.tracking]==cfg.keyword.tracking_nothen
returnfalse
end
returnnothas_list_class(cfg.pattern.hlist)andnothas_list_class(cfg.pattern.plainlist)
end

localfunctionhasBackgroundColors()
for_,keyinipairs({cfg.arg.titlestyle,cfg.arg.groupstyle,
cfg.arg.basestyle,cfg.arg.abovestyle,cfg.arg.belowstyle})do
iftostring(args[key]):find('background',1,true)then
returntrue
end
end
returnfalse
end

localfunctionhasBorders()
for_,keyinipairs({cfg.arg.groupstyle,cfg.arg.basestyle,
cfg.arg.abovestyle,cfg.arg.belowstyle})do
iftostring(args[key]):find('border',1,true)then
returntrue
end
end
returnfalse
end

localfunctionisIllegible()
localstyleratio=require('Module:Color contrast')._styleratio
forkey,styleinpairs(args)do
iftostring(key):match(cfg.pattern.style)then
ifstyleratio{mw.text.unstripNoWiki(style)}<4.5then
returntrue
end
end
end
returnfalse
end

localfunctiongetTrackingCategories(border)
localcats={}
ifneedsHorizontalLists(border)thentable.insert(cats,cfg.category.horizontal_lists)end
ifhasBackgroundColors()thentable.insert(cats,cfg.category.background_colors)end
ifisIllegible()thentable.insert(cats,cfg.category.illegible)end
ifhasBorders()thentable.insert(cats,cfg.category.borders)end
returncats
end

localfunctionrenderTrackingCategories(builder,border)
localtitle=mw.title.getCurrentTitle()
iftitle.namespace~=10thenreturnend-- not in template space
localsubpage=title.subpageText
ifsubpage==cfg.keyword.subpage_docorsubpage==cfg.keyword.subpage_sandbox
orsubpage==cfg.keyword.subpage_testcasesthenreturnend

for_,catinipairs(getTrackingCategories(border))do
builder:wikitext('[[Category:'..cat..']]')
end
end

localfunctionrenderMainTable(border,listnums)
localtbl=mw.html.create('table')
:addClass(cfg.class.nowraplinks)
:addClass(args[cfg.arg.bodyclass])

localstate=args[cfg.arg.state]
ifargs[cfg.arg.title]andstate~=cfg.keyword.state_plainandstate~=cfg.keyword.state_offthen
ifstate==cfg.keyword.state_collapsedthen
state=cfg.class.collapsed
end
tbl
:addClass(cfg.class.collapsible)
:addClass(stateorcfg.class.autocollapse)
end

tbl:css('border-spacing',0)
ifborder==cfg.keyword.border_subgrouporborder==cfg.keyword.border_nonethen
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)
locallistnums_size=#listnums
fori,listnuminipairs(listnums)do
renderListRow(tbl,i,listnum,listnums_size)
end
renderBelowRow(tbl)

returntbl
end

localfunctionadd_navbox_styles()
localframe=mw.getCurrentFrame()
-- This is a lambda so that it doesn't need the frame as a parameter
localfunctionadd_user_styles(templatestyles)
iftemplatestylesandtemplatestyles~=''then
returnframe: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
localbase_templatestyles=cfg.templatestyles
localtemplatestyles=add_user_styles(args[cfg.arg.templatestyles])
localchild_templatestyles=add_user_styles(args[cfg.arg.child_templatestyles])

-- The 'navbox-styles' div exists for two reasons:
-- 1. To wrap the styles to work around 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.
returnmw.html.create('div')
:addClass(cfg.class.navbox_styles)
:addClass(cfg.class.nomobile)
:wikitext(base_templatestyles..templatestyles..child_templatestyles)
:done()
end

functionp._navbox(navboxArgs)
args=navboxArgs
locallistnums={}

fork,_inpairs(args)do
iftype(k)=='string'then
locallistnum=k:match(cfg.pattern.listnum)
iflistnumthentable.insert(listnums,tonumber(listnum))end
end
end
table.sort(listnums)

localborder=mw.text.trim(args[cfg.arg.border]orargs[1]or'')
ifborder==cfg.keyword.border_childthen
border=cfg.keyword.border_subgroup
end

-- render the main body of the navbox
localtbl=renderMainTable(border,listnums)

localres=mw.html.create()
-- render the appropriate wrapper for the navbox, based on the border param

ifborder==cfg.keyword.border_nonethen
res:node(add_navbox_styles())
localnav=res:tag('div')
:attr('role','navigation')
:node(tbl)
-- aria-labelledby title, otherwise above, otherwise lone group
ifargs[cfg.arg.title]orargs[cfg.arg.above]or(args[cfg.arg.group1]
andnotargs[cfg.arg.group2])then
nav:attr(
'aria-labelledby',
mw.uri.anchorEncode(
args[cfg.arg.title]orargs[cfg.arg.above]orargs[cfg.arg.group1]
)
)
else
nav:attr('aria-label',cfg.aria_label)
end
elseifborder==cfg.keyword.border_subgroupthen
-- 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())
localnav=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
ifargs[cfg.arg.title]orargs[cfg.arg.above]
or(args[cfg.arg.group1]andnotargs[cfg.arg.group2])then
nav:attr(
'aria-labelledby',
mw.uri.anchorEncode(args[cfg.arg.title]orargs[cfg.arg.above]orargs[cfg.arg.group1])
)
else
nav:attr('aria-label',cfg.aria_label)
end
end

if(args[cfg.arg.nocat]orcfg.keyword.nocat_false):lower()==cfg.keyword.nocat_falsethen
renderTrackingCategories(res,border)
end
returnstriped(tostring(res),border)
end

functionp.navbox(frame)
ifnotgetArgsthen
getArgs=require('Module: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
fori=1,20do
_=args[format(cfg.arg.group_and_num,i)]
_=args[format(cfg.arg.list_and_num,i)]
end
_=args[cfg.arg.below]

returnp._navbox(args)
end

returnp