ImageLink

--

```
local ImageLink = {}

-- Dependencies
local HF        = require("Dev:HF")
local FN        = require("Module:Filename")
local lib       = require('Module:Feature')
local userError = require('Dev:User error')

--[[
{{#invoke: ImageLink | ability
...
}}

{{#invoke: ImageLink | buff
...
}}

{{#invoke: ImageLink | champion
...
}}

{{#invoke: ImageLink | item
...
}}

{{#invoke: ImageLink | loading
...
}}

{{#invoke: ImageLink | rune
...
}}

{{#invoke: ImageLink | spell
...
}}

{{#invoke: ImageLink | ward
...
}}

{{#invoke: ImageLink | TFTchampion
...
}}

{{#invoke: ImageLink | TFTitem
...
}}

{{#invoke: ImageLink | TFTtrait
...
}}

{{#invoke: ImageLink | basic
}}
]]--

function ImageLink.ability(frame)
    local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end

    _input = args['champion']
    args['champion'] = lib.validateName(args['champion'])

    args['link'] = args['link'] or formatnil('%s#%s', args['champion'], args['ability']) or args['champion'] or ''
    args['text'] = args['text'] or args['ability'] or ''
    args['image'] = args['image'] or FN.ability{args['ability'], args['variant']}

    args['editlink'] = args['editlink'] or formatnil('Template:Data %s/%s', args['champion'], args['ability'])

    local link, img = ImageLink._createLink(args)
    if args['champion'] and args['ability'] then
        link:addClass('ability-icon')
        if args['champion'] then link:attr('data-champion', args['champion']) end
        if args['ability'] then link:attr('data-ability', args['ability']) end
        if args['variant'] then link:attr('data-variant', args['variant']) end
    end
    return link
end

function ImageLink.buff(frame)
    local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end

    args['link'] = args['link'] or args['buff'] or ''
    args['text'] = args['text'] or args['buff'] or ''
    args['image'] = args['image'] or FN.buff{args['buff'], args['variant']}

    args['editlink'] = args['editlink'] or formatnil('Template:Buff data %s', args['buff'])

    local link, img  = ImageLink._createLink(args)
    link:addClass('buff-icon')
    if args['buff'] then link:attr('data-param', args['buff']) end
    if args['variant'] then link:attr('data-variant', args['variant']) end
    return link
end

function ImageLink.champion(frame)
    local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end

    _input = args['champion']
    args['champion'] = lib.validateName(args['champion'])

    args['link'] = args['link'] or args['champion'] or ''
    args['text'] = args['text'] or _input or ''
    if args['circle'] == 'true' then
        args['image'] = args['image'] or FN.championcircle{_input, args['skin'], args['variant']}
        args['border'] = args['border'] or 'false'
    else
        args['image'] = args['image'] or FN.championsquare{_input, args['skin'], args['variant']}
    end

    args['editlink'] = args['editlink'] or 'Module:ChampionData/data'
    args['selflink'] = args['selflink'] or mw.title.getCurrentTitle().rootText

    local link, img = ImageLink._createLink(args)
    link:addClass('champion-icon')
    link:attr('data-champion', args['champion'])
    link:attr('data-skin', lib.ternary(args['skin'] == '', 'Original', args['skin'] or 'Original'))
    if args['variant'] then link:attr('data-variant', args['variant']) end
    return link
end

function ImageLink.item(frame)
    local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end

    if args['enchantment'] then
        args['link'] = args['link'] or args['enchantment'] or ''
        args['text'] = formatnil('%s (%s)', args['item'], args['enchantment']) or args['text'] or ''
        args['image'] = args['image'] or FN.item{['item'] = args['item'], ['enchantment'] = args['enchantment'], ['variant'] = args['variant']}
    else
        args['link'] = args['link'] or args['item'] or ''
        args['text'] = args['text'] or args['item'] or ''
        args['image'] = args['image'] or FN.item{args['item'], args['variant']}
    end

    args['editlink'] = args['editlink'] or formatnil('Template:Item data %s', args['item']) or ''

    local link, img = ImageLink._createLink(args)
    link:addClass('item-icon')
    if args['item'] then link:attr('data-param', args['item']) end
    if args['enchantment'] then link:attr('data-enchantment', enchantment):addClass('enchantment-icon') end
    if args['variant'] then link:attr('data-variant', args['variant']) end
    return link
end

function ImageLink.loading(frame)
    local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end

    _input = args['champion']
    args['champion'] = lib.validateName(args['champion'])

    args['link'] = args['link'] or args['champion'] or ''
    args['text'] = args['text'] or _input or ''
    args['image'] = args['image'] or FN.loading{_input, args['skin'], args['variant']}
    args['border'] = args['border'] or 'false'
    args['size'] = args['size'] or '110px'

    args['selflink'] = args['selflink'] or mw.title.getCurrentTitle().rootText

    local link, img = ImageLink._createLink(args)
    link:addClass('skin-icon')
    link:attr('data-skin', lib.ternary(args['skin'] == '', 'Original', args['skin'] or 'Original'))
    if args['champion'] then link:attr('data-champion', args['champion']) end
    if args['variant'] then link:attr('data-variant', args['variant']) end
    return link
end

function ImageLink.rune(frame)
    local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end

    args['link'] = args['link'] or args['rune'] .. ' (Rune)'
    args['text'] = args['text'] or args['rune'] or ''
    args['image'] = args['image'] or FN.rune{args['rune'], args['variant']}
    args['editlink'] = args['editlink'] or formatnil('Template:Rune data %s', args['rune']) or ''
    args['border'] = args['border'] or 'false'

    local link, img  = ImageLink._createLink(args)
    link:addClass('rune-icon')
    if args['rune'] then link:attr('data-param', args['rune']) end
    if args['variant'] then link:attr('data-variant', args['variant']) end
    return link
end

function ImageLink.skin(frame)
    local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end

    _input = args['champion']
    args['champion'] = lib.validateName(args['champion'])

    local skinData  = mw.loadData('Module:SkinData/data')
    local skinname   = args['skin'] or "Original"

    if skinData[args['champion']] == nil then
        return userError("''" .. args['champion'] .. "'' is not a valid champion name" , "LuaError")
    end

    if skinData[args['champion']].skins[skinname] == nil then
        return userError("Skin ''" .. skinname .. "'' for " .. args['champion'] .. " is not specified in Module:SkinData/data" , "LuaError")
    end

    local formatname = skinData[args['champion']].skins[skinname].formatname

    args['link'] = args['link'] or args['champion'] or ''
    args['text'] = args['text'] or lib.ternary(formatname, formatname, skinname .. " " .. _input) or ''
    if args['circle'] == 'true' then
        args['image'] = args['image'] or FN.championcircle{_input, args['skin'], args['variant']}
        args['border'] = args['border'] or 'false'
    else
        args['image'] = args['image'] or FN.championsquare{_input, ["variant"] = args['variant']}
    end

    args['editlink'] = args['editlink'] or 'Module:SkinData/data'
    args['selflink'] = args['selflink'] or mw.title.getCurrentTitle().rootText

    local link, img = ImageLink._createLink(args)
    link:addClass('skin-icon')
    link:attr('data-skin', lib.ternary(args['skin'] == '', 'Original', args['skin'] or 'Original'))
    if args['champion'] then link:attr('data-champion', args['champion']) end
    if args['variant'] then link:attr('data-variant', args['variant']) end
    return link
end

function ImageLink.spell(frame)
    local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end

    args['link'] = args['link'] or args['spell'] or ''
    args['text'] = args['text'] or args['spell'] or ''
    args['image'] = args['image'] or FN.spell{args['spell'], args['variant']}
    args['editlink'] = args['editlink'] or formatnil('Template:Spell data %s', args['spell']) or ''

    local link, img = ImageLink._createLink(args)
    link:addClass('spell-icon')
    if args['spell'] then link:attr('data-param', args['spell']) end
    if args['variant'] then link:attr('data-variant', args['variant']) end
    return link
end

function ImageLink.ward(frame)
    local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end

    args['link'] = args['link'] or 'Ward skins'
    args['text'] = args['text'] or args['ward'] .. ' Ward' or ''
    args['image'] = args['image'] or FN.ward{args['ward']}

    args['size'] = args['size'] or 64
    args['border'] = args['border'] or 'false'

    local link, img = ImageLink._createLink(args)
    link:addClass('ward-icon')
    return link
end

function ImageLink.TFTchampion(frame)
    local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end
    local TFTu       = require('Module:TFTUnitData')

    _input = args['champion']
    args['champion'] = lib.validateName(args['champion'])
    if args['set'] then
        args['skin'] = args['skin'] or TFTu.get{_input, args['set'], 'skin'}
        args['variant'] = args['variant'] or TFTu.get{_input, args['set'], 'variant'}
    end

    args['link'] = args['link'] or args['champion'] .. '/TFT' or ''
    args['text'] = args['text'] or _input or ''
    if args['circle'] == 'true' then
        args['image'] = args['image'] or FN.championcircle{_input, args['skin'], args['variant']}
        args['border'] = args['border'] or 'false'
    else
        args['image'] = args['image'] or FN.championsquare{_input, args['skin'], args['variant']}
    end

    args['editlink'] = args['editlink'] or 'Module:TFTUnitData/data'
    args['selflink'] = args['selflink'] or mw.title.getCurrentTitle().rootText

    local link, img = ImageLink._createLink(args)
    if args['set'] then
        link:addClass('tft-icon')
        link:attr('data-param', args['champion'])
        link:attr('data-type', 'champion')
        link:attr('data-set', args['set'])
    end

    return link
end

function ImageLink.TFTitem(frame)
    local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end

    args['link'] = args['link'] or args['item'] .. ' (Teamfight Tactics)' or ''
    args['text'] = args['text'] or args['item'] or ''
    args['image'] = args['image'] or args['item'] .. ' TFT item.png'

    args['editlink'] = args['editlink'] or args['item'] .. ' (Teamfight Tactics)'
    args['selflink'] = args['selflink'] or mw.title.getCurrentTitle().rootText

    local link, img = ImageLink._createLink(args)
    link:addClass('tft-icon')
    link:attr('data-param', args['item'])
    link:attr('data-type', 'item')

    return link
end

function ImageLink.TFTtrait(frame)
    local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end

    args['link'] = args['link'] or args['trait'] .. ' (Teamfight Tactics)' or ''
    args['text'] = args['text'] or args['trait'] or ''
    args['image'] = args['image'] or args['trait'] .. ' TFT icon.svg'

    args['editlink'] = args['editlink'] or 'Module:TFTTraitData/data'
    args['selflink'] = args['selflink'] or mw.title.getCurrentTitle().rootText

    local link, img = ImageLink._createLink(args)
    if args['set'] then
        link:addClass('tft-icon')
        link:attr('data-param', args['trait'])
        link:attr('data-type', 'trait')
        link:attr('data-set', args['set'])
    end

    return link
end

function ImageLink.basic(frame)
    local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end

    local link, img, label = ImageLink._createLink(args)

    return link
end

function ImageLink._createLink(args)
    -- define args.display (default: inline)
    args['display'] = (({['inlineblock'] = 'inline-block'})[args['display']]) or args['display'] or 'inline'

    -- define args.image (default: '')
    args['image'] = args['image'] or ''
    if args['image'] == '*none*' then args['image'] = '' end

    -- define args.border (true or false; default: true)
    args['border'] = args['border'] or true
    if args['border'] == 'false' or args['border'] == '0' then args['border'] = false end

    -- define args.edit (true or false; default: false)
    args['edit'] = args['edit'] or false
    if args['edit'] == 'true' or args['edit'] == '1' then args['edit'] = true end

    -- define args.style (default: 'white-space:pre')
    args['style'] = args['style'] or 'white-space:pre'
    if args['style'] == '*none*' then args['style'] = nil end

    -- define args.labelstyle (default: 'white-space:normal')
    args['labelstyle'] = args['labelstyle'] or 'white-space:normal'
    if args['labelstyle'] == '*none*' then args['labelstyle'] = nil end

    -- define args.width, args.height (%%x%%px or %%x%% or %%px or %%; default: 20px)
    local width, height
    if(args['size']) then width, height = getSize(args['size']) end
    args['size'] = args['size'] or 20
    args['width'] = tonumber(mw.ustring.match(args['width'] or width or '', '%d*'))
    args['height'] = tonumber(mw.ustring.match(args['height'] or height or '', '%d*'))
    if(not args['height']) then args['width'] = args['width'] or args['size'] end

    -- define args.selflink (default: articlename)
    args['selflink'] = args['selflink'] or mw.title.getCurrentTitle().prefixedText

    -- define args.link (default: '')
    args['link'] = args['link'] or ''
    if args['link'] == '*none*' then args['link'] = '' end

    -- define args.possessive (default: '')
    args['possessive'] = args['possessive'] or ''
    if args['possessive'] == 'true' or args['possessive'] == '1' then args['possessive'] = true end

    -- define args.text (default: '')
    args['text'] = args['text'] or args['link'] or ''
    if args['text'] == '*none*' then args['text'] = '' end
    if args['possessive'] == true then
        if mw.ustring.sub(args['text'], -1) == 's' then
            args['text'] = args['text'] .. '\''
        else
            args['text'] = args['text'] .. '\'s'
        end
    end

    -- define args.alttext (default: '')
    args['alttext'] = args['alttext'] or ''

    -- define args.label (before or after; default: after)
    args['label'] = (({['after'] = 'after', ['before'] = 'before'})[args['label']]) or 'after'
    if args['image'] == '' then args['label'] = 'only' end
    if args['text'] == '' then args['label'] = 'none' end

    -- define args.labellink (true or false; default: true)
    args['labellink'] = args['labellink'] or true
    if args['labellink'] == 'false' or args['labellink'] == '0' then args['labellink'] = false end

    --define args.data-param (specified or '')
    args['data-param'] = args['data-param'] or ''
    if args['data-param'] == '*none*' then args['data-param'] = nil end

    -- define args.separator (default: ' ')
    args['separator'] = args['separator'] or ' '

    local tag = lib.ternary(args['display'] == 'inline', 'span', 'div')

    local link = mw.html.create(tag):css('display', args['display']):addClass(args['display'] .. '-image')
    if args['class'] then link:addClass(args['class']) end
    if args['style'] then link:cssText(args['style']) end
    if args['data-param'] then link:attr('data-param', args['data-param']) end

    -- //img start
    local img = mw.html.create(tag)
    if args['image'] ~= '' then
        img:css({position = 'relative', display = 'inline-block'})
        local size = tostring(args['width'] or '') .. 'x' .. tostring(args['height'] or '') .. 'px'
        if args['iconclass'] then img:addClass(args['iconclass']) end
        if args['width'] then img:attr('data-width', tostring(args['width'])) end
        if args['height'] then img:attr('data-height', tostring(args['height'])) end
        if args['border'] == true then img:addClass('border') end
        if args['iconstyle'] then img:cssText(args['iconstyle']) end
        img:wikitext(mw.ustring.format('[[File:%s%s%s|link=%s%s]]',
            args['image'],
            lib.ternary(size == 'px', '', '|'..size),
            lib.ternary(args['border'], '|border', ''),
            lib.ternary(args['link'] == args['selflink'], '', args['link']),
            lib.ternary(args['alttext'] == '',
                lib.ternary(args['text'] == '', '', '|' .. args['text']),
                '|' .. args['alttext']
            )
        ))
        if args['image2'] then
            img:wikitext(mw.ustring.format('[[File:%s%s%s|link=%s%s]]',
                args['image2'],
                lib.ternary(size == 'px', '', '|'..size),
                lib.ternary(args['border'], '|border', ''),
                lib.ternary(args['link'] == args['selflink'], '', args['link']),
                lib.ternary(args['alttext'] == '',
                lib.ternary(args['text'] == '', '', '|' .. args['text']),
                    '|' .. args['alttext']
                )
            ))
        end
        if args['image3'] then
            img:wikitext(mw.ustring.format('[[File:%s%s%s|link=%s%s]]',
                args['image3'],
                lib.ternary(size == 'px', '', '|'..size),
                lib.ternary(args['border'], '|border', ''),
                lib.ternary(args['link'] == args['selflink'], '', args['link']),
                lib.ternary(args['alttext'] == '',
                lib.ternary(args['text'] == '', '', '|' .. args['text']),
                    '|' .. args['alttext']
                )
            ))
        end
        -- //bottom right number start
        if args['number'] and args['number'] ~= '' then
            local number = mw.html.create('span')
            local t = {
                ['position'] = 'absolute',
                ['font-size'] = string.gsub(math.min(args['width'] or 1e309, args['height'] or 1e309), 'px', '')/2 ..'px',
                ['line-height'] = '1em',
                ['bottom'] = '0.08em',
                ['right'] = '0.1em',
                ['font-weight'] = 'bold',
                ['pointer-events'] = 'none',
                ['color'] = lib.ternary(args['blacknum'] == 'true', '#111', '#EEE'),
                ['text-shadow'] = lib.ternary(args['blacknum'] == 'true', '-1px 0 1px #fff, 0 1px 1px #fff, 1px 0 1px #fff, 0 -1px 1px #fff', '-1px 0 1px #000, 0 1px 1px #000, 1px 0 1px #000, 0 -1px 1px #000')
                }
            number:css(t)
            number:wikitext(args['number'])
            number:done()
            img:node(number)
        end
        -- //bottom right number end
        img:done()
    else
        img = nil
    end
    -- //img end

    -- //label start
    local label = mw.html.create(tag)
    if args['text'] ~= '' then
        link:addClass('label-' .. args['label'])
        if args['labelclass'] then label:addClass(args['labelclass']) end
        if args['labelstyle'] then label:cssText(args['labelstyle']) end
        if args['link'] == '' or args['labellink'] == false then
            label:wikitext(args['text'])
        elseif args['selflink'] == args['link'] then
            label:wikitext('<strong class="selflink">' .. args['text'] .. '</strong>')
        elseif args['text'] == args['link'] then
            label:wikitext(formatnil('[[%s]]', args['text']))
        else
            label:wikitext(formatnil('[[%s|%s]]', args['link'], args['text']))
        end
        if args['edit'] == true and args['editlink'] ~= nil then
            label:wikitext(' <sup>[' .. tostring(mw.uri.fullUrl(args['editlink'], 'action=edit')) .. ' e]</sup>')
        end
        label:done()
    else
        label = nil
    end
    -- //label end

    if args['label'] == 'before' then
        if label then link:node(label) end
        if args['separator'] and img and label then link:wikitext(args['separator']) end
        if img then link:node(img) end
    else
        if img then link:node(img) end
        if args['separator'] and img and label then link:wikitext(args['separator']) end
        if label then link:node(label) end
    end

    return link, img, label
end

function formatnil(text, ...)
    if select("#", ...) == 0 then return text end
    for i=1, select("#", ...) do
        if select(i, ...) == nil then return nil end
    end
    return mw.ustring.format(text, ...)
end

function getSize(size)
    local fields = HF.explode('x', mw.ustring.gsub(tostring(size or ''), 'px', '', 1))
    local width = tonumber(fields[1]) or nil
    local height = tonumber(fields[2]) or nil
    return width, height
end

return ImageLink
--
```

--