kiv-lib

Helper functions

As of 2023-11-04. See the latest version.

This script should not be not be installed directly. It is a library for other scripts to include with the meta directive // @require https://update.greatest.deepsurf.us/scripts/477604/1275312/kiv-lib.js

  1. const waitFor = (target, selector) => {
  2. return new Promise(resolve => {
  3. if (target.querySelector(selector)) {
  4. return resolve(target.querySelector(selector));
  5. }
  6. const observer = new MutationObserver(mutations => {
  7. if (target.querySelector(selector)) {
  8. resolve(target.querySelector(selector));
  9. observer.disconnect();
  10. }
  11. });
  12. observer.observe(document.body, {
  13. childList: true,
  14. subtree: true
  15. });
  16. });
  17. };
  18.  
  19. const gmGet = async (url, cacheKey, cacheDuration) => {
  20.  
  21. if (cacheKey) {
  22. cacheDuration = (cacheDuration == undefined) ? 604800 * 1000 : cacheDuration;
  23. const cachedData = localStorage.getItem(cacheKey);
  24. const cachedTimestamp = parseInt(localStorage.getItem(cacheKey + "_timestamp"));
  25. const cachedSince = (Date.now() - cachedTimestamp)
  26. if (cachedData && cachedTimestamp && cachedSince < cacheDuration) {
  27. console.log(`[gmGet] get cached key ${cacheKey} (${cachedSince / 1000}s < ${cacheDuration / 1000}s)`)
  28. return JSON.parse(cachedData);
  29. }
  30. }
  31.  
  32. return new Promise((resolve, reject) => {
  33. GM.xmlHttpRequest({
  34. url,
  35. method: "GET",
  36. onload: (response) => {
  37. resolve(new Response(response.response, { statusText: response.statusText, status: response.status }));
  38. },
  39. onerror: (error) => {
  40. reject(error);
  41. }
  42. });
  43. })
  44. .catch((error) => {
  45. throw { message: "critical error", code: error.status };
  46. })
  47. .then((response) => {
  48. const result = response.json();
  49. return result.then((body) => {
  50. if (typeof body.error == 'undefined') {
  51. if (cacheKey) {
  52. localStorage.setItem(cacheKey, JSON.stringify(body));
  53. localStorage.setItem(cacheKey + "_timestamp", Date.now());
  54. }
  55. return body;
  56. } else {
  57. throw { message: body.error.error, code: body.error.code };
  58. }
  59. });
  60. });
  61. };
  62.  
  63. function floatFormat(num, digits) {
  64. const lookup = [
  65. { value: 1, symbol: "" },
  66. { value: 1e3, symbol: "k" },
  67. { value: 1e6, symbol: "m" },
  68. { value: 1e9, symbol: "b" },
  69. { value: 1e12, symbol: "t" },
  70. { value: 1e15, symbol: "q" }
  71. ];
  72. const rx = /\.0+$|(\.[0-9]*[1-9])0+$/;
  73. var item = lookup.slice().reverse().find(function (item) {
  74. return num >= item.value;
  75. });
  76. return item ? (num / item.value).toPrecision(digits).replace(rx, "$1") + item.symbol : "0";
  77. }