// ==UserScript==
// @name GMLibrary
// @namespace https://greasyfork.org/users/28298
// @version 1.5
// @description GMLibary
// @author Jerry
// @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
// @grant GM_setClipboard
// @grant GM_download
// @grant GM_addStyle
// @grant GM_notification
// @grant GM_xmlhttpRequest
// @noframes
// @license GNU GPLv3
// ==/UserScript==
// match violentmonkey supports * anywhere in url
// GM_notification requires macOS to turn on notification for browser
// https://violentmonkey.github.io/api/gm/
// https://www.tampermonkey.net/documentation.php?ext=dhdg
function addbutton(text,func,top,left,width,height) {
//top, left, [width[, height]] in px
// e.g., width 100px, height 25px
// https://stackoverflow.com/a/1535421/2292993
if (window.top != window.self) {
return;
} //don't run on frames or iframes
let btn = document.createElement("button");
btn.innerHTML = text;
document.body.appendChild(btn);
btn.addEventListener("click", func);
btn.style.cssText = "border-radius: 5px; border:1px solid black; background-color:#D3D3D3; color:black";
btn.style.position = 'absolute';
btn.style.top = top+'px';
btn.style.left = left+'px';
if (width !== undefined) {btn.style.width = width+'px';}
if (height !== undefined) {btn.style.height = height+'px';}
console.log("top: " + top + 'px' + " left: " + left + 'px');
}
// must call with await in async function; otherwise not working
function asleep(ms) {
setTimeout(()=>{console.log("Sleeping...");},3000);
return new Promise(resolve => setTimeout(resolve, ms));
}
function sleep(millis) {
var date = new Date();
var curDate = null;
do { curDate = new Date(); }
while(curDate-date < millis);
}
function hget (url) {
// https://wiki.greasespot.net/GM.xmlHttpRequest
// https://stackoverflow.com/a/65561572/2292993
return new Promise((resolve, reject) => {
GM_xmlhttpRequest({
method: "GET",
url: url,
// headers: {
// "User-Agent": "Mozilla/5.0", // If not specified, navigator.userAgent will be used.
// "Accept": "text/html" // If not specified, browser defaults will be used.
// },
onload: function(response) {
var responseXML = null;
if (!response.responseXML) {
responseXML = new DOMParser()
.parseFromString(response.responseText, "text/html");
} else {
responseXML = response.responseXML;
}
resolve(responseXML);
// console.log([
// response.status,
// response.statusText,
// response.readyState,
// response.responseHeaders,
// response.responseText,
// response.finalUrl,
// responseXML
// ].join("\n"));
},
onerror: function(error) {
reject(error);
}
});
});
}
// https://github.com/zevero/simpleWebstorage
/*
Wonder how this works?
Storage is the Prototype of both localStorage and sessionStorage.
Got it?
localStorage.set('myKey',{a:[1,2,5], b: 'ok'}); //can set a json Object
localStorage.assign('myKey',{a:[6], c:42}); //shallow merge using Object.assign
localStorage.has('myKey'); // --> true
localStorage.get('myKey'); // --> {a:[6], b: 'ok', c:42}
localStorage.keys(); // --> ['myKey']
localStorage.remove('myKey'); // -
native:
localStorage.clear();
localStorage.length;
*/
Storage.prototype.set = function(key, obj) {
var t = typeof obj;
if (t==='undefined' || obj===null ) this.removeItem(key);
this.setItem(key, (t==='object')?JSON.stringify(obj):obj);
return obj;
};
Storage.prototype.get = function(key) {
var obj = this.getItem(key);
try {
var j = JSON.parse(obj);
if (j && typeof j === "object") return j;
} catch (e) { }
return obj;
};
Storage.prototype.assign = function(key, obj_merge) {
var obj = this.get(key);
if (typeof obj !== "object" || typeof obj_merge !== "object") return null;
Object.assign(obj, obj_merge);
return this.set(key,obj);
};
Storage.prototype.has = Storage.prototype.hasOwnProperty;
Storage.prototype.remove = Storage.prototype.removeItem;
Storage.prototype.keys = function() {
return Object.keys(this.valueOf());
};
function findx(xpath) {
// e.g., findx('//select[@title="Results Per Page"]')
// returns null if not found
return document.evaluate(xpath,document, null, XPathResult.ANY_TYPE, null).iterateNext();
}
function triggerevent(element,event) {
// e.g., triggerevent (page,'change')
let changeEvent = new Event(event);
element.dispatchEvent(changeEvent);
}