y-userscript-util

my userscript util function

This script should not be not be installed directly. It is a library for other scripts to include with the meta directive // @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);
    })
}