ข้ามไปเนื้อหา

มอดูล:Userbox

มอดูลถูกป้องกันถาวร
จากวิกิพีเดีย สารานุกรมเสรี

-- This module implements {{userbox}}.
local categoryHandler = require('Module:Category handler').main

local p = {}

--------------------------------------------------------------------------------
-- Helper functions
--------------------------------------------------------------------------------

local function checkNum(val, default)
    -- Checks whether a value is a number greater than or equal to zero. If so,
    -- returns it as a number. If not, returns a default value.
    val = tonumber(val)
    if val and val >= 0 then
        return val
    else
        return default
    end
end

local function addSuffix(num, suffix)
    -- Turns a number into a string and adds a suffix.
    if num then
        return tostring(num) .. suffix
    else
        return nil
    end
end

local function checkNumAndAddSuffix(num, default, suffix)
    -- Checks a value with checkNum and adds a suffix.
    num = checkNum(num, default)
    return addSuffix(num, suffix)
end

local function makeCat(cat, sort)
    -- Makes a category link.
    if sort then
        return mw.ustring.format('[[หมวดหมู่:%s|%s]]', cat, sort)
    else
        return mw.ustring.format('[[หมวดหมู่:%s]]', cat)
    end
end

local function handleId(id, args)
    if id then
        local allNames = mw.site.namespaces[6].aliases
        allNames[#allNames + 1] = mw.site.namespaces[6].name
        allNames[#allNames + 1] = mw.site.namespaces[6].canonicalName
        for i, name in ipairs(allNames) do
            if mw.ustring.lower(mw.ustring.sub(id, 1, mw.ustring.len(name) + 1)) == mw.ustring.lower(name .. ":") then
                id = '[[' .. id .. '|' ..
                         (args['logo-size'] or args['ขนาดฟอนต์รูป'] or
                             args['ขนาดรูป'] or args[5] or args['id-s'] or "40x40") .. 'px]]'
                break
            end
        end
    end
    return id
end


--------------------------------------------------------------------------------
-- Argument processing
--------------------------------------------------------------------------------

local function makeInvokeFunc(funcName)
    return function(frame)
        local origArgs = require('Module:Arguments').getArgs(frame)
        local args = {}
        for k, v in pairs(origArgs) do
            args[k] = v
        end
        return p.main(funcName, args)
    end
end

p.userbox = makeInvokeFunc('_userbox')
p['userbox-2'] = makeInvokeFunc('_userbox-2')
p['userbox-r'] = makeInvokeFunc('_userbox-r')

--------------------------------------------------------------------------------
-- Main functions
--------------------------------------------------------------------------------

function p.main(funcName, args)
    local userboxData = p[funcName](args)
    local userbox = p.render(userboxData)
    local cats = p.categories(args)
    return userbox .. (cats or '')
end

function p._userbox(args)
    -- Does argument processing for {{userbox}}.
    local data = {}

    -- Get div tag values.
    data.float = args.float or args['จัดลอย'] or 'left'
    local borderWidthNum = checkNum(args['border-width'] or args['ความกว้างขอบ'] or
                                        args['border-s'], 1) -- Used to calculate width.
    data.borderWidth = addSuffix(borderWidthNum, 'px')
    data.borderColor = args['border-color'] or args['สีขอบ'] or args['border-c'] or args[1] or args['id-c'] or
                           '#999'
    data.width = addSuffix(240 - 2 * borderWidthNum, 'px') -- Also used in the table tag.
    data.bodyClass = args.bodyclass or args['คลาสกล่อง']

    -- Get table tag values.
    data.backgroundColor = args['info-background'] or args['สีพื้นหลัง'] or args['สีพื้น'] or args[2] or
                               args['info-c'] or '#eee'

    -- Get info values.
    data.info = args.info or args['ข้อความ'] or args[4] or "<code>{{{info}}}</code>"
    data.infoTextAlign = args['info-a'] or args['จัดแนวข้อความ'] or 'left'
    data.infoFontSize = checkNumAndAddSuffix(args['info-size'] or
                                                 args['ขนาดฟอนต์ข้อความ'] or
                                                 args['info-s'], 8, 'pt')
    data.infoHeight = checkNumAndAddSuffix(args['logo-height'] or args['ความสูงโลโก้'] or
                                               args['ความสูงรูป'] or args['id-h'], 45, 'px')
    data.infoPadding =
        args['info-padding'] or args['info-p'] or args['ระยะห่างข้อความ'] or '0 4px 0 4px'
    data.infoLineHeight = args['info-line-height'] or args['info-lh'] or
                              args['ระยะบรรทัดข้อความ'] or '1.25em'
    data.infoColor = args['info-color'] or args['info-fc'] or args['สีฟอนต์ข้อความ'] or
                         'black'
    data.infoOtherParams = args['info-other-param'] or args['info-op'] or
                               args['ค่าอื่นของข้อความ']
    data.infoClass = args['info-class'] or args['คลาสข้อความ']

    -- Get id values.
    local id = args.logo or args[3] or args.id or args['รูป'] or args['โลโก้'] or args['ภาพ']
    data.id = handleId(id, args)
    data.showId = id and true or false
    data.idWidth = checkNumAndAddSuffix(args['logo-width'] or args['id-w'] or
                                            args['ความกว้างรูป'] or
                                            args['ความกว้างโลโก้'], 45, 'px')
    data.idHeight = checkNumAndAddSuffix(
        args['logo-height'] or args['id-h'] or args['ความสูงรูป'] or
            args['ความสูงโลโก้'], 45, 'px')
    data.idBackgroundColor = args['logo-background'] or args[1] or args['id-c'] or
                                 args['สีพื้นหลังรูป'] or args['สีพื้นรูป'] or '#ddd'
    data.idTextAlign = args['id-a'] or args['จัดแนวรูป'] or 'center'
    data.idFontSize = checkNum(args['logo-size'] or args[5] or args['id-s'] or args['ขนาดรูป'] or
                                   args['ขนาดฟอนต์รูป'], 14)
    data.idColor = args['logo-color'] or args['id-fc'] or args['สีฟอนต์รูป'] or data.infoColor
    data.idPadding = args['logo-padding'] or args['id-p'] or args['ระยะห่างรูป'] or '0 1px 0 0'
    data.idLineHeight = args['logo-line-height'] or args['id-lh'] or args['ระยะบรรทัดรูป'] or
                            '1.25em'
    data.idOtherParams = args['logo-other-param'] or args['id-op'] or args['ค่าอื่นของรูป']
    data.idClass = args['id-class'] or args['คลาสรูป']

    return data
end

p['_userbox-2'] = function(args)
    -- Does argument processing for {{userbox-2}}.
    local data = {}

    -- Get div tag values.
    data.float = args.float or 'left'
    local borderWidthNum = checkNum(args['border-s'] or args[9], 1) -- Used to calculate width.
    data.borderWidth = addSuffix(borderWidthNum, 'px')
    data.borderColor = args['border-c'] or args[6] or args['id1-c'] or args[1] or '#999999'
    data.width = addSuffix(240 - 2 * borderWidthNum, 'px') -- Also used in the table tag.
    data.bodyClass = args.bodyclass

    -- Get table tag values.
    data.backgroundColor = args['info-c'] or args[2] or '#eeeeee'

    -- Get info values.
    data.info = args.info or args[4] or args['ข้อความ'] or "<code>{{{info}}}</code>"
    data.infoTextAlign = args['info-a'] or 'left'
    data.infoFontSize = checkNumAndAddSuffix(args['info-s'], 8, 'pt')
    data.infoColor = args['info-fc'] or args[8] or 'black'
    data.infoPadding = args['info-p'] or '0 4px 0 4px'
    data.infoLineHeight = args['info-lh'] or '1.25em'
    data.infoOtherParams = args['info-op']

    -- Get id values.
    data.showId = true
    data.id = args.logo or args[3] or args.id1 or args['รูป'] or args['โลโก้'] or args['ภาพ'] or
                  'id1'
		data.id = handleId(data.id, args)
    data.idWidth = checkNumAndAddSuffix(args['id1-w'], 45, 'px')
    data.idHeight = checkNumAndAddSuffix(args['id-h'], 45, 'px')
    data.idBackgroundColor = args['id1-c'] or args[1] or '#dddddd'
    data.idTextAlign = 'center'
    data.idFontSize = checkNum(args['id1-s'], 14)
    data.idLineHeight = args['id1-lh'] or '1.25em'
    data.idColor = args['id1-fc'] or data.infoColor
    data.idPadding = args['id1-p'] or '0 1px 0 0'
    data.idOtherParams = args['id1-op']

    -- Get id2 values.
    data.showId2 = true
    data.id2 = args.logo or args[5] or args.id2 or 'id2'
    data.id2Width = checkNumAndAddSuffix(args['id2-w'], 45, 'px')
    data.id2Height = data.idHeight
    data.id2BackgroundColor = args['id2-c'] or args[7] or args[1] or '#dddddd'
    data.id2TextAlign = 'center'
    data.id2FontSize = checkNum(args['id2-s'], 14)
    data.id2LineHeight = args['id2-lh'] or '1.25em'
    data.id2Color = args['id2-fc'] or args['สีฟอนต์รูป'] or data.infoColor
    data.id2Padding = args['id2-p'] or '0 0 0 1px'
    data.id2OtherParams = args['id2-op']

    return data
end

p['_userbox-r'] = function(args)
    -- Does argument processing for {{userbox-r}}.
    local data = {}

    -- Get div tag values.
    data.float = args.float or 'left'
    local borderWidthNum = checkNum(args['border-width'] or args['border-s'] or
                                        args['ความกว้างขอบ'], 1) -- Used to calculate width.
    data.borderWidth = addSuffix(borderWidthNum, 'px')
    data.borderColor = args['border-color'] or args['border-c'] or args[1] or args['id-c'] or args['สีขอบ'] or
                           '#999'
    data.width = addSuffix(240 - 2 * borderWidthNum, 'px') -- Also used in the table tag.
    data.bodyClass = args.bodyclass or args['คลาสกล่อง']

    -- Get table tag values.
    data.backgroundColor = args['info-background'] or args[2] or args['info-c'] or
                               args['สีพื้นหลัง'] or args['สีพื้น'] or '#eee'

    -- Get id values.
    data.showId = false -- We only show id2 in userbox-r.

    -- Get info values.
    data.info = args.info or args[4] or args['ข้อความ'] or "<code>{{{info}}}</code>"
    data.infoTextAlign = args['info-align'] or args['info-a'] or args['จัดแนวข้อความ'] or
                             'left'
    data.infoFontSize = checkNumAndAddSuffix(args['info-size'] or args['info-s'] or
                                                 args['ขนาดฟอนต์ข้อความ'], 8, 'pt')
    data.infoPadding =
        args['info-padding'] or args['info-p'] or args['ระยะห่างข้อความ'] or '0 4px 0 4px'
    data.infoLineHeight = args['info-line-height'] or args['info-lh'] or
                              args['ระยะบรรทัดข้อความ'] or '1.25em'
    data.infoColor = args['info-color'] or args['info-fc'] or args['สีฟอนต์ข้อความ'] or
                         'black'
    data.infoOtherParams = args['info-other-param'] or args['info-op'] or
                               args['ค่าอื่นของข้อความ']

    -- Get id2 values.
    data.showId2 = true
    data.id2 = args.logo or args[3] or args.id or args['รูป'] or 'id'
    data.id2Width = checkNumAndAddSuffix(args['logo-width'] or args['id-w'] or
                                             args['ความกว้างโลโก้'] or
                                             args['ความกว้างรูป'], 45, 'px')
    data.id2Height = checkNumAndAddSuffix(args['logo-height'] or args['id-h'] or
                                              args['ความสูงโลโก้'] or
                                              args['ความสูงรูป'], 45, 'px')
    data.id2BackgroundColor = args['logo-background'] or args[1] or args['id-c'] or
                                  args['สีพื้นหลังรูป'] or args['สีพื้นรูป'] or '#ddd'
    data.id2TextAlign = args['id-a'] or args['จัดแนวรูป'] or 'center'
    data.id2FontSize = checkNum(args['logo-size'] or args[5] or args['id-s'] or args['ขนาดรูป'] or
                                    args['ขนาดฟอนต์รูป'], 14)
    data.id2Color = args['logo-color'] or args['id-fc'] or args['สีฟอนต์รูป'] or data.infoColor
    data.id2Padding = args['logo-padding'] or args['id-p'] or args['ระยะห่างรูป'] or '0 0 0 1px'
    data.id2LineHeight = args['logo-line-height'] or args['id-lh'] or args['ระยะบรรทัดรูป'] or
                             '1.25em'
    data.id2OtherParams = args['logo-other-param'] or args['ค่าอื่นของรูป'] or args['id-op']

    return data
end

function p.render(data)
    -- Renders the userbox html using the content of the data table. 
    -- Render the div tag html.
    local root = mw.html.create('div')
    root:css('float', data.float):css('border', (data.borderWidth or '') .. ' solid ' .. (data.borderColor or '')):css(
        'margin', '1px'):css('width', data.width):addClass('wikipediauserbox'):addClass(data.bodyClass)

    -- Render the table tag html.
    local tableroot = root:tag('table')
    tableroot:attr('role', 'presentation'):css('border-collapse', 'collapse'):css('width', data.width):css(
        'margin-bottom', '0'):css('margin-top', '0'):css('background', data.backgroundColor):css('color', 'inherit')

    -- Render the id html.
    local tablerow = tableroot:tag('tr')
    if data.showId then
        tablerow:tag('td'):css('border', '0'):css('width', data.idWidth):css('height', data.idHeight):css('background',
            data.idBackgroundColor):css('text-align', data.idTextAlign):css('font-size', data.idFontSize .. 'pt'):css(
            'font-weight', 'bold'):css('color', data.idColor):css('padding', data.idPadding):css('line-height',
            data.idLineHeight):css('vertical-align', 'middle'):cssText(data.idOtherParams):addClass(data.idClass)
            :wikitext(data.id)
    end

    -- Render the info html.
    tablerow:tag('td'):css('border', '0'):css('text-align', data.infoTextAlign):css('font-size', data.infoFontSize):css(
        'padding', data.infoPadding):css('height', data.infoHeight):css('line-height', data.infoLineHeight):css('color',
        data.infoColor):css('vertical-align', 'middle'):cssText(data.infoOtherParams):addClass(data.infoClass):wikitext(
        data.info)

    -- Render the second id html.
    if data.showId2 then
        tablerow:tag('td'):css('border', '0'):css('width', data.id2Width):css('height', data.id2Height):css(
            'background', data.id2BackgroundColor):css('text-align', data.id2TextAlign):css('font-size',
            data.id2FontSize .. 'pt'):css('font-weight', 'bold'):css('color', data.id2Color):css('padding',
            data.id2Padding):css('line-height', data.id2LineHeight):css('vertical-align', 'middle'):cssText(
            data.id2OtherParams):wikitext(data.id2)
    end

    local title = mw.title.getCurrentTitle()
    if (title.namespace == 2) and not title.text:match("/") then
        return tostring(root) -- regular user page
    elseif title.namespace == 14 then
        return tostring(root) -- category
    elseif title.isTalkPage then
        return tostring(root) -- talk page
    end

    local legible = true
    local contrast = require('Module:Color contrast')._ratio

    local function has_text(wikitext)
        wikitext = wikitext:gsub("]]", "|]]")
        wikitext = wikitext:gsub("%[%[%s*[Mm][Ee][Dd][Ii][Aa]%s*:[^|]-(|.-)]]", "")
        wikitext = wikitext:gsub("%[%[%s*[Ii][Mm][Aa][Gg][Ee]%s*:[^|]-(|.-)]]", "")
        wikitext = wikitext:gsub("%[%[%s*[Ff][Ii][Ll][Ee]%s*:[^|]-(|.-)]]", "")
        wikitext = wikitext:gsub("%[%[%s*สื่อ%s*:[^|]-(|.-)]]", "")
        wikitext = wikitext:gsub("%[%[%s*ภาพ%s*:[^|]-(|.-)]]", "")
        wikitext = wikitext:gsub("%[%[%s*ไฟล์%s*:[^|]-(|.-)]]", "")
        return mw.text.trim(wikitext) ~= ""
    end

    if contrast {
        data.infoColor,
        data.backgroundColor,
        error = 0
    } < 4.5 then
        legible = false
    end

    -- For bold text >= 14pt, requirement is only 3.
    local idContrastThreshold = 4.5
    local id2ContrastThreshold = 4.5
    if (data.idFontSize or 0) >= 14 then
        idContrastThreshold = 3
    end
    if (data.id2FontSize or 0) >= 14 then
        id2ContrastThreshold = 3
    end

    if data.showId and contrast {
        data.idColor,
        data.idBackgroundColor,
        error = 0
    } < idContrastThreshold then
        if has_text(data.id or "") then
            legible = false
        end
    end

    if data.showId2 and contrast {
        data.id2Color,
        data.id2BackgroundColor,
        error = 0
    } < id2ContrastThreshold then
        if has_text(data.id2 or "") then
            legible = false
        end
    end

    if not legible then
        root:wikitext(
            '[[หมวดหมู่:กล่องผู้ใช้ที่มีค่าความต่างสีต่ำ]]')
    end

    return tostring(root)
end

function p.categories(args, page)
    -- Gets categories from [[Module:Category handler]].
    -- The page parameter makes the function act as though the module was being called from that page.
    -- It is included for testing purposes.
    local cats = {}
    cats[#cats + 1] = args.usercategory or args['กลุ่มผู้ใช้']
    cats[#cats + 1] = args.usercategory2 or args['กลุ่มผู้ใช้2']
    cats[#cats + 1] = args.usercategory3 or args['กลุ่มผู้ใช้3']
    cats[#cats + 1] = args.usercategory4 or args['กลุ่มผู้ใช้4']
    cats[#cats + 1] = args.usercategory5 or args['กลุ่มผู้ใช้5']
    -- Get the title object
    local title
    if page then
        title = mw.title.new(page)
    else
        title = mw.title.getCurrentTitle()
    end
    -- Build category handler arguments.
    local chargs = {}
    chargs.page = page
    chargs.nocat = args.nocat
    chargs.main =
        '[[หมวดหมู่:หน้าที่มีแม่แบบที่ผิดเนมสเปซ]]'
    if args.notcatsubpages then
        chargs.subpage = 'no'
    end
    -- User namespace.
    local user = ''
    for i, cat in ipairs(cats) do
        user = user .. makeCat(cat)
    end
    chargs.user = user
    -- Template namespace.
    local basepage = title.baseText
    local template = ''
    for i, cat in ipairs(cats) do
        template = template .. makeCat(cat, ' ' .. basepage)
    end
    chargs.template = template
    return categoryHandler(chargs)
end

return p