Edge Rewrite
// HTMLRewriter · presentation

This page was redesigned at the edge.

Cloudflare fetched the original article and streamed it through HTMLRewriter to apply an entirely new visual system without rebuilding the source page.

Jump to content

Module:Sandbox/PhoenixAsh89/HistoryTable

From Wikipedia, the free encyclopedia
local p = {}
local tableHead
local mode = nil
local currentVersion = nil
local currentExpVersion = nil
local currentConsoleVersions = {
    xbox360 = nil,
    xbone = nil,
    ps3 = nil,
    ps4 = nil,
    psvita = nil,
    wiiu = nil,
    switch = nil
}
local consoleRowspanIndexes
local consoleRowspans
local rowspanIndex
local rowspans
local versionLink = require('Module:Sandbox/PhoenixAsh89/Version link').main

local editionAlias = {
['java pre-classic'] = "java pre-Classic",
['java classic'] = "java Classic",
['java indev'] = "java Indev",
['java infdev'] = "java Infdev",
['java alpha'] = "java Alpha", ['java edition alpha'] = "java Alpha",
['java beta'] = "java Beta", ['java edition beta'] = "java Beta",
['java combat'] = "java Combat Test", ['combat java'] = "java Combat Test", ['java edition combat'] = "java Combat Test",
je = "java", java = "java", ['java edition'] = "java",
['java edition upcoming'] = "java upcoming", ['java upcoming'] = "java upcoming", ['upcoming java'] = "java upcoming", ['upcoming java edition'] = "java upcoming",
['pe alpha'] = "pocket Alpha", ['pocket alpha'] = "pocket Alpha", ['pocket edition alpha'] = "pocket Alpha",
pe = "pocket", pocket = "pocket", ['pocket edition'] = "pocket",
ce = "console", lce = "console", console = "console", ['legacy console'] = "console", ['console edition'] = "console", ['legacy console edition'] = "console",
be = "bedrock", bedrock = "bedrock", ['bedrock edition'] = "bedrock",
['be upcoming'] = "bedrock upcoming", ['bedrock upcoming'] = "bedrock upcoming", ['bedrock edition upcoming'] = "bedrock upcoming", ['upcoming bedrock'] = "bedrock upcoming", ['upcoming bedrock edition'] = "bedrock upcoming",
['3ds'] = "new3ds", new3ds = "new3ds", ['new 3ds'] = "new3ds", ['new nintendo 3ds edition'] = "new3ds",
realms = "realms",
pi = "pi", ['pi edition'] = "pi", ['raspberry pi'] = "pi",
edu = "minecraftedu", minecraftedu = "minecraftedu",
education = "education", ['education edition'] = "education",
['education upcoming'] = "education upcoming", ['education edition upcoming'] = "education upcoming", ['upcoming education'] = "education upcoming", ['upcoming education edition'] = "education upcoming",
xbox360 = "xbox360", ['xbox 360'] = "xbox360", ['xbox 360 edition'] = "xbox360",
xbone = "xbone", xboxone = "xbone", ['xbox one'] = "xbone", ['xbox one edition'] = "xbone",
ps3 = "ps3", playstation3 = "ps3", ['playstation 3'] = "ps3", ['playstation 3 edition'] = "ps3",
ps4 = "ps4", playstation4 = "ps4", ['playstation 4'] = "ps4", ['playstation 4 edition'] = "ps4",
psvita = "psvita", psv = "psvita", playstationvita = "psvita", ['playstation vita'] = "psvita", ['playstation vita edition'] = "psvita",
wiiu = "wiiu", ['wii u'] = "wiiu", ['wii u edition'] = "wiiu",
switch = "switch", nsw = "switch", nintendoswitch = "switch", ['nintendo switch'] = "switch", ['nintendo switch edition'] = "switch",
earth = "earth", ['minecraft earth'] = "earth",
dungeons = "dungeons", ['minecraft dungeons'] = "dungeons",
['dungeons arcade'] = "dungeons arcade", ['minecraft dungeons arcade'] = "dungeons arcade",
legends = "legends", ['minecraft legends'] = "legends",
blast = "blast", ['minecraft blast'] = "blast",
china = "china", ['china edition'] = "china",
bs = "bedrock server", bds = "bedrock server", ['bedrock server'] = "bedrock server", ['bedrock dedicated server'] = "bedrock server",
['?'] = "unknown", unknown = "unknown"
}

