TSLibrary - Generic

A resource JS library file providing common useful functions to be used by other scripts

当前为 2017-04-18 提交的版本,查看 最新版本

此脚本不应直接安装,它是供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.cn-greasyfork.org/scripts/19968/189000/TSLibrary%20-%20Generic.js

  1. // ==UserScript==
  2. // @name TSLibrary - Generic
  3. // @namespace TimidScript
  4. // @version 1.0.23
  5. // @description A resource JS library file providing common useful functions to be used by other scripts
  6. // @author TimidScript
  7. // @homepageURL https://github.com/TimidScript
  8. // @copyright © 2014+ TimidScript, Some Rights Reserved.
  9. // @license https://github.com/TimidScript/UserScripts/blob/master/license.txt
  10. // @exclude *
  11. // ==/UserScript==
  12.  
  13.  
  14. /* License + Copyright Notice
  15. ********************************************************************************************
  16. License can be found at: https://github.com/TimidScript/UserScripts/blob/master/license.txt
  17. Below is a copy of the license the may not be up-to-date.
  18.  
  19. Copyright © TimidScript, Some Rights Reserved.
  20.  
  21. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
  22. following conditions are met:
  23.  
  24. 1) GPL-3 License is met that does not conflict with the rest of the license (http://www.gnu.org/licenses/gpl-3.0.en.html)
  25. 2) This notice must be included
  26. 3) Due credits and link to original author's homepage (included in this notice).
  27. 4) Notify the original author of redistribution
  28. 5) Clear clarification of the License and Notice to the end user
  29. 6) Do not upload on OpenUserJS.org or any other site that infringes on this license
  30.  
  31. TimidScript's Homepages: GitHub: https://github.com/TimidScript
  32. GreasyFork: https://greasyfork.org/users/1455
  33. */
  34. /* Information
  35. ********************************************************************************************
  36. Version History
  37. ----------------------------------------------
  38. 1.0.23 (2017-03-09)
  39. - Added randomNumber generator
  40. 1.0.22 (2017-02-25)
  41. - CRC32 added
  42. 1.0.21 (2017-02-12)
  43. - BugFix: TSL.padNumber
  44. - Added simple checksum
  45. 1.0.20 (2017-02-02)
  46. - Added GM_xmlhttpRequest Library
  47. 1.0.19 (2016-10-29)
  48. - CSS Styles are places in same position if they exists, to not break the page's style precedence. Did the same for javascript.
  49. 1.0.18 (2016-05-27)
  50. - License altered
  51. 1.0.17 (2016-04-03)
  52. - Changed license to GPL-3
  53. 1.0.16 (2015-07-20)
  54. - addScript and addStyle return created nodes
  55. - Change location of addScript to head instead of body incase of dynamic pages that alter the body
  56. 1.0.15 (2015-06-18)
  57. - updateDocumentURL renamed to updateURL
  58. 1.0.14 (2015-06-18)
  59. - Using \b for regex in class functions
  60. - Better handling of spaces in the class functions
  61. 1.0.13 (2015-01-16)
  62. - updateDocumentURL added
  63. 1.0.12 (2014-12-12)
  64. - @exclude added
  65. 1.0.11 (2014-10-12)
  66. - innerHTML instead of textContent for scripts and CSS.
  67. 1.0.10 (2014-09-17)
  68. - Optimised - When adding or removing a class it now first checks
  69. it exists thus avoiding to make any extra changes.
  70. - Ability to add or remove more than one class. Separator is space.
  71. - hasClass also handles more than one class. Returns true only
  72. if all classes are present.
  73. - addClass, removeClass return true if class is added or removed
  74. 1.0.9 (2014-09-07)
  75. - Fixed bug in addScript and moved the script to the head instead of body.
  76. - CSS appended to textContent instead of innerHTML
  77. 1.0.8 (2014-09-05)
  78. - Improved removeClass
  79. - Added absolutePosition(element)
  80. 1.0.7 (2014-09-02)
  81. - Functions added: addClass removeClass hasClass
  82. - Removed makeStruct as it is useless
  83. 1.0.6 (2014-08-29)
  84. - Changed the NTFS chars http://unicode-search.net
  85. 1.0.5 (2014-08-24)
  86. - TSL part no longer commented out
  87. 1.0.4
  88. - Added new functions createElement, createElementHTML function
  89. - Partial support for non-main document
  90. 1.0.3
  91. - Added NTFS illegal character replacer
  92. - escape regular expression function
  93. 1.0.2
  94. - Added scroll bar thickness
  95. 1.0.1
  96. - Initial Release
  97. **********************************************************************************************/
  98.  
  99.  
  100. var TimidScriptLibrary =
  101. {
  102. //http://unicode-search.net
  103. altNTFSChars: [[">", ">"],
  104. ["<", "<"],
  105. [":", ":"],
  106. ['"', """],
  107. ["/", "/"],
  108. ["\\", "\"],
  109. ["?", "?"],
  110. ["*", "*"]],
  111.  
  112. removeNode: function (node, doc)
  113. {
  114. if (!doc) doc = document;
  115. if (typeof node == "string") node = doc.getElementById(node);
  116. if (node && node.parentElement) node.parentElement.removeChild(node);
  117. },
  118.  
  119. addStyle: function (id, CSS, doc)
  120. {
  121. if (!doc) doc = document;
  122. var el = doc.createElement("style");
  123.  
  124. if (id && doc.getElementById(id)) el = doc.getElementById(id);
  125. else doc.head.appendChild(el);
  126.  
  127. if (id) el.id = id;
  128. el.type = "text/css";
  129. el.innerHTML = CSS;
  130.  
  131. return el;
  132. },
  133.  
  134. addScript: function (id, text, doc)
  135. {
  136. if (!doc) doc = document;
  137. var el = doc.createElement("script");
  138.  
  139. if (id && doc.getElementById(id)) el = doc.getElementById(id);
  140. else doc.head.appendChild(el);
  141.  
  142. if (id) el.id = id;
  143. el.innerHTML = text;
  144. return el;
  145. },
  146.  
  147. createElement: function (tag, attributes, doc)
  148. {
  149. if (!doc) doc = document;
  150. var el = doc.createElement(tag);
  151.  
  152. for (var x in attributes) el.setAttribute(x, attributes[x]);
  153. return el;
  154. },
  155.  
  156. createElementHTML: function (html, doc)
  157. {
  158. if (!doc) doc = document;
  159. var el = doc.createElement("e");
  160.  
  161. el.innerHTML = html;
  162. return el.firstElementChild;
  163. },
  164.  
  165. paddingLeft: function (str, chr, length)
  166. {
  167. while (str.length < length)
  168. str = chr + str;
  169.  
  170. return str;
  171. },
  172.  
  173. paddingRight: function (str, chr, length)
  174. {
  175. while (str.length < length)
  176. str = str + chr;
  177.  
  178. return str;
  179. },
  180.  
  181. padNumber: function (number, length)
  182. {
  183. //return TimidScriptLibrary.paddingLeft(number, "0", length);
  184. var padding = Array(length + 1).join("0");
  185. return (padding + number).slice(0 - length);
  186. },
  187.  
  188. isMouseEventInClientArea: function (event, element)
  189. {
  190. var rect = element.getBoundingClientRect();
  191. var minX = rect.left + element.clientLeft;
  192.  
  193. var x = event.clientX;
  194. if (x < minX || x >= minX + element.clientWidth) return false;
  195. var minY = rect.top + element.clientTop;
  196. var y = event.clientY;
  197. if (y < minY || y >= minY + element.clientHeight) return false;
  198. return true;
  199. },
  200.  
  201.  
  202. getScrollBarThickness: function ()
  203. {
  204. var outer = document.createElement("div");
  205. outer.style.visibility = "hidden";
  206. outer.style.width = "100px";
  207. document.body.appendChild(outer);
  208.  
  209. var widthNoScroll = outer.offsetWidth;
  210. // force scrollbars
  211. outer.style.overflow = "scroll";
  212.  
  213. // add innerdiv
  214. var inner = document.createElement("div");
  215. inner.style.width = "100%";
  216. outer.appendChild(inner);
  217.  
  218. var widthWithScroll = inner.offsetWidth;
  219.  
  220. // remove divs
  221. outer.parentNode.removeChild(outer);
  222.  
  223. return widthNoScroll - widthWithScroll;
  224. },
  225.  
  226.  
  227. escapeRegExp: function (str)
  228. {
  229. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions
  230. return str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
  231. },
  232.  
  233. replaceNTFSIllegals: function (str)
  234. {
  235. for (var i = 0; i < TimidScriptLibrary.altNTFSChars.length; i++)
  236. {
  237. var rx = new RegExp(TimidScriptLibrary.escapeRegExp(TimidScriptLibrary.altNTFSChars[i][0]), "gi");
  238. str = str.replace(rx, TimidScriptLibrary.altNTFSChars[i][1]);
  239. }
  240.  
  241. return str;
  242. },
  243.  
  244. addClass: function (node, names)
  245. {
  246. var altered = false;
  247. var newclass = node.className;
  248. var classes = names.replace(/\s+/g, " ").trim().split(" ");
  249.  
  250. for (var i = 0; i < classes.length; i++)
  251. {
  252. //var re = new RegExp("(^|\\s+)" + classes[i] + "(\\s+|$)");
  253. var re = new RegExp("\\b" + classes[i] + "\\b");
  254. if (!newclass.match(re))
  255. {
  256. newclass += " " + classes[i];
  257. altered = true;
  258. }
  259. }
  260.  
  261. if (altered) node.className = newclass.replace(/\s+/g, " ").trim();
  262. return altered;
  263. },
  264.  
  265. removeClass: function (node, names)
  266. {
  267. var altered = false;
  268. var newclass = node.className;
  269. var classes = names.replace(/(\s)\s+/g, " ").trim().split(" ");
  270.  
  271. for (var i = 0; i < classes.length; i++)
  272. {
  273. //var re = new RegExp("(^|\\s+)" + classes[i] + "(\\s+|$)");
  274. var re = new RegExp("\\b" + classes[i] + "\\b");
  275. if (newclass.match(re))
  276. {
  277. newclass = newclass.replace(re, " ");
  278. altered = true;
  279. }
  280. }
  281.  
  282. if (altered) node.className = newclass.replace(/\s+/g, " ").trim();
  283. return altered;
  284. },
  285.  
  286. hasClass: function (node, names)
  287. {
  288. var classes = names.replace(/(\s)\s+/g, " ").trim().split(" ");
  289. for (var i = 0; i < classes.length; i++)
  290. {
  291. //var re = new RegExp("(^|\\s+)" + classes[i] + "(\\s+|$)");
  292. var re = new RegExp("\\b" + classes[i] + "\\b");
  293. if (!node.className.match(re)) return false;
  294. }
  295.  
  296. return true;
  297. },
  298.  
  299. getAbsolutePosition: function (element)
  300. {
  301. var x = 0;
  302. var y = 0;
  303.  
  304. while (element && !isNaN(element.offsetLeft) && !isNaN(element.offsetTop))
  305. {
  306. x += element.offsetLeft;
  307. y += element.offsetTop;
  308. element = element.offsetParent;
  309. }
  310. return { top: y, left: x };
  311. },
  312.  
  313. updateURL: function (url)
  314. {
  315. window.history.pushState(null, "", url);
  316. },
  317.  
  318. makeCRCTable: function ()
  319. {
  320. //Code from http://stackoverflow.com/questions/18638900/javascript-crc32
  321. var c;
  322. var crcTable = [];
  323. for (var n = 0; n < 256; n++)
  324. {
  325. c = n;
  326. for (var k = 0; k < 8; k++)
  327. {
  328. c = ((c & 1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1));
  329. }
  330. crcTable[n] = c;
  331. }
  332. return crcTable;
  333. },
  334.  
  335. crc32: function (str)
  336. {
  337. //Code from http://stackoverflow.com/questions/18638900/javascript-crc32
  338. var crcTable = unsafeWindow.crcTable || (unsafeWindow.crcTable = TimidScriptLibrary.makeCRCTable());
  339. var crc = 0 ^ (-1);
  340.  
  341. for (var i = 0; i < str.length; i++)
  342. {
  343. crc = (crc >>> 8) ^ crcTable[(crc ^ str.charCodeAt(i)) & 0xFF];
  344. }
  345.  
  346. return ((crc ^ (-1)) >>> 0).toString(16);
  347. },
  348.  
  349. randomNumber: function(min, max)
  350. {
  351. min = parseInt(min);
  352. max = parseInt(max);
  353. return Math.floor(Math.random() * (max - min + 1) + min);
  354. }
  355. };
  356.  
  357.  
  358. var tsXHR =
  359. {
  360. timeout: 15000,
  361.  
  362. /* callback(state, response)
  363. state = 0 ---> success
  364. state = 1 ---> Fail most likely a 404
  365. state = 2 ---> Timeout
  366. state = 3 ---> Error
  367. -------------------------------------------------------------------*/
  368. send: function (method, callback, url, headers, data, timeout)
  369. {
  370. //console.log(method, "\r\n", url, "\r\n", headers, "\r\n", data);
  371.  
  372. if (!headers) headers = {};
  373.  
  374. var obj = {
  375. url: url,
  376. method: method,
  377. timeout: timeout,
  378. headers: headers,
  379. onload: function (response)
  380. {
  381. if (response.status == 200)
  382. {
  383. //console.log("tsXHR: Success " + response.status + " (" + url + ")");
  384. callback(0, response);
  385. }
  386. else
  387. {
  388. console.error("tsXHR: Fail " + response.status + " (" + url + ")");
  389. console.info(response);
  390. callback(1, response);
  391. }
  392. },
  393. ontimeout: function (response)
  394. {
  395. console.error("tsXHR: Timeout" + response.status + " (" + url + ")");
  396. console.info(response);
  397. callback(2, response);
  398. },
  399. onerror: function (response)
  400. {
  401. console.error("tsXHR: ERROR " + response.status + " (" + url + ")");
  402. console.info(response);
  403. callback(3, response);
  404. }
  405. };
  406.  
  407. if (data) obj.data = data;
  408.  
  409. GM_xmlhttpRequest(obj);
  410. },
  411.  
  412. /* callback(success, response) success true / false
  413. -------------------------------------------------------------------*/
  414. sendX: function (method, callback, url, headers, data, timeout)
  415. {
  416. tsXHR.send(method, cb, url, headers, data, timeout);
  417.  
  418. function cb(state, response)
  419. {
  420. callback(state == 0, response);
  421. }
  422. },
  423.  
  424. createHeaders: function (referer, accept, userAgent, contentType, authorization)
  425. {
  426. var headers = {};
  427. setHeader("User-Agent", userAgent);
  428. setHeader("Accept", accept);
  429. setHeader("Referer", referer);
  430. setHeader("Content-Type", contentType);
  431. setHeader("Authorization", authorization);
  432.  
  433. return headers;
  434. function setHeader(name, val)
  435. {
  436. if (val != null && val != undefined) headers[name] = referer;
  437. }
  438. },
  439.  
  440. /* callback(success, response)
  441. -------------------------------------------------------------------*/
  442. get: function (callback, url, headers, timeout)
  443. {
  444. tsXHR.sendX("GET", callback, url, headers, null, timeout);
  445. },
  446.  
  447. /* callback(success, response)
  448. -------------------------------------------------------------------*/
  449. head: function (callback, url, headers, timeout)
  450. {
  451. tsXHR.sendX("GET", callback, url, headers, null, timeout);
  452. },
  453.  
  454. /* callback(success, response)
  455. -------------------------------------------------------------------*/
  456. post: function (callback, url, headers, data, timeout)
  457. {
  458. tsXHR.sendX("POST", callback, url, headers, data, timeout);
  459. }
  460. };
  461.  
  462.  
  463. /*
  464. Copy and paste the code underneath into your script for quick reference
  465. and auto-complete feature if available.*/
  466. //*********************************************************************************
  467. //#region //---------------- TimidScript Library Functions
  468.  
  469. var TSL = new Object();
  470.  
  471. //Remove node from document. Accepts id or node object
  472. TSL.removeNode = function (node, doc) { TimidScriptLibrary.removeNode(node, doc); };
  473. // Creates document element. Default doc value is the document.
  474. TSL.createElement = function (tag, attributes, doc) { return TimidScriptLibrary.createElement(tag, attributes, doc) };
  475. // Creates document element using html code. Default doc value is the document.
  476. TSL.createElementHTML = function (html, doc) { return TimidScriptLibrary.createElementHTML(html, doc) };
  477. //Returns the thickness of the scrollbar
  478. TSL.getScrollBarThickness = function () { return TimidScriptLibrary.getScrollBarThickness(); };
  479.  
  480. //Add CSS styles to document header. Document can be left empty.
  481. TSL.addStyle = function (id, CSS, doc) { return TimidScriptLibrary.addStyle(id, CSS, doc); };
  482. //Add JS script to document header. Document can be left empty.
  483. TSL.addScript = function (id, script, doc) { return TimidScriptLibrary.addScript(id, script, doc); };
  484.  
  485. // Checks if mouse event is within an elements client area
  486. TSL.isMouseEventInClientArea = function (event, element) { return TimidScriptLibrary.isMouseEventInClientArea(event, element); };
  487. // Gets the position of the element within the document
  488. TSL.getAbsolutePosition = function (element) { return TimidScriptLibrary.getAbsolutePosition(element); };
  489.  
  490. //Array containing NTFS illegal characters alternatives
  491. TSL.altNTFSChars = TimidScriptLibrary.altNTFSChars;
  492. TSL.replaceNTFSIllegals = function (str) { return TimidScriptLibrary.replaceNTFSIllegals(str); };
  493. //Escape Regular expression string
  494. TSL.escapeRegExp = function (str) { return TimidScriptLibrary.escapeRegExp(str); };
  495.  
  496. //Node className functions. All three functions can handle multiple classes separated by spaces
  497. TSL.addClass = function (node, names) { return TimidScriptLibrary.addClass(node, names); };
  498. TSL.removeClass = function (node, names) { return TimidScriptLibrary.removeClass(node, names); };
  499. TSL.hasClass = function (node, names) { return TimidScriptLibrary.hasClass(node, names); };
  500.  
  501. //Allows you to change the document URL, which is reflected in the URL bar.
  502. TSL.updateURL = function (url) { TimidScriptLibrary.updateURL(url); };
  503.  
  504. //Pad a number with zeros
  505. TSL.padNumber = function (number, length) { return TimidScriptLibrary.padNumber(number, length); };
  506. //Random Whole Number Generator
  507. TSL.randomNumber = function (min, max) { min = parseInt(min); max = parseInt(max); return Math.floor(Math.random() * (max - min + 1) + min); };
  508.  
  509. //Simple string hashing crc32
  510. TSL.crc32 = function (str) { return TimidScriptLibrary.crc32(str);}
  511.  
  512. //String Padding
  513. String.prototype.lPad = function (chr, length) { return TimidScriptLibrary.paddingLeft(this, chr[0], length); };
  514. String.prototype.rPad = function (chr, length) { return TimidScriptLibrary.paddingRight(this, chr[0], length); };
  515.  
  516.  
  517. var XHR = new Object();
  518. // Default value is 10000ms
  519. XHR.timeout = tsXHR.timeout;
  520. // callback(state, response) --- state: 0 = success | 1 = Fail | 2 = Timeout | 3 = Error
  521. XHR.send = function (method, callback, url, headers, data, timeout) { tsXHR.send(method, callback, url, headers, data, timeout); };
  522. // callback(success, response) --- state: 0 = success | 1 = Fail | 2 = Timeout | 3 = Error
  523. XHR.sendX = function (method, callback, url, headers, data, timeout) { tsXHR.sendX(method, callback, url, headers, data, timeout); };
  524. // callback(success, response)
  525. XHR.createHeaders = function (referer, accept, userAgent, contentType, authorization) { tsXHR.createHeaders(referer, accept, userAgent, contentType, authorization) };
  526. // callback(success, response)
  527. XHR.get = function (callback, url, headers, timeout) { tsXHR.get(callback, url, headers, timeout) };
  528. // callback(success, response)
  529. XHR.head = function (callback, url, headers, timeout) { tsXHR.head(callback, url, headers, timeout) };
  530. // callback(success, response)
  531. XHR.post = function (callback, url, headers, data, timeout) { tsXHR.post(callback, url, headers, data, timeout) };
  532. //#endregion
  533. //*********************************************************************************