2

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?

double-beep
  • 5,031
  • 17
  • 33
  • 41
Razetime
  • 216
  • 3
  • 19
  • 1
    Can you provide a minimal reproducible example the `innerText` error? What's an example chat message that this is failing on? If you reduce your entire code to just `console.log(codes[codes.length-1].innerText)` does it still fail in the same way? Does it still fail when you exclude the `@require apl.min.js`? – Kyle Pollard Dec 28 '20 at 06:44
  • Sorry, but I bountied this by mistake. This version has been fixed with a better algorithm. [This is the current problem I need help with.](https://stackoverflow.com/questions/65446457/tampermonkey-userscript-prevents-pages-from-loading) – Razetime Dec 28 '20 at 07:03

1 Answers1

1

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.

double-beep
  • 5,031
  • 17
  • 33
  • 41