local headerText = {
    ['java pre-Classic']    = '[[Java Edition pre-Classic]]',
    ['java Classic']        = '[[Java Edition Classic]]',
    ['java Indev']          = '[[Java Edition Indev]]',
    ['java Infdev']         = '[[Java Edition Infdev]]',
    ['java Alpha']          = '[[Java Edition Alpha]]',
    ['java Beta']           = '[[Java Edition Beta]]',
    ['java']                = "[[Java Edition version history|''Java Edition'']]",
    ['java Combat Test']    = "[[Java Edition Combat Tests]]",
    ['java upcoming']       = "[[Planned versions#Java Edition|Upcoming ''Java Edition'']]",
    ['pocket Alpha']        = '[[Pocket Edition Alpha]]',
    ['pocket']              = "''[[Pocket Edition]]''",
    ['bedrock']             = "[[Bedrock Edition version history|''Bedrock Edition'']]",
    ['bedrock upcoming']    = "[[Planned versions#Bedrock Edition|Upcoming ''Bedrock Edition'']]",
    ['minecraftedu']        = "[[MinecraftEdu#Versions|''MinecraftEdu'']]",
    ['education']           = "[[Minecraft Education version history|''Minecraft Education'']]",
    ['education upcoming']  = "[[Planned versions#Minecraft Education|Upcoming ''Minecraft Education'']]",
    ['china']               = "[[China Edition#History|''China Edition'']]",
    ['bedrock server']      = '[[Bedrock Dedicated Server#History|Realms Plus & Bedrock Dedicated Server]]',
    ['console']             = '[[Legacy Console Edition version history|Legacy Console Edition]]',
    ['realms']              = '[[Realms#History|Realms]]',
    ['new3ds']              = "[[New Nintendo 3DS Edition version history|''New Nintendo 3DS Edition'']]",
    ['pi']                  = "[[Pi Edition#Release|''Pi Edition'']]",
    ['xbox360']             = "[[Legacy Console Edition version history|''Xbox 360 Edition'']]",
    ['xbone']               = "[[Legacy Console Edition version history|''Xbox One Edition'']]",
    ['ps3']                 = "[[Legacy Console Edition version history|''PlayStation 3 Edition'']]",
    ['ps4']                 = "[[Legacy Console Edition version history|''PlayStation 4 Edition'']]",
    ['psvita']              = "[[Legacy Console Edition version history|''PlayStation Vita Edition'']]",
    ['wiiu']                = "[[Legacy Console Edition version history|''Wii U Edition'']]",
    ['switch']              = "[[Legacy Console Edition version history|''Nintendo Switch Edition'']]",
    ['earth']               = "[[Earth:Version history|''Minecraft Earth'']]",
    ['dungeons']            = "[[Dungeons:Version history|''Minecraft Dungeons'']]",
    ['dungeons arcade']     = "[[Dungeons:Arcade|''Minecraft Dungeons Arcade'']]",
    ['legends']             = "[[Legends:Version history|''Minecraft Legends'']]",
    ['blast']               = "[[Minecraft Blast#Version history|''Minecraft Blast'']]",
    ['launcher']            = "[[Launcher version history|''Minecraft Launcher'']]",
    ['unknown']             = "Unknown"
}

local headerCategories = {
    ['java upcoming']       = "[[Category:Java Edition upcoming]]",
    ['bedrock upcoming']    = "[[Category:Bedrock Edition upcoming]]",
    ['education upcoming']  = "[[Category:Minecraft Education upcoming]]",
    ['unknown']             = "[[Category:Unknown version history]]"
}

