Изменения

Перейти к: навигация, поиск

Модуль:Navbox

5411 байт убрано, 13:27, 28 августа 2017
Нет описания правки
--
-- Этот модуль реализует This module implements {{Навигационная таблицаNavbox}}.-- Основной объём кода заимствован из английского Module:Navbox.
--
local p = {}
local navbar = require('Module:Navbar')._navbar
local getArgs -- lazily initialized
local args
local tableRowAdded = false
local border
local listnums = {}
local ODD_EVEN_MARKER = '\127_ODDEVEN_\127'
local RESTART_MARKER = '\127_ODDEVEN0_\127'
local REGEX_MARKER = '\127_ODDEVEN(%d?)_\127'
local maintitlefunction trim(s)local name return (mw.ustring.gsub(s, "^%s*(.-)%s*$", "%1"))local navbarlocal abovelocal imagelocal belowend
local titlestylefunction addNewline(s)local groupstyle if s:match('^[*:;#]') or s:match('^{|') thenlocal bodystyle return '\n' .. s ..'\n'local basestyle elselocal liststyle return slocal oddstyle endlocal evenstylelocal evenoddARGlocal abovestylelocal belowstylelocal imageleftlocal imageleftstylelocal styleend
local groupwidthfunction addTableRow(tbl)local listpadding -- If any other rows have already been added, then we add a 2px gutter row. if tableRowAdded then tbl :tag('tr') :css('height', '2px') :tag('td') :attr('colspan',2) end
local bodyclasslocal titleclasslocal aboveclasslocal belowclasslocal groupclasslocal listclasslocal imageclass tableRowAdded = true
local function striped(wikitext) -- 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 = '[[Категория:Навигационные шаблоны без родителя]]' if border == 'subgroup' and args.orphan ~= 'yes' then -- No change; striping occurs in outermost navbox. return wikitext .. orphanCat end local first, second = 'odd', 'even' if args.evenodd then if args.evenodd == 'swap' then first, second = second, first else first = args.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 (wikitexttbl:gsubtag(regex, 'tr'):gsub(REGEX_MARKER, changer)) -- () omits gsub count
end
local function addNewlinerenderNavBar(stitleCell) if s:match('^[*:;#]') -- Depending on the presence of the navbar and/or s:match('^{|') thenshow/hide link, we may need to add a spacer div on the left return '\n' -- or right to keep the title centered.. s ..'\n' else return s endend local spacerSide = nil
local function renderNavBar if args.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. if args.state == 'plain' then spacerSide = 'right' end elseif args.navbar == 'plain' or (titleCellnot args.name and mw.getCurrentFrame():getParent():getTitle() == 'Template:Navbox' and (border == 'subgroup' or border == 'child' or border == 'none')) then -- No navbar. Need a spacer on the left to balance out the width of the show/hide link. if args.state ~= 'plain' then spacerSide = 'left' end else -- 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. if args.state == 'plain' then spacerSide = 'right' end
if titleCell:wikitext(navbar ~= 'off' and navbar ~= 'plain' and not (not { args.name and mw.getCurrentFrame():getParent():getTitle():gsub('/песочница$', '') mini == 'Шаблон:Навигационная таблица') then -- Check color contrast of the gear icon1, local styleratio fontstyle = require(args.basestyle or 'Module:Color contrast')._styleratio local gearColor = . ';' local contrastStyle = titlestyle or basestyle local gearStyleBlack = (contrastStyle and mw.text.unstripNoWiki(contrastStyle) args.. '; color:#666;' titlestyle or '') local gearStyleWhite = (contrastStyle and mw.text.unstripNoWiki(contrastStyle) .. '; colorbackground:#fffnone transparent;border:none;' or '') if styleratio{gearStyleBlack} < styleratio{gearStyleWhite } then gearColor = ' white' end --- Gear creation titleCell :tag('span') :css('float', 'left') :css('text-align', 'left') :css('width', '5em') :css('margin-right', '0.5em') :wikitext('[[Файл:Wikipedia interwiki section gear icon' .. gearColor .. '.svg|14px|Просмотр этого шаблона|link=Шаблон:' .. name .. '|alt=⛭]]') end
-- Render the spacer div.
if spacerSide then
titleCell
:tag('span')
:css('float', spacerSide)
:css('width', '6em')
:wikitext('&nbsp;')
end
end
--
local function renderTitleRow(tbl)
if not maintitle args.title then return end
local titleRow = addTableRow(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.imageleft then titleColspan = titleColspan + 1 end if args.image then titleColspan = titleColspan + 1 end if args.titlegroup then titleColspan = titleColspan - 1 end
titleCell :cssText(args.basestyle) :cssText(args.titlestyle) :addClass('navbox-title') :attr('colspan', titleColspan)
renderNavBar(titleCell)
titleCell :tag('div') :attraddClass('id', mwargs.uri.anchorEncode(maintitle)) :addClass(titleclass) :css('font-size', '114110%') :css('margin', '0 5em') :wikitext(addNewline(maintitleargs.title))
end
local function getAboveBelowColspan()
local ret = 2 if args.imageleft then ret = ret + 1 end if args.image then ret = ret + 1 end return ret
end
local function renderAboveRow(tbl)
if not args.above then return end
addTableRow(tbl:tag('tr') :tag('td') :addClass('navbox-abovebelow') :addClass(args.aboveclass) :cssText(args.basestyle) :cssText(args.abovestyle) :attr('colspan', getAboveBelowColspan()) :tag('div') :wikitext(addNewline(args.above))
end
local function renderBelowRow(tbl)
if not args.below then return end
addTableRow(tbl:tag('tr') :tag('td') :addClass('navbox-abovebelow') :addClass(args.belowclass) :cssText(args.basestyle) :cssText(args.belowstyle) :attr('colspan', getAboveBelowColspan()) :tag('div') :wikitext(addNewline(args.below))
end
-- List rows
--
local function renderListRow(tbl, listnum)
local row = addTableRow(tbl)
 
if listnum == 1 and args.imageleft then
row
: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')
:wikitext(addNewline(args.imageleft))
end
 
if args['group' .. listnum] then
local groupCell = row:tag('th')
 
groupCell
:attr('scope', 'row')
:addClass('navbox-group')
:addClass(args.groupclass)
:cssText(args.basestyle)
 
if args.groupwidth then
groupCell:css('width', args.groupwidth)
end
local function haveSubgroups groupCell :cssText(args.groupstyle) for i = 1, 23 do if :cssText(args['group' .. i] or args['заголовок' listnum .. i] or args['группаstyle' .. i]) and :wikitext(args['listgroup' .. i] or args['список' .. ilistnum]) then return true end end return false end
local function renderListRow(tbl, index, listnum) local listCell = row = tbl:tag('trtd')
if index == 1 and imageleft args['group' .. listnum] then row listCell :tagcss('tdtext-align') :addClass(, 'navbox-imageleft') :addClass(imageclass) :css('border-left-width', '1px2px') :css('paddingborder-left-style', '0px 7px 0px 0pxsolid') :cssText(imageleftstyle) else listCell:attr('rowspancolspan', #listnums) :tag('div') :wikitext(addNewline(imageleft)2) end
if (args['group' .. listnum] or args['заголовок' .. listnum] or not args['группа' .. listnum]) groupwidth then local groupCell = row listCell:tagcss('thwidth', '100%') end
groupCell :attr local isOdd = ('scope', 'row'listnum % 2)== 1 :addClass('navbox-group') :addClass(groupclass) :cssText(basestyle) :css('width', local rowstyle = args.groupwidth or '1px') -- If groupwidth not specified, minimize width -- заголовки без списков - для обратной совместимости, только в нашем разделеevenstyle if not (isOdd then rowstyle = args['list' .. listnum] or args['список' .. listnum]) then groupCell :css('text-align', 'center') if haveSubgroups() then groupCell:attr('colspan', 2) end oddstyle end
groupCell local evenOdd :cssText(groupstyle) :cssText( if args['group' .. listnum .. evenodd == 'styleswap'] or args[then if isOdd then evenOdd = 'стиль_группыeven' .. listnum] or args[else evenOdd = 'стиль_заголовкаodd' .. listnum])end else :wikitext( if isOdd then evenOdd = args['group' .. listnum] evenodd or args['заголовокodd' else evenOdd = args.. listnum] evenodd or args['группаeven' .. listnum])end end
if args['list' .. listnum] or args['список' .. listnum] then -- проверка на наличие списков, иначе временный наш безсписочный функционал не поддерживается local listCell = row:tag('td') if (args['group' .. listnum] or args['заголовок' .. listnum] or args['группа' .. listnum]) then listCell :css('text-alignpadding', 'left') :css('border-left-width', '2px') :css('border-left-style', 'solid0px') else if haveSubgroups() then listCell :attr('colspan', 2) end end if not groupwidth then listCell:css('width', '100%') end local rowstyle -- usually nil so cssText(rowstyle) usually adds nothing if index % 2 == 1 then rowstyle = oddstyle else rowstyle = evenstyle end local listText = args['list' .. listnum] or args['список' .. listnum] local oddEven = ODD_EVEN_MARKER 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('<th[^>]*"navbox%-title"') and RESTART_MARKER or 'odd' end listCell :css('padding', '0px') :cssText(liststyle) :cssText(rowstyle) :cssText(args['list' .. listnum .. 'style'] or args['стиль_списка' .. listnum]) :addClass('navbox-list') :addClass('navbox-' .. oddEvenevenOdd) :addClass(args.listclass) :tag('div') :css('padding', (index listnum == 1 and args.list1padding) or args.listpadding or '0em 0.25em') :wikitext(addNewline(listTextargs['list' .. listnum])) end
if index listnum == 1 and args.image then row :tag('td') :addClass('navbox-image') :addClass(args.imageclass) :css('width', '1px0%') :css('padding', '0px 0px 0px 7px2px') :cssText(args.imagestyle) :attr('rowspan', 2 * #listnums- 1) :tag('div') :wikitext(addNewline(args.image)) end
end
 
--
-- Tracking categories
--
local function needsChangetoSubgroups()
for i = 1, 23 do
if (args['group' .. i] or args['заголовок' .. i] or args['группа' .. i]) and not (args['list' .. i] or args['список' .. i]) then
return true
end
end
return false
end
local function needsHorizontalLists()
if border == 'child' or border == 'subgroup' or args.tracking == 'no' then return false end local listClasses = { ['plainlist'] = true, ['hlist'] = true, ['hlist hnum'] = true, ['hlist hwrap'] = true, ['hlist vcard'] = true, ['vcard hlist'] = true, ['hlist vevent'] = true, ['hlist hlist-items-nowrap'] = true, ['hlist-items-nowrap'] = true, } return not (listClasses[listclass] or listClasses[bodyclass])end
-- local function hasBackgroundColors()-- return mw.ustring.match(titlestyle or listClasses = {'plainlist', 'hlist','backgroundhlist hnum') or mw.ustring.match(groupstyle or , 'hlist hwrap','backgroundhlist vcard') or mw.ustring.match(basestyle or , 'vcard hlist','backgroundhlist vevent'} for i, cls in ipairs(listClasses)do if args.listclass == cls or args.bodyclass == cls then return false end-- end
local function isIllegible() return true local styleratio = require('Module:Color contrast')._styleratioend
for key, style in pairslocal function hasBackgroundColors(args) do if tostring(key): return mw.ustring.match("style$"args.titlestyle or '','background') or tostring(key):mw.ustring.match("^стиль"args.groupstyle or '','background') then if styleratio{or mw.textustring.unstripNoWikimatch(styleargs.basestyle or '','background')} < 4.5 then return true end end end return false
end
local function getTrackingCategories()
local cats = {} if needsChangetoSubgroups() then table.insert(cats, 'Навигационные шаблоны с ошибочным использованием заголовков') end if needsHorizontalLists() then table.insert(cats, 'Навигационные шаблоны без горизонтальных списковNavigational boxes without horizontal lists') end if isIllegiblehasBackgroundColors() then table.insert(cats, 'Потенциально нечитаемые навигационные шаблоныNavboxes using background colors') end return cats
end
local function renderTrackingCategories(builder)
local title = mw.title.getCurrentTitle() 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
for i, cat in ipairs(getTrackingCategories()) do builder:wikitext('[[КатегорияCategory:' .. cat .. ']]') end
end
--
local function renderMainTable()
local tbl = mw.html.create('table') :addClass('nowraplinks') :addClass(args.bodyclass)
if maintitle args.title and (args.state ~= 'plain' and args.state ~= 'off') then tbl :addClass('collapsible') :addClass(args.state or 'autocollapse') end
tbl:css('border-spacing', 0) if border == 'subgroup' or border == 'child' or border == 'none' then tbl :addClass('navbox-subgroup') :cssText(args.bodystyle) :cssText(args.style) else -- regular navbox navobx - bodystyle and style will be applied to the wrapper table tbl :addClass('navbox-inner') :css('background', 'transparent') :css('color', 'inherit') end tbl:cssText(args.innerstyle)
renderTitleRow(tbl) renderAboveRow(tbl) for i, listnum in ipairs(listnums) do renderListRow(tbl, i, listnum) end renderBelowRow(tbl)
return tbl
end
function p._navbox(navboxArgs)
args = navboxArgs
for k, v in pairs(args) do local listnum = ('' .. k):match('^list(%d+)$') or ('' .. k):match('^список(%d+)$') if listnum then table.insert(listnums, tonumber(listnum)) end end table.sort(listnums)
-- заголовки без списков - для обратной совместимости, только в нашем разделе for k, v in pairs border = trim(args) do local double = false local groupnum = ('' .. k):match(border or args[1] or '^заголовок(%d+)$') --group не нужен, так как в английском шаблоне эта фукнциональность не поддерживается if groupnum then for k2, v2 in pairs(listnums) do if tonumber(groupnum) == v2 then double = true break end end if not double then table.insert(listnums, tonumber(groupnum)) end --добавляем только номера заголовков, для которых нет списков end end table.sort(listnums)
border = mw.text.trim(args.border or args[1] or '') if border == 'child' then border = 'subgroup' end maintitle = args.title or args['заголовок'] navbar = args.navbar or args['ссылка_на_просмотр'] name = args.name or args['имя'] above = args.above or args['вверху'] image = args.image or args['изображение'] imagestyle = args.imagestyle or args['стиль_изображения'] imageleft = args.imageleft or args['изображение2'] or args['изображение_слева'] imageleftstyle = args.imageleftstyle or args.imagestyle2 or args['стиль_изображения_слева'] below = args.below or args['внизу'] titlestyle = args.titlestyle or args['стиль_основного_заголовка'] or args['стиль_заголовка'] groupstyle = args.groupstyle or args['стиль_заголовков'] or args['стиль_групп'] bodystyle = args.bodystyle or args['стиль_тела'] basestyle = args.basestyle or args['стиль_базовый'] or args['стиль'] style = args.style liststyle = args.liststyle or args['стиль_списков'] oddstyle = args.oddstyle or args['стиль_нечётных'] or args['стиль_нечетных'] evenstyle = args.evenstyle or args['стиль_чётных'] or args['стиль_четных'] abovestyle = args.abovestyle or args['стиль_вверху'] belowstyle = args.belowstyle or args['стиль_внизу'] evenoddARG = args.evenodd or args['чётные_нечётные'] or args['четные_нечетные'] groupwidth = args.groupwidth or args['ширина_групп'] listpadding = args.listpadding or args['отступ_списков'] bodyclass = args.bodyclass or args['класс_тела'] titleclass = args.titleclass or args['класс_заголовка'] aboveclass =args.aboveclass or args['класс_вверху'] belowclass = args.belowclass or args['класс_внизу'] groupclass = args.groupclass or args['класс_групп'] listclass = args.listclass or args['класс_списков'] imageclass = args.imageclass or args['класс_изображения'] -- render the main body of the navbox local tbl = renderMainTable()
-- render the appropriate wrapper around the navbox, depending on the border param local res = mw.html.create() if border == 'none' then local nav = res:tag('div') :attr('role', 'navigation') :node(tbl) if maintitle then nav:attr( elseif border == 'aria-labelledbysubgroup', mw.uri.anchorEncode(maintitle)) else nav:attr('aria-label', 'Навигационный шаблон') end elseif or border == 'subgroupchild' 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>') -- XXX: hack due to lack of unclosed support in mw.html. :node(tbl) :wikitext('<div>') -- XXX: hack due to lack of unclosed support in mw.html. else local nav = res :tag('divtable') :attraddClass('role', 'navigationnavbox') :addClasscss('navboxborder-spacing', 0) :cssText(args.bodystyle) :cssText(args.style) :csstag('padding', '3pxtr') :node(tbl) if maintitle then nav:attrtag('aria-labelledbytd', mw.uri.anchorEncode(maintitle)) else nav :attrcss('aria-labelpadding', 'Навигационный шаблон2px') end :node(tbl) end
renderTrackingCategories(res)
return striped(tostring(res))
end
function p.navbox(frame)
if not getArgs then getArgs = require('Module:Arguments').getArgs end args = getArgs(frame, {wrappers = {'Шаблон:Навигационная таблица', 'ШаблонTemplate:Навигационная таблица/песочницаNavbox'}})
-- Read the arguments in the order they'll be output in, to make references number in the right order. local _ _ = maintitleargs.title _ = args.above for i = 1, 23 20 do _ = args["group" .. tostring(i)] and args["заголовок" .. tostring(i)] and args["группа" .. tostring(i)] _ = args["list" .. tostring(i)] and args["список" .. tostring(i)] end _ = args.below
return p._navbox(args)
end
return p

Навигация