打开/关闭菜单
打开/关闭外观设置菜单
打开/关闭个人菜单
未登录
登录后可编辑和发表评论。

Module:Notice

来自Vocawiki
Wecury留言 | 贡献2025年12月26日 (五) 14:55的版本
模块文档  [查看] [编辑] [历史] [刷新]

用于{{Notice}}

local p = {}

-- 生成相对iconURL
local function buildIconUrl(icon)
    if not icon or icon == "" then
        return nil
    end

    icon = mw.text.trim(icon):gsub("[\r\n]", "")

    -- 去掉前缀
    icon = icon:gsub("^[Ff]ile:", "")
               :gsub("^文件:", "")
               :gsub("^檔案:", "")

    -- 禁止外链
    if icon:match("^https?://") or icon:match("^//") then
        return nil
    end

    -- 站内绝对路径,允许
    if icon:match("^/") then
        return icon
    end

    -- 站内文件名生成相对链接
    local title = mw.title.makeTitle("Special", "FilePath/" .. icon)
    if title then
        return title:localUrl()
    end

    return nil
end

-- 避免引号/括号等打断 style
local function sanitizeForCssUrl(url)
    if not url then return nil end
    url = url:gsub("[\r\n]", "")
    url = url:gsub("[\"'%;%)%(%<%>]", "")
    return url
end

local function renderNotice(type, iconStyleExtra, innerHtml)
    return string.format([[
<div class="notice notice-%s">
  <div class="notice-icon" style="-webkit-mask-repeat: no-repeat; -webkit-mask-position: center; -webkit-mask-size: contain;%s"></div>
  %s
</div>
]], type, iconStyleExtra, innerHtml)
end

function p.main(frame)
    local args = frame:getParent().args
    local type = args.type or "info"

    local iconUrl = sanitizeForCssUrl(buildIconUrl(args.icon))

    local iconStyleExtra = ""
    if iconUrl and iconUrl ~= "" then
        iconStyleExtra = string.format(" --notice-icon: url(%s);", iconUrl)
    end

    -- text模式
    local textContent = args.text or args[1]
    if textContent and textContent ~= "" then
        local inner = string.format([[
  <div class="notice-text text-base">
    <div class="notice-text-only text-base">%s</div>
  </div>
]], textContent)
        return renderNotice(type, iconStyleExtra, inner)
    end

    -- 列表
    local listItems = {}
    for i = 1, 50 do
        local key = "l" .. i
        if args[key] and args[key] ~= "" then
            table.insert(listItems, "<li>" .. args[key] .. "</li>")
        end
    end

    local listHtml = ""
    if #listItems > 0 then
        listHtml = '<ul class="notice-list text-sm">' .. table.concat(listItems, "\n") .. "</ul>"
    elseif args.list and args.list ~= "" then
        listHtml = '<ul class="notice-list text-sm">' .. args.list .. "</ul>"
    end

    local inner = string.format([[
  <div class="notice-text text-base">
    <div class="notice-title text-base">%s</div>
    %s
    <div class="notice-detail text-sm">%s</div>
  </div>
]], args.title or "", listHtml, args.detail or "")

    return renderNotice(type, iconStyleExtra, inner)
end

return p