Module:Storm categories/demo/sandbox
Appearance
--
-- This module handles demonstration and list of possible values for all storm
-- category templates! Please test this module on [[Module:Storm categories/demo/doc]]
-- before publishing to avoid errros. Thank you!
--
local colorRatio = require("Module:Color contrast")._ratio
local TableTools = require("Module:TableTools")
local stormcats = require("Module:Storm categories/sandbox")
local cats = require("Module:Storm categories/categories/sandbox").cats
local colors = require("Module:Storm categories/colors/sandbox").colors
local icons = require("Module:Storm categories/icons/sandbox").icons
local p = {}
local customKeys = {}
for k, v in pairs(colors) do
table.insert(customKeys, k)
end
for k, v in pairs(icons) do
table.insert(customKeys, k)
end
TableTools.removeDuplicates(customKeys)
function tableEmpty(_table)
for k, v in pairs(_table) do
return false
end
return true
end
--- Generates and renderds the demo table.
-- @param frame The Scribunto frame.
function p.demo(frame)
local plain = (frame.args["plain"] or frame:getParent().args["plain"] or "") ~= ""
local verbose = (frame.args["verbose"] or frame:getParent().args["verbose"] or "") ~= ""
local legend = setmetatable({}, { refgroupname = "" })
local errors = setmetatable({}, { refgroupname = "E" })
local warnings = setmetatable({}, { refgroupname = "W" })
--- Builds the entire reflist
-- @param _group The group to build for. Uses `legend` by default.
function buildReflist(_group)
group = _group or legend
return frame:expandTemplate{ title = 'reflist', args = {
group = getmetatable(group)["refgroupname"]
} }
end
--- Returns a single <ref> tag containing the legend provided and
-- attaches the note definition to the list of notes.
-- @param details The details of the legend.
-- @param _group The group to write in. Uses `legend` by default.
function createLegend(details, _group)
hash = string.sub(mw.hash.hashValue("md5", details), 0, 8)
group = _group or legend
if group[hash] == nil then
group[hash] = plain and "" or frame:extensionTag{
-- <ref name="hash">details</ref>
name = 'ref',
content = mw.ustring.gsub(details, "%[%[File:([^%|]+)[^%]]*%]%]", "[[:File:%1]]"),
args = {
name = hash,
group = getmetatable(group)["refgroupname"]
}
}
end
-- <ref name="hash"/>
return plain and "" or frame:extensionTag{ name = 'ref', args = {
name = hash,
group = getmetatable(group)["refgroupname"]
} }
end
--- Checks for color contrast issues and tags accordingly.
-- Returns the refernce tag, so this should be used in conjunction with an
-- HTML node's :wikitext function.
function contrastCheck(color)
local catColorBlackRatio = colorRatio({ "#" .. color, "black" })
local catColorLinkRatio = colorRatio({ "#" .. color, "#0645ad" })
local catColorVisitedLinkRatio = colorRatio({ "#" .. color, "#0b0080" })
local finalWikitext = ""
if catColorBlackRatio == "?" or catColorLinkRatio == "?" or catColorVisitedLinkRatio == "?" then
finalWikitext = finalWikitext ..
createLegend("This color must be a hexadecimal color.", errors)
else
if catColorBlackRatio < 4.5 then
finalWikitext = finalWikitext ..
createLegend("This color has [[MOS:COLOR|contrast issues]] with black (not WCAG 2.0 AA-compatible). It will be unusable on all infoboxes and storm season summaries.", errors)
end
if catColorLinkRatio < 4.5 then
finalWikitext = finalWikitext ..
createLegend("This color has [[MOS:COLOR|contrast issues]] with links (not WCAG 2.0 AA-compatible). It should not be used in conjunction with a link.", warnings)
end
if catColorVisitedLinkRatio < 4.5 then
finalWikitext = finalWikitext ..
createLegend("This color has [[MOS:COLOR|contrast issues]] with visited links (not WCAG 2.0 AA-compatible with #0b0080). It should not be used in conjunction with a visited link.", warnings)
end
if actualCat == "c0c0c0" and cat[sortkey] ~= 0 then
finalWikitext = finalWikitext ..
createLegend("This category is using a color reserved specifically for the \"unknown\" category.", warnings)
end
end
return finalWikitext
end
function colorInfo(color, verbose, extra)
local catColorBlackRatio = colorRatio({ "#" .. color, "black" })
local catColorLinkRatio = colorRatio({ "#" .. color, "#0645ad" })
local catColorVisitedLinkRatio = colorRatio({ "#" .. color, "#0b0080" })
local nc = tostring(mw.html.create("abbr")
:wikitext("NC")
:attr("title", "Does not satisfy the minimum WCAG 2.1 compliance level for color contrast (AA)")
);
local aa = tostring(mw.html.create("abbr")
:wikitext("AA")
:attr("title", "WCAG 2.1 Level AA: Acceptable compliance")
);
local aaa = tostring(mw.html.create("abbr")
:wikitext("AAA")
:attr("title", "WCAG 2.1 Level AAA: Optimal compliance")
);
function contrastLevel(contrast)
return contrast >= 7 and aaa or (contrast >= 4.5 and aa or nc)
end
return mw.html.create("td")
:attr("data-sort-value", math.min(catColorBlackRatio))
:wikitext(
"#" .. color .. (extra or "") .. contrastCheck(color) .. (verbose and ("<br/>"
.. tostring(
mw.html.create("abbr")
:attr("title", "Contrast to black")
:wikitext("CTB")
) .. ": " .. string.format("%.2f", catColorBlackRatio) .. " (" .. contrastLevel(catColorBlackRatio) .. ")<br/>"
.. tostring(
mw.html.create("abbr")
:attr("title", "Contrast to links")
:wikitext("CTL")
) .. ": " .. string.format("%.2f", catColorLinkRatio) .. " (" .. contrastLevel(catColorLinkRatio) .. ")<br/>"
.. tostring(
mw.html.create("abbr")
:attr("title", "Contrast to visited links")
:wikitext("CTVL")
) .. ": " .. string.format("%.2f", catColorVisitedLinkRatio) .. " (" .. contrastLevel(catColorVisitedLinkRatio) .. ")") or "")
)
end
local categoryTable = mw.html.create("table")
:addClass("wikitable")
:addClass("sortable")
:attr("style", "width: 100%")
categoryTable
:node(
mw.html.create("tr")
:node(mw.html.create("th"):wikitext("Icon")
:attr("class", "unsortable")
:attr("rowspan", "2")
:css("width", "0"))
:node(mw.html.create("th"):wikitext("ID")
:attr("rowspan", "2"))
:node(mw.html.create("th"):wikitext("Name")
:attr("colspan", "2"))
:node(mw.html.create("th"):wikitext("Color")
:attr("rowspan", "2")
:attr("colspan", "2"))
:node(mw.html.create("th"):wikitext("Sortkey")
:attr("colspan", "2"))
):node(
mw.html.create("tr")
:node(mw.html.create("th"):wikitext("Basin"))
:node(mw.html.create("th"):wikitext("Name"))
:node(mw.html.create("th"):wikitext("Basin"))
:node(mw.html.create("th"):wikitext("Sortkey")
:attr("data-sort-type", "number"))
)
for name, cat in TableTools.sortedPairs(cats) do
local rows = { mw.html.create("tr") }
local row = rows[1]
local actualIcon = stormcats._icon(name)
local icon = mw.html.create("td")
:wikitext(actualIcon)
if cat["icon"] ~= nil and actualIcon ~= cat["icon"] then
icon:wikitext(
createLegend("Overriden from original icon (" .. cat["icon"] .. ")")
)
end
local id = mw.html.create("td")
:wikitext(name)
local actualColor = stormcats._color(name)
local colorPreview = mw.html.create("td")
:attr("style", "background-color: #" .. actualColor .. "; padding: 0; width: 1.8em")
local color = colorInfo(
actualColor,
verbose,
actualColor ~= cat["color"] and createLegend(
"Overriden from original color ({{color box|#"
.. cat["color"]
.. "}} #"
.. cat["color"]
.. ")"
) or ""
):css("width", "0"):css("white-space", "nowrap")
local sortkeyCategory = mw.html.create("td")
:attr("data-sort-value", cat["sortkey"])
local sortkey = mw.html.create("td")
:attr("data-sort-value", cat["sortkey"])
:wikitext(cat["sortkey"])
if cat["sortkey"] < 0 then
sortkeyCategory:wikitext("Invalid")
elseif cat["sortkey"] < 20000 then
sortkeyCategory:wikitext("Global")
elseif cat["sortkey"] < 30000 then
sortkeyCategory:wikitext("Historical")
elseif cat["sortkey"] < 40000 then
sortkeyCategory:wikitext("SWIO")
elseif cat["sortkey"] < 50000 then
sortkeyCategory:wikitext("Aus/Fiji")
elseif cat["sortkey"] < 60000 then
sortkeyCategory:wikitext("NIO")
elseif cat["sortkey"] < 80000 then
sortkeyCategory:wikitext("WPAC")
elseif cat["sortkey"] < 90000 then
sortkeyCategory:wikitext("Atl/EPac/SAtl")
elseif cat["sortkey"] < 100000 then
sortkeyCategory:attr("style", "color: gray")
sortkeyCategory:wikitext("''Global''")
else
sortkeyCategory:wikitext("Invalid")
end
if type(cat["name"]) == "string" then
local name = mw.html.create("td")
:attr("colspan", "2")
:wikitext(cat["name"])
row:node(icon)
row:node(id)
row:node(name)
else
local nameTableLength = TableTools.size(cat["name"])
icon:attr("rowspan", nameTableLength)
id:attr("rowspan", nameTableLength)
colorPreview:attr("rowspan", nameTableLength)
color:attr("rowspan", nameTableLength)
sortkeyCategory:attr("rowspan", nameTableLength)
sortkey:attr("rowspan", nameTableLength)
row:node(icon)
row:node(id)
local firstDone = false
for key, basinName in TableTools.sortedPairs(cat["name"]) do
if firstDone then
local nameRow = mw.html.create("tr")
nameRow
:node(mw.html.create("td"):wikitext(key))
:node(mw.html.create("td"):wikitext(basinName))
table.insert(rows, nameRow)
else
firstDone = true
row
:node(mw.html.create("td"):wikitext(key))
:node(mw.html.create("td"):wikitext(basinName))
end
end
end
row:node(colorPreview)
row:node(color)
row:node(sortkeyCategory)
row:node(sortkey)
for _, _row in TableTools.sortedPairs(rows) do
categoryTable:node(_row)
end
end
for name, _ in TableTools.sortedPairs(TableTools.listToSet(customKeys)) do
if cats[name] == nil then
local row = mw.html.create("tr")
local icon = stormcats._icon(name, true)
row
:node(mw.html.create("td")
:wikitext(
icon ~= nil
and icon
or "''<span style=\"color:gray\">N/A</span>''"
))
:node(mw.html.create("td"):wikitext(name))
local color = stormcats._color(name, true)
-- Add more conditions eventually
if color ~= nil then
row
:node(mw.html.create("td")
:attr("colspan", "2")
:wikitext("''<span style=\"color:gray\">not available</span>''"))
:node(mw.html.create("td")
:attr("style", "background-color: #" .. color .. "; padding: 0; width: 1.8em"))
:node(colorInfo(color, verbose))
:css("width", "0")
:css("white-space", "nowrap")
:node(mw.html.create("td")
:attr("colspan", "2")
:wikitext("''<span style=\"color:gray\">not available</span>''"))
else
row
:node(mw.html.create("td")
:attr("colspan", "6")
:wikitext("''<span style=\"color:gray\">not available</span>''"))
end
categoryTable:node(row)
end
end
out = ""
if not plain and not tableEmpty(errors) then
out = out
.. tostring(mw.html.create("h4"):wikitext("Error"))
.. tostring(mw.html.create("p"):wikitext("This table contains errors than need to be addressed immediately, as it may cause errors on a large amount of pages."))
.. buildReflist(errors)
end
if not plain and not tableEmpty(legend) then
out = out
.. tostring(mw.html.create("h4"):wikitext("Legend"))
.. buildReflist(legend)
end
out = out .. tostring(categoryTable)
if not plain and not tableEmpty(warnings) then
out = out
.. tostring(mw.html.create("h4"):wikitext("Warnings"))
.. tostring(mw.html.create("p"):wikitext("This table contains warnings than should be addressed. Please note that some warnings cannot be fully addressed without changes that would require consensus."))
.. buildReflist(warnings)
end
return mw.text.trim(out)
end
return p