DRSAgile / Colour-visited-URLs

Works in YouTube and Twitter
Apache License 2.0
0 stars 0 forks source link

Can you help me? #1

Open znoow opened 2 years ago

znoow commented 2 years ago

Hi there,

Are you the creator of this? https://stackoverflow.com/a/54755153/10438142

I wanted to contact you via email, but I can't find any email address of yours, on StackOverflow I cannot DM you or anything like this. 😞

I cannot use your UpgradedMutationObserver together with https://gist.github.com/sidneys/ee7a6b80315148ad1fb6847e72a22313

Can you help me to adapt the code? My JS skills are limited, the idea of having isConnected() integrated into the above Gist could be really useful and may improve performance.

Ty in advance and sorry for disturbing you.

znoow commented 2 years ago

@DRSAgile Can you please help me? 😞

znoow commented 2 years ago

I get errors that mention Uncaught error. TypeError: Cannot read properties of undefined (reading 'isConnected') and I don't understand why. 😣

DRSAgile commented 2 years ago

Hi,

I only now saw the notification. I will check your question and write back.

znoow commented 2 years ago

If you are curious, this is my failed attempt: https://pastebin.com/raw/ihmu8u8V

So most likely your code must be adapted somehow to work with sidneys's userscript.

Thank you very much, I truly appreciate you want to help me. 😊

DRSAgile commented 2 years ago

Your code

        const observer = new UpgradedMutationObserver(() => {
            // DOM Changes detected
            queryForElements(selector, (element) => {
                resolve(element)
                callback(element)
            })
            if (findOnce) { observer.disconnect() }
        })

for the callback function does not seem to have two required input parameters for MutationObserver object to be created, hence the error.

You might see an example either in my code you linked to, near the end, or in the documentation I just referenced in this post.

