وحدة:Navbox: الفرق بين النسختين

[نسخة منشورة][نسخة منشورة]
تم حذف المحتوى تمت إضافة المحتوى
الرجوع عن التعديل 67218462 بواسطة وهراني (نقاش)
وسمان: رجوع مُسترجَع
الرجوع عن التعديل 67214423 بواسطة حبيشان (نقاش) حصل تشوه في عدد كبير جداً من القوالب: الرجاء فحص التحديثات قبل إدراجها
وسمان: رجوع مُسترجَع
سطر 1:
--
require('strict')
-- This module implements {{Navbox}}
--
 
local p = {}
 
local navbar = require('Module:Navbar')._navbar
local cfg = mw.loadData('Module:Navbox/configuration')
local getArgs -- lazily initialized
 
local args
local format = string.formatborder
local listnums
local ODD_EVEN_MARKER = '\127_ODDEVEN_\127'
local RESTART_MARKER = '\127_ODDEVEN0_\127'
local REGEX_MARKER = '\127_ODDEVEN(%d?)_\127'
 
local function striped(wikitext, 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'[[Category:Navbox orphans]]'
if border == cfg.keyword.border_subgroup'subgroup' and args[cfg.arg.orphan] ~= cfg.keyword.orphan_yes'yes' then
-- No change; striping occurs in outermost navbox.
return wikitext .. orphanCat
end
local first, second = cfg.class.navbox_odd_part'odd', cfg.class.navbox_even_part'even'
if args[cfg.arg.evenodd] then
if args[cfg.arg.evenodd] == cfg.keyword.evenodd_swap'swap' then
first, second = second, first
else
first = args[cfg.arg.evenodd]
second = first
end
السطر 45 ⟵ 53:
end
local regex = orphanCat:gsub('([%[%]])', '%%%1')
return (wikitext:gsub(regex, ''):gsub(cfg.marker.regexREGEX_MARKER, changer)) -- () omits gsub count
end
 
السطر 54 ⟵ 62:
return '\n' .. item ..'\n'
end
if nowrapitems == cfg.keyword.nowrapitems_yes'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.'^<span class="nowrap">') then
line = format(cfgprefix ..nowrap_item, prefix,'<span class="nowrap">' .. content) .. '</span>'
end
table.insert(lines, line)
السطر 71 ⟵ 79:
end
 
local function has_navbarrenderNavBar(titleCell)
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
 
if args.navbar ~= 'off' and args.navbar ~= 'plain' and not (not args.name and mw.getCurrentFrame():getParent():getTitle():gsub('/sandbox$', '') == 'Template:Navbox') then
-- extract text color from css, which is the only permitted inline CSS for the navbar
local function extract_color(css_str)
-- return nil because navbar takes its argument into mw.html which handles
-- nil gracefully, removing the associated style attribute
return mw.ustring.match(';' .. css_str .. ';', '.*;%s*([Cc][Oo][Ll][Oo][Rr]%s*:%s*.-)%s*;') or nil
end
 
local function renderNavBar(titleCell)
if has_navbar() then
titleCell:wikitext(navbar{
[cfg.navbar.name] = args[cfg.arg.name],
[cfg.navbar.mini] = 1,
fontstyle = (args.basestyle or '') .. ';' .. (args.titlestyle or '') .. ';background:none transparent;border:none;box-shadow:none;padding:0;'
[cfg.navbar.fontstyle] = extract_color(
(args[cfg.arg.basestyle] or '') .. ';' .. (args[cfg.arg.titlestyle] or '')
)
})
end
السطر 101 ⟵ 91:
end
 
--
-- Title row
--
local function renderTitleRow(tbl)
if not args[cfg.arg.title] then return end
 
local titleRow = tbl:tag('tr')
 
if args.titlegroup then
titleRow
:tag('th')
:attr('scope', 'row')
:addClass('navbox-group')
:addClass(args.titlegroupclass)
:cssText(args.basestyle)
:cssText(args.groupstyle)
:cssText(args.titlegroupstyle)
:wikitext(args.titlegroup)
end
 
local titleCell = titleRow:tag('th'):attr('scope', 'col')
 
if args.titlegroup then
titleCell
:css('border-left', '2px solid #fdfdfd')
:css('width', '100%')
end
 
local titleColspan = 2
if args[cfg.arg.imageleft] then titleColspan = titleColspan + 1 end
if args[cfg.arg.image] then titleColspan = titleColspan + 1 end
if args.titlegroup then titleColspan = titleColspan - 1 end
 
titleCell
:cssText(args[cfg.arg.basestyle])
:cssText(args[cfg.arg.titlestyle])
:addClass(cfg.class.navbox_title'navbox-title')
:attr('colspan', titleColspan)
 
السطر 123 ⟵ 135:
: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
 
--
-- Above/Below rows
--
 
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'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 nil or 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'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)
-- List rows
--
local function renderListRow(tbl, index, listnum)
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'navbox-image')
:addClass(args[cfg.arg.imageclass])
:css('width', '1px') -- Minimize width
:css('padding', '00px 2px 00px 00px')
:cssText(args[cfg.arg.imageleftstyle])
:attr('rowspan', listnums_size#listnums)
:tag('div')
:wikitext(processItem(args[cfg.arg.imageleft]))
end
 
if args['group' .. listnum] then
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'navbox-group')
:addClass(args[cfg.arg.groupclass])
:cssText(args[cfg.arg.basestyle])
:css('width', args.groupwidth or '1%') -- 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'group' .. listnum .. 'style'])
:wikitext(args[group_and_num'group' .. listnum])
end
 