local versionLinks = {
    ['java upcoming'] = 'java',
    ['bedrock upcoming'] = 'bedrock',
    ['education upcoming'] = 'education',
    ['bedrock server'] = 'Bedrock Dedicated Server',
    ['dungeons arcade'] = 'Dungeons:' -- This is needed or else version link module doesn't correctly link to the arcade
}

local sortKeys = {
	-- is this still needed? why is it not updated since 2020/1.16 then?
    ['java 1.0.0'] = "A",
    ['java 1.1'] = "B",
    ['java 1.2.1'] = "C",
    ['java 1.3.1'] = "D",
    ['java 1.4.2'] = "E",
    ['java 1.5'] = "F",
    ['java 1.6.1'] = "G",
    ['java 1.7.2'] = "F",
    ['java 1.8'] = "G",
    ['java 1.9'] = "H",
    ['java 1.10'] = "I",
    ['java 1.11'] = "J",
    ['java 1.12'] = "K",
    ['java 1.13'] = "L",
    ['java 1.14'] = "M",
    ['java 1.15'] = "N",
    ['java 1.16'] = "O",
    ['java texture update'] = "_",
    ['java indev 0.31'] = "0",
    ['java alpha v1.2.0'] = "2",
    ['java beta 1.6'] = "6",
    ['java beta 1.8'] = "8",
    ['pocket alpha v0.8.0'] = "A",
    ['pocket alpha 0.8.0'] = "A",
    ['pocket alpha v0.9.0'] = "B",
    ['pocket alpha 0.9.0'] = "B",
    ['pocket alpha v0.10.0'] = "C",
    ['pocket alpha 0.10.0'] = "C",
    ['pocket alpha v0.11.0'] = "D",
    ['pocket alpha 0.11.0'] = "D",
    ['pocket alpha v0.12.1'] = "E",
    ['pocket alpha 0.12.1'] = "E",
    ['pocket alpha v0.13.0'] = "F",
    ['pocket alpha 0.13.0'] = "F",
    ['pocket alpha v0.14.0'] = "G",
    ['pocket alpha 0.14.0'] = "G",
    ['pocket alpha v0.15.0'] = "H",
    ['pocket alpha 0.15.0'] = "H",
    ['pocket alpha v0.16.0'] = "I",
    ['pocket alpha 0.16.0'] = "I",
    ['pocket 1.0.0'] = "X",
    ['pocket 1.1.0'] = "Y",
    ['pocket 1.1.3'] = "Z",
    ['bedrock 1.2.0'] = "A",
    ['bedrock 1.2.13'] = "B",
    ['bedrock 1.4.0'] = "C",
    ['bedrock 1.5.0'] = "D",
    ['bedrock 1.6.0'] = "E",
    ['bedrock 1.7.0'] = "F",
    ['bedrock 1.8.0'] = "G",
    ['bedrock 1.9.0'] = "H",
    ['bedrock 1.10.0'] = "I",
    ['bedrock 1.11.0'] = "J",
    ['bedrock 1.12.0'] = "K",
    ['bedrock 1.13.0'] = "L",
    ['bedrock 1.14.0'] = "M",
    ['bedrock 1.14.60'] = "M",
    ['bedrock 1.16.0'] = "N",
    ['bedrock 1.16.100'] = "N"
}

local function isInMainspace()
	return mw.title.getCurrentTitle().namespace == 0
end

local function getUnknownCat()
    if(mode==nil or mode=='unknown') then return '' end
    if(mode=='xbox360' or mode=='xbone' or mode=='ps3' or mode=='ps4' or mode=='psvita' or mode=='wiiu' or mode=='switch') then mode = 'console' end
    local sortKey = sortKeys[mode .. (currentVersion or '')] or "*"
    if isInMainspace() then
    	return '[[Category:Unknown ' .. string.gsub(mode, '^%l', string.upper) .. ' version history|' .. sortKey .. ']]'
	end
	return ''
end

