FANDOM


local p = {}
 
-- Основа спрайта
function p.base( f )
	local args = f
	if f == mw.getCurrentFrame() then 
		args = require( 'Модуль:ProcessArgs' ).merge( true )
	else
		f = mw.getCurrentFrame()
	end
 
	-- Настройки по умолчанию
	local default = {
		["масштаб"] = 1,
		["формат"] = 256,
		["разм"] = 16,
		["поз"] = 1,
		["выравн"] = 'text-top'
	}
 
	local defaultStyle = default
	if args["настройки"] then
		local settings = mw.loadData( 'Модуль:' .. args["настройки"] )
		if not settings["таблстилей"] then
			-- Создаём отдельную копию текущих настроек по умолчанию:
			defaultStyle = mw.clone( default )
		end
		for k, v in pairs( settings ) do
			default[k] = v
		end
	end
 
	-- Выбрать настройки указанные или по умолчанию
	local setting = function( arg )
		return args[arg] or default[arg]
	end
 
	-- Начало сборки кода
	local sprite = mw.html.create( 'span' ):addClass( 'sprite' ) -- создать <span class="sprite">...</span>
	sprite:tag( 'br' ) -- добавить <br>
 
	-- CSS-стили
	-- Метод css от mw.html производит очень медленное экранирование входных данных, что тормозит работу в два раза. В обход
	-- этого стили будут создаваться вручную, и будут передаваться через метод cssText, который делает только экранирование HTML,
	-- что куда быстрее.
	local styles = {}
 
	if setting('таблстилей') then -- использовать CSS-классы для общих настроек
		sprite:addClass(setting( 'имякласса' ) or mw.ustring.lower( setting( 'имя' ):gsub( ' ', '-' ) ) .. '-sprite')
	else
		table.insert(styles, 'background-image: {{FileUrl|' .. ( setting( 'изобр' ) or setting( 'имя' ) .. 'CSS.png' ) .. '}}')
	end
 
	local class = setting('класс')
	if class then
		sprite:addClass(class)
	end
 
	local size = setting( 'разм' )
	local pos = math.abs( setting( 'поз' ) ) - 1
	local sheetWidth = setting( 'формат' )
	local tiles = sheetWidth / size
	local left = pos % tiles * size
	local top = math.floor( pos / tiles ) * size
	local scale = setting( 'масштаб' )
	local autoscale = setting( 'автомасштаб' )
	local align = setting('выравн')
 
	if left > 0 or top > 0 then
		table.insert(styles, 'background-position: -' .. left * scale .. 'px -' .. top * scale .. 'px')
	end
 
	if not autoscale and scale ~= defaultStyle["масштаб"] then
		table.insert(styles, 'background-size: ' .. sheetWidth * scale .. 'px auto')
	end
 
	if size ~= defaultStyle["разм"] or ( not autoscale and scale ~= defaultStyle["масштаб"] ) then
		table.insert(styles, 'height: ' .. size * scale .. 'px')
		table.insert(styles, 'width: ' .. size * scale .. 'px')
	end
 
	if align ~= defaultStyle["выравн"] then
		table.insert(styles, 'vertical-align: ' .. align)
	end
 
	table.insert(styles, setting('css'))
 
	sprite:cssText(table.concat(styles, ';'))
 
	-- Текстовые данные
	local root
	local test = setting('текст')
	local spriteText
	if test then
		root = mw.html.create( 'span' ):addClass( 'nowrap' )
		spriteText = mw.html.create( 'span' ):addClass( 'sprite-text' ):wikitext(test)
	end
 
	local title = setting( 'назв' )
	if title then
		( root or sprite ):attr('title', title)
	end
 
	if not root then
		root = mw.html.create( '' )
	end
	root:node( sprite )
	if spriteText then
		root:node( spriteText )
	end
 
	-- Ссылка
	local link = setting( 'ссылка' ) or ""
	if link ~= "" and mw.ustring.lower( link ) ~= 'none' then
		-- Внешняя ссылка
		if link:find( '//' ) then
			return '[' .. link .. ' ' .. tostring( root ) .. ']'
		end
 
		-- Внутренняя ссылка
		local linkPrefix = setting( 'предссылки' ) or ''
		return '[[' .. linkPrefix .. link .. '|' .. tostring( root ) .. ']]'
	end
 
	return tostring( root )
end
 
-- Весь спрайт
function p.sprite( f )
	local args = f
	if f == mw.getCurrentFrame() then
		args = require( 'Module:ProcessArgs' ).merge( true )
	end
 
	local categories = {}
	local idData = args["данныеID"]
	if not idData then
		local default = {}
		if args["настройки"] then
			default = mw.loadData( 'Модуль:' .. args["настройки"] )
		end
 
		local name = args["имя"] or default["имя"]
		local ids = mw.loadData( 'Модуль:' .. ( args["IDы"] or default["IDы"] or name .. 'Спрайт/ID' ) )["IDы"]
		ids = ids["IDы"] or ids
		local id = mw.text.trim( tostring(args[1] or '') )
		if tonumber(id) then
			idData = {["поз"] = id}
			table.insert(categories, '[[Категория:Страницы, использующие для спрайтов числовые идентификаторы]]')
		else
			idData = ids[id] or ids[mw.ustring.lower( id ):gsub( '[_%-%s%+]+', '-' )]
		end
	end 
 
	local title = mw.title.getCurrentTitle()
 
	-- запретить категории соответственно в подстраницах, в пространствах участников и на страницах обсуждений
	local disallowCats = title.isSubpage or title:inNamespace(2) or (title.namespace % 2 == 1)
	if idData then
		if type(idData) == 'table' then -- новый формат полей ID
			if idData["устарел"] and not disallowCats then
				table.insert( categories, '[[Категория:Страницы с устаревшими названиями спрайтов]]' )
			end
 
			args["поз"] = idData["поз"]
		else -- старый формат
			args["поз"] = idData
		end
	elseif not disallowCats then
		table.insert( categories, '[[Категория:Страницы с отсутствующими спрайтами]]' )
	end
 
	return p.base( args ), table.concat( categories, '' )
