|
|
| (Не показано 3 проміжні версії ще одного користувача) |
| Рядок 1: |
Рядок 1: |
| | -------------------------------------------------------------------- |
| | --<pre> Navbox Module |
| -- | | -- |
| -- Реализует {{Навигационная таблица}} и {{Подгруппы навигационной таблицы}}. | | -- * Fully CSS styled (inline styles possible but not default) |
| -- Основной объём кода заимствован из английского Module:Navbox. | | -- * Supports unlimited rows |
| -- | | -- |
| | | -- By User:Tjcool007 from layton.fandom.com |
| | -------------------------------------------------------------------- |
| | |
| local p = {} | | local p = {} |
| | | |
| local getArgs -- lazily initialized | | local args = {} -- Arguments passed to template |
| local yesno -- lazily initialized | | local navbox -- Actual navbox |
| | | |
| local args | | --local working = {} |
| local border
| | local rownums, skiprows = {}, {} |
| local listnums = {} | | local hasrows, alt, hasData, isChild = false, false, false, false |
| local ODD_EVEN_MARKER = '\127_ODDEVEN_\127' | | local activeSection, sections, cimage, cimageleft |
| local RESTART_MARKER = '\127_ODDEVEN0_\127' | | local colspan, rowspan |
| local REGEX_MARKER = '\127_ODDEVEN(%d?)_\127' | | |
| | | local showText, hideText = 'Show', 'Hide' |
| local maintitle | | |
| local name
| | local langCode = mw.getContentLanguage():getCode() |
| local navigation
| | local localization = {} --localized strings table |
| local navbar
| | localization['en'] = {show = 'Show', hide = 'Hide'} |
| local above
| | localization['ru'] = {show = 'показать', hide = 'скрыть'} |
| local image
| | localization['zh'] = {show = '显示', hide = '隐藏'} |
| local below
| | if localization[langCode] then |
| | | showText = localization[langCode]['show'] |
| local titlestyle
| | hideText = localization[langCode]['hide'] |
| local groupstyle
| | end |
| local bodystyle
| | |
| local basestyle
| | ------------------------------------------------ |
| local liststyle
| | -- Title |
| local evenodd_VARIABLE
| | ------------------------------------------------ |
| local abovestyle
| | |
| local belowstyle
| | --- Processes the VDE links in the title |
| local imageleft | | -- |
| local imageleftstyle
| | -- @param titlecell The table cell of the title |
| local style
| | local function processVde( titlecell ) |
| | | if not args.template then return end |
| local groupwidth
| | |
| local listpadding
| | titlecell:wikitext('<span class="navbox-vde">' |
| | | .. mw.getCurrentFrame():expandTemplate({ |
| local bodyclass
| | title = 'vdelinks', |
| local titleclass
| | args = { args.template, ['type'] = 'navbox' } |
| local aboveclass
| | }) .. '</span>') |
| local belowclass
| | end |
| local groupclass
| | |
| local listclass
| | --- Processes the main title row |
| local imageclass
| | local function processTitle() |
| | | local titlerow = mw.html.create('tr'):addClass('navbox-title') |
| local function striped(wikitext) | | local titlecell = mw.html.create('th'):attr('colspan',colspan):attr('scope','col') |
| -- Return wikitext with markers replaced for odd/even striping. | | |
| -- Child (subgroup) navboxes are flagged with a category that is removed
| | if not pcall( processVde, titlecell ) then |
| -- by parent navboxes. The result is that the category shows all pages
| | titlecell:wikitext( '<b class="navbox-vde error" title="Missing Template:Vdelinks">!!!</b>' ) |
| -- 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 | | end |
| local first, second = 'odd', 'even' | | |
| if evenodd_VARIABLE then | | titlecell:wikitext( args.title or '{{{title}}}' ) |
| if evenodd_VARIABLE == 'swap' then | | |
| first, second = second, first | | -- Padding |
| | local hasTemplate = args.template ~= nil |
| | local hasState = not args.state or args.state ~= 'plain' |
| | |
| | if hasTemplate ~= hasState then |
| | if hasTemplate then |
| | titlecell:addClass('navbox-title-padright') |
| else | | else |
| first = evenodd_VARIABLE | | titlecell:addClass('navbox-title-padleft') |
| second = first
| |
| end | | end |
| end | | end |
| local changer | | |
| if first == second then | | if args.titleclass then titlerow:addClass( args.titleclass ) end |
| changer = first
| | if args.titlestyle then titlecell:cssText( args.titlestyle ) end |
| else | | |
| local index = 0
| | titlerow:node(titlecell) |
| changer = function (code)
| | navbox:node(titlerow) |
| if code == '0' then
| | end |
| -- Current occurrence is for a group before a nested table.
| | |
| -- Set it to first as a valid although pointless class.
| | local function _addGutter( parent, incRowspan ) |
| -- The next occurrence will be the first row after a title
| | parent:tag('tr'):addClass('navbox-gutter'):tag('td'):attr('colspan',2) |
| -- in a subgroup and will also be first.
| | |
| index = 0
| | if incRowspan then |
| return first
| | rowspan = rowspan + 1 |
| end
| |
| index = index + 1
| |
| return index % 2 == 1 and first or second
| |
| end
| |
| end | | end |
| local regex = orphanCat:gsub('([%[%]])', '%%%1')
| |
| return (wikitext:gsub(regex, ''):gsub(REGEX_MARKER, changer)) -- () omits gsub count
| |
| end | | end |
| | | |
| local function addNewline(s) | | ------------------------------------------------ |
| if s:match('^[*:;#]') or s:match('^{|') then | | -- Above/Below |
| return '\n' .. s ..'\n' | | ------------------------------------------------ |
| | |
| | --- Processes the above and below rows |
| | -- |
| | -- @param rowtype Either 'above' or 'below' |
| | local function processAboveBelow( rowtype ) |
| | if not args[rowtype] then return end |
| | |
| | local abrow = mw.html.create('tr'):addClass('navbox-'..rowtype) |
| | local abcell = mw.html.create('td'):attr('colspan',colspan):wikitext( args[rowtype] ) |
| | |
| | if args[rowtype .. 'class'] then abrow:addClass( args[rowtype .. 'class'] ) end |
| | if args[rowtype .. 'style'] then abcell:cssText( args[rowtype .. 'style'] ) end |
| | |
| | abrow:node( abcell ) |
| | _addGutter( navbox ) |
| | navbox:node( abrow ) |
| | end |
| | |
| | ------------------------------------------------ |
| | -- Main Rows |
| | ------------------------------------------------ |
| | |
| | --- Processes the images |
| | local function _processImage(row, imgtype) |
| | if not args[imgtype] then return end |
| | |
| | local iclass = imgtype == 'image' and 'navbox-image-right' or 'navbox-image-left' |
| | |
| | local imagecell = mw.html.create('td'):addClass('navbox-image'):addClass(iclass) |
| | |
| | local image = args[imgtype] |
| | if image:sub(1,1) ~= '[' then |
| | local width = args[imgtype .. 'width'] or '100px' |
| | imagecell:css('width',width):wikitext('['..'[' .. image .. '|' .. width .. '|link=' .. (args[imgtype .. 'link'] or '') .. ']]') |
| else | | else |
| return s | | imagecell:css('width','0%'):wikitext(image) |
| end | | end |
| end
| | |
| | | if args[imgtype .. 'class'] then imagecell:addClass( args[imgtype .. 'class'] ) end |
| local function renderNavBar(titleCell)
| | if args[imgtype .. 'style'] then imagecell:cssText( args[imgtype .. 'style'] ) end |
| | | |
| if navbar ~= 'off' and navbar ~= 'plain' and not (not name and mw.getCurrentFrame():getParent():getTitle():gsub('/песочница$', '') == 'Шаблон:Навигационная таблица') then | | row:node( imagecell ) |
|
| | if imgtype == 'image' then |
| -- Check color contrast of the gear icon
| | cimage = imagecell |
| local styleratio = require('Module:Color contrast')._styleratio
| | else |
| local gearColor = ''
| | cimageleft = imagecell |
| local contrastStyle = titlestyle or basestyle
| |
| local gearStyleBlack = (contrastStyle and mw.text.unstripNoWiki(contrastStyle) .. '; color:#666;' or '')
| |
| local gearStyleWhite = (contrastStyle and mw.text.unstripNoWiki(contrastStyle) .. '; color:#fff;' or '')
| |
| if styleratio{gearStyleBlack} < styleratio{gearStyleWhite} then
| |
| gearColor = ' white'
| |
| end
| |
|
| |
| --- Gear creation
| |
| titleCell
| |
| :tag('span')
| |
| :addClass('navbox-gear')
| |
| :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 | | end |
|
| |
| end | | end |
| | | |
| -- | | --- Closes the currently active section (if any) |
| -- Title row
| | local function _closeCurrentSection() |
| -- | | if not activeSection then return end |
| local function renderTitleRow(tbl) | | |
| if not maintitle then return end | | local row = mw.html.create('tr'):addClass('navbox-section-row') |
| | | local cell = mw.html.create('td'):attr('colspan',2) |
| local titleRow = tbl:tag('tr') | | |
| | | if not hasrows then |
| if args.titlegroup then
| | _processImage(row,'imageleft') |
| titleRow
| |
| :tag('th')
| |
| :attr('scope', 'row')
| |
| :addClass('navbox-group')
| |
| :addClass(args.titlegroupclass)
| |
| :cssText(basestyle)
| |
| :cssText(groupstyle)
| |
| :cssText(args.titlegroupstyle)
| |
| :wikitext(args.titlegroup)
| |
| end | | end |
| | | |
| local titleCell = titleRow:tag('th'):attr('scope', 'col') | | cell:node(sections[activeSection]) |
| | | row:node(cell) |
| if args.titlegroup then | | |
| titleCell | | local firstRow = false |
| :css('border-left', '2px solid #fdfdfd')
| | if not hasrows then |
| :css('width', '100%')
| | firstRow = true |
| | hasrows = true |
| | _processImage(row,'image') |
| end | | end |
| | | |
| local titleColspan = 2 | | _addGutter(navbox,not firstRow) |
| if imageleft then titleColspan = titleColspan + 1 end
| | navbox:node(row) |
| if image then titleColspan = titleColspan + 1 end
| | rowspan = rowspan + 1 |
| if args.titlegroup then titleColspan = titleColspan - 1 end
| | |
| | | activeSection = false |
| titleCell
| | hasData = false |
| :cssText(basestyle)
| |
| :cssText(titlestyle)
| |
| :addClass('navbox-title')
| |
| :attr('colspan', titleColspan)
| |
| | |
| renderNavBar(titleCell) | |
| | |
| titleCell | |
| :tag('div')
| |
| :attr('id', mw.uri.anchorEncode(maintitle))
| |
| :addClass(titleclass)
| |
| :css('font-size', '114%')
| |
| :css('margin', '0 5em')
| |
| :wikitext(addNewline(maintitle))
| |
| end | | end |
| | | |
| | --- Handles alternating rows |
| -- | | -- |
| -- Above/Below rows | | -- @return Alternatingly returns true or false. Always returns false if alternating rows |
| -- | | -- are disabled with "alternaterows = no" |
| | | local function _alternateRow() |
| local function getAboveBelowColspan() | | if args.alternaterows == 'no' then return false end |
| local ret = 2 | | if alt then |
| if imageleft then ret = ret + 1 end
| | alt = false |
| if image then ret = ret + 1 end
| | return true |
| return ret
| | else |
| end | | alt = true |
| | | return false |
| local function renderAboveRow(tbl)
| | end |
| if not above then return end | |
| | |
| tbl:tag('tr')
| |
| :tag('td') | |
| :addClass('navbox-abovebelow')
| |
| :addClass(aboveclass)
| |
| :cssText(basestyle)
| |
| :cssText(abovestyle)
| |
| :attr('colspan', getAboveBelowColspan())
| |
| :tag('div')
| |
| :wikitext(addNewline(above))
| |
| end
| |
| | |
| local function renderBelowRow(tbl)
| |
| if not below then return end
| |
| | |
| tbl:tag('tr') | |
| :tag('td') | |
| :addClass('navbox-abovebelow')
| |
| :addClass(belowclass)
| |
| :cssText(basestyle)
| |
| :cssText(belowstyle)
| |
| :attr('colspan', getAboveBelowColspan())
| |
| :tag('div')
| |
| :wikitext(addNewline(below))
| |
| end | | end |
| | | |
| | --- Process a single Header "row" |
| -- | | -- |
| -- List rows | | -- @param num Number of the row to be processed |
| -- | | local function processHeader(num) |
| | | if not args['header'..num] then return end |
| local function haveSubgroups() | | |
| for i = 1, 23 do | | _closeCurrentSection() |
| if (args['group' .. i] or args['заголовок' .. i] or args['группа' .. i]) and (args['list' .. i] or args['список' .. i]) then
| | |
| return true | | local subtable = mw.html.create('table'):addClass('navbox-section') |
| | local headerrow = mw.html.create('tr') |
| | local header = mw.html.create('th'):addClass('navbox-header'):attr('colspan',2):attr('scope','col'):wikitext( args['header'..num] ) |
| | |
| | local collapseme = args['state'..num] or false |
| | local state = false |
| | |
| | if collapseme then |
| | -- Look at this one |
| | if collapseme ~= 'plain' then |
| | state = collapseme == 'expanded' and 'expanded' or 'collapsed' |
| | end |
| | else |
| | -- Look at default |
| | local collapseall = args.defaultstate or false |
| | if collapseall then |
| | state = collapseall == 'expanded' and 'expanded' or 'collapsed' |
| | end |
| | end |
| | |
| | if state then |
| | subtable:addClass('mw-collapsible'):attr('data-expandtext',args['expandtext'..num] or args['defaultexpandtext'] or showText):attr('data-collapsetext',args['collapsetext'..num] or args['defaultcollapsetext'] or hideText) |
| | if state == 'collapsed' then |
| | subtable:addClass('mw-collapsed') |
| end | | end |
| | header:addClass('navbox-header-collapsible') |
| end | | end |
| return false | | |
| | if args.headerclass then headerrow:addClass( args.headerclass ) end |
| | if args.headerstyle then header:cssText( args.headerstyle ) end |
| | |
| | headerrow:node(header) |
| | subtable:node(headerrow) |
| | |
| | sections[num] = subtable |
| | activeSection = num |
| end | | end |
| | | |
| local function renderListRow(tbl, index, listnum) | | --- Processes a single list row |
| local row = tbl:tag('tr') | | -- |
| | | -- @param num Number of the row to be processed |
| if index == 1 and imageleft then | | local function processList(num) |
| row
| | if not args['list'..num] then return end |
| :tag('td')
| | |
| :addClass('navbox-image')
| | local row = mw.html.create('tr'):addClass('navbox-row') |
| :addClass(imageclass)
| | |
| :css('width', '1px')
| | if not hasrows and not activeSection then |
| :css('padding', '0px 7px 0px 0px')
| | _processImage(row, 'imageleft') |
| :cssText(imageleftstyle)
| |
| :attr('rowspan', #listnums)
| |
| :tag('div')
| |
| :wikitext(addNewline(imageleft))
| |
| end | | end |
| | | |
| if (args['group' .. listnum] or args['заголовок' .. listnum] or args['группа' .. listnum]) then | | local listcell = mw.html.create('td'):addClass('navbox-list') |
| local groupCell = row:tag('th')
| | local hlistcell = listcell:tag('div'):addClass('hlist') |
| | | |
| groupCell
| | local data = args['list'..num] |
| :attr('scope', 'row')
| | |
| :addClass('navbox-group')
| | if data:sub(1,1) == '*' then |
| :addClass(groupclass)
| | -- Add newlines to support lists properly |
| :cssText(basestyle)
| | hlistcell |
| :css('width', groupwidth or '1px') -- If groupwidth not specified, minimize width
| | :newline() |
| | | :wikitext( data ) |
| groupCell | | :newline() |
| :cssText(groupstyle) | | else |
| :cssText(args['group' .. listnum .. 'style'] or args['стиль_группы' .. listnum] or args['стиль_заголовка' .. listnum]) | | hlistcell:wikitext( data ) |
| :wikitext(args['group' .. listnum] or args['заголовок' .. listnum] or args['группа' .. listnum]) | |
| end | | end |
| | | |
| local listCell = row:tag('td') | | local altRow = _alternateRow() |
| | | if altRow then |
| if (args['group' .. listnum] or args['заголовок' .. listnum] or args['группа' .. listnum]) then | | row:addClass( args.altrowclass or 'alt' ) |
| listCell | | |
| :css('text-align', 'left')
| | local listclass = args.altlistclass or args.listclass or false |
| :css('border-left-width', '2px')
| | if listclass then listcell:addClass( listclass ) end |
| :css('border-left-style', 'solid')
| | |
| | local liststyle = args.altliststyle or args.liststyle or false |
| | if liststyle then listcell:cssText( liststyle ) end |
| else | | else |
| if haveSubgroups() then | | if args.rowclass then row:addClass( args.rowclass ) end |
| listCell
| | if args.listclass then listcell:addClass( args.listclass ) end |
| :attr('colspan', 2)
| | if args.liststyle then listcell:cssText( args.liststyle ) end |
| | end |
| | |
| | if args['group'..num] then |
| | local groupcell = mw.html.create('th'):addClass('navbox-group'):attr('scope','row'):wikitext( args['group'..num] ) |
| | |
| | if altRow then |
| | local groupclass = args.altgroupclass or args.groupclass or false |
| | if groupclass then groupcell:addClass( groupclass ) end |
| | |
| | local groupstyle = args.altgroupstyle or args.groupstyle or false |
| | if groupstyle then groupcell:cssText( groupstyle ) end |
| | else |
| | if args.groupclass then groupcell:addClass( args.groupclass ) end |
| | if args.groupstyle then groupcell:cssText( args.groupstyle ) end |
| end | | end |
| | |
| | row:node( groupcell ) |
| | else |
| | listcell:attr('colspan',2):addClass('no-group') |
| end | | end |
| | | |
| if not groupwidth then | | row:node( listcell ) |
| listCell:css('width', '100%') | | |
| | local firstRow = false |
| | if not hasrows and not activeSection then |
| | firstRow = true |
| | hasrows = true |
| | _processImage(row, 'image') |
| end | | end |
| | | |
| local listText = args['list' .. listnum] or args['список' .. listnum]
| | if activeSection then |
| local oddEven = ODD_EVEN_MARKER
| | local parent = sections[activeSection] |
| if listText:sub(1, 12) == '</div><table' then | | if not isChild or not firstRow then |
| -- Assume list text is for a subgroup navbox so no automatic striping for this row. | | _addGutter(parent) |
| oddEven = listText:find('<th[^>]*"navbox%-title"') and RESTART_MARKER or 'odd'
| | end |
| end
| | parent:node(row) |
| listCell
| | hasData = true |
| :css('padding', '0px') | | else |
| :cssText(liststyle)
| | if not isChild or not firstRow then |
| :cssText(args['list' .. listnum .. 'style'] or args['стиль_списка' .. listnum]) | | _addGutter(navbox,not firstRow) |
| :addClass('navbox-list') | | end |
| :addClass('navbox-' .. oddEven) | | navbox:node( row ) |
| :addClass(listclass)
| | rowspan = rowspan + 1 |
| :tag('div') | |
| :css('padding', args['list' .. listnum .. 'padding'] or listpadding or '0em 0.25em')
| |
| :wikitext(addNewline(listText))
| |
| | |
| if index == 1 and image then
| |
| row
| |
| :tag('td') | |
| :addClass('navbox-image')
| |
| :addClass(imageclass)
| |
| :css('width', '1px')
| |
| :css('padding', '0px 0px 0px 7px')
| |
| :cssText(imagestyle)
| |
| :attr('rowspan', #listnums)
| |
| :tag('div')
| |
| :wikitext(addNewline(image))
| |
| end | | end |
| end | | end |
| | | |
| -- | | --- Processes all rows |
| -- Tracking categories
| | local function processRows() |
| -- | | sections = {} |
| local function needsChangetoSubgroups() | | for i=1,#rownums do |
| for i = 1, 23 do | | local num = rownums[i] |
| if (args['group' .. i] or args['заголовок' .. i] or args['группа' .. i]) and not (args['list' .. i] or args['список' .. i]) then | | if not skiprows[num] then |
| return true | | processHeader(num) |
| | processList(num) |
| end | | end |
| end | | end |
| return false | | _closeCurrentSection() |
| end
| | |
| | | if cimageleft then |
| local function needsHorizontalLists()
| | cimageleft:attr('rowspan',rowspan) |
| if border == 'subgroup' or args.tracking == 'no' then | |
| return false | |
| end | | end |
| local listClasses = { | | if cimage then |
| ['plainlist'] = true, ['hlist'] = true, ['hlist hnum'] = true, | | cimage:attr('rowspan',rowspan) |
| ['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 '','background') or mw.ustring.match(groupstyle or '','background') or mw.ustring.match(basestyle or '','background')
| |
| -- end
| |
| | |
| local function isIllegible()
| |
| local styleratio = require('Module:Color contrast')._styleratio
| |
| | |
| for key, style in pairs(args) do
| |
| if tostring(key):match("style$") or tostring(key):match("^стиль") then
| |
| if styleratio{mw.text.unstripNoWiki(style)} < 4.5 then
| |
| return true
| |
| end
| |
| end
| |
| end | | end |
| return false
| |
| end
| |
|
| |
| local function getTrackingCategories()
| |
| local cats = {}
| |
| if needsChangetoSubgroups() then table.insert(cats, 'Навигационные шаблоны с ошибочным использованием заголовков') end
| |
| if needsHorizontalLists() then table.insert(cats, 'Навигационные шаблоны без горизонтальных списков') end
| |
| if isIllegible() then table.insert(cats, 'Потенциально нечитаемые навигационные шаблоны') end
| |
| return cats
| |
| end | | end |
| | | |
| local function renderTrackingCategories(builder)
| | ------------------------------------------------ |
| local title = mw.title.getCurrentTitle()
| | -- ARGUMENTS PREPROCESSOR |
| if title.namespace ~= 10 then return end -- not in template space
| | -- * Extracts arguments from frame and stores them in args table |
| local subpage = title.subpageText
| | -- * At the same time, checks for valid row numbers |
| if subpage == 'doc' or subpage == 'песочница' or subpage == 'тесты' then return end
| | ------------------------------------------------ |
| | | |
| for i, cat in ipairs(getTrackingCategories()) do
| | --- Preprocessor for the arguments. |
| builder:wikitext('[[Категория:' .. cat .. ']]')
| | -- Will fill up the args table with the parameters from the frame grouped by their type. |
| end
| |
| end
| |
| | |
| -- | | -- |
| -- Main navbox tables | | -- @param frame The frame passed to the Module. |
| --
| | local function preProcessArgs(frame) |
| local function renderMainTable() | | local tmp = {} |
| local tbl = mw.html.create('table') | | |
| :addClass('nowraplinks')
| | if frame == mw.getCurrentFrame() then |
| :addClass(bodyclass)
| | tmp = frame:getParent().args |
| | | else |
| if maintitle and (args.state ~= 'plain' and args.state ~= 'off') then | | tmp = frame |
| tbl | |
| :addClass('collapsible')
| |
| :addClass(args.state or 'autocollapse')
| |
| end | | end |
| | | |
| tbl:css('border-spacing', 0) | | -- Storage tables |
| if border == 'subgroup' or border == 'none' then | | local nums = {} |
| tbl
| | |
| :addClass('navbox-subgroup')
| | -- Loop over all the args |
| :cssText(bodystyle)
| | for k,v in pairs(tmp) do |
| :cssText(style)
| | -- Skip empty args, which are useless |
| else -- regular navbox - bodystyle and style will be applied to the wrapper table
| | if v ~= '' then |
| tbl | | local cat,num = tostring(k):match('^(%a+)([1-9]%d*)$') |
| :addClass('navbox-inner') | | |
| :css('background', 'transparent') | | if cat == 'header' or cat == 'list' then |
| :css('color', 'inherit') | | nums[num] = true |
| end
| | end |
| tbl:cssText(args.innerstyle)
| | |
| | | args[k] = v -- Simple copy |
| renderTitleRow(tbl)
| | end |
| renderAboveRow(tbl)
| |
| for i, listnum in ipairs(listnums) do
| |
| renderListRow(tbl, i, listnum) | |
| end | | end |
| renderBelowRow(tbl) | | |
| | | colspan = args.image and 3 or 2 |
| return tbl | | if args.imageleft then colspan = colspan + 1 end |
| end | | rowspan = 0 |
| | | |
| function p._navbox(navboxArgs)
| | if args.alternaterows == 'swap' then |
| args = navboxArgs | | alt = true |
| if not yesno then
| |
| yesno = require('Module:Yesno'); | |
| end | | end |
| | | |
| for k, v in pairs(args) do | | for k, v in pairs(nums) do |
| local listnum = ('' .. k):match('^list(%d+)$') or ('' .. k):match('^список(%d+)$') | | rownums[#rownums+1] = tonumber(k) |
| if listnum then table.insert(listnums, tonumber(listnum)) end
| |
| end | | end |
|
| | |
| table.sort(listnums) | | table.sort(rownums) |
| | | |
| border = mw.text.trim(args.border or args[1] or '') | | -- Calculate skip rows |
| if border == 'child' then | | local cSection, cSkip |
| border = 'subgroup'
| | local showall = args.showall |
| end | | for i=1,#rownums do |
|
| | local num = rownums[i] |
| maintitle = args.title or args['заголовок']
| | if args['header'..num] then |
| navbar = args.navbar or args['ссылка_на_просмотр'] | | cSection = true |
| name = args.name or args['имя']
| | cSkip = false |
| navigation = yesno(args.navigation or args['навигация'], '')
| | local showme = args['show'..num] |
| above = args.above or args['вверху']
| | if showme == 'no' then |
| image = args.image or args['изображение']
| | cSkip = true |
| imagestyle = args.imagestyle or args['стиль_изображения']
| | elseif showme == 'auto' or (showme ~= 'yes' and showall ~= 'yes') then |
| imageleft = args.imageleft or args['изображение2'] or args['изображение_слева']
| | if not args['list'..num] then |
| imageleftstyle = args.imageleftstyle or args.imagestyle2 or args['стиль_изображения_слева']
| | local nextNum = rownums[i+1] |
| below = args.below or args['внизу']
| | cSkip = not nextNum or args['header'..nextNum] -- If next has a header -> skip |
| titlestyle = args.titlestyle or args['стиль_основного_заголовка'] or args['стиль_заголовка']
| | end |
| groupstyle = args.groupstyle or args['стиль_заголовков'] or args['стиль_групп']
| | end |
| bodystyle = args.bodystyle or args['стиль_тела']
| |
| basestyle = args.basestyle or args['стиль_базовый'] or args['стиль']
| |
| style = args.style
| |
| liststyle = args.liststyle or args['стиль_списков']
| |
| abovestyle = args.abovestyle or args['стиль_вверху']
| |
| belowstyle = args.belowstyle or args['стиль_внизу']
| |
| evenodd_VARIABLE = 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('aria-labelledby', mw.uri.anchorEncode(maintitle))
| |
| else
| |
| nav:attr('aria-label', 'Навигационный шаблон')
| |
| end
| |
| if name and name ~= '-' then
| |
| nav:attr('data-name', name)
| |
| end
| |
| if navigation == true then
| |
| nav:attr('data-navboxnavigation', '1')
| |
| elseif navigation == false then
| |
| nav:attr('data-navboxnavigation', '0')
| |
| end
| |
| elseif 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>') -- 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('div')
| |
| :attr('role', 'navigation')
| |
| :addClass('navbox')
| |
| :cssText(bodystyle)
| |
| :cssText(style)
| |
| :css('padding', '3px')
| |
| :node(tbl)
| |
| if maintitle then
| |
| nav:attr('aria-labelledby', mw.uri.anchorEncode(maintitle))
| |
| else
| |
| nav:attr('aria-label', 'Навигационный шаблон')
| |
| end
| |
| if name and name ~= '-' then
| |
| nav:attr('data-name', name)
| |
| end | | end |
| if navigation == true then | | if cSection and cSkip then |
| nav:attr('data-navboxnavigation', '1') | | skiprows[num] = true |
| elseif navigation == false then
| |
| nav:attr('data-navboxnavigation', '0')
| |
| end | | end |
|
| |
| end | | end |
|
| |
| renderTrackingCategories(res)
| |
|
| |
| return striped(tostring(res))
| |
| end | | end |
| | | |
| function p.navbox(frame)
| | ------------------------------------------------ |
| if not getArgs then | | -- MAIN FUNCTIONS |
| getArgs = require('Module:Arguments').getArgs | | ------------------------------------------------ |
| | |
| | --- Processes the arguments to create the navbox. |
| | -- |
| | -- @return A string with HTML that is the navbox. |
| | local function _navbox() |
| | -- Create the root HTML element |
| | local trim = function(s) |
| | return s and mw.ustring.gsub(s, "^%s*(.-)%s*$", "%1") or '' |
| end | | end |
| if not yesno then | | local border = args.border or trim(args[1]) or '' |
| yesno = require('Module:Yesno'); | | isChild = (border == 'child' or border == 'subgroup') |
| | |
| | if isChild then |
| | navbox = mw.html.create('table'):addClass('navbox-subgroup') |
| | else |
| | navbox = mw.html.create('table'):addClass('navbox') |
| | |
| | if args.state ~= 'plain' then |
| | navbox:addClass('mw-collapsible'):attr('data-expandtext',args['expandtext'] or args['defaultexpandtext'] or showText):attr('data-collapsetext',args['collapsetext'] or args['defaultcollapsetext'] or hideText) |
| | if args.state == 'collapsed' then |
| | navbox:addClass('mw-collapsed') |
| | end |
| | end |
| end | | end |
| args = getArgs(frame, {wrappers = {'Шаблон:Навигационная таблица', 'Шаблон:Подгруппы навигационной таблицы'}}) | | |
| if frame.args.border then | | if args.bodyclass then navbox:addClass(args.bodyclass) end |
| -- This allows Template:Navbox_subgroup to use {{#invoke:Navbox|navbox|border=...}}. | | if args.bodystyle then navbox:cssText(args.bodystyle) end |
| args.border = frame.args.border | | |
| | -- Process... |
| | if not isChild then |
| | processTitle() |
| | processAboveBelow('above') |
| | processRows() |
| | processAboveBelow('below') |
| | |
| | return tostring(navbox) |
| | else |
| | processRows() |
| | |
| | local wrapper = mw.html.create('') |
| | wrapper:wikitext('</div>') |
| | wrapper:node(navbox) |
| | wrapper:wikitext('<div class="hlist">') |
| | return tostring(wrapper) |
| end | | end |
|
| |
| -- Read the arguments in the order they'll be output in, to make references number in the right order.
| |
| local _
| |
| _ = maintitle
| |
| _ = above
| |
| for i = 1, 23 do
| |
| _ = args["group" .. tostring(i)] and args["заголовок" .. tostring(i)] and args["группа" .. tostring(i)]
| |
| _ = args["list" .. tostring(i)] and args["список" .. tostring(i)]
| |
| end
| |
| _ = below
| |
|
| |
| return p._navbox(args)
| |
| end | | end |
| | | |
| | --- Main module entry point. |
| | -- To be called with {{#invoke:navbox|main}} or directly from another module. |
| | -- |
| | -- @param frame The frame passed to the module via the #invoke. If called from another |
| | -- module directly, this should be a table with the parameter definition. |
| | function p.main(frame) |
| | -- Save the arguments in a local variable so other functions can use them. |
| | preProcessArgs(frame) |
| | |
| | return _navbox() |
| | end |
| | |
| return p | | return p |