This module is similar to {{Tooltip}} but for modules. It contains a number of related utility functions.
tooltip
This function generates a tooltip with the display text shown on the wiki page and the header and body shown when hovering over the display text.
| Parameter | Description | Required | Default |
|---|---|---|---|
| 1 | Text/content shown on page (displayText) | required | none |
| 2 | Initial text/content of tooltip (header) | optional | none |
| 3 | Final text/content of tooltip (body) | optional | none |
| tagType | HTML tag used to wrap tooltip
|
optional | div |
| index | tooltip level, for tooltip-in-a-tooltip
|
optional | none |
| style | CSS style effects for tooltip | optional | none |
Numbered parameters must be passed in order, named parameters must be passed as a table following; i.e. tooltip( 1, 2, 3, { tagType = val, index = val, style = val } ) Empty strings must be used for empty header or body if using named parameters.
headerStyle
This function makes it easier to style the header for tooltips by providing a standard frame
| Parameter | Description | Required | Default |
|---|---|---|---|
| 1 | Name of header style (headerType) | required | none |
| mainText | Main text/title | optional | none |
| subText | Subtitle | optional | none |
| leftText | Text/content to left of mainText | optional | none |
| rightText | Text/content to right of mainText | optional | none |
| extra | Additional CSS style effects for tooltip | optional | none |
Numbered parameters must be passed in order, named parameters must be passed as a table following; i.e. headerStyle( 1, { mainText = val, subText = val, leftText = val, rightText = val, extra = val } )
ttList
This function creates a list of tooltippable items
| Parameter | Description | Required | Default |
|---|---|---|---|
| 1 | Table of arrays (listTable)
|
required | none |
| multiKey | Text header for arrays with multiple items | optional | Any of: |
| index | Tooltip level, disables tooltipping by default | optional | 4 |
| listStyle | Sets styling of list
|
optional | inline |
| indent | Sets list level and type for newline |
optional | * |
Numbered parameters must be passed in order, named parameters must be passed as a table following; i.e. ttList( 1, { multiKey = val, index = val, listStyle = val, indent = val } )
effectList
This function creates a list of modifier effects
| Parameter | Description | Required | Default |
|---|---|---|---|
| 1 | Table of arrays or 'pseudo'-arrays (list) | required | none |
| color | Passes table of named arguments for Module:Color | optional | none |
| listStyle | Sets styling of list
|
optional | inline |
| indent | Sets list level and type for newline |
optional | * |
| icon | Sets an {{Iconify}} icon "group" for each effect
|
optional | none |
| page | Sets a page link for alternate linking with icon |
optional | icon
|
The array elements must be formatted as in the table below. Color values can be any that are valid for Module:Color. If using an array, the third argument can be a table of parameters for Module:Iconify as well, which then uses the color and value as a mod parameter.
Numbered parameters must be passed in order, named parameters must be passed as a table following; i.e. effectList( 1, { color = val, listStyle = val, indent = val, icon = val, page = val } )
| No icon/prefix | With icon/prefix |
|---|---|
| "<color>_<value>_<text>" | "<color>_<value>_<text>_<prefix>" |
| { "<color>", "<value>", "<text>" } | { "<color>", "<value>", "<text>", "<prefix>"/icon = "<prefix>" } |
| { "<color>", "<value>", { icon="<text>", <other iconify parameters as needed> } } | |
| "<text>" | |
| { "<text>" } |
local uFormat = mw.ustring.format
local htmlCreate = mw.html.create
local getArgs = require('Module:Arguments').getArgs
local p = {};
function p.main(frame)
local args = getArgs(frame)
--[[
local funct = {}
funct.tooltip = p.tooltip(args[1], args.header, args.body, args)
funct.headerStyle = p.headerStyle(args[1], args)
funct.ttList = p.ttList(args[1], args)
funct.effectList = p.effectList(args[1], args)
--]]
return p.tooltip(args[1], args.header, args.body, args) --funct[args.funct]
end
function p.tooltip(displayText, header, body, options)
options = options or {} -- allow null options
local tagType = options.tagType or 'div' -- expects span or similar html tag
local index = tonumber(options.index) -- force number
if type(index) ~= 'number' or index > 3 then -- any non number or index over 3 returns basic display
return tostring(htmlCreate(tagType):css('display','inline'):wikitext(displayText))
elseif index < 2 then
index = '' -- 1st index is unnumbered in CSS
end
-- empty string if nil header or body
header = header or ''
body = body or ''
local tt = htmlCreate(tagType)
:addClass('tooltip'..index)
:wikitext(displayText)
tt:tag(tagType)
:addClass('tooltiptext'..index)
:cssText(options.style)
:wikitext(header,body)
return tostring(tt)
end
-- sets header style within tooltip, only one style currently
function p.headerStyle(headerType, args)
args = args or {} -- allow null options
-- start list of header types
local headerTypes = {}
-- header with left float (icon), right float (group/category), and two lines of text, with gradient backing matching in-game style
headerTypes.twoLineLr = tostring(
htmlCreate('div'):cssText("display: flex; background: linear-gradient(to right, #5c42565a, #47373a3a);"):cssText(args.extra)
:tag('div'):css('margin-right','5px'):wikitext(args.leftText):done()
:tag('div'):css('width','100%')
:tag('span'):cssText('float: right; text-align: right; margin-left: 5px;'):wikitext(args.rightText):done()
:tag('span'):cssText("color: white; font-weight:bold;"):wikitext(args.mainText):done()
:wikitext('<br>',args.subText):done()
)
headerTypes['2LR'] = headerTypes.twoLineLr -- shorthand
return headerTypes[headerType]
end
-- assumes listTable is table containing arrays, t1 = { t2 = { 1, 2, ... }, ... }
function p.ttList(listTable, args)
args = args or {} -- allow null options
local t = args.functs or {}
t.pm = t.pm or require('Module:Production method').productionMethod
t.building = t.building or require('Module:Building').building
t.tech = t.tech or require('Module:Technology').tech
t.law = t.law or require('Module:Law').law
t.decree = t.decree or require('Module:Decree').decree
t.ideology = t.ideology or require('Module:Ideology').ideology
t.unit = t.unit or require('Module:Unit').unit
local uSub = mw.ustring.sub
local list = "" -- return string
local multiKey = args.multiKey or "Any of:"
local index = tonumber(args.index) or 4
local newline = args.listStyle == "newline" -- inline, newline
local indent = args.indent or "*"
-- set newline style
local lineIndent = newline and '\n'..indent or ''
-- main loop; look at table and return arrays
for functName, arr in pairs(listTable) do
local lt = {} -- table of processed values
local i = 1 -- iterator, reused for substring
-- loop through array
for _, v in ipairs(arr) do
if type(t[functName]) == 'function' then
v = t[functName]{v, index=index, from=args.from, fromfrom=args.fromfrom}
elseif (not newline) then
v = tostring(htmlCreate('div'):wikitext(v))--uFormat("<div>%s</div>", v)
end
-- table
lt[i] = v
i = i + 1
end
-- prepend multiKey for arrays with 2 or more elements
if arr[2] and (not newline) and (multiKey ~= "") then
i = tostring(htmlCreate('div'):wikitext(multiKey)
:tag('div'):cssText('display:grid; justify-items: start; margin-left:1em;'):wikitext(table.concat(lt)):done())
elseif arr[2] and newline and (multiKey ~= "") then
-- increase indent level by one, and prepend multiKey
table.insert(lt, 1, multiKey) -- with multiKey as first element, should use default indent
i = uFormat("%s %s", lineIndent, table.concat(lt, lineIndent .. uSub(indent, -1)))
else
i = lineIndent..table.concat(lt, lineIndent)
end
if #lt > 5 and (multiKey == "") then
i = '<div style="display:grid; justify-items: start; grid-template-columns: auto auto; gap:0px 10px;">'..i..'</div>'
end
list = list .. i
end
if not newline then
list = '<div style="display:grid; justify-items: start; margin-left:1em;">'..list..'</div>'
end
return list
end
-- assumes list is array containing 'pseudo'-arrays, t1 = { 'e1_e2_e3', ... }, or actual arrays, t1 = { 1 = { e1, e2, e3 }, ... }
-- single value effects can be passed for a 'plain'text output
function p.effectList(list, args)
args = args or {} -- allow null options
local colorMod = require('Module:Color').color
local iconify = require('Module:Iconify').iconify
local l = "" -- return string
args.color = args.color or {}
local newline = args.listStyle == "newline" -- inline, newline
local indent = args.indent or "*"
local textSplit = mw.text.split
--enough for now
local function deepCopyTable(original)
local copy = {}
for k, v in pairs(original) do
if type(v) == "table" then
-- Recursively copy tables
copy[k] = deepCopyTable(v)
else
-- Directly copy non-table values
copy[k] = v
end
end
return copy
end
-- main loop
for _, effect in ipairs(list) do
local effects
local s = '' -- substring
if type(effect) == 'string' then
effects = textSplit(effect,"_") -- split effect pseudo-sub-array into actual array
elseif type(effect) == 'table' then
effects = deepCopyTable(effect)
else
return '<span style="color:red; font-size:11px;">Invalid effect list given</span>'
end
args.page = args.page or args.icon
local color = colorMod(effects[1], effects[2], args.color) -- color, value, text
if #effects == 1 then
s = effects[1] -- single value effect (no effect size)
elseif args.page and args.icon then
s = iconify{icon=effects[3], group=args.icon, width="20px", mod=color, link=args.page.."#"..effects[3], extra=effects[3]}
elseif type(effects[3]) == 'table' then
local efIc = {}
for k, v in pairs(effects[3]) do efIc[k] = v end
efIc.mod = color -- add mod arg
s = iconify(efIc) -- pass-through table of iconify args
elseif effects[4] or effects.icon then
local icon = effects[4] or effects.icon
s = uFormat("%s %s %s", icon, color, effects[3])
else
s = uFormat("%s %s", color, effects[3])
end
if not newline then l = l .. s .. "<br>"
elseif newline then l = uFormat("%s\n%s %s",l, indent, s)
end
end
if not newline then l = l:sub(1, -5) end -- trim last <br>
return l
end
return p