local function resetConsole()
    currentConsoleVersions.xbox360 = nil
    currentConsoleVersions.xbone = nil
    currentConsoleVersions.ps3 = nil
    currentConsoleVersions.ps4 = nil
    currentConsoleVersions.psvita = nil
    currentConsoleVersions.wiiu = nil
    currentConsoleVersions.switch = nil
end

local function reset()
    currentVersion = nil
    currentExpVersion = nil
    resetConsole()
end

local function footReset()
    mode = nil
    reset()
end

local function getVersionLink(link,text,isDev)
    if (link=='none') then 
      	if (text=='unknown' or text=='?') then return '?'..getUnknownCat() end
		if (isDev and text=='java') then return '' end
      	return text
    end
    if (link=='ver') then 
      	if (text=='unknown' or text=='?') then
      		return '[[:Category:Unknown version history|?]]' .. (isInMainspace() and getUnknownCat() or '')
  		end
		if (isDev and text=='java') then
			return ''
		end
      	if ((not isDev) and (mode=='realms')) then
      		return text
  		end
      	local c
		if(not isDev) then
			if(text=='Pre-release' and mode == 'pocket Alpha') then c = 'pocket Pre-release'
			else c = (versionLinks[mode] or mode)..' '..text
			end
		else
            c=text:lower()
            if(c:match('^test build') or c:match('^pre%-release') or c:match('^build') or c:match('^20[01]') or c:match('^release candidate') or c:match('^experimental snapshot')) then c=currentVersion..' '..text
            elseif(c:match('^preview [0-9]')) then c=text -- Bedrock edition previews
            elseif(c:match('^pre')) then c=currentVersion..'-'..text
            elseif(c:match('^snap')) then c=currentVersion..' Snapshot '..text:gsub('^snap', '')      
            elseif(c:match('^release')) then c=currentVersion
            else c = text
            end
			c=(versionLinks[mode] or mode)..' '..c
		end
      	return versionLink({c,text:gsub( '^%((.*)%)$', '%1')})
    end
    local cat = ''
    if (text=='unknown' or text=='?') then
    	cat = getUnknownCat()
	end
    if(link:find('//',1,true)) then
    	return '['..link..' '..text..']'..(isInMainspace() and cat or '')
	else
		return '[['..link..'|'..text..']]'..cat
	end
end


local function consoleVersionLink(platform,version,link)
    if(version=='none') then return ' ' end
    if(version=='unknown' or version=='?') then
    	return '?'..(isInMainspace() and getUnknownCat() or '')
	end
    if(link) then
    	if(link=='none') then return version end
    	if(link:find('//',1,true)) then return '['..link..' '..version..']' else return '[['..link..'|'..version..']]' end
    end
    local r=platform..' '..version
    return versionLink({r,version})
end

local function addConsoleVersions(platform,version,link,prnt)
    if(((version~=nil and version~='') and version == currentConsoleVersions[platform]) or ((version==nil or version=='') and currentConsoleVersions[platform]~=nil))
    then
        return
    end
    prnt('<th class="nowrap" rowspan="')
    currentConsoleVersions[platform] = version or "none"
    consoleRowspanIndexes[platform] = consoleRowspanIndexes[platform] + 1
    prnt(consoleRowspans[platform][consoleRowspanIndexes[platform]]..'">')
    prnt(consoleVersionLink(platform,version or 'none',link))
    prnt('</th>')
end

local function consoleSubHeader(content, prnt)
	prnt("<th style=\"border-style: none dashed\">" .. content .. "</th>")
end

