MDA library

my JS library

目前為 2025-01-22 提交的版本,檢視 最新版本

此腳本不應該直接安裝,它是一個供其他腳本使用的函式庫。欲使用本函式庫,請在腳本 metadata 寫上: // @require https://update.gf.qytechs.cn/scripts/524553/1525219/MDA%20library.js

  1. // ==UserScript==
  2. // @name MDA library
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.2.1
  5. // @description my JS library
  6. // @author mr-d-r
  7. // ==/UserScript==
  8.  
  9.  
  10. // @require file://D:\...\_MDAlib_tampermonkey.js ВСЕГДА добавляет в самое начало скрипта, где он использован
  11. // т.о. переменные объявленные здесь всегда глобальные !!!
  12.  
  13. // try to make global functions as in https://stackoverflow.com/questions/27680230/how-do-i-make-functions-added-by-tampermonkey-be-available-in-console-after-the
  14. // пробовать делать библиотеку, которая запускается на каждой странице
  15.  
  16. var MDAlib="included", dbg; // real global vars !!! // dbg - отладка // verb - немного расширенные сообщения
  17. // localStorage.setItem("MDAlib", "loaded @" +Date.now());
  18.  
  19. // !!! в скриптах можно проверять так:
  20. // MDAlib=${(typeof MDAlib == "undefined") ? "absent" : MDAlib}
  21. // if(typeof MDAlib == 'undefined') console.log("MDAlib 1212 is NOT defined in _MDAlib_tampermonkey"); else console.log("MDAlib 1212 DEFINED in _MDAlib_tampermonkey = " +MDAlib);
  22. // if(typeof dbg == 'undefined') console.log("dbg 1212 is NOT defined in _MDAlib_tampermonkey"); else console.log("dbg 1212 DEFINED in _MDAlib_tampermonkey = " +dbg);
  23. // !!! пользовать tampermonkey storage для persistent vars и обмена между скриптами !!!
  24.  
  25. // TRY !!! from https://gf.qytechs.cn/en/scripts/14782-facebook-event-exporter/code
  26. /*
  27. var err = console.error.bind(console),
  28. log = console.log.bind(console),
  29. */
  30.  
  31. function anyActiveInput () {
  32. if( Array.from(document.querySelectorAll("input,textarea")).includes(document.activeElement) ) return true;
  33. if( document.activeElement.contentEditable == 'true' ) return true; // for stupid youtube reply mini-window // !!! warning: MUST BE: document.activeElement.contentEditable == true
  34. if( document.activeElement.querySelector('span[data-lexical-text="true"]') ) return true; // for stupid facebook input fields
  35. //if ((aaBB = document.activeElement) && (editable(a) || (a.tagName === "INPUT") || (a.tagName === "TEXTAREA"))) return;
  36. } // anyActiveInput()
  37.  
  38.  
  39. function ttout (delay, func) { // wrap for setTimeout() // WORKS
  40. setTimeout(() => { func(); }, delay);
  41. } // ttout()
  42. var tTO=ttout;
  43.  
  44.  
  45. function ttoutSMART (delay=1000, label, cmd='new', func) { // wrap for setTimeout() // static массив всех вызванных таймеров с метками
  46. let a, b, hnd, min=10000, max=99999, fn=fnName();
  47. if ( typeof ttout.arr == 'undefined' ) { ttout.arr = []; if(dbg && dbg>5) log(`${fn}: static arr init`); }
  48. if( ! isNumber(delay) ) { console.error(`${fn}: delay is not a number: ${delay}`); return; } // isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)
  49. switch (cmd) {
  50. case 'chk': case 'exists': case 'exist':
  51. if( a=ttout.arr.find( (el) => el.label == label ) ) return a; // a.hnd
  52. else return false;
  53. break;
  54. case 'list': showArrQvTyIk();
  55. break;
  56. case 'del': // delete by label from array
  57. case 'delete': delQvTyIk(label);
  58. break;
  59. default: // create new or update existing
  60. case 'new':
  61. case 'set': if( !label ) label=`lbl_${Math.floor(Math.random() * (max - min + 1)) + min}`; // если label пуста, то сгенерировать случайную !!!
  62. delQvTyIk(label); // ищет в массиве существующий таймер, делает ему clear и удаляет его из массива
  63. //log(`creating new: ${label}`);
  64. hnd=setTimeout(() => { func(); }, delay);
  65. b=setTimeout(()=>{ //log(`deleting on TIMEOUT ${label}`);
  66. delQvTyIk(label); }, delay+3); // по истечении таймера удалить его из массива !!!
  67. ttout.arr.push( { label: label, hnd: hnd, hnd2: b, delay: delay } );
  68. break;
  69. } // switch
  70. function showArrQvTyIk() { for( let i in ttout.arr ) log(ttout.arr[i]); console.log('---'); }
  71. function delQvTyIk(ll) { let a=ttout.arr.findIndex( (el) => el.label == ll );
  72. // log(`${fn}: deleting ${ll} at ${a}`);
  73. if(a>=0) { clearTimeout(ttout.arr[a].hnd);
  74. clearTimeout(ttout.arr[a].hnd2);
  75. ttout.arr.splice(a, 1); } // splice here deletes the element!!!
  76. }
  77. } // ttoutSMART()
  78. var tTS=ttoutSMART;
  79.  
  80.  
  81.  
  82. function showMSGsimple (msg, duration, hook, styl) { // one line showmsg () // - hook in querySelector form, i.e. "#smth" or "div[id='smth']"
  83. // looks GOOD and debugged
  84. let aa, mydiv, pareFou, fn=fnName(); // - if msg="" - then mydiv will be removed
  85. let mydivBase="showMSGsimple", mydivTitle="sshowMSGsimple_title"; // - is styl starts with + then add style, if no + then replace mydiv.style
  86. if( !duration ) duration=2000_000; // НЕ переносить в декларацию (... , duration, ...)
  87. if( !hook ) hook=document.body; // НЕ переносить в декларацию (... , hook, ...)
  88. if( hook!=document.body ) pareFou=document.querySelector(hook);
  89. else pareFou=document.body; // log(fn +": hook= ", hook, "\n", "pareFou= ", pareFou);
  90. if( !pareFou ) { log(fn +": hook is not found"); return; }
  91. aa=pareFou.querySelector('#' +mydivBase);
  92. if(aa) { mydiv = aa; if(!msg) { aa?.remove(); return; }
  93. } else { if(!msg) return; // if (msg="" или undefined)
  94. mydiv = document.createElement("div"); if(dbg && dbg>5) log(fn +": append child hook= ", hook, "\n", "pareFou= ", pareFou);
  95. pareFou.insertBefore(mydiv, pareFou.firstChild); //pareFou.appendChild(mydiv); // pareFou.insertBefore(mydiv, pareFou.firstChild);
  96. }
  97. mydiv.innerHTML = msg; // mydiv.style.zIndex=100; // border: solid 5px Red;
  98. mydiv.id=mydivBase; mydiv.title=mydivTitle; // mydiv.style.position="absolute";
  99. if(styl) if( styl.startsWith("+") ) mydiv.style.cssText = `${mydiv.style.cssText} ${styl.replace(/^\+/,'')}`; // trim '+' & add ещ styles
  100. else mydiv.style.cssText = styl; // replace style
  101. setTimeout(() => { if(dbg && dbg>5) log(fn +" removing", mydiv); mydiv?.parentNode?.removeChild(mydiv); }, duration);
  102. } // end of showMSGsimple()
  103.  
  104.  
  105. async function mySaveAs (fname, url, opt1 ) { // WORKS FINE // usage: (async() => { ww=await mySaveAs("filename", "http://abc", ''); })();
  106. if(!opt1) opt1={ suggestedName: fname, types: [ { description: 'Images', accept: { 'image/*': ['.png', '.gif', '.jpeg', '.jpg'] } }, ], };
  107. if(dbg) log("mySaveAs(): " +fname, url, opt1, "---");
  108. // если с opt1 что-то не то, window.showSaveFilePicker молча обламывается
  109. var fhnd = await window.showSaveFilePicker(opt1); if (!fhnd) { log("mySaveAs(): showSaveFilePicker() failed"); return null; }
  110. var wr = await fhnd.createWritable(); if (!wr) { log("mySaveAs(): createWritable() failed"); return null; } // Create a FileSystemWritableFileStream to write to.
  111. var re = await fetch(url); if (!re) { log("mySaveAs(): fetch()"); return null; } // Make an HTTP request for the contents.
  112. await re.body.pipeTo(wr); // Stream the response into the file. // pipeTo() closes the destination pipe by default, no need to close it.
  113. }
  114.  
  115.  
  116. //console.log(DOMRegex(/^service\//)); // your regex here
  117. function DOMRegex(regex) { // try as function and as prototype
  118. let output = [];
  119. for (let i of document.querySelectorAll('*')) {
  120. if (regex.test(i.type)) { // or whatever attribute you want to search
  121. output.push(i);
  122. }
  123. }
  124. return output;
  125. }
  126.  
  127. //getAllTagMatches(/^di/i); // Returns an array of all elements that begin with "di", eg "div"
  128. function getAllTagMatches(regEx) {
  129. return Array.prototype.slice.call(document.querySelectorAll('*')).filter(function (el) {
  130. return el.tagName.match(regEx);
  131. });
  132. }
  133.  
  134. function showmsg578 (msg, duration) {
  135. var dbg=9, fn="showmsg578"; let mydivBase="showmsg", mydivTitle="showmsgCOMMONtitle"; //, myDivN=mydivBase;
  136. let parents=[ mydivBase, "styles_photo__", "body" ]; // 'body' must be ALWAYS present !!!
  137. let pareFou=0, mydiv, aa="n/a", bb="n/a", ddd1, ddd2;
  138. for (let x=0;x<2;x++) {
  139. for (let i of parents) { pareFou=document.querySelector(i); if(pareFou != null) { aa=i; break; }
  140. // потом допилить еще блее красивый поиск
  141. pareFou=document.querySelector(`[class*="${i}"]`); if(pareFou != null) { aa=i; break; }
  142. pareFou=document.getElementById(i); if(pareFou != null) { aa=i; break; } }; if(dbg>5) log(`${fn}(): ${msg}`, ` found parent ${aa} pareFou=`, pareFou);
  143. if (!pareFou) { console.log("showmsg(): can NOT add child to HTML"); return 11; }
  144. if (pareFou.id != mydivBase) { if(dbg>5) log(`${fn}(): creating the anchor DIV !!!: `, aa);
  145. mydiv = document.createElement("div"); mydiv.id=mydivBase; mydiv.style.position="absolute"; mydiv.title=mydivTitle + "_anchor";
  146. bb=pareFou.insertAdjacentElement("afterbegin", mydiv); // new way to appendChild !!! https://www.w3schools.com/jsref/met_node_insertadjacentelement.asp https://stackoverflow.com/questions/2007357/how-to-set-dom-element-as-first-child
  147. }
  148. } // for x
  149.  
  150. mydiv = document.createElement("div"); mydiv.id=mydivBase + Math.floor(Math.random() * 10000); mydiv.style.position="relative";
  151. mydiv.setAttribute("style",`width:auto; height:auto; top:10%; left:5%; padding: 10px; color:Silver; font-size:15px; background-color:#00008B; z-index:99;`); // opacity:0.9; text-shadow: 5px 5px 20px #00FF00;`);
  152. mydiv.innerHTML = `<h2> ${msg} </h2>`; // border: solid 5px Red;
  153. bb=pareFou.appendChild(mydiv); if(dbg>5) log(`${fn}(): ---- new DIV=|${mydiv.id}|`, mydiv.id);
  154. setTimeout(function() { if(pareFou!=null) mydiv.parentNode.removeChild(mydiv); }, duration);
  155.  
  156. if(dbg>5) { log(`${fn}(): ${mydiv.id} appended to ${aa} rc=${bb} <===`);
  157. ddd1 = document.querySelector(mydiv.id); ddd2 = document.getElementById(mydiv.id); log(`${fn}(): check ${mydiv.id} getElementById=${ddd1} querySelector=${ddd2}`); } // !!!!!! и querySelector и getElementById глючат и часто показывают null
  158. return
  159. } // end of showmsg()
  160.  
  161.  
  162.  
  163. function WLH () { let aa=window.location.href; if (aa.match(/accounts.youtube/)) return "accounts.yotube";
  164. return aa.replace(/http.*\/\/(www.)*(.*)\?.*/g,'$2');
  165. }
  166.  
  167. var fnName = getFunctionsNameThatCalledThisFunction; // get name of currently executing function //function gFNTCTF() { return gFNTCTF.caller.name; }
  168. function getFunctionsNameThatCalledThisFunction() { return getFunctionsNameThatCalledThisFunction.caller.name; }
  169.  
  170. var log = console.log;
  171. //var originalLogger = console.log;
  172. // var log = function() { for (var i of arguments) originalLogger(i); } // писать одним аргументом, чтобы вывод был в пределах одного сообщения в логе !!! \n отрабатыват отлично! log("1\n2", "3");
  173.  
  174. function sleepSYNC (millis) { // BLOCK execution of others threads!!! ex.pausecomp
  175. // выполнять блоками по 100-200 мс, чтобы не ставила все раком
  176. let date = new Date(), curDate = null; do { curDate = new Date(); }
  177. while(curDate-date < millis);
  178. }
  179.  
  180. function sleepASYNC (ms) {
  181. return new Promise((resolve) => setTimeout(resolve, ms));
  182. }
  183. const repeatedGreetings = async () => { // one more sleep ASYNC - WORKS !!!
  184. console.log("First"); await sleepASYNC(1000)
  185. console.log("Second"); await sleepASYNC(1000)
  186. console.log("Third"); await sleepASYNC(1000)
  187. } // repeatedGreetings()
  188.  
  189.  
  190. // function sleepQW (durat) { setTimeout(function(){ log("sleepQW()"); },durat); }
  191.  
  192.  
  193. let mySleepInterim = (g) => (...args) => { let f, res = () => f.next(), sleep = (ms) => setTimeout(res, ms); f = g.apply({sleep}, args); f.next(); };
  194. let mySleepExample = mySleepInterim(function*() { // https://developer.mozilla.org/ru/docs/Learn/JavaScript/Asynchronous/Promises
  195. let sl=1200, cnt; let {sleep} = this; // !!! в песочнице работало хорошо
  196. console.log("Sleeping"); yield sleep(sl);
  197. console.log("stage2"); yield sleep(sl);
  198. console.log("stage3"); yield sleep(sl);
  199. console.log("Done");
  200. });
  201. //mySleepExample(); // run step by step with delays // ВРОДЕ РАБОТАЕТ и НЕ жрет проц
  202.  
  203.  
  204. function vsc_font(fntsz="") { // change of Video Speed Controller (VSC) font size
  205. //document.querySelector(".vsc-controller").shadowRoot.styleSheets[0].rules[0].styleSheet.cssRules[0].style.fontSize = '25px';
  206. let font1=document.querySelector(".vsc-controller");
  207. if (fntsz == "") return font1?.shadowRoot?.styleSheets[0]?.rules[0]?.styleSheet?.cssRules[0]?.style?.fontSize;
  208. if (font1?.shadowRoot?.styleSheets[0]?.rules[0]?.styleSheet?.cssRules[0]?.style?.fontSize) {
  209. document.querySelector(".vsc-controller").shadowRoot.styleSheets[0].rules[0].styleSheet.cssRules[0].style.fontSize = fntsz;
  210. if (dbg) console.log("vsc_font(): change " + font1?.shadowRoot?.styleSheets[0]?.rules[0]?.styleSheet?.cssRules[0]?.style?.fontSize + " -> " +fntsz);
  211. return fntsz;
  212. }
  213. else console.error("vsc_font(): .vsc-controller....cssRules[0].style.fontSize is not found")
  214. return 0;
  215. }
  216.  
  217.  
  218. // fu nc tion waitElement(ele) { // rc=1 - FOUND
  219.  
  220.  
  221. function qS (query, elem=document) { return elem.querySelector(query); } // WORKS
  222. //function qSA (que, elem=document) { return elem.querySelectorALL(que); } // FAILs если в que перечислены несколько критериев
  223.  
  224. function queryElement(ele, doc=document) { // еще доделать, чтобы сначала искать указанный doc, а потом в нем искать ele
  225. let aaa=doс?.querySelector(ele); if(dbg>5) log("getEl(): " + aaa); return aaa;
  226. }
  227. //const qS = queryElement;
  228. //const qSA = document.querySelectorAll; // FAILs
  229. //var qs = document.querySelector.bind(document),
  230. var qSA = document.querySelectorAll.bind(document); // WORKS
  231. const getEl = queryElement;
  232. const queryEl = queryElement; // !!! see also https://stackoverflow.com/questions/13383886/making-a-short-alias-for-document-queryselectorall
  233.  
  234. function deleteElement (ele) {
  235. let aaa=document.querySelector(ele); if(aaa) aaa.remove(); if(dbg && dbg>=5) console.log("deleteElement(" +ele+ "): ", aaa);
  236. }
  237.  
  238.  
  239.  
  240. function showmsg (msg, duration=2000, styl="", paren='n/a') { // ``` ёёё
  241. let mydivBase="showmsg", mydivTitle="showmsgCOMMONtitle"; //, myDivN=mydivBase;
  242. let sL1="n/a"; // static label
  243. // let parents=[ mydivBase, "#player", "body > div.container-fluid.inner-pages-banner > div", "body > div.ribbon-container > div", "body > header > div.container.less-margin", "body > div.container-fluid.inner-pages-banner > div"];
  244. // let parents=[ mydivBase, "body > div.mfp-wrap.mfp-gallery.mfp-close-btn-in.mfp-auto-cursor.mfp-fade.mfp-ready > div", "#player", "body > div.container-fluid.inner-pages-banner > div", "body > div.ribbon-container > div", "body > header > div.container.less-margin", "body > div.container-fluid.inner-pages-banner > div"];
  245. // терпимо, но когда картинка на весь экран, то showmsg не видно "body > div.mfp-wrap.mfp-gallery.mfp-close-btn-in.mfp-auto-cursor.mfp-fade.mfp-ready > div"
  246.  
  247. let parents=[ mydivBase, "body > div.mfp-wrap.mfp-gallery.mfp-close-btn-in.mfp-auto-cursor.mfp-fade.mfp-ready > div > div.mfp-content > div > button", "#player", "body > div.container-fluid.inner-pages-banner > div", "body > div.ribbon-container > div", "body > header > div.container.less-margin", "body > div.container-fluid.inner-pages-banner > div"];
  248. let pareFou=0, mydiv, aa="n/a", bb="n/a", ddd1, ddd2;
  249.  
  250. for (let i of parents) { pareFou=document.querySelector(i); if(pareFou != null) { aa=i; break; } // try add id[i]
  251. pareFou=document.getElementById(i); if(pareFou != null) { aa=i; break; }
  252. }; if(dbg>5) log(` showmsg(): ${msg}`, ` found parent ${aa} pareFou=`, pareFou);
  253.  
  254. mydiv = document.createElement("div");
  255. //mydiv.setAttribute("style",`width:auto; top:5%; left:9%; height:auto; color:Silver; font-size: 20px; background-color:black; `); // position & z-index можно и тут прописать
  256. //mydiv.setAttribute("style",`width:800px; top:5%; left:9%; height:auto; color:Silver; font-size: 20px; background-color:black; `); // position & z-index можно и тут прописать
  257. if(styl) mydiv.setAttribute("style",styl);
  258. mydiv.style.zIndex=100;
  259. //mydiv.innerHTML = `<h1> ${msg} </h1>`; // border: solid 5px Red; // padding later // padding: 15px;
  260. mydiv.innerHTML = msg;
  261.  
  262. var qaz=pareFou.id; // qaz=pareFou.title; //log(` qaz=|${qaz}| new DIV=|${mydiv.id}|`);
  263. if(qaz==mydivBase) {
  264. mydiv.id=mydivBase + Math.floor(Math.random() * 10000); mydiv.style.position="relative";
  265. //aa=document.querySelector(`[title='showmsgCOMMONtitle']`);
  266. if(dbg) log("found by title: ", aa);
  267. }
  268. else { mydiv.id=mydivBase; mydiv.style.position="absolute"; mydiv.title=mydivTitle; }
  269. if(dbg>5) log(` ---- new DIV=|${mydiv.id}|`);
  270.  
  271. //log(` ------- cmp qaz==mydivBase ${qaz==mydivBase} ${qaz===mydivBase}`); // ${qaz.localeCompare(mydivBase)}`);
  272. //var zx=new String(qaz); log(zx.length); var zy=new String(mydivBase); log(zy.length); log(zx==zy); log(zx===zy);
  273.  
  274.  
  275. //if ( aa=staticL('chk') ) // cmp ?
  276. // log(`mydivBase= ${aa} already exists=${staticL('get')}`);
  277.  
  278.  
  279. if(pareFou==null) { aa="document.body"; bb=document.body.appendChild(mydiv); }
  280. else bb=pareFou.appendChild(mydiv);
  281.  
  282. setTimeout(function() { //if (mydiv.id=mydivBase) return; // never delete base
  283. if(pareFou!=null) mydiv.parentNode.removeChild(mydiv);
  284. // также восстановить staticLabel
  285. }, duration);
  286.  
  287. if(dbg>5) log(` showmsg(): ${mydiv.id} appended to ${aa} rc=${bb} <===`);
  288. ddd1 = document.querySelector(mydiv.id); ddd2 = document.getElementById(mydiv.id); if(dbg) log(` showmsg(): check ${mydiv.id} getElementById=${ddd1} querySelector=${ddd2}`); // !!!!!! и querySelector и getElementById глючат и часто показывают null
  289. return
  290. } // end of showmsg()
  291.  
  292. function deletemsg() {
  293. let what="showmsg"; let ddd1 = document.querySelector(what); let ddd2 = document.getElementById(what);
  294. if(dbg) log(`hidemsg(): ${what} getElementById=${ddd1} querySelector=${ddd2}`); // querySelector ВСЕГДА показывает null // getElementById - WORKS FINE !!!
  295. if(ddd1!=null) ddd1.parentNode.removeChild(ddd1); if(ddd2!=null) ddd2.parentNode.removeChild(ddd2);
  296. }
  297.  
  298.  
  299.  
  300. function staticL_example () { // !!! for use as static variables // persistent
  301. let aa;
  302. aa=staticL('create', "myLabel13", "cr567"); log(`create: rc=${aa} exists: ${staticL('chk', "myLabel13")} value=${staticL('get', "myLabel13")}`);
  303. aa=staticL('zero', "myLabel13"); log(`zero: rc=${aa} exists: ${staticL('chk', "myLabel13")} value=${staticL('get', "myLabel13")}`);
  304. aa=staticL('update', "myLabel13", "upd755"); log(`update: rc=${aa} exists: ${staticL('chk', "myLabel13")} value=${staticL('get', "myLabel13")}`);
  305. aa=staticL('compare', "myLabel13", "upd444"); log(`compare bad rc=${aa} exists: ${staticL('chk', "myLabel13")} value=${staticL('get', "myLabel13")}`);
  306. aa=staticL('compare', "myLabel13", "upd755"); log(`compare ok rc=${aa} exists: ${staticL('chk', "myLabel13")} value=${staticL('get', "myLabel13")}`);
  307. aa=staticL('wrong', "smr332"); log(`wrong_cmd rc=${aa} exists: ${staticL('chk', "myLabel13")} value=${staticL('get', "myLabel13")}`);
  308. } // end of staticL_example()
  309.  
  310. //function staticL (cmd, staticLabel="sampleStatLabel111", txt="n/a") { // !!! for use as static variables // persistent
  311. // let sLL="n/a", aa, staticLabel="showmsg_static1"
  312. function staticL (cmd, staticLabel="sampleStatLabel111", txt="n/a") { // !!! for use as static variables // persistent
  313. let sLL="n/a", aa; // staticLabel="showmsg_static1"
  314. switch (cmd) {
  315. case 'cr': case 'create': sLL=queryL(); // usage: aa=staticL('cr|create', "myLabel13", "init123"); log(`create: rc=${aa} exists: ${staticL('chk')} value=${staticL('get')}`);
  316. if(sLL == null) { sLL=document.createElement("LABEL"); sLL.htmlFor=staticLabel;
  317. document.body.appendChild(sLL); sLL.setAttribute("display","none"); }
  318. sLL.innerText=txt;
  319. return true; break;
  320. case 'get': // usage: aa=staticL('get', "myLabel13"); log(`get: rc=${aa} exists: ${staticL('chk')} value=${staticL('get')}`);
  321. sLL=queryL(); if(sLL == null) return null;
  322. return sLL.innerText; break;
  323. case 'zero': case 'reset': case 'upd': case 'update': // usage: aa=staticL('zero|reset', "myLabel13"); log(`zero: rc=${aa} exists: ${staticL('chk')} value=${staticL('get')}`);
  324. // usage: aa=staticL('upd|update', "myLabel13", "upd555") ; log(`update: rc=${aa} exists: ${staticL('chk')} value=${staticL('get')}`);
  325. sLL=queryL(); if(sLL == null) return null;
  326. (cmd=="zero" || cmd=="reset") ? sLL.innerText="" : sLL.innerText=txt;
  327. return true; break;
  328. case 'cmp': case 'compare': // usage: aa=staticL('cmp|compare', "myLabel13", "upd555"); log(`compare rc=${aa} exists: ${staticL('chk')} value=${staticL('get')}`);
  329. sLL=queryL(); if(sLL.innerText != txt) return null;
  330. return true; break;
  331. case 'chk': case 'exist': case 'check': // usage: aa=staticL('chk|exist|check', "myLabel13"); log(`check rc=${aa} exists: ${staticL('chk')} value=${staticL('get')}`);
  332. if (queryL()) return true; else return null;
  333. break;
  334. default: log("staticL(): bad cmd=" + cmd); // usage: aa=staticL('wrong', "smr332"); log(`wrong_cmd rc=${aa} exists: ${staticL('chk')} value=${staticL('get')}`);
  335. return null; break;
  336. }
  337. function queryL() { return document.querySelector( `label[for=${staticLabel}]` ); }
  338. } // end of staticL()
  339.  
  340.  
  341. function isNumber(n){
  342. return Number(n)=== n;
  343. // see also function isNumber(val) { return !isNaN(val); }
  344. // // https://stackoverflow.com/questions/18082/validate-decimal-numbers-in-javascript-isnumeric
  345. // // https://stackoverflow.com/questions/20169217/how-to-write-isnumber-in-javascript
  346. //test
  347. // [0, 1, 2, -1, 1.345e+17, Infinity, false, true, NaN, '1', '0'].map(function(itm){ return itm+'= '+isNumber(itm); });
  348. } // isNumber()
  349.  
  350. function TrustedHTMLworkaround () {
  351. if (window.trustedTypes && window.trustedTypes.createPolicy) {
  352. window.trustedTypes.createPolicy('default', { createHTML: (string, sink) => string });
  353. }
  354. } // TrustedHTMLworkaround()
  355.  
  356. function TrustedHTMLworkaround2 () {
  357. // WORKAROUND: TypeError: Failed to set the 'innerHTML' property on 'Element': This document requires 'TrustedHTML' assignment.
  358. if (window.trustedTypes) {
  359. if (!window.trustedTypes.defaultPolicy) {
  360. const passThroughFn = (x) => x;
  361. window.trustedTypes.createPolicy('default', {
  362. createHTML: passThroughFn,
  363. createScriptURL: passThroughFn,
  364. createScript: passThroughFn,
  365. });
  366. }
  367. }
  368. } // TrustedHTMLworkaround2()

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址