diff --git a/code/controllers/subsystem/statpanel.dm b/code/controllers/subsystem/statpanel.dm
index a5f768923b..4731940f41 100644
--- a/code/controllers/subsystem/statpanel.dm
+++ b/code/controllers/subsystem/statpanel.dm
@@ -60,7 +60,7 @@ SUBSYSTEM_DEF(statpanels)
var/list/ahelp_tickets = GLOB.ahelp_tickets.stat_entry()
target << output("[url_encode(json_encode(ahelp_tickets))];", "statbrowser:update_tickets")
if(!length(GLOB.sdql2_queries))
- target << output("", "statbrowser:remove_sqdl2")
+ target << output("", "statbrowser:remove_sdql2")
else
var/list/sqdl2A = list()
sqdl2A[++sqdl2A.len] = list("", "Access Global SDQL2 List", REF(GLOB.sdql2_vv_statobj))
@@ -69,7 +69,7 @@ SUBSYSTEM_DEF(statpanels)
var/datum/SDQL2_query/Q = i
sqdl2B = Q.generate_stat()
sqdl2A += sqdl2B
- target << output(url_encode(json_encode(sqdl2A)), "statbrowser:update_sqdl2")
+ target << output(url_encode(json_encode(sqdl2A)), "statbrowser:update_sdql2")
var/list/proc_holders = target.mob.get_proc_holders()
target.spell_tabs.Cut()
for(var/phl in proc_holders)
diff --git a/html/statbrowser.html b/html/statbrowser.html
index 4d202bd177..fbdbb61449 100644
--- a/html/statbrowser.html
+++ b/html/statbrowser.html
@@ -4,6 +4,7 @@
Stat Browser
+
@@ -169,6 +174,50 @@ if (!String.prototype.trim) {
return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
};
}
+/*\
+|*|
+|*| Polyfill which enables the passage of arbitrary arguments to the
+|*| callback functions of JavaScript timers (HTML5 standard syntax).
+|*|
+|*| https://developer.mozilla.org/en-US/docs/DOM/window.setInterval
+|*|
+|*| Syntax:
+|*| var timeoutID = window.setTimeout(func, delay[, arg1, arg2, ...]);
+|*| var timeoutID = window.setTimeout(code, delay);
+|*| var intervalID = window.setInterval(func, delay[, arg1, arg2, ...]);
+|*| var intervalID = window.setInterval(code, delay);
+|*|
+\*/
+(function() {
+ setTimeout(function(arg1) {
+ if (arg1 === 'test') {
+ // feature test is passed, no need for polyfill
+ return;
+ }
+ var __nativeST__ = window.setTimeout;
+ window.setTimeout = function(vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */ ) {
+ var aArgs = Array.prototype.slice.call(arguments, 2);
+ return __nativeST__(vCallback instanceof Function ? function() {
+ vCallback.apply(null, aArgs);
+ } : vCallback, nDelay);
+ };
+ }, 0, 'test');
+
+ var interval = setInterval(function(arg1) {
+ clearInterval(interval);
+ if (arg1 === 'test') {
+ // feature test is passed, no need for polyfill
+ return;
+ }
+ var __nativeSI__ = window.setInterval;
+ window.setInterval = function(vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */ ) {
+ var aArgs = Array.prototype.slice.call(arguments, 2);
+ return __nativeSI__(vCallback instanceof Function ? function() {
+ vCallback.apply(null, aArgs);
+ } : vCallback, nDelay);
+ };
+ }, 0, 'test');
+}())
// Browser passthrough code ---------------------------------------------------
if (window.location) {
@@ -182,13 +231,11 @@ if (window.location) {
if(!anti_spam[e.which]) {
anti_spam[e.which] = true;
var key = String.fromCharCode(e.which);
- if(key == "t")
- window.location.href = "byond://winset?command=Say"
- else if(key == "o")
- window.location.href = "byond://winset?command=OOC"
- else if(key == "m")
- window.location.href = "byond://winset?command=Me"
- window.location.href = "byond://winset?command=keyDown " + key;
+ var x = event.x || event.clientX;
+ var y = event.y || event.clientY;
+ if(x || y ) // if either of these exist this is happening after a click
+ return;
+ window.location.href = "byond://winset?command=keyDown " + e.key;
}
}
});
@@ -200,7 +247,12 @@ if (window.location) {
if(e.which) {
anti_spam[e.which] = false;
var key = String.fromCharCode(e.which);
- window.location.href = "byond://winset?command=keyUp " + key;
+ var x = event.x || event.clientX;
+ var y = event.y || event.clientY;
+ if( x || y ) // if either of these exist this is happening after a click
+ return;
+
+ window.location.href = "byond://winset?command=keyUp " + e.key;
}
});
}
@@ -223,14 +275,17 @@ var spells = [];
var spell_tabs = [];
var verb_tabs = [];
var verbs = [["", ""]]; // list with a list inside
-var inner = "";
var tickets = [];
-var sqdl2 = [];
+var sdql2 = [];
var permanent_tabs = []; // tabs that won't be cleared by wipes
var turfcontents = [];
var turfname = "";
+var imageRetryDelay = 500;
+var imageRetryLimit = 50;
var menu = document.querySelector('#menu');
var under_menu = document.querySelector('#under_menu');
+var statcontentdiv = document.querySelector('#statcontent');
+var storedimages = [];
function createStatusTab(name) {
if(document.getElementById(name) || name.trim() == "")
@@ -255,6 +310,7 @@ function createStatusTab(name) {
}
//END ORDERING
menu.appendChild(B);
+ SendTabToByond(name);
under_menu.style.height = menu.clientHeight + 'px';
}
@@ -267,9 +323,8 @@ function removeStatusTab(name) {
}
}
menu.removeChild(document.getElementById(name));
+ TakeTabFromByond(name);
under_menu.style.height = menu.clientHeight + 'px';
- if(document.getElementById(name)) // repeat for duplicates
- removeStatusTab(name);
}
window.onresize = function () {
@@ -294,7 +349,7 @@ function removePermanentTab(name) {
function checkStatusTab() {
for(var i=0; i < menu.children.length; i++)
if(!verb_tabs.includes(menu.children[i].id) && !permanent_tabs.includes(menu.children[i].id))
- removeStatusTab(menu.children[i].id);
+ menu.removeChild(menu.children[i]);
}
function remove_verb(v) {
var verb_to_remove = v; // to_remove = [verb:category, verb:name]
@@ -338,6 +393,13 @@ function verbs_cat_check(cat) {
}
}
+function findVerbindex(name, verblist) {
+ for(var i = 0; i < verblist.length; i++) {
+ var part = verblist[i];
+ if(part[1] == name)
+ return i;
+ }
+}
function wipe_verbs() {
verbs = [["", ""]];
verb_tabs = [];
@@ -349,10 +411,9 @@ function add_verb_list(v) {
to_add.sort(); // sort what we're adding
for(var i = 0; i < to_add.length; i++) {
var part = to_add[i];
+ if(findVerbindex(part[1], verbs))
+ continue;
if(verb_tabs.includes(part[0])){
- if(verbs.includes(part)){
- continue;
- }
verbs.push(part);
if(current_tab == part[0]) {
draw_verbs(part[0]); // redraw if we added a verb to the tab we're currently in
@@ -393,12 +454,30 @@ function init_verbs(c, v) {
do_update = true;
}
if(v) {
- verbs = JSON.parse(v);
+ add_verb_list(v);
verbs.sort(); // sort them
if(do_update) {
draw_verbs(current_tab);
}
}
+ SendTabsToByond();
+}
+
+function SendTabsToByond(){
+ var tabstosend = [];
+ tabstosend = tabstosend.concat(permanent_tabs, verb_tabs);
+ for(var i=0; i < tabstosend.length; i++){
+ SendTabToByond(tabstosend[i]);
+ }
+}
+
+function SendTabToByond(tab) {
+ window.location.href = "byond://winset?command=Send-Tabs " + tab;
+}
+
+//Byond can't have this tab anymore since we're removing it
+function TakeTabFromByond(tab) {
+ window.location.href = "byond://winset?command=Remove-Tabs " + tab;
}
function update(global_data, ping_entry, other_entries) {
@@ -413,10 +492,9 @@ function update(global_data, ping_entry, other_entries) {
draw_debug();
}
-function update_mc(global_mc_data, coords_entry, ht) {
+function update_mc(global_mc_data, coords_entry) {
mc_tab_parts = JSON.parse(global_mc_data);
mc_tab_parts.splice(0,0,["Location:",coords_entry]);
- href_token = ht;
if(!verb_tabs.includes("MC"))
verb_tabs.push("MC");
createStatusTab("MC");
@@ -486,6 +564,7 @@ function tab_change(tab) {
if(document.getElementById(current_tab))
document.getElementById(current_tab).className = "button"; // disable active on last button
current_tab = tab;
+ set_byond_tab(tab);
if(document.getElementById(tab))
document.getElementById(tab).className = "button active"; // make current button active
var spell_tabs_thingy = (spell_tabs.includes(tab));
@@ -502,19 +581,20 @@ function tab_change(tab) {
draw_debug();
} else if(tab == "Tickets") {
draw_tickets();
- } else if(tab == "SQDL2") {
- draw_sqdl2();
+ } else if(tab == "SDQL2") {
+ draw_sdql2();
}else if(tab == turfname) {
draw_listedturf();
} else {
- var statcontentdiv = document.getElementById("statcontent");
statcontentdiv[textContentKey] = "loading...";
}
window.location.href = "byond://winset?statbrowser.is-visible=true";
}
+function set_byond_tab(tab){
+ window.location.href = "byond://winset?command=Set-Tab " + tab;
+}
function draw_debug() {
- var statcontentdiv = document.getElementById("statcontent");
statcontentdiv[textContentKey] = "";
var wipeverbstabs = document.createElement("div");
var link = document.createElement("a");
@@ -573,12 +653,11 @@ function draw_debug() {
}
function draw_status() {
- var statcontentdiv = document.getElementById("statcontent");
if(!document.getElementById("Status")) {
createStatusTab("Status");
current_tab = "Status";
}
- statcontentdiv[textContentKey] = inner;
+ statcontentdiv[textContentKey] = '';
for(var i = 0; i < status_tab_parts.length; i++) {
if(status_tab_parts[i].trim() == "") {
document.getElementById("statcontent").appendChild(document.createElement("br"));
@@ -595,7 +674,6 @@ function draw_status() {
}
function draw_mc() {
- var statcontentdiv = document.getElementById("statcontent");
statcontentdiv[textContentKey] = "";
var table = document.createElement("table");
for(var i = 0; i < mc_tab_parts.length; i++) {
@@ -627,21 +705,21 @@ function update_tickets(T){
if(current_tab == "Tickets")
draw_tickets();
}
-function update_sqdl2(S) {
- sqdl2 = JSON.parse(S);
- if(sqdl2.length > 0 && !verb_tabs.includes("SQDL2")) {
- verb_tabs.push("SQDL2");
- addPermanentTab("SQDL2");
+function update_sdql2(S) {
+ sdql2 = JSON.parse(S);
+ if(sdql2.length > 0 && !verb_tabs.includes("SDQL2")) {
+ verb_tabs.push("SDQL2");
+ addPermanentTab("SDQL2");
}
- if(current_tab == "SQDL2")
- draw_sqdl2();
+ if(current_tab == "SDQL2")
+ draw_sdql2();
}
-function remove_sqdl2() {
- if(sqdl2) {
- sqdl2 = [];
- removePermanentTab("SQDL2");
- if(current_tab == "SQDL2")
+function remove_sdql2() {
+ if(sdql2) {
+ sdql2 = [];
+ removePermanentTab("SDQL2");
+ if(current_tab == "SDQL2")
tab_change("Status");
}
checkStatusTab();
@@ -658,11 +736,17 @@ function remove_tickets() {
}
// removes MC, Tickets and MC tabs.
function remove_admin_tabs() {
+ href_token = null;
remove_mc();
remove_tickets();
- remove_sqdl2();
+ remove_sdql2();
}
+function add_admin_tabs(ht) {
+ href_token = ht;
+ addPermanentTab("MC");
+ addPermanentTab("Tickets");
+}
function create_listedturf(TN) {
remove_listedturf(); // remove the last one if we had one
turfname = JSON.parse(TN);
@@ -674,16 +758,42 @@ function update_listedturf(TC) {
if(current_tab == turfname)
draw_listedturf();
}
-
+function iconError() {
+ var that = this;
+ setTimeout(function() {
+ var current_attempts = that.id; // a bit of a hack, change this if we need to call on img id's later
+ if(!current_attempts)
+ that.id = 1;
+ if (current_attempts > imageRetryLimit)
+ return;
+ var src = that.src;
+ that.src = null;
+ that.src = src + '#' + current_attempts;
+ that.id++;
+ draw_listedturf();
+ }, imageRetryDelay);
+}
function draw_listedturf() {
- var statcontentdiv = document.getElementById("statcontent");
statcontentdiv[textContentKey] = "";
var table = document.createElement("table");
for(var i = 0; i < turfcontents.length; i++) {
var part = turfcontents[i];
- if(part[2]) {
+ if(storedimages[part[1]] == null && part[2]) {
var img = document.createElement("img");
img.src = part[2];
+ img.id = part[1];
+ storedimages[part[1]] = part[2];
+ img.onerror = function() {
+ iconError();
+ };
+ table.appendChild(img);
+ } else {
+ var img = document.createElement("img");
+ img.onerror = function() {
+ iconError();
+ };
+ img.src = storedimages[part[1]];
+ img.id = part[1];
table.appendChild(img);
}
var b = document.createElement("div");
@@ -720,12 +830,11 @@ function remove_listedturf() {
if(current_tab == turfname)
tab_change("Status");
}
-function draw_sqdl2(){
- var statcontentdiv = document.getElementById("statcontent");
+function draw_sdql2(){
statcontentdiv[textContentKey] = "";
var table = document.createElement("table");
- for(var i = 0; i < sqdl2.length; i++) {
- var part = sqdl2[i];
+ for(var i = 0; i < sdql2.length; i++) {
+ var part = sdql2[i];
var tr = document.createElement("tr");
var td1 = document.createElement("td");
td1[textContentKey] = part[0];
@@ -746,7 +855,6 @@ function draw_sqdl2(){
}
function draw_tickets() {
- var statcontentdiv = document.getElementById("statcontent");
statcontentdiv[textContentKey] = "";
var table = document.createElement("table");
if(!tickets)
@@ -778,7 +886,6 @@ function draw_tickets() {
}
function draw_spells(cat) {
- var statcontentdiv = document.getElementById("statcontent");
statcontentdiv[textContentKey] = "";
var table = document.createElement("table");
for(var i = 0; i < spells.length; i++) {
@@ -804,7 +911,6 @@ function draw_spells(cat) {
}
function draw_verbs(cat){
- var statcontentdiv = document.getElementById("statcontent");
statcontentdiv[textContentKey] = "";
var table = document.createElement("newdiv");
table.className = "grid-container";
@@ -832,13 +938,13 @@ function draw_verbs(cat){
}
function set_theme(which) {
- if (which == "light") {
- document.body.className = "";
- set_style_sheet("browserOutput_white");
- } else if (which == "dark" || which == "default") {
- document.body.className = "dark";
- set_style_sheet("browserOutput");
- }
+ if (which == "light") {
+ document.body.className = "";
+ set_style_sheet("browserOutput_white");
+ } else if (which == "dark" || which == "default") {
+ document.body.className = "dark";
+ set_style_sheet("browserOutput");
+ }
}
function set_style_sheet(sheet) {
@@ -865,6 +971,14 @@ if(!current_tab) {
tab_change("Status");
}
+window.onload = function() {
+ NotifyByondOnload();
+ };
+
+function NotifyByondOnload() {
+ window.location.href = "byond://winset?command=Panel-Ready";
+}
+
function create_debug(){
if(!document.getElementById("Debug Stat Panel")) {
addPermanentTab("Debug Stat Panel");