local function processLine(args, prnt)
    local snapRows = 1
    for i,_ in ipairs(args) do if(i>3) then snapRows = snapRows+1 end end

    --Header or Foot
    if(args[1] ~= nil and args[1] ~= '') then
        local temp = (args[1]):lower()
        if (temp == 'foot') then
            prnt('</table>')
            footReset()
            tableHead = 0
            return
        end
        mode = editionAlias[temp] or args[1]
        reset()
        prnt('<tr class="collapsible collapsible-rows"><th colspan="8" style="border-bottom: none">')
        prnt(headerText[mode] or mode)
        if mw.title.getCurrentTitle().namespace == 0 then
        	prnt(headerCategories[mode] or '')
        end
        prnt('</th></tr>')
        if mode == 'console' then
        	prnt('<tr style="font-size: smaller">')
	        consoleSubHeader("[[Xbox 360 Edition|Xbox&nbsp;360]]", prnt)
	        consoleSubHeader("[[Xbox One Edition|Xbox&nbsp;One]]", prnt)
	        consoleSubHeader("[[PlayStation 3 Edition|PS3]]", prnt)
	        consoleSubHeader("[[PlayStation 4 Edition|PS4]]", prnt)
	        consoleSubHeader("[[PlayStation Vita Edition|PS&nbsp;Vita]]", prnt)
	        consoleSubHeader("[[Wii U Edition|Wii U]]", prnt)
	        consoleSubHeader("[[Nintendo Switch Edition|Switch]]", prnt)
	        consoleSubHeader("", prnt)
	        prnt("</tr>")
        end
        return
    end

    --Content rows

    prnt('<tr>')

    if((mode == 'console') and (args.xbox or args.xbone or args.ps3 or args.ps4 or args.psvita or args.wiiu or args.switch )) then
        currentVersion = nil

        if(args[3] ~= nil and args[3] ~= '') then
            snapRows = snapRows+1
        end
  
        addConsoleVersions("xbox360",args.xbox,args.xboxlink,prnt)
        addConsoleVersions("xbone",args.xbone,args.xbonelink,prnt)
        addConsoleVersions("ps3",args.ps3,args.ps3link,prnt)
        addConsoleVersions("ps4",args.ps4,args.ps4link,prnt)
        addConsoleVersions("psvita",args.psvita,args.psvitalink,prnt)
        addConsoleVersions("wiiu",args.wiiu,args.wiiulink,prnt)
        addConsoleVersions("switch",args.switch,args.switchlink,prnt)
  
        prnt('<td>'..args[2]..'</td></tr>')
  
        for k,v in ipairs(args) do if(k>2) then prnt('<tr><td>'..v..'</td></tr>') end end

        return
    end

    --Other versions:

    resetConsole()
    if((args.dev == nil) or (args[2] and args[2]~='') or (args.exp and args.exp~='' and args.exp ~= currentExpVersion)) then
  	    currentVersion = nil
  	    currentExpVersion = nil
        prnt('<th ')
        if( not (args.link or args[2]:find('(',1,true))) then prnt('class="nowrap"') end
        prnt(' rowspan="')
        if( args.exp ~= nil) then
        	currentExpVersion = args.exp
        end
        if( args.dev ~= nil) then
            currentVersion = args[2]
            rowspanIndex = rowspanIndex + 1
            prnt(rowspans[rowspanIndex]..'" colspan="3">')
        else
            prnt(snapRows .. '" colspan="7">')
        end
        prnt(getVersionLink(args.link or 'ver', args[2],false))
        if (args.exp ~= nil or args.experiment ~= nil) then
        	prnt("<div class=\"historytable-experiment\"><div>Experiment</div></div><span>"..(args.exp or args.experiment).."</span>")	
        end
        prnt('</th>')
    end

    if(args.dev ~= nil) then
        prnt('<th colspan="4" rowspan="' .. snapRows ..'">')
        prnt(getVersionLink(args.slink or 'ver', args.dev,true))
        prnt('</th>')
    end

	if args[3] then
    	prnt('<td>'..args[3]..'</td></tr>')
    end
    for k,v in ipairs(args) do if(k>3) then prnt('<tr><td>'..v..'</td></tr>') end end

    return
end

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

