Jump to content

Module:User:Uzume/MWcap

From Wikipedia, the free encyclopedia

require[[strict]]

local modname = ... or mw.getCurrentFrame():getTitle()
local modpath = modname:match("^(.*)/") and modname
local config = mw.loadData(modpath .. '/Config')
local message_map = config.map
local p = {}

local function CAP_FAILURE() end -- A unique sentinel to cache invalid results
local cap_cache = {} -- cache tracking true, false, or the failed sentinel

--[============================================================================[
-- OPTIMIZATION NOTE FOR MODULE DEVELOPERS:
-- If you see a [Capability Optimization Notice] in the parser profile logs,
-- you can enable page-level caching for that feature by creating a sub-page:
-- Module:Capability/featureName
--
-- The sub-page should contain this single line of code:
-- return require((...):match[[^(.*)/]])._internal.evaluate((...):match[[/([^/]*)$]])
--]============================================================================]

local function evaluate(feature)
	local messageKey = message_map[feature]
	if messageKey then 
		return mw.message.new(messageKey):exists() 
	end
end

local function has(feature)
	local cachedValue = cap_cache[feature]
	local result

	if cachedValue ~= nil then
		if cachedValue == CAP_FAILURE then return end
		return cachedValue
	end

	--[[XXX: Possible optimization to enable page-level caching
	local success
	success, result = pcall(mw.loadData, modpath .. '/' .. feature)
	if success and (result == true or result == false) then
		cap_cache[feature] = result
		return result
	end
	]]
	
	result = evaluate(feature)
	if result == true or result == false then
		--[[XXX: Possible optimization to enable page-level caching
		mw.log("[Capability Optimization Notice] Feature '" .. feature .. "' evaluated live. See source code comments in Module:Capability to enable page-wide caching.")
		]]

		cap_cache[feature] = result
		return result
	end

	cap_cache[feature] = CAP_FAILURE
end

p._internal = { evaluate = evaluate }

p.api = { has = has }

function p.has(frame)
	local args = frame.args
	if '' ~= (args.usetemplate or '') then
		args = frame:getParent().args
	end
	local feature = mw.text.trim(args['feature'] or args[1] or "")
	local state = has(feature)

	if nil == state then 
		return ('<span class="error" style="font-weight:bold; color:#d33;">Capability Error: \'%s\' is not a recognized or mapped capability string.</span>'):format(mw.text.nowiki(feature))
	end

	return state and "1" or ""
end

function p.dashboard(frame)
	local html = {
		'<table class="wikitable" style="width: 100%; border-collapse: collapse;">',
		'<caption>Live Wiki Capability Status Dashboard</caption>',
		'<tr>',
		'  <th scope="col" style="width: 30%; text-align: left;">Capability String</th>',
		'  <th scope="col" style="width: 20%; text-align: left;">Status</th>',
		'  <th scope="col" style="width: 50%; text-align: left;">Mapped System Message Key</th>',
		'</tr>'
	}

	for _, entry in ipairs(config.list) do
		local key = entry[1]
		local msgKey = entry[2]
		local isSupported = has(key)
		local statusText, statusStyle

		if isSupported then
			statusText = '✔ Supported'
			statusStyle = 'background-color: #e1f5fe; color: #0288d1; font-weight: bold;'
		else
			statusText = '❌ Missing'
			statusStyle = 'background-color: #ffebee; color: #c62828; font-weight: bold;'
		end

		table.insert(html, '<tr>')
		table.insert(html, ('  <td><code>%s</code></td>'):format(mw.text.nowiki(key)))
		table.insert(html, ('  <td style="%s">%s</td>'):format(statusStyle, statusText))
		table.insert(html, ('  <td><code>MediaWiki:%s</code></td>'):format(mw.text.nowiki(msgKey)))
		table.insert(html, '</tr>')
	end

	table.insert(html, '</table>')
	return table.concat(html, '\n')
end

return p