Greasy Fork is available in English.

y-userscript-util

my userscript util function

Script này sẽ không được không được cài đặt trực tiếp. Nó là một thư viện cho các script khác để bao gồm các chỉ thị meta // @require https://greasyfork.org/scripts/394408-y-userscript-util/code/y-userscript-util.js?version=762903

/**
 * 
 * @param {any} data 要保存的数据
 * @param {String}} filename 要保存的文件名
 */
function saveAs(data, filename) {
    if (!filename) filename = 'console.json'

    if (typeof data == 'object') {
        data = JSON.stringify(data, undefined, 4);
    }

    var blob = new Blob([data], { type: 'application/octet-stream' });
    var url = window.URL.createObjectURL(blob);
    var saveas = document.createElement('a');
    saveas.href = url;
    saveas.style.display = 'none';
    document.body.appendChild(saveas);
    saveas.download = filename;
    saveas.click();
    setTimeout(function () {
        saveas.parentNode.removeChild(saveas);
    }, 1000)
    document.addEventListener('unload', function () {
        window.URL.revokeObjectURL(url);
    });
}

function getCookie(cname) {
    var name = cname + "=";
    var decodedCookie = decodeURIComponent(document.cookie);
    var ca = decodedCookie.split(';');
    for (var i = 0; i < ca.length; i++) {
        var c = ca[i];
        while (c.charAt(0) == ' ') {
            c = c.substring(1);
        }
        if (c.indexOf(name) == 0) {
            return c.substring(name.length, c.length);
        }
    }
    return "";
}

function getParam(name, url) {
    var regexp = new RegExp("(?:^|\\?|#|&)" + name + "=([^&#]*)(?:$|&|#)", "i"),
        matches = regexp.exec(url || location.href);
    return matches ? decodeURIComponent(matches[1]) : ""
}

function GM_request(url, opt = {}) {
    if (typeof GM_xmlhttpRequest == 'undefined') {
        throw new Error('GM_xmlhttpRequest 不存在')
    }

    return new Promise((resolve, reject) => {
        opt = Object.assign({
            method: "GET",
            url,
            onload: function (response) {
                resolve(response.responseText)
            },
            onerror: function (res) {
                reject(res)
            },
            timeout: 30 * 1000,
            ontimeout: function () {
                reject('timeout')
            }
        }, opt);

        GM_xmlhttpRequest(opt);
    })
}

function addMutationObserver(selector, callback) {
    let timer;
    var watch = document.querySelector(selector);
    if (!watch) return;

    var observer = new MutationObserver(function (mutations) {
        mutations.forEach(function (m) {
            if (m.addedNodes.length > 0) {
                clearTimeout(timer)
                timer = setTimeout(callback, 100)
            }
        });
    });
    observer.observe(watch, { childList: true, subtree: true });
}

function parseHTML(html) {
    var doc;
    try {
        // firefox and chrome 30+,Opera 12 会报错
        doc = new DOMParser().parseFromString(html, 'text/html');
    } catch (ex) {}
    if (!doc) {
        doc = document.implementation.createHTMLDocument("");
        doc.querySelector('html').innerHTML = html;
    }
    return doc;
}

function waitForSelector(selector, then) {
    waitFor(function _check() {
        return document.querySelector(selector);
    }, function _done() {
        then(document.querySelector(selector));
    });
}

function waitFor(condition, callback, timeout, timeoutFn) {
    timeout = timeout || 30 * 1000;
    timeoutFn = timeoutFn || function() {};

    var startTime = Date.now();
    var timeId = setInterval(function() {
        if (condition()) {
            callback();
            clearInterval(timeId);
        } else if ((Date.now() - startTime) > timeout) {
            timeoutFn();
            clearInterval(timeId);
        }
    }, 500);
}

function delay(ms=null) {
    if (!ms) {
        // 1 - 2 秒之间
        ms = (Math.random() + 1)* 1000
    }

    return new Promise(resolve => {
        setTimeout(resolve, ms);
    })
}