.mw-parser-output .documentation,.mw-parser-output .documentation-metadata{border:1px solid var(--border-color-base,#a2a9b1);background-color:#ecfcf4;color:inhe
local Calculator = {}
Calculator.__index__ = Calculator
function Calculator:new(params)
params = params or {}
local root = params.root or mw.html.create(getElement(params))
if params.scoped ~= false then
root:addClass('calculator-container')
:attr('data-calculator-refresh-on-load', boolString(params.refreshOnLoad))
end
root:addClass(params.class)
:attr('style', params.style)
local obj = {
root = root,
noJSFallback = '',
templatestyles = {}
}
if params.noJSFallback then
-- If fallback exists, wrap with calculatorgadget-enabled class
root:addClass('calculatorgadget-enabled')
:css('display', 'none')
-- No need to create html node for fallback if it's an empty string
if params.noJSFallback ~= '' then
obj.noJSFallback = tostring(
mw.html.create(getElement(params))
:addClass('calculatorgadget-fallback')
:wikitext(params.noJSFallback)
)
end
end
self.__index = self
return setmetatable(obj, Calculator)
end
function Calculator:field(params)
return self.root:tag('span')
:addClass('calculator-field')
:addClass(params.class)
:attr('id', params.id and ('calculator-field-' .. params.id) or nil)
:attr('data-calculator-type', params.type or 'number')
:attr('style', params.style)
:css('display', params.type == 'hidden' and 'none' or nil)
:attr('data-calculator-formula', params.formula)
:attr('data-calculator-readonly', boolString(params.readonly))
:attr('data-calculator-size', params.size)
:attr('data-calculator-max', params.max)
:attr('data-calculator-min', params.min)
:attr('data-calculator-placeholder', params.placeholder)
:attr('data-calculator-name', params.name)
:attr('data-calculator-precision', params.precision)
:attr('data-calculator-exponential-precision', params['exponential-precision'])
:attr('data-calculator-decimals', params.decimals)
:attr('data-calculator-nan-text', params['NaN-text'])
:attr('data-calculator-class', params['class-live'])
:attr('aria-describedby', params['aria-describedby'])
:attr('aria-labelledby', params['aria-labelledby'])
:attr('aria-label', params['aria-label'])
:attr('data-calculator-enterkeyhint', params.enterkeyhint)
:attr('data-calculator-mapping', params.mapping)
:attr('data-calculator-aria-role', params.role)
:attr('data-calculator-aria-atomic', params['aria-atomic'])
:attr('data-calculator-aria-relevant', params['aria-relevant'])
:attr('data-calculator-aria-live', params['aria-live'])
:attr('data-calculator-checked', boolString(params.checked))
:attr('data-calculator-value', params.value)
:attr('data-calculator-inputmode', params.inputmode or
(params.type == 'text' and params.mapping == nil and 'numeric' or nil))
:attr('data-calculator-step', params.step)
:wikitext(params.default or '')
end
function Calculator:button(params)
local button = self.root:tag('span')
:addClass('calculator-field-button')
:addClass(params.class)
:attr('id', params.id)
:attr('title', params.title)
:attr('style', params.style)
:attr('data-calculator-alt', params.alt)
:attr('data-calculator-disabled', boolString(params.disabled))
:attr('data-calculator-for', params['for'])
:attr('data-calculator-formula', params.formula)
:attr('role', params.role)
:attr('data-calculator-aria-live', params['aria-live'])
:attr('data-calculator-delay', params.delay)
:attr('data-calculator-max-iterations', params['max iterations'])
:attr('data-calculator-toggle', params.toggle)
:attr('data-calculator-class', params['class-live'])
:wikitext(params.contents or params.text or params[1] or 'Click me')
local type = params.type or 'plain'
if type ~= 'plain' then
button:addClass('cdx-button')
button:addClass('cdx-button--action-'..type)
button:addClass('cdx-button--weight-'..(params.weight or 'normal'))
button:addClass('cdx-button--size-'..(params.size or 'medium'))
end
return button
end
function Calculator:hidden(params)
params.type = 'hidden'
return self:field(params)
end
function Calculator:plain(params)
params.type = 'plain'
return self:field(params)
end
function Calculator:text(params)
params.type = 'text'
return self:field(params)
end
function Calculator:radio(params)
params.type = 'radio'
return self:field(params)
end
function Calculator:checkbox(params)
params.type = 'checkbox'
return self:field(params)
end
function Calculator:codexText(params)
params.type = 'text'
params['class-live'] = 'cdx-text-input__input ' .. (params['class-live'] or '')
return self:field(params)
end
function Calculator:codexRadio(params)
params.type = 'radio'
params['class-live'] = 'cdx-radio__input ' .. (params['class-live'] or '')
local outer = self:subContainer({
class = 'cdx-radio '
.. (params.inline and 'cdx-radio--inline' or '')
.. (params['codex-div-class'] or '')
})
local inner = outer:subContainer({
class = 'cdx-radio__wrapper'
})
inner:field(params)
inner:tag('span'):addClass('cdx-radio__icon')
inner:codexLabel({
['codex-class'] = 'cdx-radio__label',
['for'] = params.id,
description = params.description,
label = params.label
})
if params.custominput then
outer:tag('div')
:addClass('cdx-radio__custom-input')
:wikitext(params.custominput)
end
return outer
end
function Calculator:codexCheckbox(params)
params.type = 'checkbox'
params['class-live'] = 'cdx-checkbox__input ' .. (params['class-live'] or '')
local outer = self:subContainer({
class = 'cdx-checkbox '
.. (params.inline and 'cdx-checkbox--inline' or '')
.. (params['codex-div-class'] or '')
})
local inner = outer:subContainer({
class = 'cdx-checkbox__wrapper'
})
inner:field(params)
inner:tag('span'):addClass('cdx-checkbox__icon')
inner:codexLabel({
['codex-class'] = 'cdx-checkbox__label',
['for'] = params.id,
description = params.description,
label = params.label
})
if params.custominput then
outer:tag('div')
:addClass('cdx-checkbox__custom-input')
:wikitext(params.custominput)
end
return outer
end
function Calculator:codexToggle(params)
params.type = 'checkbox'
params['class-live'] = 'cdx-toggle-switch__input ' .. (params['codex-live'] or '')
params.default = '<span style="display:none">' .. (params.default or '') .. '</span>'
local container = self:subContainer({
element = 'span',
class = 'cdx-toggle-switch'
})
container:field(params)
container:tag('span'):addClass('cdx-toggle-switch__switch')
:tag('span'):addClass('cdx-toggle-switch__switch__grip')
container:codexLabel({
['codex-class'] = 'cdx-toggle-switch__label '
.. (params.hiddendescription and 'cdx-label--visually-hidden' or ''),
['for'] = params.id,
description = params.description,
label = params.label,
style = params.labelstyle
})
return container
end
function Calculator:passthru(params)
params.type = 'passthru'
return self:field(params)
end
function Calculator:label(params)
if params.codex then
return self:codexLabel(params)
end
return self.root:tag('span')
:addClass('calculator-field-label')
:addClass(params.class)
:attr('data-for', params['for'] and ('calculator-field-'.. params['for']) or nil)
:attr('data-calculator-class', params['class-live'])
:attr('title', params.title)
:attr('id', params.id)
:attr('style', params.style)
:wikitext(params.label or params[1])
end
function Calculator:codexLabel(params)
local div = self.root:tag('div')
:addClass('cdx-label')
:addClass(params['codex-class'])
local outerSpan = div:tag('span')
:addClass('calculator-field-label cdx-label__label')
:addClass(params.class)
:attr('data-for', params['for'] and ('calculator-field-' .. params['for']) or nil)
:attr('data-calculator-class', params['class-live'])
:attr('title', params.title)
:attr('id', params.id)
:attr('style', params.style)
outerSpan:tag('span')
:addClass('cdx-label__label__text')
:wikitext(params.label or params[1])
if params.flag then
outerSpan:tag('span')
:addClass('cdx-label__label__optional-flag')
:wikitext(' ' .. params.flag)
end
if params.description then
-- Note: this doesn't yet set proper aria-describedby on the input widget
div:tag('span')
:addClass('cdx-label__description')
:attr('id', params['description-id'])
:wikitext(params.description)
end
return div
end
function Calculator:hideIfZero(params)
table.insert(self.templatestyles, 'Template:Calculator-hideifzero/styles.css')
return self.root:tag(getElement(params))
:addClass('calculator-field calculator-hideifzero')
:addClass(params.starthidden and 'calculator-value-false' or nil)
:addClass(params.class)
:attr('data-calculator-type', 'passthru')
:attr('style', params.style)
:attr('data-calculator-formula', params.formula)
:attr('data-calculator-aria-live', params['aria-live'])
:attr('data-calculator-aria-atomic', params['aria-atomic'])
:attr('role', params.role)
:attr('data-calculator-class', params['class-live'])
:wikitext(params.text or params[1])
end
-- Add arbitrary wikitext within the calculator container
function Calculator:wikitext(text)
self.root:wikitext(text)
end
-- Add arbitrary html node within the calculator container.
-- Note: if you would need to add calculator fields within that
-- node, use subContainer() instead.
function Calculator:tag(tagName)
return self.root:tag(tagName)
end
-- Add a wrapper html node within the calculator container,
-- for instance for styling. Additional calculator fields can
-- be added inside it.
function Calculator:subContainer(params)
params = params or {}
local subRoot = self.root:tag(getElement(params))
return Calculator:new({
root = subRoot,
scoped = false,
class = params.class,
style = params.style,
noJSFallback = params.noJSFallback
})
end
function Calculator:__tostring()
local frame = mw.getCurrentFrame()
local styles = ''
for idx, page in ipairs(self.templatestyles) do
styles = styles .. frame:extensionTag('templatestyles', '', {src = page})
end
return styles
.. tostring(self.root)
.. self.noJSFallback
.. '[[Category:Pages using gadget Calculator]]'
end
function getElement(params)
return params.element or (params.block == false and 'span' or 'div')
end
function boolString(value)
return value and tostring(value) or nil
end
return Calculator
Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.