Last active
July 18, 2024 06:37
-
-
Save rajdakin/35142f25be1a92660a6eb656a59286f6 to your computer and use it in GitHub Desktop.
box86.org compatibility list code
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<style> | |
#table_stats { | |
width: 100%; | |
height: 1em; | |
background: #808080; | |
} | |
#table_stats > div { | |
height: 100%; | |
float: left; | |
} | |
#table_fail { background: #ff8080; } #table_most { background: #ffff40; } #table_pass { background: #80ff80; } | |
#pagination { | |
height: 34px; | |
} | |
#paginationlist { | |
float: left; | |
margin: 0; | |
padding: 0; | |
} | |
#paginationlist li { | |
list-style-type: none; | |
float: left; | |
margin: 0; | |
border: 1px solid #aaaaaa; | |
border-right: none; | |
padding: 0; | |
width: 34px; | |
height: 34px; | |
text-align: center; | |
line-height: 34px; | |
} | |
#paginationlist li.selected { | |
background: #888888; | |
} | |
#paginationlist li:hover:not(.selected) { | |
background: #00ffff80; | |
} | |
#paginationlist li:first-child { | |
border-top-left-radius: 3px; | |
border-bottom-left-radius: 3px; | |
} | |
#paginationlist li.last-child-pag { | |
border-top-right-radius: 3px; | |
border-bottom-right-radius: 3px; | |
border-right: 1px solid #aaaaaa; | |
} | |
#paginationlist li a { | |
user-select: none; | |
color: #000000; | |
text-decoration: none; | |
text-align: center; | |
} | |
#statusfilter ul { | |
margin: 0; | |
display: inline-flex; | |
} | |
#statusfilter li { | |
list-style-type: none; | |
float: left; | |
margin: 0; | |
border: 1px solid #aaaaaa; | |
border-right: none; | |
padding: 0 5px; | |
text-align: center; | |
line-height: 34px; | |
} | |
#statusfilter li.selected { | |
background: #888888; | |
} | |
#statusfilter li:hover:not(.selected) { | |
background: #00ffff80; | |
} | |
#statusfilter li:first-child { | |
border-top-left-radius: 3px; | |
border-bottom-left-radius: 3px; | |
} | |
#statusfilter li:last-child { | |
border-top-right-radius: 3px; | |
border-bottom-right-radius: 3px; | |
border-right: 1px solid #aaaaaa; | |
} | |
#statusfilter li a { | |
user-select: none; | |
color: #000000; | |
text-decoration: none; | |
text-align: center; | |
vertical-align: middle; | |
} | |
#boxfilter ul { | |
margin: 0; | |
display: inline-flex; | |
} | |
#boxfilter li { | |
list-style-type: none; | |
float: left; | |
margin: 0; | |
border: 1px solid #aaaaaa; | |
border-right: none; | |
padding: 0 5px; | |
text-align: center; | |
line-height: 34px; | |
} | |
#boxfilter li.selected { | |
background: #888888; | |
} | |
#boxfilter li:hover:not(.selected) { | |
background: #00ffff80; | |
} | |
#boxfilter li:first-child { | |
border-top-left-radius: 3px; | |
border-bottom-left-radius: 3px; | |
} | |
#boxfilter li:last-child { | |
border-top-right-radius: 3px; | |
border-bottom-right-radius: 3px; | |
border-right: 1px solid #aaaaaa; | |
} | |
#boxfilter li a { | |
user-select: none; | |
color: #000000; | |
text-decoration: none; | |
text-align: center; | |
vertical-align: middle; | |
} | |
#table_here { | |
width: 100%; | |
text-align: center; | |
vertical-align: middle; | |
} | |
#table_here > .entry-1 { background-color: #ff0000; } #table_here > .entry0 { background-color: #d8d8d8; } | |
#table_here > .entry1 { background-color: #ff8080; } #table_here > .entry2 { background-color: #ffff40; } | |
#table_here > .entry3 { background-color: #80ff80; } | |
#table_here > .entry > td { | |
overflow-x: hidden; | |
padding: 5px; | |
} | |
.entrytitle { width: 30%; } .entryuser { width: 15%; } .entrybox { width: 7%; } .entrytype { width: 15%; } .entrypic { width: 30%; } | |
.entrypic > img { max-width: 100%; max-height: 100%; } | |
</style> | |
<div id="table_stats"><div id="table_fail"></div><div id="table_most"></div><div id="table_pass"></div></div> | |
<div>Red: not working; Yellow: partially working; Green: working; Gray: unknown.</div> | |
<div><input type="text" placeholder="Search for a game..." onchange="search_changed(this.value);" onkeypress="this.onchange();" onpaste="this.onchange();" oninput="this.onchange();"></div> | |
<div id="statusfilter">Filter on status: <ul><li onclick="statusButtonClick(null, this)"><a>Any</a></li><li onclick="statusButtonClick(1, this)"><a>Not working</a></li><li onclick="statusButtonClick(2, this)"><a>Partially working</a></li><li onclick="statusButtonClick(3, this)"><a>Working</a></li><li onclick="statusButtonClick(0, this)"><a>Unknown</a></li></ul></div> | |
<div id="boxfilter">Filter on box version: <ul style="margin: 0; display: inline-flex;"><li onclick="boxButtonClick(null, this)"><a>Any</a></li><li onclick="boxButtonClick(['box86', 'Both'], this)"><a>box86</a></li><li onclick="boxButtonClick(['box64', 'Both'], this)"><a>box64</a></li><li onclick="boxButtonClick(['Unknown'], this)"><a>Unknown</a></li></ul></div> | |
<div id="pagination"><ul id="paginationlist"></ul></div> | |
<table id="table_here"><tbody><tr><th>Title</th><th>Original poster</th><th>box86/box64</th><th>Status</th><th>Picture (if available)</th></tr></tbody></table> | |
<div id="please_wait_loading">Please wait, loading...</div> | |
<script> | |
function maybe_convert_element(id) { | |
elem = window.trcompatibilitylist[id]; | |
if (elem.constructor === Object) { | |
newdiv = document.createElement("tr"); | |
newdiv.className = "entry entry" + elem.ttype; | |
title = document.createElement("td"); | |
title.className = "entrytitle"; | |
title.innerHTML = "<a href=" + elem.html_url + ">" + elem.title + "</a>"; | |
user = document.createElement("td"); | |
user.className = "entryuser"; | |
user.innerText = elem.user; | |
boxd = document.createElement("td"); | |
boxd.className = "entrybox"; | |
boxd.innerText = elem.boxtxt; | |
type = document.createElement("td"); | |
type.className = "entrytype"; | |
type.innerText = elem.typetxt; | |
pic = document.createElement("td"); | |
pic.className = "entrypic"; | |
if (elem.picsrc === null) { pic.innerText = "Picture unavailable"; } | |
else { pic.innerHTML = "<img src=\"" + elem.picsrc + "\">"; } | |
newdiv.appendChild(title); | |
newdiv.appendChild(user); | |
newdiv.appendChild(boxd); | |
newdiv.appendChild(type); | |
newdiv.appendChild(pic); | |
window.trcompatibilitylist[id] = newdiv; | |
} | |
} | |
document.addEventListener("DOMContentLoaded", function(){ | |
reqstr = "https://api.github.com/repos/ptitSeb/box86-compatibility-list/issues?accept=application/vnd.github.v3+json&state=open&per_page=100&page="; | |
failcnt = 0; mostcnt = 0; passcnt = 0; unkncnt = 0; | |
window.trcompatibilitylist = []; window.trcompatibilitynos = []; window.curtbl = 0; window.itemsppage = 15; window.tablerowdummies = []; | |
window.title_filter = ""; window.type_filter = null; window.boxtxt_filter = null; window.lastButton = 0; | |
window.finished_load = false; | |
window.sel_type = document.getElementById("statusfilter").children[0].children[0]; window.sel_type.className = "selected"; | |
window.sel_box = document.getElementById("boxfilter").children[0].children[0]; window.sel_box.className = "selected"; | |
for (i = 0; i < window.itemsppage; ++i) { | |
window.tablerowdummies[i] = document.createElement("div"); | |
document.getElementById("table_here").appendChild(window.tablerowdummies[i]); | |
} | |
function addfailedstr(msg) { | |
faileddiv = document.createElement("div"); | |
failedtxt = document.createTextDiv(msg); | |
faileddiv.style.color = "red"; | |
faileddiv.appendChild(failedtxt); | |
document.getElementById("table_here").appendChild(faileddiv); | |
console.error(msg); | |
} | |
function addtr(tablerow) { | |
window.trcompatibilitynos.push(window.trcompatibilitylist.length); | |
window.trcompatibilitylist.push(tablerow); | |
if (window.curtbl === 0) { | |
window.curtbl = 1; | |
window.itemcount = 0; | |
} | |
if (window.itemcount % window.itemsppage === 0) { | |
paglst = document.getElementById("paginationlist"); | |
if (paglst.childElementCount >= 0) { | |
// TODO: change this to not add infinitely many pages and update the buttons later | |
newPage = document.createElement("li"); | |
if (paglst.childElementCount === 0) { | |
window.selectedPage = 0; | |
} else { | |
remove_class(paglst.children[window.lastButton], "last-child-pag"); | |
} | |
window.lastButton = paglst.childElementCount; | |
paglst.appendChild(newPage); | |
newPage.outerHTML = "<li class=\"" + ((paglst.childElementCount === 1) ? "selected last-child-pag" : "last-child-pag") + "\" onclick=\"paginationButtonClick(" + (paglst.childElementCount-1) + ")\"><a>" + paglst.childElementCount + "</a></li>"; | |
} | |
} | |
if (window.itemcount < window.itemsppage) { | |
maybe_convert_element(window.itemcount); | |
document.getElementById("table_here").replaceChild(window.trcompatibilitylist[window.itemcount], document.getElementById("table_here").children[window.itemcount+1]); | |
} | |
++window.itemcount; | |
} | |
function nextPage(page) { | |
req = new XMLHttpRequest(); | |
req.open("GET", reqstr + page); | |
req.onerror = function(){ | |
addfailedstr("Failed to fetch the GitHub issues"); | |
}; | |
req.onload = function(){ | |
if (req.responseType !== "") { | |
addfailedstr("Unknown response type " + req.responseType); | |
} else { | |
var resp = JSON.parse(req.response); | |
for (const issueID in resp) { | |
const issue = resp[issueID]; | |
ttype = 0; // -1 = conflict, 0 = unknown, 1 = Not-working, 2 = Partially-working, 3 = Working | |
boxs = 0; // 1 = box86, 2 = box64 (bitfield) | |
for (const labelID in issue["labels"]) { | |
otype = ttype; | |
switch (issue["labels"][labelID].id) { | |
case 2018095883: // Not-working | |
ttype = 1; | |
break; | |
case 2018095900: // Partly-working | |
ttype = 2; | |
break; | |
case 2024688036: // Working | |
ttype = 3; | |
break; | |
case 3486241431: // Box86 | |
boxs |= 1; | |
continue; | |
case 3486242986: // Box64 | |
boxs |= 2; | |
continue; | |
default: | |
continue; | |
} | |
if (otype !== 0) if (otype !== ttype) { // Apparently && gets transformed into `&038;&038;'... | |
console.error("Conflicting types for " + issue["title"] + ": " + otype + " and " + ttype); | |
ttype = -1; | |
break; | |
} | |
} | |
if (ttype === 1) ++failcnt; | |
else if (ttype === 2) ++mostcnt; | |
else if (ttype === 3) ++passcnt; | |
else ++unkncnt; | |
newrow = { ttype: ttype, html_url: issue.html_url, title: issue.title, user: issue.user.login, | |
boxtxt: (boxs === 0) ? "Unknown" : | |
((boxs === 1) ? "box86" : | |
((boxs === 2) ? "box64" : "Both")), | |
typetxt: (ttype === -1) ? "Unknown*" : | |
((ttype === 0) ? "Unknown" : | |
((ttype === 1) ? "Not working" : | |
((ttype === 2) ? "Partially working" : "Working"))) | |
}; | |
picsrcregexp = /(https?:\/\/[^:<>"']+\/[^:<>"'\/]+\.(png(!thumbnail)?|jpe?g))/gi; | |
picsrc = picsrcregexp.exec(issue.body); | |
if (picsrc === null) { | |
fallbackregexp = /]\((https:\/\/github.com\/(ptitSeb\/box86-compatibility-list|user-attachments)\/assets\/[^)]+)/gi; | |
picsrc = fallbackregexp.exec(issue.body); | |
} | |
if (picsrc === null) { newrow.picsrc = null; } | |
else { newrow.picsrc = picsrc[1]; } | |
addtr(newrow); | |
} | |
totcnt = failcnt + mostcnt + passcnt + unkncnt; | |
document.getElementById("table_fail").style.width = (100*failcnt / totcnt) + "%"; | |
document.getElementById("table_most").style.width = (100*mostcnt / totcnt) + "%"; | |
document.getElementById("table_pass").style.width = (100*passcnt / totcnt) + "%"; | |
if (resp.length === 100) { | |
nextPage(page + 1); | |
} else { | |
please_wait = document.getElementById("please_wait_loading"); | |
please_wait.parentElement.removeChild(please_wait); | |
window.finished_load = true; | |
refilter(); | |
} | |
} | |
}; | |
req.send(); | |
} | |
nextPage(1); | |
}); | |
function add_class(elem, cname) { | |
elem.className = (elem.className.length === 0) ? cname : (elem.className + " " + cname); | |
} | |
function remove_class(elem, cname) { | |
elem.className = elem.className.startsWith(cname + " ") ? elem.className.substr(cname.length + 1) : | |
((elem.className.startsWith(cname) && (elem.className.length === cname.length)) ? "" : | |
elem.className.replace(" " + cname, "")); | |
} | |
function paginationButtonClick(pageno) { | |
tab = document.getElementById("table_here"); | |
offset = pageno*window.itemsppage; | |
for (i = 0; i < window.itemsppage; ++i) { | |
id = offset + i; | |
if (id < window.trcompatibilitynos.length) { | |
id = window.trcompatibilitynos[id]; | |
maybe_convert_element(id); | |
tab.replaceChild(window.trcompatibilitylist[id], tab.children[i+1]); | |
} else { | |
tab.replaceChild(window.tablerowdummies[i], tab.children[i+1]); | |
} | |
} | |
paglst = document.getElementById("paginationlist"); | |
remove_class(paglst.children[window.selectedPage], "selected"); | |
window.selectedPage = pageno; | |
add_class(paglst.children[window.selectedPage], "selected"); | |
} | |
function refilter() { | |
if (!window.finished_load) return; // Wait until the requests are done; filtering will be done at the end | |
trcompatibilitynos = []; | |
for (i = 0; i < window.trcompatibilitylist.length; ++i) { | |
elem = window.trcompatibilitylist[i]; | |
if (elem.constructor === Object) { | |
title = elem.title; | |
ttype = elem.ttype; | |
boxtxt = elem.boxtxt; | |
} else { | |
title = elem.children[0].children[0].firstChild.textContent; | |
ttype = parseInt(elem.classList[1].substr("entry".length)); | |
boxtxt = elem.children[2].textContent; | |
} | |
if (((window.title_filter === "") || (title.toUpperCase().replace(/\s+/g, "").indexOf(window.title_filter) > -1)) | |
&& ((window.type_filter === null) || (ttype === window.type_filter)) | |
&& ((window.boxtxt_filter === null) || (window.boxtxt_filter.indexOf(boxtxt) >= 0))) { | |
trcompatibilitynos.push(i); | |
} | |
} | |
// We may end up replacing a visible child by another one, which is *bad* | |
tab = document.getElementById("table_here"); | |
for (i = 0; i < window.itemsppage; ++i) { | |
tab.replaceChild(window.tablerowdummies[i], tab.children[i+1]); | |
} | |
paglst = document.getElementById("paginationlist"); | |
remove_class(paglst.children[window.lastButton], "last-child-pag"); | |
window.lastButton = (trcompatibilitynos.length === 0) ? 0 : (((trcompatibilitynos.length - 1) / window.itemsppage) >> 0); | |
add_class(paglst.children[window.lastButton], "last-child-pag"); | |
for (i = 0; i <= window.lastButton; ++i) { | |
paglst.children[i].style.display = ''; | |
} | |
for (i = window.lastButton + 1; i < paglst.childElementCount; ++i) { | |
paglst.children[i].style.display = 'none'; | |
} | |
window.trcompatibilitynos = trcompatibilitynos; | |
paginationButtonClick(0); | |
} | |
function search_changed(new_search) { | |
window.title_filter = new_search.toUpperCase().replace(/\s+/g, ""); | |
refilter(); | |
} | |
function statusButtonClick(buttonid, button) { | |
window.type_filter = buttonid; | |
window.sel_type.className = ""; | |
window.sel_type = button; | |
window.sel_type.className = "selected"; | |
refilter(); | |
} | |
function boxButtonClick(buttonid, button) { | |
window.boxtxt_filter = buttonid; | |
window.sel_box.className = ""; | |
window.sel_box = button; | |
window.sel_box.className = "selected"; | |
refilter(); | |
} | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment