LateLog - Simple storage-based Log Library

Simple library to log to the storage, granting the possibility of viewing the log after the URL changes

此腳本不應該直接安裝,它是一個供其他腳本使用的函式庫。欲使用本函式庫,請在腳本 metadata 寫上: // @require https://update.gf.qytechs.cn/scripts/461057/1156386/LateLog%20-%20Simple%20storage-based%20Log%20Library.js

  1. // ==UserScript==
  2. // @name LateLog - Simple storage-based Log Library
  3. // @namespace satology.latelog
  4. // @version 0.2
  5. // @description Simple library to log to the storage, granting the possibility of viewing the log after the URL changes
  6. // @author satology
  7. // @grant GM_getValue
  8. // @grant GM_setValue
  9. // @grant GM_registerMenuCommand
  10. // ==/UserScript==
  11.  
  12. var LateLog = (function() {
  13. 'use strict';
  14. const latelog_getDateTimeString = (date = new Date()) => `${('' + date.getUTCFullYear()).slice(-2)}-${('0' + date.getUTCMonth()).slice(-2)}-${('0' + date.getUTCDate()).slice(-2)} ${('0' + date.getUTCHours()).slice(-2)}:${('0' + date.getUTCMinutes()).slice(-2)}:${('0' + date.getUTCSeconds()).slice(-2)}`;
  15.  
  16. class Storage {
  17. constructor(prefix = '', config = {}) {
  18. this.prefix = prefix;
  19. this.config = config;
  20. }
  21.  
  22. write(key, value, parseIt = false) {
  23. GM_setValue(this.prefix + key, parseIt ? JSON.stringify(value) : value);
  24. }
  25.  
  26. read(key, parseIt = false) {
  27. let value = GM_getValue(this.prefix + key);
  28. if(value && parseIt) {
  29. value = JSON.parse(value);
  30. }
  31. return value;
  32. }
  33. }
  34.  
  35. class LateLog {
  36. constructor(options = {}) {
  37. if(!this._isValidSetup(options)) return;
  38. this.storage = new Storage();
  39. this.options = {
  40. level: 5,
  41. maxLines: 200,
  42. addTimestamp: true,
  43. printWhileLogging: false,
  44. // showDisplayButton: true,
  45. ...options
  46. };
  47. this._init();
  48. }
  49.  
  50. _isValidSetup(options) {
  51. if(! (typeof GM_getValue === "function" &&
  52. typeof GM_setValue === "function" &&
  53. typeof GM_registerMenuCommand === "function") ) {
  54. console.warn(
  55. `LateLog cannot be initialized - At least one off the following @grant is missing in your script:
  56. @grant GM_getValue
  57. @grant GM_setValue
  58. @grant GM_registerMenuCommand`);
  59. return false;
  60. }
  61. // TODO: validate options
  62. return true;
  63. }
  64.  
  65. _init() {
  66. let that = this;
  67. GM_registerMenuCommand('View log', function(evt) {
  68. console.log('Printing LateLog');
  69. that.display();
  70. });
  71. return true;
  72. }
  73.  
  74. _write(msg, msgLevel = 1) {
  75. if (this.options.level < msgLevel) {
  76. return;
  77. }
  78.  
  79. let log = this.storage.read('log', true);
  80. log = log ? log : [];
  81.  
  82. if (msg === null) {
  83. msg = 'null';
  84. }
  85. if (msg === undefined) {
  86. msg = 'undefined';
  87. }
  88.  
  89. let savable = {
  90. lvl: msgLevel
  91. };
  92. if (this.options.addTimestamp) {
  93. savable.ts = `${latelog_getDateTimeString()}`;
  94. }
  95. if (msg instanceof Error) {
  96. savable.msg = msg.toString();
  97. } else if (typeof(msg) == 'object') {
  98. savable.msg = JSON.stringify(msg);
  99. savable.parse = true;
  100. } else {
  101. savable.msg = msg;
  102. }
  103. log.push(savable);
  104.  
  105. if(log.length > this.options.maxLines) {
  106. log.splice(0, log.length - this.options.maxLines);
  107. }
  108.  
  109. this.storage.write('log', log, true);
  110. this._formatPrint(savable);
  111. }
  112.  
  113. _getPrintFn(level) {
  114. switch(level) {
  115. case 1:
  116. return console.log;
  117. case 2:
  118. return console.info;
  119. case 3:
  120. return console.debug;
  121. case 4:
  122. return console.warn;
  123. case 5:
  124. return console.error;
  125. default:
  126. return console.log;
  127. }
  128. }
  129.  
  130. _formatPrint(x) {
  131. if (x.parse) {
  132. try {
  133. x.msg = JSON.parse(x.msg);
  134. } catch (err) {}
  135. if (this.options.addTimestamp) {
  136. this._getPrintFn(x.lvl)(`${x.ts}:`);
  137. }
  138. this._getPrintFn(x.lvl)(x.msg);
  139. } else {
  140. this._getPrintFn(x.lvl)(`${this.options.addTimestamp ? x.ts + ' ' : ''} ${x.msg}`);
  141. }
  142. }
  143.  
  144. clear() { this.storage.write('log', [], true); }
  145.  
  146. display() {
  147. let log = this.storage.read('log', true);
  148. if(!log) {
  149. console.log('LateLog - Nothing to show')
  150. return;
  151. }
  152.  
  153. log.forEach(x => {
  154. this._formatPrint(x);
  155. });
  156. }
  157.  
  158. log(msg) { this._write(msg, 1); }
  159.  
  160. info(msg) { this._write(msg, 2); }
  161.  
  162. debug(msg) { this._write(msg, 3); }
  163.  
  164. warn(msg) { this._write(msg, 4); }
  165.  
  166. error(msg) { this._write(msg, 5); }
  167. }
  168. return LateLog;
  169. })();

QingJ © 2025

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