local listCell = row:tag('td')
 
if args[group_and_num'group' .. listnum] then
listCell
:css('text-align', 'right')
:addClass(cfg.class.navbox_list_with_group)
:css('border-right-width', '2px')
:css('border-right-style', 'solid')
else
listCell:attr('colspan', 2)
end
 
if not args[cfg.arg.groupwidth] then
listCell:css('width', '100%')
end
السطر 224 ⟵ 242:
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_numlistText = format(cfgargs['list' .arg.list_and_num, listnum)]
local listTextoddEven = args[list_and_num]ODD_EVEN_MARKER
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'<th[^>]*"navbox%-title"') and cfg.marker.restartRESTART_MARKER or cfg.class.navbox_odd_part'odd'
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', '00px')
:cssText(args[cfg.arg.liststyle])
:cssText(rowstyle)
:cssText(args[liststyle_and_num'list' .. listnum .. 'style'])
:addClass(cfg.class.navbox_list'navbox-list')
:addClass(cfg.class.navbox_part'navbox-' .. oddEven)
:addClass(args[cfg.arg.listclass])
:addClass(args[listclass_and_num'list' .. listnum .. 'class'])
:tag('div')
:css('padding', (index == 1 and args.list1padding) or args.listpadding or '0em 0.25em')
:css('padding',
:wikitext(processItem(listText, args.nowrapitems))
(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'navbox-image')
:addClass(args[cfg.arg.imageclass])
:css('width', '1px') -- Minimize width
:css('padding', '00px 00px 00px 2px')
:cssText(args[cfg.arg.imagestyle])
:attr('rowspan', listnums_size#listnums)
: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
-- Tracking categories
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'subgroup' or args[cfg.arg.tracking] == cfg.keyword.tracking_no'no' then
return false
end
local listClasses = {
return not has_list_class(cfg.pattern.hlist) and not has_list_class(cfg.pattern.plainlist)
['plainlist'] = true, ['hlist'] = true, ['hlist hnum'] = true,
['hlist hwrap'] = true, ['hlist vcard'] = true, ['vcard hlist'] = true,
['hlist vevent'] = true,
}
return not (listClasses[args.listclass] or listClasses[args.bodyclass])
end
 
local function hasBackgroundColors()
for _, key in ipairs({cfg.arg.'titlestyle', cfg.arg.'groupstyle', 'basestyle', 'abovestyle', 'belowstyle'}) do
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', 'abovestyle', 'belowstyle'}) do
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('Module: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
السطر 359 ⟵ 327:
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'doc' or subpage == cfg.keyword.subpage_sandbox'sandbox' or subpage == 'testcases' then return end
or subpage == cfg.keyword.subpage_testcases then return end
 
for _, cat in ipairs(getTrackingCategories(border)) do
builder:wikitext('[[Category:' .. cat .. ']]')
end
end
 
--
local function renderMainTable(border, listnums)
-- Main navbox tables
--
local function renderMainTable()
local tbl = mw.html.create('table')
:addClass(cfg.class.'nowraplinks')
:addClass(args[cfg.arg.bodyclass])
 
localif args.title and (args.state ~= 'plain' and args[cfg.arg.state] ~= 'off') then
if args[cfg.arg.title] and state ~== cfg.keyword.state_plain'collapsed' andthen args.state ~= cfg.keyword.state_off'mw-collapsed' thenend
if state == cfg.keyword.state_collapsed then
state = cfg.class.collapsed
end
tbl
:addClass(cfg.class.'mw-collapsible')
:addClass(args.state or cfg.class.'autocollapse')
end
 
tbl:css('border-spacing', 0)
if border == cfg.keyword.border_subgroup'subgroup' or border == cfg.keyword.border_none'none' then
tbl
:addClass(cfg.class.navbox_subgroup'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'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)
السطر 420 ⟵ 386:
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
--#Added function
function p.getTransArgs(args0)
local args1={}
السطر 492 ⟵ 409:
function p._navbox(navboxArgs)
args = navboxArgs
listnums = {}
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'^list(%d+)$')
if listnum then table.insert(listnums, tonumber(listnum)) end
end
السطر 503 ⟵ 419:
table.sort(listnums)
 
local border = mw.text.trim(args[cfg.arg.border] or args[1] or '')
if border == cfg.keyword.border_child'child' then
border = cfg.keyword.border_subgroup'subgroup'
end
 
-- render the main body of the navbox
local tbl = renderMainTable(border, listnums)
 
-- render the appropriate wrapper around the navbox, depending on the border param
local res = mw.html.create()
if border == 'none' then
-- 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.group2) then
nav:attr('aria-labelledby', mw.uri.anchorEncode(args.title or args.above or args.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'Navbox')
end
elseif border == cfg.keyword.border_subgroup'subgroup' then
-- We assume that this navbox is being rendered in a list cell of a parent navbox, and is
-- parent navbox, and is therefore inside a div with padding:0em 0.25em. We start with a </div> to avoid the
-- Wepadding being applied, and at the startend withadd a </div> to avoidbalance out the paddingparent's being applied, and at the</div>
-- end add a <div> to balance out the parent's </div>
res
:wikitext('</div>')
السطر 541 ⟵ 448:
: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', '1px')
:node(tbl)
-- aria-labelledby title, otherwise above, otherwise lone group
if args[cfg.arg.title] or args[cfg.arg.above] or (args.group1 and not args.group2) then
nav:attr('aria-labelledby', mw.uri.anchorEncode(args.title or args.above or args.group1))
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'Navbox')
end
end
 
if (args[cfg.arg.nocat] or cfg.keyword.nocat_false'false'):lower() == cfg.keyword.nocat_false'false' then
renderTrackingCategories(res, border)
end
return striped(tostring(res), border)
end
 
السطر 572 ⟵ 474:
getArgs = require('Module:Arguments').getArgs
end
--args = getArgs(frame, {wrappers = {'Template:Navbox'}})
--#Modified
args = p.getTransArgs(getArgs(frame))
--args = getArgs(frame, {wrappers = {cfg.pattern.navbox}})
 
args = p.getTransArgs(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.
-- 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"group" .arg.group_and_num, tostring(i)]
_ = args[format(cfg"list" .arg.list_and_num, tostring(i)]
end
_ = args[cfg.arg.below]
 
return p._navbox(args)