fuzetsu / userscripts

Various browser userscripts I created/maintain
25 stars 11 forks source link

`waitForUrl` calls the function with the old body #16

Open TheBestPessimist opened 2 years ago

TheBestPessimist commented 2 years ago

My scripts here: https://github.com/TheBestPessimist/UserScripts/blob/master/youtube-auto-dislike/youtube-auto-dislike.user.js#L36-L43

I am calling waitForUrl(waitForElems()), and waitForElems is called before the content of the page is updated. It looks as if waitForUrl is "too fast".

Am I using this wrong (I am a Kotlin/Backend dev)? Is this expected? Do you have any advice if what I did there is OK?

fuzetsu commented 2 years ago

Strange, I haven't hit this issue before. What error are you getting? Is it that document.body isn't available yet? I mainly use violentmonkey and I haven't hit this, may have to do with how/when the script runner injects the script.

One option may be to change when your script runs, https://www.tampermonkey.net/documentation.php#_run_at For example using document-body

Also looking at your code you may not need waitForUrl at all. If you don't pass stop:true to waitForElems it will just keep looking for new matches to that element, so even without waitiing for the url it should keep picking the new button as it appears.

TheBestPessimist commented 2 years ago

I'm not getting errors afais, it's just that when i click a new video from the suggested on the right, the userscript is run IMMEDIATELY but the html elements it finds are the old ones. That's why my solution is to sleep 1 second

I'm already using violentmonkey.

TheBestPessimist commented 2 years ago

Regarding the "use only wait for elems with stop=false" advice: this doesnt work.

For the code below, do the following: un-dislike a yt video and wait 1 second. the video is not disliked again. no logs are written to console either. (logs should be written no matter what)


const util = {
    log: (...args) => console.log(`%c${SCRIPT_NAME}:`, "font-weight: bold;color: green;", ...args)
};

const SCRIPT_NAME = "YouTube Auto Dislike";

const CSS = {
    like: "ytd-video-primary-info-renderer #top-level-buttons-computed > ytd-toggle-button-renderer:nth-child(1)",
    dislike: "ytd-video-primary-info-renderer #top-level-buttons-computed > ytd-toggle-button-renderer:nth-child(2)",
    buttonClicked: "style-default-active"
}

waitForElems({ 
                sel: CSS.like,
                onmatch: dislike,
                stop: false,
                throttle: 1000,
            });

function dislike(btn) {
    util.log("begin debug")
    util.log(btn)

    const likeButton = document.querySelector(CSS.like)
    const dislikeButton = document.querySelector(CSS.dislike)

    if (likeButton.classList.contains(CSS.buttonClicked)) {
        util.log("Video is Liked by user => Nothing to do here. Will not dislike.")
        return
    }

    if (dislikeButton.classList.contains(CSS.buttonClicked)) {
        util.log("Video is already Disliked => Nothing to do here.")
        return
    }

    util.log("Will Dislike video.")
    dislikeButton.click()
    util.log("end debug")
}