Module:Sandbox/User:Mudscape/HistoryTable

Jump to navigation Jump to search
Documentation[create] [refresh]
This module has no documentation. If you know how to use this module, please create it.
local p = {}

local historyData = {}
local lastVersionString = ''
local lastDevVersionString = ''
local tableTag

-- Objects used to facilitate comparison and standardized data storage.
local HM = {
	NONE = {headerText = ""},
	UNKNOWN = {headerText = "unknown"},
	JAVA_PRE_CLASSIC = {headerText = "[[Java Edition pre-Classic]]"},
	JAVA = {headerText = "[[Java Edition]]"},
	POCKET_ALPHA = {headerText = "[[Pocket Edition Alpha]]"},
	BEDROCK = {headerText="[[Bedrock Edition]]"},
	BEDROCK_UPCOMING = {headerText="[[Bedrock Edition Upcoming]]"},
	CONSOLE = {headerText="[[Legacy Console Edition]]"},
	NEW_3DS = {headerText="[[New Nintendo 3DS Edition version history]]"}
}

-- Takes all args and puts them into a json string, used by HistoryLine
function p.serialize(frame)
	return mw.text.jsonEncode(frame:getParent().args)
end

-- Undo the serialization for parsing
function p.deserialize(args)
	local out = {}
	for k, v in pairs(args) do
		out[k] = mw.text.jsonDecode(v)
	end
	return out
end

-- Takes input of a single string representing a history mode.
-- Returns an object with all data needed for that history mode.
function p.parseHistoryMode(str)
	-- normalize input
	if str ~= nil then
		str = string.lower(str)
	else
		return nil
	end
	
	if str == '' then -- no defined mode
		return nil
	end
	
	if str == "java pre-classic" then
		return HM.JAVA_PRE_CLASSIC
	end
	
	if str == "java" then
		return HM.JAVA
	end
	
	if str == "pocket alpha" then
		return HM.POCKET_ALPHA
	end
	
	if str == "bedrock" then
		return HM.BEDROCK
	end
	
	if str == "bedrock upcoming" then
		return HM.BEDROCK_UPCOMING
	end
	
	if str == "console" then
		return HM.CONSOLE
	end
	
	if str == "new 3ds" then
		return HM.NEW_3DS
	end
	
	-- foot is a deprecated param, do nothing
	if str == "foot" then
		return nil
	end
	
	return HM.UNKNOWN
end

function p.setupRowSpan(line)
	-- loop through the list of history lines and calculate the row spans
	-- each line can define the next version, or leave blank to create a row span
	local historyModeString = line[1]
	local version = line[2]
	local devVersion = line["dev"]
	local tr
	
	mw.log(devVersion)

	-- Update history mode to know how to index into historyData
	if p.parseHistoryMode(historyModeString) then
		historyMode = p.parseHistoryMode(historyModeString)
		historyData[historyMode] = historyData[historyMode] or {}
		-- Clear tracked versions
		lastVersionString = ''
		lastDevVersionString = ''
		return
	end
	
	if version == '' then
		local rowSpan = historyData[historyMode][lastVersionString] or 1
		historyData[historyMode][lastVersionString] = rowSpan + 1
	elseif version ~= lastVersionString then
		lastVersionString = version
	end
	
	if devVersion == '' then
		local rowSpan = historyData[historyMode][lastVersionString..lastDevVersionString] or 1
		historyData[historyMode][lastVersionString..lastDevVersionString] = rowSpan + 1
		mw.log(rowspan)
	elseif devVersion ~= lastDevVersionString then
		lastDevVersionString = devVersion
	end
	
	for localKey, cellContent in ipairs(line) do
		if localKey > 3 then
			-- Every param past 3 adds another row for the same versions.
			p.setupRowSpan({"", "", dev="", cellContent})
		end
	end
end

function p.parseLine(line)
	local historyModeString = line[1]
	local version = line[2]
	local devVersion = line["dev"]
	local tr

	-- Put a header in if history mode is defined
	if p.parseHistoryMode(historyModeString) then
		historyMode = p.parseHistoryMode(historyModeString)
		tableTag:tag('th'):attr('colspan', '8'):css('border-bottom', 'none'):wikitext(historyMode.headerText)
		-- Clear tracked versions
		lastVersionString = ''
		lastVersionTd = nil
		lastDevVersionString = ''
		lastDevVersionTd = nil
		return
	end
	
	tr = tableTag:tag("tr")
	
	-- Either create a cell for version or extend the rowspan of an existing version
	if version == '' then
	elseif version ~= lastVersionString then
		lastVersionString = version
		tr
			:tag("td")
			:attr("rowspan", historyData[historyMode][lastVersionString])
			:wikitext(version)
	end
	
	-- Either create a cell for dev version or extend the rowspan of an existing version
	if lastVersionString ~= nil and devVersion ~= nil and devVersion ~= '' and devVersion ~= lastDevVersionString then
		lastDevVersionString = devVersion
		-- mw.log(lastVersionString..lastDevVersionString.. "   " .. historyData[historyMode][lastVersionString..lastDevVersionString])
		tr
			:tag("td")
			:attr("rowspan", historyData[historyMode][lastVersionString..lastDevVersionString])
			:wikitext(devVersion)
	end
	
	for localKey, cellContent in ipairs(line) do
		-- Need a new row for any param > 3
		if localKey > 3 then
			tr = tableTag:tag("tr")
		end
		-- Set the content of the row based on param 3, 4, 5, etc
		if localKey >= 3 then
			tr:tag("td"):wikitext(cellContent)
		end
	end
end

function p.main(frame)
	return p._main(frame:getParent().args)
end

function p._main(args)
	local historyMode = HM.NONE
	args = p.deserialize(args) -- HistoryLine serializes its inputs, so we deserialize them

	-- calculate row spans
	for key,line in ipairs(args) do
		p.setupRowSpan(line)
	end
	
	mw.log(dump(historyData))

	-- create the html
	local ret = mw.html.create('div')
	tableTag = ret:tag('table')--Create table
		:addClass('wikitable historytable pixel-image') -- TODO data-description
	-- for each {{HistoryLine}}
	for key,line in ipairs(args) do
		p.parseLine(line)
	end
	
	return tostring(ret)
end

return p