I am currently making a userscript to interpret the APL programming language in a Stack Exchange chat window. This is the code I have come up with:
// ==UserScript==
// @name APL chat
// @version 1
// @grant none
// @match https://chat.stackexchange.com/*
// @require https://cdn.jsdelivr.net/npm/apl@0.1.15/lib/apl.min.js
// ==/UserScript==
window.onload = function() {
var prevCode = "";
setInterval(function() {
var codes=document.getElementsByTagName("code");
//console.log(codes);
var elem = codes[codes.length-1];
if((elem != prevCode) && (elem.innerText[0] == '⋄')){
var result = apl(elem.innerText).toString();
prevCode = elem;
var tmp = document.createElement("div");
tmp.innerHTML = "<pre style=\"color:red\">"+result.replace("\n","<br>")+"</pre>";
var parent = elem.parentElement;
parent.appendChild(tmp.firstChild);
console.log(result);
}
},100);
}
When a code block is written to the body with a ⋄
character in it, it should be executed and displayed in red, underneath the code. However, this doesn't work at all times.
These are the errors I got while testing in the Chat Sandbox:
The script turns on in the correct websites, but in the console in Chrome 87.0.4280.88, I get the following error message:
Uncaught TypeError: Cannot read property 'innerText' of undefined
at eval (userscript.html?name=APL%20chat.user.js&id=eb8ebba5-9381-48c2-9f2d-d735cbcb847e:1260)
The apl()
function takes a single string and interprets in in the APL language, and it is imported from the @require
statement, using ngn's javascript APL interpreter.
Another problem is that when I try accessing the apl()
function from the @require
, it says ReferenceError: apl is not defined
. This happens on both Chrome and Firefox.
What is the correct fix for these problems?
The .main
class takes some time to appear when you load the chat page and sometimes it loads after your userscript. So you need to find a way to ensure that your code is executed immediately after .main
loads. Fortunately, there's a hack to do this.
const ready = CHAT.Hub.roomReady.fire;
CHAT.Hub.roomReady.fire = function(...args) {
ready(...args);
executeSomeCode(); // chat page loaded
}
It seems that a function CHAT.Hub.roomReady.fire()
is called when the messages load. In this example, we edit it in order to add the code that needs to run.