In your case, the code should look something like const observer = new UpgradedMutationObserver((mutationsList, observer) => {, where both arguments are necessary even if you do not really plan to actually use them within the callback function. mutationsList provides a list of DOM changes, which you can process one by one or filter for specific actions such as addition of nodes or their destruction, etc. Or, as I mentioned, the processing can be skipped altogether if you do not care which mutations to the DOM have happened, but rather want to know if anything has happened at all.

znoow commented 2 years ago

Hi there,

I made the change you told me: const observer = new UpgradedMutationObserver(() => { => const observer = new UpgradedMutationObserver((mutationsList, observer) => {

Unfortunately, same error Uncaught error. TypeError: Cannot read properties of undefined (reading 'isConnected') keeps appearing. 🤔

DRSAgile commented 2 years ago

Do you have a CodePen or JSFiddle or something to check?

Because I copied your code to ViolentMonkey and got no errors. 'isConnected' is defined, just as expected -- I confirmed it by inserting console.log in a few places.

znoow commented 2 years ago

Unfortunately, I don't have any CodePen or JSFiddle.

It looks like this error isn't related to the onElementReady userscript, but I'm not 100% sure.

What I noticed is that this error DOES appear for a check like:

if (!observer.isConnected()) {
    observer.observe(mutations => { .......
}

But DOESN'T appear for checks like this:

if (typeof observer !== 'undefined' && !observer.isConnected()) {
    observer.observe(mutations => { .......
}

So it throws the error as long the observer's variable is undefined?! And therefore doesn't know what isConnected() represents?! 🤔

DRSAgile commented 2 years ago

With your exact code in ViolentMonkey for Firefox, I get no errors in this check, but somehow in your programming environment observer constant is not an object (or it is an object, but it does not have isConnected property, though the error should rather talk about the former).

If you insert console.log(observer) before this check, what will be the output of that? It should be just empty, considering the error. If so, I am not sure that I can help further since on my side I can not reproduce the error.

znoow commented 2 years ago

The output is undefined.

What is interesting is that I get the error:

[ERROR] Uncaught error. TypeError: Cannot read properties of undefined (reading 'isConnected')
    at Userscript.user.js:323:15
    at UpgradedMutationObserver.<anonymous> (Userscript.user.js:201:16)

323:15 is actually the line where I use if (!observer.isConnected()) { and 201:16 is return callback( ...args, this); (from your code)

Btw, I use this in Chrome, not in Firefox.

znoow commented 2 years ago

Btw, my MutationObserver is defined as this.mo, I wanted to have observer as a global variable. Is that why the error happens?

Most likely I'll stick with the approach if (typeof observer !== 'undefined' && !observer.isConnected()) {, your code is very useful to avoid running multiple MOs. 😊

DRSAgile commented 2 years ago

The issue is that the check if (!observer.isConnected()) should not give an error, since it only comes after observer itself is defined, not in some detached place.

My guess is that maybe specifically Chrome's way to execute MutationObserver creation is a bit asynchronous -- at least within Promise object -- which results in observer constant is not being ready immediately after the definition.

znoow commented 2 years ago

@DRSAgile Btw, why there's no takeRecords() into your UpgradedMutationObserver? Can you add it too?

DRSAgile commented 2 years ago

Thanks for reminding me; updated the code in StackOverflow.

znoow commented 2 years ago

I think there's another issue: It looks like UpgradedMutationObserver isn't able to initialize properly the MO between pages, while the unaltered/original MutationObserver is able to work without any issue. 🤔

znoow commented 2 years ago

I mean I'm not sure if it starts to observe (properly) or not between different pages, but with the same code/logic and by using the original MutationObserver, it will work as expected. So I'm not sure what's happening.

DRSAgile commented 2 years ago

What does "between pages" mean?

znoow commented 2 years ago

What does "between pages" mean?

When I move from one page to another, it looks like UpgradedMutationObserver will not work properly, unlike the original MutationObserver.

DRSAgile commented 2 years ago

This is possible since UpgradedMutationObserver is created in a script, whose context might change between pages. But it also might depend on the browser and a type of *Monkey you are using, just like your initial issue. The original MutationObserver is built-in, so it might survive this better.

Depending on what exactly is malfunctioning in the scenario you describe, it might be not fixable on UserScript level.

znoow commented 2 years ago

Is there any way to make it "survive" between pages? Perhaps some changes in your code can improve that?

Not sure, but it looks like it could be something related to timing when the script resumes/(re)starts after a new page is loaded.

And I even print in console messages like "MO is starting", which I can see in the console, the messages appear when they're supposed to appear, but somehow only UpgradedMutationObserver is not initialized properly and/or won't see the elements it has to see. I only use it for addedNodes, the elements appear perhaps after minutes since the (new) page is loaded.

As I said, with the same logic, and same code, the original MutationObserver works as expected, I only changed new MutationObserver(... to new UpgradedMutationObserver(... and added your code in my user script to make it work. So it has to be something that might need to be changed into your code that doesn't work for my use case, I guess. 🤔

znoow commented 2 years ago

Despite it looks like UpgradedMutationObserver is really isConnected() it does nothing when it's supposed to do. 😞 Any ideas/suggestions to try? 😊

DRSAgile commented 2 years ago

As I mentioned, it might not be possible to fix on the UserScript level.

The code of UpgradedMutationObserver is simple. It is a composition-type inheritance wrapper over MutationObserver with its core functionality provided by the original object.

If you can provide a CodePen or JSFiddle or UserScript for testing and explain your steps in terms of what you do, then I might be able to check it.

znoow commented 2 years ago

I can make a video, I use the script on Twitch.

I can compare between original MutationObserver and the UpgradedMutationObserver.

Ofc, I will provide you both scripts.

znoow commented 2 years ago

The video: https://youtu.be/aERwD9hvtZU

You can see the first two minutes of the video, then skip to the last 30 secs.

The key moments in the video: 01:54 - First script clicks when it's supposed to do. 05:38 - Second script that has UpgradedMutationObserver doesn't click when it's supposed to do.

First script: https://gist.githubusercontent.com/sn-o-w/0c10dcba6c5947160294797a77e97700/raw/365ffd113191132c69e72351850a387a977d234d/gistfile1.txt Second script: https://gist.githubusercontent.com/sn-o-w/dea517c74d496f209fcbe1abc2295214/raw/439f8bbe52adcef96b34904e9416b39c1bff0d32/gistfile1.txt

DRSAgile commented 2 years ago

I opened link "twitch.tv/ninja" to test, but with either "Twitch Test 1" or "Twitch Test 2" in the logs, I get a variant of this:

20:32:16.607 [Snow] Starting script (ninja)

8:32:22 PM [ERROR] Uncaught error. TypeError: can't access property "getElementsByClassName", target is null
    snow moz-extension://33fcf49c-74da-4efd-8e5b-a003ecca752c/ Twitch Test 2.user.js#33:266
    observer moz-extension://33fcf49c-74da-4efd-8e5b-a003ecca752c/ Twitch Test 2.user.js#33:130
    queryForElements moz-extension://33fcf49c-74da-4efd-8e5b-a003ecca752c/ Twitch Test 2.user.js#33:100
    queryForElements moz-extension://33fcf49c-74da-4efd-8e5b-a003ecca752c/ Twitch Test 2.user.js#33:97
    observer moz-extension://33fcf49c-74da-4efd-8e5b-a003ecca752c/ Twitch Test 2.user.js#33:128
    MutationObserver moz-extension://33fcf49c-74da-4efd-8e5b-a003ecca752c/ Twitch Test 2.user.js#33:30
core-bfba6ee2b0ef6fb522d3.js:1:1326506
    writeToConsole https://static.twitchcdn.net/assets/core-bfba6ee2b0ef6fb522d3.js:1
    write https://static.twitchcdn.net/assets/core-bfba6ee2b0ef6fb522d3.js:1
    onWindowError https://static.twitchcdn.net/assets/core-bfba6ee2b0ef6fb522d3.js:1

It does not happen in your video, but the "Snow" function does not seem to work correctly in my case, unless I miss something.

DRSAgile commented 2 years ago

Also, can you explain what the script exactly is waiting for?

Because I commented the code inside "snow" function and replaced it with console.log(`%c[Snow] snow, onElementReady, inside if`, `background: #0949C7`); line to see if the execution gets there, but then it has to create an observer object, which in not happening by now unless the error above is resolved or the code is edited in a way to circumvent it.

znoow commented 2 years ago

You have to be logged in, you need to register a Twitch account.

The MutationObserver waits for an element to appear and to click it. The element appears every about 15 minutes.

znoow commented 2 years ago

So...? It must work if you are logged into a Twitch account.

znoow commented 2 years ago

@DRSAgile Any news? Can you help me man?