-- Undo the serialization for parsing
local function deserialize(args)
	local e
	local out = {}
	for k, v in pairs(args) do
		e, out[k] = pcall( mw.text.jsonDecode, v )
		if not e then
			local errorCat = ''
			local errorMsg = mw.message.new( 'scribunto-common-error-category' )
			if not errorMsg:isDisabled() then
				errorCat = '[[Category:'..errorMsg:plain()..']]'
			end
			out[k] = { '', 'unknown', v..' <strong class="error">Lua error: '..out[k]..errorCat..' Input:'.. v ..'</strong>' }
		end
	end
	return out
end

local function countConsoleRowspans(platform,version,snapRows)
    if(((version~=nil and version~='') and version == currentConsoleVersions[platform]) or ((version==nil or version=='') and currentConsoleVersions[platform]~=nil))
    then
        consoleRowspans[platform][consoleRowspanIndexes[platform]] = consoleRowspans[platform][consoleRowspanIndexes[platform]] + snapRows
        return
    end
    currentConsoleVersions[platform] = version or "none"
    consoleRowspanIndexes[platform] = consoleRowspanIndexes[platform] + 1
    consoleRowspans[platform][consoleRowspanIndexes[platform]] = (consoleRowspans[platform][consoleRowspanIndexes[platform]] or 0) + snapRows
end


local function countRowspan(args)
    local snapRows = 1
    for i,_ in ipairs(args) do if(i>3) then snapRows = snapRows+1 end end

    --Header or Foot
    if(args[1] ~= nil and args[1] ~= '') then
        local temp = (args[1]):lower()
        if (temp == 'foot') then
            footReset()
            return
        end
        mode = editionAlias[temp] or args[1]
        reset()
        return
    end

    --Content rows

    if((mode == 'console') and (args.xbox or args.xbone or args.ps3 or args.ps4 or args.psvita or args.wiiu or args.switch )) then
        currentVersion = nil

        if(args[3] ~= nil and args[3] ~= '') then
            snapRows = snapRows+1
        end
  
        countConsoleRowspans("xbox360",args.xbox,snapRows)
        countConsoleRowspans("xbone",args.xbone,snapRows)
        countConsoleRowspans("ps3",args.ps3,snapRows)
        countConsoleRowspans("ps4",args.ps4,snapRows)
        countConsoleRowspans("psvita",args.psvita,snapRows)
        countConsoleRowspans("wiiu",args.wiiu,snapRows)
        countConsoleRowspans("switch",args.switch,snapRows)
  
        return
    end

    --Other versions:

    resetConsole()
    if((args.dev == nil) or (args[2] and args[2]~='') or (args.exp and args.exp~='' and args.exp ~= currentExpVersion)) then
  	    currentVersion = nil
  	    currentExpVersion = nil
  	    if(args.dev ~= nil) then
            currentVersion = args[2]
            rowspanIndex = rowspanIndex + 1
        end
    end

    if(args.dev ~= nil) then
        rowspans[rowspanIndex] = (rowspans[rowspanIndex] or 0) + snapRows
    end
    return
end

local function initRowspans()
    rowspans = {}
    consoleRowspans = {
        xbox360 = {},
        xbone = {},
        ps3 = {},
        ps4 = {},
        psvita = {},
        wiiu = {},
        switch = {}
    }
end

local function resetRowspanIndexes()
	rowspanIndex = 0
	consoleRowspanIndexes = {
		xbox360 = 0,
		xbone = 0,
		ps3 = 0,
		ps4 = 0,
		psvita = 0,
		wiiu = 0,
		switch = 0
	}
end

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

function p._main(args)
    local lines = deserialize(args)

    initRowspans()
    resetRowspanIndexes()
	for _,v in ipairs(lines) do
		countRowspan(v)
	end

	resetRowspanIndexes()
    tableHead=0
    local result = {}
	for _,v in ipairs(lines) do
		if(tableHead~=1) then
        	table.insert(result, '<table class="wikitable pixel-image" data-description="History">')
        	tableHead = 1
		end
		processLine(v,function(a) table.insert(result, a) end)
	end
	if tableHead~=0 then
        table.insert(result, '</table>')
        footReset()
        tableHead = 0
	end
	return table.concat(result)
end

return p