Module:Sprite: Difference between revisions
mw.html seems to use a lot of memory. Converting elements to wikitext string where possible before inserting them into an existing HtmlBuilder significantly reduces that memory usage for some reason, even though that just happens later anyway on output. |
m 91 revisions imported |
||
| (38 intermediate revisions by 6 users not shown) | |||
| Line 7: | Line 7: | ||
f = mw.getCurrentFrame() | f = mw.getCurrentFrame() | ||
end | end | ||
local data = args.data and mw.loadData( 'Module:' .. args.data ) or {} | |||
local settings = data.settings | |||
-- Default settings | -- Default settings | ||
| Line 18: | Line 21: | ||
local defaultStyle = default | local defaultStyle = default | ||
if | if settings then | ||
if not settings.stylesheet then | if not settings.stylesheet then | ||
-- Make a separate clone of the current default settings | -- Make a separate clone of the current default settings | ||
| Line 34: | Line 36: | ||
local sprite = mw.html.create( 'span' ):addClass( 'sprite' ) | 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 = {} | |||
-- for tint | |||
local classname = setting( 'classname' ) or mw.ustring.lower( setting( 'name' ):gsub( ' ', '-' ) ) .. '-sprite' | |||
local css_image = "background" | |||
if setting( 'formask' ) then | |||
classname = classname .. '-mask' | |||
css_image = "mask" | |||
end | end | ||
sprite:addClass( | sprite:addClass( classname ) | ||
local class = setting( 'class' ) | |||
if class then | |||
sprite:addClass( class ) | |||
end | end | ||
local | local width = setting( 'width' ) or setting( 'size' ) | ||
local | local height = setting( 'height' ) or setting( 'size' ) | ||
local | local sheetWidth = setting( 'sheetsize' ) | ||
local | local tiles = sheetWidth / width | ||
local | local pos = setting( 'pos' ) - 1 | ||
local scale = setting( 'scale' ) | local scale = setting( 'scale' ) | ||
if left | local autoScale = setting( 'autoscale' ) | ||
if pos then | |||
local left = pos % tiles * width * scale | |||
local top = math.floor( pos / tiles ) * height * scale | |||
if css_image == 'mask' then | |||
styles[#styles + 1] = '-webkit-mask-position:-' .. left .. 'px -' .. top .. 'px' | |||
end | |||
styles[#styles + 1] = css_image .. '-position:-' .. left .. 'px -' .. top .. 'px' | |||
end | end | ||
if not | |||
if not autoScale and scale ~= defaultStyle.scale then | |||
if css_image == 'mask' then | |||
styles[#styles + 1] = '-webkit-mask-size:' .. sheetWidth * scale .. 'px auto' | |||
end | |||
styles[#styles + 1] = css_image .. '-size:' .. sheetWidth * scale .. 'px auto' | |||
end | end | ||
if size ~= defaultStyle.size or ( not | 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 | |||
styles[#styles + 1] = 'vertical-align:' .. align | |||
end | end | ||
styles[#styles + 1] = setting( 'css' ) | |||
sprite:cssText( table.concat( styles, ';' ) ) | |||
local text = setting( 'text' ) | |||
local root | local root | ||
local spriteText | local spriteText | ||
if | if text then | ||
if not args['wrap'] then | |||
spriteText = mw.html.create( 'span' ):addClass( 'sprite-text' ):wikitext( | root = mw.html.create( 'span' ):addClass( 'nowrap' ) | ||
end | |||
spriteText = mw.html.create( 'span' ):addClass( 'sprite-text' ):wikitext( text ) | |||
end | end | ||
local title = setting( 'title' ) | |||
( root or sprite ):attr( 'title', | if title then | ||
( root or sprite ):attr( 'title', title ) | |||
end | end | ||
| Line 92: | Line 115: | ||
end | end | ||
local link = setting( 'link' ) | local link = setting( 'link' ) or '' | ||
if link and mw.ustring.lower( link ) ~= 'none' then | if link ~= '' and mw.ustring.lower( link ) ~= 'none' then | ||
-- External link | -- External link | ||
if link:find( '//' ) then | if link:find( '//' ) then | ||
| Line 111: | Line 134: | ||
if f == mw.getCurrentFrame() then | if f == mw.getCurrentFrame() then | ||
args = require( 'Module:ProcessArgs' ).merge( true ) | args = require( 'Module:ProcessArgs' ).merge( true ) | ||
else | |||
f = mw.getCurrentFrame() | |||
end | end | ||
local data = args.data and mw.loadData( 'Module:' .. args.data ) or {} | |||
local categories = {} | local categories = {} | ||
if | local idData = args.iddata | ||
args. | 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%+]', '-' )] | |||
if | end | ||
if | 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 = { 'Pages using deprecated sprite names', project = 0 } } | |||
end | end | ||
end | end | ||
args.pos = idData.pos | |||
elseif not disallowCats then | |||
categories[#categories + 1] = f:expandTemplate{ title = 'Translation category', args = { 'Pages with missing sprites', project = 0 } } | |||
end | end | ||
return p.base( args ), table.concat( categories | return p.base( args ), table.concat( categories ) | ||
end | end | ||
| Line 156: | Line 176: | ||
link = args[1]:match( '^(.-)%+' ) or args[1] | link = args[1]:match( '^(.-)%+' ) or args[1] | ||
end | end | ||
local text = args.text or args[2] or link | 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] | ||
| Line 172: | Line 195: | ||
f = mw.getCurrentFrame() | f = mw.getCurrentFrame() | ||
end | end | ||
local | local dataPage = mw.text.trim( args[1] ) | ||
local | local data = mw.loadData( 'Module:' .. dataPage ) | ||
local | |||
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 | local spriteStyle = '' | ||
if | if data.settings.url and data.settings.url.style then | ||
spriteStyle = data.settings.url.style | |||
end | end | ||
local data = mw. | local dataTitle = mw.title.new( 'Module:' .. dataPage ) | ||
-- Temporary until this is updated | |||
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-refreshtext'] = mw.text.nowiki( '{{#invoke:sprite|doc|' .. dataPage .. '|refresh=1}}' ), | |||
['data-settings'] = mw.text.jsonEncode( data.settings ), | |||
} ) | |||
local sections = {} | local sections = {} | ||
for _, sectionData in ipairs( data.sections or { 'Uncategorized' } ) do | for _, sectionData in ipairs( data.sections or { name = 'Uncategorized' } ) do | ||
local sectionTag = body:tag( 'div' ):addClass( 'spritedoc-section' ):attr( 'data-section-id', sectionData.id ) | local sectionTag = body:tag( 'div' ):addClass( 'spritedoc-section' ):attr( 'data-section-id', sectionData.id ) | ||
sectionTag:tag( 'h3' ):wikitext( sectionData.name ) | |||
sectionTag: | |||
sections[sectionData.id] = { boxes = sectionTag:tag( 'ul' ):addClass( 'spritedoc-boxes' ) } | sections[sectionData.id] = { boxes = sectionTag:tag( 'ul' ):addClass( 'spritedoc-boxes' ) } | ||
end | end | ||
local keyedData = {} | local keyedData = {} | ||
local i = 1 | |||
for name, idData in pairs( data.ids ) do | for name, idData in pairs( data.ids ) do | ||
keyedData[i] = { | |||
sortKey = mw.ustring.lower( name ), | sortKey = mw.ustring.lower( name ), | ||
name = name, | name = name, | ||
data = idData | data = idData | ||
} | } | ||
i = i + 1 | |||
end | end | ||
table.sort( keyedData, function( a, b ) | table.sort( keyedData, function( a, b ) | ||
| Line 221: | Line 280: | ||
local box = section.boxes:tag( 'li' ):addClass( 'spritedoc-box' ):attr( 'data-pos', pos ) | local box = section.boxes:tag( 'li' ):addClass( 'spritedoc-box' ):attr( 'data-pos', pos ) | ||
box:tag( 'div' ):addClass( 'spritedoc-image' ) | box:tag( 'div' ):addClass( 'spritedoc-image' ) | ||
:wikitext( p.base{ pos = pos, | :wikitext( p.base{ pos = pos, data = dataPage, nourl = spriteStyle ~= '' } ) | ||
names = box:tag( 'ul' ):addClass( 'spritedoc-names' ) | names = box:tag( 'ul' ):addClass( 'spritedoc-names' ) | ||
| Line 236: | Line 295: | ||
if args.refresh then | if args.refresh then | ||
return tostring( body ) | return '', '', tostring( body ) | ||
end | end | ||
local styles = f:extensionTag( 'templatestyles', '', { src = 'Sprite/doc.css' } ) | |||
return styles, spriteStyle, tostring( body ) | |||
end | end | ||
return p | return p | ||