Jump to content

Module:Calculator

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by SD0001 (talk | contribs) at 13:16, 29 January 2025 (rmv getRoot(), add subContainer() instead). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
local Calculator = {}
Calculator.__index__ = Calculator

function Calculator:new(params)
	local obj = {}
	
	local root = params.root or mw.html.create(getElement(params))
	if params.wrap ~= false then
		root:addClass('calculator-container')
			:attr('data-calculator-refresh-on-load', boolString(params.refreshOnLoad))
	end
	root:addClass(params.class)
		:attr('style', params.style)
		
	obj.root = root
	obj.templatestyles = {}

	self.__index = self
	return setmetatable(obj, Calculator)
end

function Calculator:field(params)
	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 '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
end

function Calculator:hidden(params)
	params.type = 'hidden'
	self:field(params)
end

function Calculator:plain(params)
	params.type = 'plain'
	self:field(params)
end

function Calculator:text(params)
	params.type = 'text'
	self:field(params)
end

function Calculator:passthru(params)
	params.type = 'passthru'
	self:field(params)
end

function Calculator:hideIfZero(params)
	params.type = 'passthru'
	params.class = (params.class or '') .. ' calculator-hideifzero'
	table.insert(self.templatestyles, 'Template:Calculator-hideifzero/styles.css')
	self:field(params)
end

-- To faciliate adding wrapper elements within the calculator container 
-- for styling
function Calculator:subContainer(params)
	local subRoot = self.root:tag(params.tag)
	return Calculator:new({ root = subRoot, wrap = false, class = params.class, style = params.style })
end

function Calculator:__tostring()
	local frame = mw.getCurrentFrame()

	local output = ''
	for idx, page in ipairs(self.templatestyles) do
		output = output .. frame:extensionTag('templatestyles', '', {src = page})
	end
	return output .. tostring(self.root) .. '[[Category:Pages using gadget Calculator]]'
end

function getElement(params)
	return params.element and params.element or (params.block and 'div' or 'span')
end

function boolString(value)
	return value and tostring(value) or nil
end

return Calculator