(Se ha deshecho la revisión 104185 de Sawyerar (disc.)) Etiqueta: Deshacer |
mSin resumen de edición |
||
(No se muestran 14 ediciones intermedias de 5 usuarios) | |||
Línea 3: | Línea 3: | ||
local args = f |
local args = f |
||
if f == mw.getCurrentFrame() then |
if f == mw.getCurrentFrame() then |
||
− | args = require( ' |
+ | args = require( 'Module:ProcessArgs' ).merge( true ) |
+ | else |
||
+ | f = mw.getCurrentFrame() |
||
end |
end |
||
+ | |||
+ | local data = args.data and mw.loadData( 'Module:' .. args.data ) or {} |
||
+ | local settings = data.settings |
||
-- Default settings |
-- Default settings |
||
Línea 12: | Línea 17: | ||
size = 16, |
size = 16, |
||
pos = 1, |
pos = 1, |
||
− | + | align = 'text-top' |
|
− | align = 'text-top', |
||
− | class = '', |
||
− | text = '', |
||
− | title = '' |
||
} |
} |
||
− | local defaultStyle = |
+ | local defaultStyle = default |
− | if |
+ | if settings then |
+ | if not settings.stylesheet then |
||
− | local settings = mw.loadData( 'Módulo:' .. args.settings ) |
||
+ | -- Make a separate clone of the current default settings |
||
+ | defaultStyle = mw.clone( default ) |
||
+ | end |
||
for k, v in pairs( settings ) do |
for k, v in pairs( settings ) do |
||
default[k] = v |
default[k] = v |
||
− | if settings.stylesheet then |
||
− | defaultStyle[k] = v |
||
− | end |
||
end |
end |
||
end |
end |
||
− | local |
+ | local setting = function( arg ) |
− | + | return args[arg] or default[arg] |
|
+ | end |
||
− | local autoScale = args.autoscale or default.autoscale |
||
− | local sheetWidth = args.sheetsize or default.sheetsize |
||
− | local size = args.size or default.size |
||
− | local pos = math.abs( args.pos or default.pos ) - 1 |
||
− | local link = args.link or default.link |
||
− | local align = args.align or default.align |
||
− | local class = args.class or default.class |
||
− | local text = args.text or default.text |
||
− | local title = args.title or default.title |
||
− | local css = args.css or default.css |
||
− | local className = args.classname or default.classname |
||
− | |||
− | local tiles = sheetWidth / size |
||
− | local left = pos % tiles * size |
||
− | local top = math.floor( pos / tiles ) * size |
||
+ | local sprite = mw.html.create( 'span' ):addClass( 'sprite' ) |
||
+ | |||
+ | -- mw.html's css method performs very slow escaping, which doubles the time it takes |
||
+ | -- to run, so we'll construct the styles manually, and put them in the cssText |
||
+ | -- method, which only does html escaping (which isn't slow) |
||
local styles = {} |
local styles = {} |
||
+ | |||
− | if args.stylesheet or default.stylesheet then |
||
+ | if not setting( 'nourl' ) and setting( 'url' ) then |
||
− | class = ( className or mw.ustring.lower( name:gsub( ' ', '-' ) ) .. '-sprite ' ) .. class |
||
+ | styles[#styles + 1] = 'background-image:' .. ( setting( 'url' ).url or setting( 'url' ) ) |
||
− | else |
||
− | table.insert( styles, 'background-image:{{FileUrl|' .. ( args.image or default.image or name .. 'Sprite.png' ) .. '}}' ) |
||
end |
end |
||
− | if |
+ | if setting( 'stylesheet' ) then |
+ | sprite:addClass( |
||
− | table.insert( styles, 'background-position:-' .. left * scale .. 'px -' .. top * scale .. 'px' ) |
||
+ | setting( 'classname' ) or |
||
+ | mw.ustring.lower( setting( 'name' ):gsub( ' ', '-' ) ) .. '-sprite' |
||
+ | ) |
||
+ | elseif not setting( 'url' ) then |
||
+ | styles[#styles + 1] = 'background-image:' .. p.getUrl( |
||
+ | setting( 'image' ) or setting( 'name' ) .. 'Sprite.png' |
||
+ | ).url |
||
end |
end |
||
+ | local class = setting( 'class' ) |
||
+ | if class then |
||
+ | sprite:addClass( class ) |
||
+ | end |
||
+ | |||
+ | local width = setting( 'width' ) or setting( 'size' ) |
||
+ | local height = setting( 'height' ) or setting( 'size' ) |
||
+ | local sheetWidth = setting( 'sheetsize' ) |
||
+ | local tiles = sheetWidth / width |
||
+ | local pos = setting( 'pos' ) - 1 |
||
+ | local scale = setting( 'scale' ) |
||
+ | local autoScale = setting( 'autoscale' ) |
||
+ | |||
+ | if pos then |
||
+ | local left = pos % tiles * width * scale |
||
+ | local top = math.floor( pos / tiles ) * height * scale |
||
+ | styles[#styles + 1] = 'background-position:-' .. left .. 'px -' .. top .. 'px' |
||
+ | end |
||
+ | |||
if not autoScale and scale ~= defaultStyle.scale then |
if not autoScale and scale ~= defaultStyle.scale then |
||
− | + | styles[#styles + 1] = 'background-size:' .. sheetWidth * scale .. 'px auto' |
|
end |
end |
||
− | if size ~= defaultStyle.size or ( not autoScale and scale ~= defaultStyle.scale ) then |
+ | if height ~= defaultStyle.size or width ~= defaultStyle.size or ( not autoScale and scale ~= defaultStyle.scale ) then |
− | + | styles[#styles + 1] = 'height:' .. height * scale .. 'px' |
|
+ | styles[#styles + 1] = 'width:' .. width * scale .. 'px' |
||
end |
end |
||
+ | |||
+ | local align = setting( 'align' ) |
||
if align ~= defaultStyle.align then |
if align ~= defaultStyle.align then |
||
− | + | styles[#styles + 1] = 'vertical-align:' .. align |
|
end |
end |
||
+ | styles[#styles + 1] = setting( 'css' ) |
||
− | if css then |
||
+ | |||
− | table.insert( styles, css ) |
||
+ | sprite:cssText( table.concat( styles, ';' ) ) |
||
+ | |||
+ | local text = setting( 'text' ) |
||
+ | local root |
||
+ | local spriteText |
||
+ | if text then |
||
+ | if not args['wrap'] then |
||
+ | root = mw.html.create( 'span' ):addClass( 'nowrap' ) |
||
+ | end |
||
+ | spriteText = mw.html.create( 'span' ):addClass( 'sprite-text' ):wikitext( text ) |
||
end |
end |
||
+ | |||
− | if title ~= '' then |
||
− | + | local title = setting( 'title' ) |
|
+ | if title then |
||
+ | ( root or sprite ):attr( 'title', title ) |
||
end |
end |
||
+ | if not root then |
||
− | local sprite = table.concat( { |
||
+ | root = mw.html.create( '' ) |
||
− | '<span', |
||
+ | end |
||
− | 'class="sprite ' .. class .. '"', |
||
+ | root:node( sprite ) |
||
− | 'style="' .. table.concat( styles, ';' ) .. '"', |
||
+ | if spriteText then |
||
− | title, |
||
+ | root:node( spriteText ) |
||
− | '><br></span>' |
||
− | }, ' ' ) |
||
− | sprite = sprite:gsub( '%s+([">])', '%1' ) |
||
− | |||
− | if text ~= '' then |
||
− | text = '<span class="sprite-text nowrap"' .. title .. '>' .. text .. '</span>' |
||
end |
end |
||
− | + | local link = setting( 'link' ) or '' |
|
+ | if link ~= '' and mw.ustring.lower( link ) ~= 'none' then |
||
+ | -- External link |
||
if link:find( '//' ) then |
if link:find( '//' ) then |
||
+ | return '[' .. link .. ' ' .. tostring( root ) .. ']' |
||
− | -- External link |
||
− | return '[' .. link .. ' ' .. sprite .. text .. ']' |
||
− | else |
||
− | -- Internal link |
||
− | local linkPrefix = args.linkprefix or default.linkprefix or '' |
||
− | return '[[' .. linkPrefix .. link .. '|' .. sprite .. text .. ']]' |
||
end |
end |
||
+ | |||
− | else |
||
+ | -- Internal link |
||
− | return sprite .. text |
||
+ | local linkPrefix = setting( 'linkprefix' ) or '' |
||
+ | return '[[' .. linkPrefix .. link .. '|' .. tostring( root ) .. ']]' |
||
end |
end |
||
+ | |||
+ | return tostring( root ) |
||
end |
end |
||
Línea 103: | Línea 131: | ||
local args = f |
local args = f |
||
if f == mw.getCurrentFrame() then |
if f == mw.getCurrentFrame() then |
||
− | args = require( ' |
+ | args = require( 'Module:ProcessArgs' ).merge( true ) |
+ | else |
||
+ | f = mw.getCurrentFrame() |
||
end |
end |
||
+ | local data = args.data and mw.loadData( 'Module:' .. args.data ) or {} |
||
− | local category = '' |
||
+ | local categories = {} |
||
− | if tonumber( args[1] ) then |
||
− | + | local idData = args.iddata |
|
+ | if not idData then |
||
− | else |
||
− | local |
+ | local name = args.name or data.settings.name |
+ | local id = mw.text.trim( tostring( args[1] or '' ) ) |
||
− | if args.settings then |
||
+ | idData = data.ids[id] or data.ids[mw.ustring.lower( id ):gsub( '[%s%+]', '-' )] |
||
− | default = mw.loadData( 'Módulo:' .. args.settings ) |
||
+ | end |
||
+ | |||
+ | local title = mw.title.getCurrentTitle() |
||
+ | -- Remove categories on language pages, talk pages, and in User/UserWiki/UserProfile namespaces |
||
+ | local disallowCats = args.nocat or title.isTalkPage or title.nsText:find( '^User' ) |
||
+ | if idData then |
||
+ | if idData.deprecated then |
||
+ | args.class = ( args.class or '' ) .. ' sprite-deprecated' |
||
+ | if not disallowCats then |
||
+ | categories[#categories + 1] = f:expandTemplate{ title = 'Translation category', args = { 'Páginas con sprite obsoleto', project = 0 } } |
||
+ | end |
||
end |
end |
||
− | + | args.pos = idData.pos |
|
+ | elseif not disallowCats then |
||
− | local ids = mw.loadData( 'Módulo:' .. ( args.ids or default.ids or 'Sprite/' .. name ) ) |
||
+ | categories[#categories + 1] = f:expandTemplate{ title = 'Translation category', args = { 'Páginas con sprite faltante', project = 0 } } |
||
− | local id = mw.text.trim( args[1] or '' ) |
||
− | local pos = ids[id] or ids[mw.ustring.lower( id ):gsub( '[%s%+]', '-' )] |
||
− | if not pos and not mw.title.getCurrentTitle().isSubpage then |
||
− | category = '[[Categoría:Páginas con sprite ausente]]' |
||
− | end |
||
− | args.pos = pos |
||
end |
end |
||
− | return p.base( args ) . |
+ | return p.base( args ), table.concat( categories ) |
end |
end |
||
Línea 131: | Línea 167: | ||
local args = f |
local args = f |
||
if f == mw.getCurrentFrame() then |
if f == mw.getCurrentFrame() then |
||
− | args = require( ' |
+ | args = require( 'Module:ProcessArgs' ).merge( true ) |
end |
end |
||
Línea 138: | Línea 174: | ||
link = args[1]:match( '^(.-)%+' ) or args[1] |
link = args[1]:match( '^(.-)%+' ) or args[1] |
||
end |
end |
||
− | local text |
+ | local text |
+ | if not args.notext then |
||
+ | text = args.text or args[2] or link |
||
+ | end |
||
args[1] = args.id or args[1] |
args[1] = args.id or args[1] |
||
− | args.link = link |
+ | args.link = args.link or link |
args.text = text |
args.text = text |
||
return p.sprite( args ) |
return p.sprite( args ) |
||
+ | end |
||
+ | |||
+ | function p.getUrl( image, query, classname ) |
||
+ | local f = mw.getCurrentFrame() |
||
+ | local t = { |
||
+ | url = f:expandTemplate{ |
||
+ | title = 'FileUrl', |
||
+ | args = { image, query = query } |
||
+ | }, |
||
+ | } |
||
+ | if classname and classname ~= '' then |
||
+ | t.style = f:expandTemplate{ |
||
+ | title = 'FileUrlStyle', |
||
+ | args = { classname, image, query = query } |
||
+ | } |
||
+ | end |
||
+ | return t |
||
+ | end |
||
+ | |||
+ | function p.getParsedUrlStyle( f ) |
||
+ | local args = f:getParent().args |
||
+ | local module = args[1] |
||
+ | return require( 'Module:' .. module ).settings.url.style |
||
end |
end |
||
function p.doc( f ) |
function p.doc( f ) |
||
+ | local args = f |
||
− | local settings = mw.loadData( 'Módulo:' .. f.args[1] ) |
||
+ | if f == mw.getCurrentFrame() then |
||
− | local idTable = mw.title.new( 'Módulo:' .. ( settings.ids or 'Sprite/' .. settings.name ) ):getContent() |
||
+ | args = f.args |
||
− | idTable = idTable:gsub( '(\n%s*%-%-%s*.-%s*%-%-%s*\n)', '%1,' ):gsub( '^return {', '' ):gsub( '}$', '' ) |
||
+ | else |
||
+ | f = mw.getCurrentFrame() |
||
+ | end |
||
+ | local dataPage = mw.text.trim( args[1] ) |
||
+ | local data = mw.loadData( 'Module:' .. dataPage ) |
||
+ | local getProtection = function( title, action, extra ) |
||
− | local html = {} |
||
− | + | local protections = { 'edit' } |
|
+ | if extra then |
||
− | local posKeys = {} |
||
+ | protections[#protections + 1] = extra |
||
− | local section = '' |
||
+ | end |
||
− | for line in mw.text.gsplit( idTable, ',' ) do |
||
− | line = mw.text.trim( line ) |
||
− | id = line:match( '^%[[\'"](.+)[\'"]%]' ) or line:match( '^%w+' ) or '' |
||
− | pos = line:match( '=%s*(%d+)%s*,?$' ) or '' |
||
− | section = line:match( '^%-%-%s*(.+)%s*%-%-$' ) or section |
||
+ | local addProtection = function( protection ) |
||
− | if id ~= '' and pos ~= '' then |
||
− | if |
+ | if protection == 'autoconfirmed' then |
+ | protection = 'editsemiprotected' |
||
− | if type( ids[pos].id ) == 'table' then |
||
+ | elseif protection == 'sysop' then |
||
− | table.insert( ids[pos].id, id ) |
||
+ | protection = 'editprotected' |
||
− | else |
||
− | ids[pos].id = { ids[pos].id, id } |
||
− | end |
||
− | else |
||
− | ids[pos] = { id = id, section = section } |
||
− | table.insert( posKeys, pos ) |
||
end |
end |
||
+ | |||
+ | protections[#protections + 1] = protection |
||
end |
end |
||
− | end |
||
− | |||
− | local list = {} |
||
− | local listHead = '<ul class="spritedoc-multicolumn">' |
||
− | local listFoot = '</ul>' |
||
− | local lastSection = '' |
||
− | for i, pos in ipairs( posKeys ) do |
||
− | local id = ids[pos].id |
||
− | local newSection = mw.text.trim( ids[pos].section ) |
||
+ | local direct = title.protectionLevels[action] or {} |
||
− | if newSection ~= lastSection or i == 1 then |
||
+ | for _, protection in ipairs( direct ) do |
||
− | if newSection ~= lastSection then |
||
+ | addProtection( protection ) |
||
− | if lastSection ~= '' then |
||
− | table.insert( list, listFoot ) |
||
− | end |
||
− | |||
− | table.insert( list, '\n===' .. newSection .. '===\n' ) |
||
− | lastSection = newSection |
||
− | end |
||
− | table.insert( list, listHead ) |
||
end |
end |
||
+ | local cascading = title.cascadingProtection.restrictions[action] or {} |
||
− | table.insert( list, '<li><table><tr><td data-pos="' .. pos .. '">' ) |
||
− | if |
+ | if #cascading > 0 then |
+ | protections[#protections + 1] = 'protect' |
||
− | for i, id2 in ipairs( id ) do |
||
− | if i == 1 then |
||
− | table.insert( list, p.sprite{ id2, settings = f.args[1] } .. '</td><td><div class="sprite-id"><code>' .. id2 .. '</code></div>' ) |
||
− | else |
||
− | table.insert( list, '<div class="sprite-id"><code>' .. id2 .. '</code></div>' ) |
||
− | end |
||
− | end |
||
− | else |
||
− | table.insert( list, p.sprite{ id, settings = f.args[1] } .. '</td><td><div class="sprite-id"><code>' .. id .. '</code></div>' ) |
||
end |
end |
||
+ | for _, protection in ipairs( cascading ) do |
||
− | table.insert( list, '</td></tr></table></li>' ) |
||
+ | addProtection( protection ) |
||
− | |||
− | if i == #posKeys then |
||
− | table.insert( list, listFoot ) |
||
end |
end |
||
+ | |||
+ | return table.concat( protections, ',' ) |
||
end |
end |
||
− | local |
+ | local spriteStyle = '' |
− | if |
+ | if data.settings.url and data.settings.url.style then |
+ | spriteStyle = data.settings.url.style |
||
− | out = f:preprocess( '{{#widget:stylesheet|page=Sprite doc}}' ) .. '<div id="sprite-doc" data-settings="' .. f.args[1] .. '">' .. out .. '</div>' |
||
end |
end |
||
+ | local dataTitle = mw.title.new( 'Module:' .. dataPage ) |
||
− | return out |
||
+ | -- Temporary until this is updated |
||
+ | local classname = '' |
||
+ | if data.settings.stylesheet then |
||
+ | classname = data.settings.classname or |
||
+ | mw.ustring.lower( data.settings.name:gsub( ' ', '-' ) ) .. '-sprite' |
||
+ | end |
||
+ | local spritesheet = data.settings.image or data.settings.name .. 'Sprite.png' |
||
+ | local spriteTitle = mw.title.new( 'File:' .. spritesheet ) |
||
+ | local dataProtection = getProtection( dataTitle, 'edit' ) |
||
+ | local spriteProtection = getProtection( spriteTitle, 'upload', 'upload,reupload' ) |
||
+ | local body = mw.html.create( 'div' ):attr( { |
||
+ | id = 'spritedoc', |
||
+ | ['data-dataprotection'] = dataProtection, |
||
+ | ['data-datatimestamp'] = f:callParserFunction( 'REVISIONTIMESTAMP', 'Module:' .. dataPage ), |
||
+ | ['data-datapage'] = 'Module:' .. dataPage, |
||
+ | ['data-spritesheet'] = spritesheet, |
||
+ | ['data-spriteprotection'] = spriteProtection, |
||
+ | ['data-urlfunc'] = "require( [[Module:Sprite]] ).getUrl( '" .. spritesheet .. "', '$1', '" .. classname .. "' )", |
||
+ | ['data-refreshtext'] = mw.text.nowiki( '{{#invoke:sprite|doc|' .. dataPage .. '|refresh=1}}' ), |
||
+ | ['data-settings'] = mw.text.jsonEncode( data.settings ), |
||
+ | } ) |
||
+ | |||
+ | local sections = {} |
||
+ | for _, sectionData in ipairs( data.sections or { name = 'Uncategorized' } ) do |
||
+ | local sectionTag = body:tag( 'div' ):addClass( 'spritedoc-section' ):attr( 'data-section-id', sectionData.id ) |
||
+ | sectionTag:tag( 'h3' ):wikitext( sectionData.name ) |
||
+ | sections[sectionData.id] = { boxes = sectionTag:tag( 'ul' ):addClass( 'spritedoc-boxes' ) } |
||
+ | end |
||
+ | |||
+ | local keyedData = {} |
||
+ | local i = 1 |
||
+ | for name, idData in pairs( data.ids ) do |
||
+ | keyedData[i] = { |
||
+ | sortKey = mw.ustring.lower( name ), |
||
+ | name = name, |
||
+ | data = idData |
||
+ | } |
||
+ | i = i + 1 |
||
+ | end |
||
+ | table.sort( keyedData, function( a, b ) |
||
+ | return a.sortKey < b.sortKey |
||
+ | end ) |
||
+ | |||
+ | for _, data in ipairs( keyedData ) do |
||
+ | local idData = data.data |
||
+ | local pos = idData.pos |
||
+ | local section = sections[idData.section] |
||
+ | local names = section[pos] |
||
+ | if not names then |
||
+ | local box = section.boxes:tag( 'li' ):addClass( 'spritedoc-box' ):attr( 'data-pos', pos ) |
||
+ | box:tag( 'div' ):addClass( 'spritedoc-image' ) |
||
+ | :wikitext( p.base{ pos = pos, data = dataPage, nourl = spriteStyle ~= '' } ) |
||
+ | |||
+ | 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.name ) |
||
+ | |||
+ | if idData.deprecated then |
||
+ | codeElem:addClass( 'spritedoc-deprecated' ) |
||
+ | end |
||
+ | names:wikitext( tostring( nameElem ) ) |
||
+ | end |
||
+ | |||
+ | if args.refresh then |
||
+ | return '', '', tostring( body ) |
||
+ | end |
||
+ | local styles = f:callParserFunction( '#widget:SpriteDoc.css' ) |
||
+ | return styles, spriteStyle, tostring( body ) |
||
end |
end |
||
return p |
return p |
Revisión actual - 18:12 11 abr 2023
This module implements {{sprite}}
. It should generally be invoked directly on template pages, rather than using the sprite template.
Parent arguments are automatically merged with directly passed arguments (the latter overwriting the former) and all arguments are normalised to trim whitespace and set empty arguments to nil
.
Dependencies
See also
- Minecraft
{{SpriteBioma}}
{{SpriteBloque}}
{{SpriteEfecto}}
{{SpriteEntidad}}
{{SpriteEntorno}}
{{SpriteObjeto}}
{{InvSprite}}
{{SchematicSprite}}
{{SlotSprite}}
{{AchievementSprite}}
- Minecraft (legacy)
{{LegacyBlockSprite}}
{{LegacyEntitySprite}}
- Minecraft Dungeons
{{DungeonsSpriteNivel}}
{{DungeonsSpriteEncantamiento}}
{{DungeonsSpriteEfecto}}
{{DungeonsSpriteEntidad}}
{{DungeonsSpriteObjeto}}
{{DungeonsAchievementSprite}}
- Otras
{{Sprite}}
{{Sprite grid}}
{{Plano en capas}}
{{Esquemática}}
{{CommentSprite}}
{{FrontPageSprite}}
{{ProgressSprite}}
- Módulo:Sprite
[Ver | Editar | Purgar]La documentación arriba es transcluída desde Módulo:Sprite/doc.
local p = {}
function p.base( f )
local args = f
if f == mw.getCurrentFrame() then
args = require( 'Module:ProcessArgs' ).merge( true )
else
f = mw.getCurrentFrame()
end
local data = args.data and mw.loadData( 'Module:' .. args.data ) or {}
local settings = data.settings
-- Default settings
local default = {
scale = 1,
sheetsize = 256,
size = 16,
pos = 1,
align = 'text-top'
}
local defaultStyle = default
if settings then
if not settings.stylesheet then
-- Make a separate clone of the current default settings
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' )
-- mw.html's css method performs very slow escaping, which doubles the time it takes
-- to run, so we'll construct the styles manually, and put them in the cssText
-- method, which only does html escaping (which isn't slow)
local styles = {}
if not setting( 'nourl' ) and setting( 'url' ) then
styles[#styles + 1] = 'background-image:' .. ( setting( 'url' ).url or setting( 'url' ) )
end
if setting( 'stylesheet' ) then
sprite:addClass(
setting( 'classname' ) or
mw.ustring.lower( setting( 'name' ):gsub( ' ', '-' ) ) .. '-sprite'
)
elseif not setting( 'url' ) then
styles[#styles + 1] = 'background-image:' .. p.getUrl(
setting( 'image' ) or setting( 'name' ) .. 'Sprite.png'
).url
end
local class = setting( 'class' )
if class then
sprite:addClass( class )
end
local width = setting( 'width' ) or setting( 'size' )
local height = setting( 'height' ) or setting( 'size' )
local sheetWidth = setting( 'sheetsize' )
local tiles = sheetWidth / width
local pos = setting( 'pos' ) - 1
local scale = setting( 'scale' )
local autoScale = setting( 'autoscale' )
if pos then
local left = pos % tiles * width * scale
local top = math.floor( pos / tiles ) * height * scale
styles[#styles + 1] = 'background-position:-' .. left .. 'px -' .. top .. 'px'
end
if not autoScale and scale ~= defaultStyle.scale then
styles[#styles + 1] = 'background-size:' .. sheetWidth * scale .. 'px auto'
end
if height ~= defaultStyle.size or width ~= defaultStyle.size or ( not autoScale and scale ~= defaultStyle.scale ) then
styles[#styles + 1] = 'height:' .. height * scale .. 'px'
styles[#styles + 1] = 'width:' .. width * scale .. 'px'
end
local align = setting( 'align' )
if align ~= defaultStyle.align then
styles[#styles + 1] = 'vertical-align:' .. align
end
styles[#styles + 1] = setting( 'css' )
sprite:cssText( table.concat( styles, ';' ) )
local text = setting( 'text' )
local root
local spriteText
if text then
if not args['wrap'] then
root = mw.html.create( 'span' ):addClass( 'nowrap' )
end
spriteText = mw.html.create( 'span' ):addClass( 'sprite-text' ):wikitext( text )
end
local title = setting( 'title' )
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( 'link' ) or ''
if link ~= '' and mw.ustring.lower( link ) ~= 'none' then
-- External link
if link:find( '//' ) then
return '[' .. link .. ' ' .. tostring( root ) .. ']'
end
-- Internal link
local linkPrefix = setting( 'linkprefix' ) 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 )
else
f = mw.getCurrentFrame()
end
local data = args.data and mw.loadData( 'Module:' .. args.data ) or {}
local categories = {}
local idData = args.iddata
if not idData then
local name = args.name or data.settings.name
local id = mw.text.trim( tostring( args[1] or '' ) )
idData = data.ids[id] or data.ids[mw.ustring.lower( id ):gsub( '[%s%+]', '-' )]
end
local title = mw.title.getCurrentTitle()
-- Remove categories on language pages, talk pages, and in User/UserWiki/UserProfile namespaces
local disallowCats = args.nocat or title.isTalkPage or title.nsText:find( '^User' )
if idData then
if idData.deprecated then
args.class = ( args.class or '' ) .. ' sprite-deprecated'
if not disallowCats then
categories[#categories + 1] = f:expandTemplate{ title = 'Translation category', args = { 'Páginas con sprite obsoleto', project = 0 } }
end
end
args.pos = idData.pos
elseif not disallowCats then
categories[#categories + 1] = f:expandTemplate{ title = 'Translation category', args = { 'Páginas con sprite faltante', project = 0 } }
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
local link = args[1]
if args[1] and not args.id then
link = args[1]:match( '^(.-)%+' ) or args[1]
end
local text
if not args.notext then
text = args.text or args[2] or link
end
args[1] = args.id or args[1]
args.link = args.link or link
args.text = text
return p.sprite( args )
end
function p.getUrl( image, query, classname )
local f = mw.getCurrentFrame()
local t = {
url = f:expandTemplate{
title = 'FileUrl',
args = { image, query = query }
},
}
if classname and classname ~= '' then
t.style = f:expandTemplate{
title = 'FileUrlStyle',
args = { classname, image, query = query }
}
end
return t
end
function p.getParsedUrlStyle( f )
local args = f:getParent().args
local module = args[1]
return require( 'Module:' .. module ).settings.url.style
end
function p.doc( f )
local args = f
if f == mw.getCurrentFrame() then
args = f.args
else
f = mw.getCurrentFrame()
end
local dataPage = mw.text.trim( args[1] )
local data = mw.loadData( 'Module:' .. dataPage )
local getProtection = function( title, action, extra )
local protections = { 'edit' }
if extra then
protections[#protections + 1] = extra
end
local addProtection = function( protection )
if protection == 'autoconfirmed' then
protection = 'editsemiprotected'
elseif protection == 'sysop' then
protection = 'editprotected'
end
protections[#protections + 1] = protection
end
local direct = title.protectionLevels[action] or {}
for _, protection in ipairs( direct ) do
addProtection( protection )
end
local cascading = title.cascadingProtection.restrictions[action] or {}
if #cascading > 0 then
protections[#protections + 1] = 'protect'
end
for _, protection in ipairs( cascading ) do
addProtection( protection )
end
return table.concat( protections, ',' )
end
local spriteStyle = ''
if data.settings.url and data.settings.url.style then
spriteStyle = data.settings.url.style
end
local dataTitle = mw.title.new( 'Module:' .. dataPage )
-- Temporary until this is updated
local classname = ''
if data.settings.stylesheet then
classname = data.settings.classname or
mw.ustring.lower( data.settings.name:gsub( ' ', '-' ) ) .. '-sprite'
end
local spritesheet = data.settings.image or data.settings.name .. 'Sprite.png'
local spriteTitle = mw.title.new( 'File:' .. spritesheet )
local dataProtection = getProtection( dataTitle, 'edit' )
local spriteProtection = getProtection( spriteTitle, 'upload', 'upload,reupload' )
local body = mw.html.create( 'div' ):attr( {
id = 'spritedoc',
['data-dataprotection'] = dataProtection,
['data-datatimestamp'] = f:callParserFunction( 'REVISIONTIMESTAMP', 'Module:' .. dataPage ),
['data-datapage'] = 'Module:' .. dataPage,
['data-spritesheet'] = spritesheet,
['data-spriteprotection'] = spriteProtection,
['data-urlfunc'] = "require( [[Module:Sprite]] ).getUrl( '" .. spritesheet .. "', '$1', '" .. classname .. "' )",
['data-refreshtext'] = mw.text.nowiki( '{{#invoke:sprite|doc|' .. dataPage .. '|refresh=1}}' ),
['data-settings'] = mw.text.jsonEncode( data.settings ),
} )
local sections = {}
for _, sectionData in ipairs( data.sections or { name = 'Uncategorized' } ) do
local sectionTag = body:tag( 'div' ):addClass( 'spritedoc-section' ):attr( 'data-section-id', sectionData.id )
sectionTag:tag( 'h3' ):wikitext( sectionData.name )
sections[sectionData.id] = { boxes = sectionTag:tag( 'ul' ):addClass( 'spritedoc-boxes' ) }
end
local keyedData = {}
local i = 1
for name, idData in pairs( data.ids ) do
keyedData[i] = {
sortKey = mw.ustring.lower( name ),
name = name,
data = idData
}
i = i + 1
end
table.sort( keyedData, function( a, b )
return a.sortKey < b.sortKey
end )
for _, data in ipairs( keyedData ) do
local idData = data.data
local pos = idData.pos
local section = sections[idData.section]
local names = section[pos]
if not names then
local box = section.boxes:tag( 'li' ):addClass( 'spritedoc-box' ):attr( 'data-pos', pos )
box:tag( 'div' ):addClass( 'spritedoc-image' )
:wikitext( p.base{ pos = pos, data = dataPage, nourl = spriteStyle ~= '' } )
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.name )
if idData.deprecated then
codeElem:addClass( 'spritedoc-deprecated' )
end
names:wikitext( tostring( nameElem ) )
end
if args.refresh then
return '', '', tostring( body )
end
local styles = f:callParserFunction( '#widget:SpriteDoc.css' )
return styles, spriteStyle, tostring( body )
end
return p