end
 
-- Ссылки
function p.link( f )
	local args = f
	if f == mw.getCurrentFrame() then
		args = require( 'Module:ProcessArgs' ).merge( true )
	end
 
	if not args["ID"] then
		args["ID"] = args["ид"] -- для совместимости
	end
 
	local link = args[1]
	if args[1] and not args["ID"] then
		link = args[1]:match( '^(.-)%+' ) or args[1]
	end
	local text = args["текст"] or args[2] or link
 
	args[1] = args["ID"] or args[1]
	args["ссылка"] = args["ссылка"] or link
	args["текст"] = text
 
	return p.sprite( args )
end
 
-- Документация
function p.doc( f )
    local args = f
    if f == mw.getCurrentFrame() then
        args = f.args
    else
        f = mw.getCurrentFrame()
    end
    local settingsPage = mw.text.trim( args[1] )
    local settings = mw.loadData( 'Модуль:' .. settingsPage )
    local idsPage = 'Модуль:' .. ( settings["IDы"] or settings["имя"] .. 'Спрайт/ID' )
    local spriteargs = {}
    for k, v in pairs(args) do
        if type(k) ~= 'number' then
            spriteargs[k] = v
        end
    end
 
    local getProtection = function( title, action, extra )
        local protections = { 'edit' }
        if extra then
            table.insert( protections, extra )
        end
 
        local addProtection = function( protection )
            if protection == 'autoconfirmed' then
                protection = 'editsemiprotected'
            elseif protection == 'sysop' then
                protection = 'editprotected'
            end
 
            table.insert( protections, protection )
        end
 
        local direct = title.protectionLevels[action]
        for _, protection in ipairs( direct ) do
            addProtection( protection )
        end
        local cascading = title.cascadingProtection.restrictions[action] or {}
        if #cascading > 0 then
            table.insert( protections, 'protect' )
        end
        for _, protection in ipairs( cascading ) do
            addProtection( protection )
        end
 
        return table.concat( protections, ',' )
    end
 
    local body
    if args.refresh then
        body = mw.html.create( '' )
    else
        local idsTitle = mw.title.new( idsPage )
        local spritesheet = settings["изобр"] or settings["имя"] .. 'CSS.png'
        local spriteTitle = mw.title.new( 'Файл:' .. spritesheet )
        local idsProtection = getProtection( idsTitle, 'edit' )
        local spriteProtection = getProtection( spriteTitle, 'upload', 'upload,reupload' )
        body = mw.html.create( 'div' ):attr( {
            id = 'spritedoc',
            ['data-idspage'] = idsTitle.id,
            ['data-idsprotection'] = idsProtection,
            ['data-idstimestamp'] = f:callParserFunction( 'REVISIONTIMESTAMP', idsPage ),
            ['data-spritesheet'] = spritesheet,
            ['data-spriteprotection'] = spriteProtection,
            ['data-pos'] = settings["поз"] or 1,
            ['data-refreshtext'] = mw.text.nowiki( '{{#invoke:Спрайт|doc|' .. settingsPage .. '|обновить=1}}' )
        } )
    end
 
    local data = mw.loadData( idsPage )
 
    local sections = {}
    for _, sectionData in ipairs( data["разделы"] or {"Некатегоризованные"} ) do
        local sectionTag = body:tag( 'div' ):addClass( 'spritedoc-section' ):attr( 'data-section-id', sectionData["ID"] )
        -- https://phabricator.wikimedia.org/T73594
        sectionTag:wikitext( '<h3>', sectionData[1], '</h3>' )
        sections[sectionData["ID"]] = { boxes = sectionTag:tag( 'ul' ):addClass( 'spritedoc-boxes' ) }
    end
 
    local keyedData = {}
    for name, idData in pairs( data["IDы"] ) do
        table.insert( keyedData, {
            ["ключ"] = mw.ustring.lower( name ),
            ["имя"] = name,
            ["данные"] = idData
        } )
    end
    table.sort( keyedData, function( a, b )
        return a["ключ"] < b["ключ"]
    end )
 
    for _, data in ipairs( keyedData ) do
        local idData = data["данные"]
        local pos = idData["поз"]
        local section = sections[idData["раздел"]]
        local names = section[pos]
        if not names then
            local box = section.boxes:tag( 'li' ):addClass( 'spritedoc-box' ):attr( 'data-pos', pos )
            local lspriteargs = mw.clone(spriteargs)
            lspriteargs["поз"] = pos
            lspriteargs["настройки"] = settingsPage
 
            box:tag( 'div' ):addClass( 'spritedoc-image' )
                :wikitext( p.base(lspriteargs) )
 
            names = box:tag( 'ul' ):addClass( 'spritedoc-names' )
            section[pos] = names
        end
        local nameElem = mw.html.create( 'li' ):addClass( 'spritedoc-name' )
        local codeElem = nameElem:tag( 'code' ):wikitext( data["имя"] )
 
        if idData["устарел"] then
            codeElem:addClass( 'spritedoc-deprecated' )
        end
        names:wikitext( tostring( nameElem ) )
    end
 
    if args["обновить"] then
        return '', tostring( body )
    end
    return f:callParserFunction( '#widget:Stylesheet', { page = 'SpriteDoc' } ), tostring( body )
end
 
return p

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.

Відвідайте інші вікіпроекти на Вікія!

Випадкова вікі