м (Захистила «Модуль:Інвентарний слот» ([Редагування=Дозволено тільки автопідтвердженим користувачам] (безстроково) [Перейменування=Доз...) |
(Сторінка очищена) Мітка: Очищення |
||
Рядок 1: | Рядок 1: | ||
− | local p = {} |
||
− | |||
− | local i18n = { |
||
− | filename = 'Invicon $1', |
||
− | legacyFilename = 'Grid $1.png', |
||
− | modLink = 'Моди/$1/$2', |
||
− | moduleAliases = [[Модуль:Інвентарний слот/Псевдоніми]], |
||
− | moduleInvData = [[Модуль:ІнвСпрайт]], |
||
− | moduleModData = 'Модуль:ІнвСпрайт/Моди/$1', |
||
− | moduleRandom = [[Модуль:Випадкові числа]], |
||
− | moduleSprite = [[Модуль:Спрайт]], |
||
− | -- List of special prefixes which should be handled by |
||
− | -- other modules (such as being moved outside links) |
||
− | prefixes = { |
||
− | 'Any', |
||
− | 'Matching', |
||
− | 'Damaged', |
||
− | any = 'Any', |
||
− | matching = 'Matching', |
||
− | damaged = 'Damaged', |
||
− | }, |
||
− | templateFileUrl = 'FileUrl', |
||
− | } |
||
− | p.i18n = i18n |
||
− | p.prefixes = i18n.prefixes |
||
− | |||
− | local random = require( i18n.moduleRandom ).random |
||
− | local sprite = require( i18n.moduleSprite ).sprite |
||
− | local aliases = mw.loadData( i18n.moduleAliases ) |
||
− | local ids = mw.loadData( i18n.moduleInvData ).ids |
||
− | local modIds = {} |
||
− | local pageName = mw.title.getCurrentTitle().text |
||
− | |||
− | |||
− | -- Performs a simple recursive clone of a table's values |
||
− | local function cloneTable( origTable ) |
||
− | local newTable = {} |
||
− | for k, v in pairs( origTable ) do |
||
− | if type( v ) == 'table' then |
||
− | v = cloneTable( v ) |
||
− | end |
||
− | newTable[k] = v |
||
− | end |
||
− | return newTable |
||
− | end |
||
− | |||
− | --[[Merges a list, or inserts a string |
||
− | or table into a table |
||
− | --]] |
||
− | local function mergeList( parentTable, content ) |
||
− | local i = #parentTable + 1 |
||
− | if content[1] then |
||
− | -- Merge list into table |
||
− | for _, v in ipairs( content ) do |
||
− | parentTable[i] = v |
||
− | i = i + 1 |
||
− | end |
||
− | else |
||
− | -- Add strings or tables to table |
||
− | parentTable[i] = content |
||
− | end |
||
− | end |
||
− | |||
− | -- Creates the HTML for an item |
||
− | local function makeItem( frame, i, args ) |
||
− | local item = mw.html.create( 'span' ):addClass( 'invslot-item' ) |
||
− | if args["класзобр"] then |
||
− | item:addClass( args["класзобр"] ) |
||
− | end |
||
− | if frame.name == '' then |
||
− | item:tag( 'br' ) |
||
− | return item |
||
− | end |
||
− | local category |
||
− | local title = frame.title or mw.text.trim( args["назва"] or '' ) |
||
− | local mod = frame.mod |
||
− | local name = frame.name or '' |
||
− | local num = frame.num |
||
− | local description = frame.text |
||
− | |||
− | local img, idData |
||
− | if mod then |
||
− | local modData = modIds[mod] |
||
− | if not modData and mw.title.new( i18n.moduleModData:gsub( '%$1', mod ) ).exists then |
||
− | modData = mw.loadData( i18n.moduleModData:gsub( '%$1', mod ) ) |
||
− | modIds[mod] = modData |
||
− | end |
||
− | if modData and modData[name] then |
||
− | idData = modData[name] |
||
− | else |
||
− | img = i18n.legacyFilename:gsub( '%$1', name .. ' (' .. mod .. ')' ) |
||
− | end |
||
− | elseif ids[name] then |
||
− | idData = ids[name] |
||
− | elseif name:match( '\.gif$' ) or name:match( '\.png$' ) then |
||
− | img = i18n.filename:gsub( '%$1', name ) |
||
− | -- Remove file extension from name |
||
− | name = name:sub( 0, -5 ) |
||
− | else |
||
− | img = i18n.legacyFilename:gsub( '%$1', name ) |
||
− | end |
||
− | |||
− | local link = args["посилання"] or '' |
||
− | if link == '' then |
||
− | if mod then |
||
− | link = i18n.modLink:gsub( '%$1', mod ):gsub( '%$2', name ) |
||
− | else |
||
− | link = name:gsub( '^' .. i18n.prefixes.damaged .. ' ', '' ) |
||
− | end |
||
− | elseif link:lower() == 'none' then |
||
− | link = nil |
||
− | end |
||
− | if link == pageName then |
||
− | link = nil |
||
− | end |
||
− | |||
− | local formattedTitle |
||
− | local plainTitle |
||
− | if title == '' then |
||
− | plainTitle = name |
||
− | elseif title:lower() ~= 'none' then |
||
− | plainTitle = title:gsub( '\\\\', '\' ):gsub( '\\&', '&' ) |
||
− | |||
− | local formatPattern = '&[0-9a-fk-or]' |
||
− | if plainTitle:match( formatPattern ) then |
||
− | formattedTitle = title |
||
− | plainTitle = plainTitle:gsub( formatPattern, '' ) |
||
− | end |
||
− | |||
− | if plainTitle == '' then |
||
− | plainTitle = name |
||
− | else |
||
− | plainTitle = plainTitle:gsub( '\', '\\' ):gsub( '&', '&' ) |
||
− | end |
||
− | elseif link then |
||
− | if img then |
||
− | formattedTitle = '' |
||
− | else |
||
− | plainTitle = '' |
||
− | end |
||
− | end |
||
− | |||
− | item:attr{ |
||
− | ['data-minetip-title'] = formattedTitle, |
||
− | ['data-minetip-text'] = description |
||
− | } |
||
− | |||
− | if img then |
||
− | -- & is re-escaped because mw.html treats attributes |
||
− | -- as plain text, but MediaWiki doesn't |
||
− | local escapedTitle = ( plainTitle or '' ):gsub( '&', '&' ) |
||
− | item:addClass( 'invslot-item-image' ) |
||
− | :wikitext( '[[File:', img, '|32x32px|link=', link or '', '|', escapedTitle, ']]' ) |
||
− | else |
||
− | local image |
||
− | if mod then |
||
− | image = args.spritesheet or mod .. 'Sprite.png' |
||
− | end |
||
− | if link then |
||
− | item:wikitext( '[[', link, '|' ) |
||
− | end |
||
− | local image, spriteCat = sprite{ |
||
− | iddata = idData, title = plainTitle, |
||
− | image = image, data = 'ІнвСпрайт' |
||
− | } |
||
− | item:node( image ) |
||
− | category = spriteCat |
||
− | end |
||
− | |||
− | if num and num > 1 and num < 1000 then |
||
− | if img and link then |
||
− | item:wikitext( '[[', link, '|' ) |
||
− | end |
||
− | local number = item |
||
− | :tag( 'span' ) |
||
− | :addClass( 'invslot-stacksize' ) |
||
− | :attr{ title = plainTitle } |
||
− | :wikitext( num ) |
||
− | if numStyle then |
||
− | number:cssText( numStyle ) |
||
− | end |
||
− | if img and link then |
||
− | item:wikitext( ']]' ) |
||
− | end |
||
− | end |
||
− | |||
− | if idData and link then |
||
− | item:wikitext( ']]' ) |
||
− | end |
||
− | |||
− | item:wikitext( category ) |
||
− | |||
− | return item |
||
− | end |
||
− | |||
− | -- Main entry point |
||
− | function p.slot( f ) |
||
− | local args = f.args or f |
||
− | if f == mw.getCurrentFrame() and args[1] == nil then |
||
− | args = f:getParent().args |
||
− | end |
||
− | |||
− | if not args.parsed then |
||
− | args[1] = mw.text.trim( args[1] or '' ) |
||
− | end |
||
− | |||
− | local modData = { |
||
− | aliases = args.modaliases or '', |
||
− | default = args["мод"] |
||
− | } |
||
− | if modData.aliases ~= '' then |
||
− | modData.aliases = mw.loadData( 'Module:' .. modData.aliases ) |
||
− | else |
||
− | modData.aliases = nil |
||
− | end |
||
− | if args["мод"] == '' then |
||
− | modData.default = nil |
||
− | end |
||
− | |||
− | local frames |
||
− | if args.parsed then |
||
− | frames = args[1] |
||
− | elseif args[1] ~= '' then |
||
− | local randomise = args["клас"] == 'invslot-large' and 'never' or nil |
||
− | frames = p.parseFrameText( args[1], randomise, false, modData ) |
||
− | end |
||
− | local animated = frames and #frames > 1 |
||
− | local imgClass = args["класзобр"] |
||
− | local numStyle = args["стильцифр"] |
||
− | local body = mw.html.create( 'span' ):addClass( 'invslot' ):css{ ['vertical-align'] = args["вирівн"] } |
||
− | if animated then |
||
− | body:addClass( 'animated' ) |
||
− | end |
||
− | if args["клас"] then |
||
− | body:addClass( args["клас"] ) |
||
− | end |
||
− | if args["стиль"] then |
||
− | body:cssText( args["стиль"] ) |
||
− | end |
||
− | if ( args["замовчування"] or '' ) ~= '' then |
||
− | body:css( 'background-image', f:expandTemplate{ title = i18n.templateFileUrl, args = { args["замовчування"] .. '.png' } } ) |
||
− | end |
||
− | |||
− | --mw.logObject( frames ) |
||
− | if not frames then |
||
− | body:tag( 'br' ) |
||
− | return tostring( body ) |
||
− | end |
||
− | |||
− | local activeFrame = frames.randomise == true and random( #frames ) or 1 |
||
− | for i, frame in ipairs( frames ) do |
||
− | local item |
||
− | -- Table is a list, must contain subframes |
||
− | if frame[1] then |
||
− | item = body:tag( 'span' ):addClass( 'animated-subframe' ) |
||
− | local subActiveFrame = frame.randomise and random( #frame ) or 1 |
||
− | for sI, sFrame in ipairs( frame ) do |
||
− | local sItem = makeItem( sFrame, sI, args ) |
||
− | item:node( sItem ) |
||
− | |||
− | if sI == subActiveFrame then |
||
− | sItem:addClass( 'animated-active' ) |
||
− | end |
||
− | end |
||
− | else |
||
− | item = makeItem( frame, i, args ) |
||
− | body:node( item ) |
||
− | end |
||
− | if i == activeFrame and animated then |
||
− | item:addClass( 'animated-active' ) |
||
− | end |
||
− | end |
||
− | |||
− | return tostring( body ) |
||
− | end |
||
− | |||
− | --[[Parses the frame text into a table of frames and subframes, |
||
− | expanding aliases (and optionally retaining a reference), and |
||
− | deciding if the slot can be randomised |
||
− | --]] |
||
− | function p.parseFrameText( framesText, randomise, aliasReference, modData ) |
||
− | local frames = { randomise = randomise } |
||
− | local subframes = {} |
||
− | local subframe |
||
− | local expandedAliases |
||
− | local splitFrames = mw.text.split( mw.text.trim( framesText ), '%s*;%s*' ) |
||
− | for _, frameText in ipairs( splitFrames ) do |
||
− | frameText = frameText:gsub( '^%s*{%s*', function() |
||
− | subframe = true |
||
− | return '' |
||
− | end ) |
||
− | if subframe then |
||
− | frameText = frameText:gsub( '%s*}%s*$', function() |
||
− | subframe = 'last' |
||
− | return '' |
||
− | end ) |
||
− | end |
||
− | local frame = p.makeFrame( frameText, modData and modData.default ) |
||
− | local newFrame = frame |
||
− | if aliases or modData.aliases then |
||
− | local id = frame.name |
||
− | if frame.mod then |
||
− | id = frame.mod .. ':' .. id |
||
− | end |
||
− | |||
− | local alias = modData and modData.aliases and modData.aliases[id] or |
||
− | aliases and aliases[id] |
||
− | if alias then |
||
− | newFrame = p.getAlias( alias, frame ) |
||
− | if aliasReference then |
||
− | local curFrame = #frames + 1 |
||
− | local aliasData = { frame = frame, length = #newFrame } |
||
− | if subframe then |
||
− | if not subframes.aliasReference then |
||
− | subframes.aliasReference = {} |
||
− | end |
||
− | subframes.aliasReference[#subframes + 1] = aliasData |
||
− | else |
||
− | if not expandedAliases then |
||
− | expandedAliases = {} |
||
− | end |
||
− | expandedAliases[curFrame] = aliasData |
||
− | end |
||
− | end |
||
− | end |
||
− | end |
||
− | |||
− | if subframe then |
||
− | mergeList( subframes, newFrame ) |
||
− | -- Randomise starting frame for "Any *" aliases, as long as the alias is the only subframe |
||
− | if frames.randomise ~= 'never' and subframes.randomise == nil and |
||
− | frame.name:match( '^' .. i18n.prefixes.any .. ' ' ) then |
||
− | subframes.randomise = true |
||
− | else |
||
− | subframes.randomise = false |
||
− | end |
||
− | if frames.randomise ~= 'never' then |
||
− | frames.randomise = false |
||
− | end |
||
− | if subframe == 'last' then |
||
− | -- No point having a subframe containing a single frame, |
||
− | -- or the subframe being the only frame |
||
− | if #subframes == 1 or #splitFrames == i and #frames == 0 then |
||
− | mergeList( frames, subframes ) |
||
− | else |
||
− | table.insert( frames, subframes ) |
||
− | end |
||
− | subframes = {} |
||
− | subframe = nil |
||
− | end |
||
− | else |
||
− | -- Randomise starting frame for "Any *" aliases, as long as the alias is the only frame |
||
− | if frames.randomise == nil and frame.name:match( '^' .. i18n.prefixes.any .. ' ' ) then |
||
− | frames.randomise = true |
||
− | elseif frames.randomise ~= 'never' then |
||
− | frames.randomise = false |
||
− | end |
||
− | mergeList( frames, newFrame ) |
||
− | end |
||
− | end |
||
− | |||
− | frames.aliasReference = expandedAliases |
||
− | |||
− | return frames |
||
− | end |
||
− | |||
− | --[[Returns a new table with the parts of the parent frame |
||
− | added to the alias |
||
− | --]] |
||
− | function p.getAlias( aliasFrames, parentFrame ) |
||
− | -- If alias is just a name, return the parent frame with the new name |
||
− | if type( aliasFrames ) == 'string' then |
||
− | local expandedFrame = mw.clone( parentFrame ) |
||
− | expandedFrame.name = aliasFrames |
||
− | return { expandedFrame } |
||
− | end |
||
− | |||
− | -- Single frame alias, put in list |
||
− | if aliasFrames.name then |
||
− | aliasFrames = { aliasFrames } |
||
− | end |
||
− | |||
− | local expandedFrames = {} |
||
− | for i, aliasFrame in ipairs( aliasFrames ) do |
||
− | local expandedFrame |
||
− | if type( aliasFrame ) == 'string' then |
||
− | expandedFrame = { name = aliasFrame } |
||
− | else |
||
− | expandedFrame = cloneTable( aliasFrame ) |
||
− | end |
||
− | expandedFrame.title = parentFrame.title or expandedFrame.title |
||
− | expandedFrame.mod = parentFrame.mod or expandedFrame.mod |
||
− | expandedFrame.num = parentFrame.num or expandedFrame.num |
||
− | expandedFrame.text = parentFrame.text or expandedFrame.text |
||
− | |||
− | expandedFrames[i] = expandedFrame |
||
− | end |
||
− | |||
− | return expandedFrames |
||
− | end |
||
− | |||
− | function p.expandAlias( parentFrame, alias ) |
||
− | return p.getAlias( alias, parentFrame ) |
||
− | end |
||
− | |||
− | function p.stringifyFrame( frame ) |
||
− | if not frame.name then |
||
− | return '' |
||
− | end |
||
− | return string.format( |
||
− | '[%s]%s:%s,%s[%s]', |
||
− | frame.title or '', |
||
− | frame.mod or 'Minecraft', |
||
− | frame.name, |
||
− | frame.num or '', |
||
− | frame.text or '' |
||
− | ) |
||
− | end |
||
− | |||
− | function p.stringifyFrames( frames ) |
||
− | for i, frame in ipairs( frames ) do |
||
− | frames[i] = p.stringifyFrame( frame ) |
||
− | end |
||
− | return table.concat( frames, ';' ) |
||
− | end |
||
− | |||
− | -- Splits up the frame text into its parts |
||
− | function p.makeFrame( frameText, mod ) |
||
− | -- Simple frame with no parts |
||
− | if not frameText:match( '[%[:,]' ) then |
||
− | return { |
||
− | mod = mod, |
||
− | name = mw.text.trim( frameText ), |
||
− | } |
||
− | end |
||
− | |||
− | frameText = frameText:gsub( '%s*([%[%]:,;])%s*', '%1' ) |
||
− | |||
− | local frame = {} |
||
− | frame.title = frameText:match( '^%[([^%]]+)%]' ) |
||
− | |||
− | frame.mod = frameText:match( '([^:%]]+):' ) or mod |
||
− | local vanilla = { v = 1, vanilla = 1, mc = 1, minecraft = 1 } |
||
− | if frame.mod and vanilla[mw.ustring.lower( frame.mod )] or frame.mod == '' then |
||
− | frame.mod = nil |
||
− | end |
||
− | |||
− | local nameStart = ( frameText:find( ':' ) or frameText:find( '%]' ) or 0 ) + 1 |
||
− | if nameStart - 1 == #frameText then |
||
− | nameStart = 1 |
||
− | end |
||
− | frame.name = frameText:sub( nameStart, ( frameText:find( '[,%[]', nameStart ) or 0 ) - 1 ) |
||
− | |||
− | frame.num = math.floor( frameText:match( ',(%d+)' ) or 0 ) |
||
− | if frame.num == 0 then |
||
− | frame.num = nil |
||
− | end |
||
− | |||
− | frame.text = frameText:match( '%[([^%]]+)%]$' ) |
||
− | |||
− | return frame |
||
− | end |
||
− | function p.getParts( frameText, mod ) |
||
− | return p.makeFrame( frameText, mod ) |
||
− | end |
||
− | |||
− | return p |
Версія за 09:07, 23 грудня 2018
Цей модуль реалізує {{Інвентарний слот}}
.