Tampermonkey / tampermonkey

Tampermonkey is the most popular userscript manager, with over 10 million users. It's available for Chrome, Microsoft Edge, Safari, Opera Next, and Firefox.
GNU General Public License v3.0
4.29k stars 424 forks source link

Global variables become unavailable in functions, some things get executed/evaluated out of order? #2178

Closed Black-Platypus closed 1 month ago

Black-Platypus commented 1 month ago

Expected Behavior

Variables in global scope stay available and things are executed/evaluated in the expected order. In Example script:

Actual Behavior

Variables are undefined, An absolute chaotic nightmare 😵 In Example sctipt:

Specifications

Script

// ==UserScript==
// @name        IGG links direct + Titles
// @version     1.1.0
// @downloadURL https://benjamin-philipp.com/fff/userScripts/IGG_links_direct.user.js
// @updateURL   https://benjamin-philipp.com/fff/userScripts/IGG_links_direct.user.js
// @namespace   bp
// @author      Benjamin Philipp <dev [at - please don't spam] benjamin-philipp.com>
// @icon64URL   http://imgur.com/1J34GZD.png
// @include     https://igg-games.com/*
// @include     https://example.com/*
// @require     https://update.greasyfork.org/scripts/433051/Trusted-Types%20Helper.user.js
// @require     https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js
// @require     https://benjamin-philipp.com/js/gm/funcs.js?a=bcd
// @run-at      document-start
// @grant       GM_xmlhttpRequest
// @grant       GM_openInTab
// @connect     *
// @sandbox     DOM
// ==/UserScript==

var logger = new BPLogger(GM_info.script.name);
var {log, warn, error, success} = logger;
var logLines = [];
var _log = logger.log;
function log(...args){
    console.log("logger:", logger);
    //logLines.push([args]);
    //_log(...args);
    console.log(...args);
}
console.warn("WTF IS GOING ON???");
console.log("WTF", log, error);
log("error top:", error);

var jQ = Object.assign({}, $);

var sels = {
    searchResult: "uk-grid-margin.uk-first-column",
    sTitle: "article h2>a",
    sText: "article>div[property='text']>p, article>div.uk-margin-medium>p"
};

console.log("top", $);
log("top", $);

function doit(_$){
    log(log, logger, error, jQ, _$);
    log(logLines);
    if(!_$)
        return error("Could not get JQ", {jQ, _$});
    //$ = _$;
    log("doit", $);
    $("article .uk-margin-medium-top p a").each(function(){
        var l = this.href;
        var os = this.href.indexOf("xurl=");
        if(os>0){
            l = "http" + this.href.substr(os + 5);
//          alert(l);
            this.href = l;
        }
    });

    $("article h2 a, article h1.uk-article-title a").each(function(){
        this.innerHTML = this.innerHTML.before(" Free Download", false, true);
    });

    $(sels.sText).each(function(){
        this.text(this.text().after("Torrent. ", false, true));
        log(this);
    });

    $("div.uk-container div.n2-ss-margin .n2-ss-slider").parent().parent().parent().remove();
    $("#n2-ss-3-placeholder").remove();
    $("body").on("click", "a[href*=bluemedia]", blueMediaClick);
    $("a[href*=bluemedia]").on("click", blueMediaClick);
    log("here");
}

function blueMediaClick(e){
    var url = e.target.href;
    var active = true;
    if(e.ctrlKey){
        url += "&copyAndClose=true";
        // alert(url);
        // active = false;
        e.preventDefault();
        e.stopImmediatePropagation();
        log(url);
        window.open(url);
        return false;
    }
    // else return alert("nope");
    // log(e.ctrlKey, url, active);
    // GM_openInTab(url,{
    //  active,
    //  insert: true,
    //  parent: true
    // });
}

function waitForJQ(cb, cbFail, interval=200, maxTries=50){
    var j = hasJQuery();
    log("wfJQ:", j, maxTries);
    if(typeof cbFail != "function")
        cbFail = ()=>{log("Could not find jQuery");};
    if(!j){
        maxTries--;
        if(maxTries>0){
            warn("Could not find jQuery, retry", maxTries);
            return setTimeout(()=>{
                waitForJQ(cb, cbFail, interval, maxTries);
            }, interval);
        }
        else
            return cbFail();
    }
    $ = jQ = j;
    log("in WFJ:", j, $);
    cb(j);
}

// setTimeout(()=>{
    //waitForJQ(doit);
// }, 500);

/* jshint loopfunc: true, -W027 */
/* eslint-env browser, es6 */
/* eslint no-trailing-spaces: 0, curly: 0, no-redeclare: 0 */
/* globals $:true, GM_info, GM_setValue, GM_getValue, GM_xmlhttpRequest, GM_addStyle, GM_openInTab, GM_setClipboard, GM_download, GM_config, escape, uneval, unsafeWindow, BPLogger, BPLogger_default, log, error: true, warn, getParam, waitFor, bpMenu, bpModal, escapeHtml, saveText, hasJQuery */

site: https://example.com/

Black-Platypus commented 1 month ago

Hold the effing phone. I just realized that a @require script calls a function of the same name as this one (doit) 🤦‍♀️ I was not expecting that to happen. Sorry for the confusion 😵