移动页面的阅读模式

只是希望能够稍微提高一点在移动端的阅读体验。

  1. // ==UserScript==
  2. // @name 移动页面的阅读模式
  3. // @namespace Reading_mode_for_mobile_CN
  4. // @version 0.0.6beta
  5. // @description 只是希望能够稍微提高一点在移动端的阅读体验。
  6. // @author 稻米鼠
  7. // @run-at document-start
  8. // @icon https://i.v2ex.co/L00DUOAOl.png
  9. // @contributionURL https://script.izyx.xyz/reading-mode-for-mobile/
  10. // @require https://cdn.bootcdn.net/ajax/libs/highlight.js/11.0.0-alpha0/highlight.min.js
  11. // @noframes
  12. // @antifeature payment
  13. // @match *://www.jianshu.com/p/*
  14. // @match *://www.zhihu.com/question/*
  15. // @match *://zhuanlan.zhihu.com/p/*
  16. // @grant none
  17. // ==/UserScript==
  18.  
  19.  
  20. (() => {
  21. "use strict";
  22. var e = {
  23. 863: (e, t, o) => {
  24. o.d(t, {
  25. Z: () => l
  26. });
  27. var r = o(645);
  28. var n = o.n(r);
  29. var i = n()((function(e) {
  30. return e[1];
  31. }));
  32. i.push([ e.id, "/*\n\nAtom One Dark by Daniel Gamage\nOriginal One Dark Syntax theme from https://github.com/atom/one-dark-syntax\n\nbase: #282c34\nmono-1: #abb2bf\nmono-2: #818896\nmono-3: #5c6370\nhue-1: #56b6c2\nhue-2: #61aeee\nhue-3: #c678dd\nhue-4: #98c379\nhue-5: #e06c75\nhue-5-2: #be5046\nhue-6: #d19a66\nhue-6-2: #e6c07b\n\n*/\n\n.hljs {\n display: block;\n overflow-x: auto;\n padding: 0.5em;\n color: #abb2bf;\n background: #282c34;\n}\n\n.hljs-comment,\n.hljs-quote {\n color: #5c6370;\n font-style: italic;\n}\n\n.hljs-doctag,\n.hljs-keyword,\n.hljs-formula {\n color: #c678dd;\n}\n\n.hljs-section,\n.hljs-name,\n.hljs-selector-tag,\n.hljs-deletion,\n.hljs-subst {\n color: #e06c75;\n}\n\n.hljs-literal {\n color: #56b6c2;\n}\n\n.hljs-string,\n.hljs-regexp,\n.hljs-addition,\n.hljs-attribute,\n.hljs-meta-string {\n color: #98c379;\n}\n\n.hljs-built_in,\n.hljs-class .hljs-title {\n color: #e6c07b;\n}\n\n.hljs-attr,\n.hljs-variable,\n.hljs-template-variable,\n.hljs-type,\n.hljs-selector-class,\n.hljs-selector-attr,\n.hljs-selector-pseudo,\n.hljs-number {\n color: #d19a66;\n}\n\n.hljs-symbol,\n.hljs-bullet,\n.hljs-link,\n.hljs-meta,\n.hljs-selector-id,\n.hljs-title {\n color: #61aeee;\n}\n\n.hljs-emphasis {\n font-style: italic;\n}\n\n.hljs-strong {\n font-weight: bold;\n}\n\n.hljs-link {\n text-decoration: underline;\n}\n", "" ]);
  33. const l = i;
  34. },
  35. 152: (e, t, o) => {
  36. o.d(t, {
  37. Z: () => l
  38. });
  39. var r = o(645);
  40. var n = o.n(r);
  41. var i = n()((function(e) {
  42. return e[1];
  43. }));
  44. i.push([ e.id, '.rmfm-body-hidden{display:none !important}#reading-mode-for-mobile{position:fixed;top:0;left:0;width:100vw;height:100vh;margin:0;padding:0;overflow-y:auto;overflow-x:hidden;font-family:-apple-system,SF UI Text,Arial,PingFang SC,Hiragino Sans GB,Microsoft YaHei,WenQuanYi Micro Hei,sans-serif;font-size:16px;line-height:1.8;background-color:#e0e0e4;box-sizing:border-box;z-index:2147483647}#reading-mode-for-mobile *{box-sizing:border-box}#reading-mode-for-mobile > article.rmfm-main{position:relative;width:100vw;max-width:800px;margin:0 auto;padding:36px 72px;background-color:#fff;box-shadow:0 0 72px rgba(0,0,0,0.1);color:#18181c}#reading-mode-for-mobile > article.rmfm-main > .rmfm-title,#reading-mode-for-mobile > article.rmfm-main > .rmfm-content{position:relative}#reading-mode-for-mobile > article.rmfm-main > .rmfm-title > .rmfm-section,#reading-mode-for-mobile > article.rmfm-main > .rmfm-content > .rmfm-section{border-top:3px solid #f0f0f4;padding:18px 0}#reading-mode-for-mobile h1,#reading-mode-for-mobile h2,#reading-mode-for-mobile h3,#reading-mode-for-mobile h4,#reading-mode-for-mobile h5,#reading-mode-for-mobile h6{line-height:2.16;margin:18px 0}#reading-mode-for-mobile h1{font-size:22.4px;font-weight:200;text-align:center}#reading-mode-for-mobile h2{font-size:20.8px;font-weight:200}#reading-mode-for-mobile h3{font-size:19.2px;font-weight:600;color:#505054}#reading-mode-for-mobile h4{font-size:17.6px;font-weight:600;color:#78787c}#reading-mode-for-mobile h5{font-size:17.6px;font-weight:400;color:#a0a0a4}#reading-mode-for-mobile h6{font-size:17.6px;font-weight:200;color:#c8c8cc}#reading-mode-for-mobile p{margin:18px 0;text-indent:2em}#reading-mode-for-mobile hr{height:3px;background-color:#f0f0f4;margin:18px 0}#reading-mode-for-mobile b,#reading-mode-for-mobile strong{color:#000}#reading-mode-for-mobile del{color:#c0c0c4}#reading-mode-for-mobile ul,#reading-mode-for-mobile ol{margin:18px 0 18px 36px}#reading-mode-for-mobile li > ol,#reading-mode-for-mobile li > ul{margin:0 0 0 36px}#reading-mode-for-mobile table{border:2px solid #e0e0e4;border-spacing:0}#reading-mode-for-mobile table tr,#reading-mode-for-mobile table td,#reading-mode-for-mobile table th{border:1px solid #e0e0e4}#reading-mode-for-mobile table td,#reading-mode-for-mobile table th{padding:9px 18px}#reading-mode-for-mobile img,#reading-mode-for-mobile video,#reading-mode-for-mobile embed,#reading-mode-for-mobile svg{max-width:100%}#reading-mode-for-mobile a{color:#f46;text-decoration:none}#reading-mode-for-mobile a:hover{text-decoration:underline}#reading-mode-for-mobile blockquote{background-color:rgba(0,0,32,0.05);border-left:5px solid rgba(0,0,32,0.08);padding:9px 18px;margin:18px 0}#reading-mode-for-mobile pre{margin:36px -72px;padding:18px 0;background-color:#282c34;color:#a8a8ac;white-space:pre-wrap;word-break:break-all}#reading-mode-for-mobile pre code{padding:18px 72px;position:relative;font-family:"Fira Code",monospace,MonoLisa,"source code pro","consolas"}#reading-mode-for-mobile pre code::before{content:\' \';position:absolute;height:100%;left:63px;top:0;z-index:100;border-left:1px solid #88888c}#reading-mode-for-mobile pre code .rmfm-code-line{position:relative}#reading-mode-for-mobile pre code .rmfm-code-line .rmfm-code-line-num{position:absolute;top:0;left:-90px;width:72px;height:100%;background-repeat:no-repeat;background-position:top right}#reading-mode-for-mobile #rmfm-menu{position:fixed;width:100vh;height:28.8px;top:calc(50vh - 14.4px);left:calc(14.4px - 50vh);transform:rotate(90deg)}#reading-mode-for-mobile #rmfm-menu .rmfm-menu-item{display:inline-block;padding:0 9px;cursor:pointer;color:#c0c0c4;font-size:12.8px}#reading-mode-for-mobile #rmfm-menu .rmfm-menu-item:hover{color:#f46}#reading-mode-for-mobile #rmfm-menu .rmfm-menu-hidden{display:none}#reading-mode-for-mobile .rmfm-menu-top,#reading-mode-for-mobile .rmfm-menu-bottom{float:left}#reading-mode-for-mobile .rmfm-menu-bottom{float:right}#reading-mode-for-mobile #rmfm-toc-list{position:fixed;top:0;left:0;z-index:-1;width:400px;max-width:90vw;margin:0;padding:9px 9px 9px 36px;font-size:12.8px}#reading-mode-for-mobile #rmfm-toc-list .rmfm-toc-item{cursor:pointer;list-style-type:disc;overflow-wrap:break-word;word-break:break-all}#reading-mode-for-mobile #rmfm-toc-list .rmfm-toc-item:hover{color:#f46}@media screen and (max-width:800px){#reading-mode-for-mobile > article.rmfm-main{padding:36px 9vw}#reading-mode-for-mobile pre{margin:36px -9vw}#reading-mode-for-mobile pre code{padding:18px -9vw 18px 72px}}', "" ]);
  45. const l = i;
  46. },
  47. 920: (e, t, o) => {
  48. o.d(t, {
  49. Z: () => l
  50. });
  51. var r = o(645);
  52. var n = o.n(r);
  53. var i = n()((function(e) {
  54. return e[1];
  55. }));
  56. i.push([ e.id, "#reading-mode-for-mobile-start-card{width:100vw;height:100vh;position:fixed;bottom:0;left:0;background-color:rgba(0,0,0,0.8);z-index:2147483647}#reading-mode-for-mobile-start-card .start-content{position:absolute;bottom:0;width:90vw;left:5vw;text-align:center;box-sizing:border-box}#reading-mode-for-mobile-start-card .start-content p.rmfm-small-tip{font-size:12.8px;color:#a8a8ac;line-height:1.8;padding:0;margin:9px}#reading-mode-for-mobile-start-card .start-content .start-card{padding:18px 0}#reading-mode-for-mobile-start-card .start-content button{display:block;color:#909094;font-weight:200;line-height:1em;padding:16px;margin:8px auto}#reading-mode-for-mobile-start-card .start-content button#rmfm-show-button{background-color:#3ae;color:#fff;font-size:19.2px;border:1px solid #d0d0d4;border-radius:8px}#reading-mode-for-mobile-start-card .start-content button#rmfm-hide-button{font-size:48px}#reading-mode-for-mobile-start-card .start-content span#rmfm-countdown{font-weight:600;color:#f46}", "" ]);
  57. const l = i;
  58. },
  59. 645: e => {
  60. e.exports = function(e) {
  61. var t = [];
  62. t.toString = function toString() {
  63. return this.map((function(t) {
  64. var o = e(t);
  65. if (t[2]) return "@media ".concat(t[2], " {").concat(o, "}");
  66. return o;
  67. })).join("");
  68. };
  69. t.i = function(e, o, r) {
  70. if ("string" === typeof e) e = [ [ null, e, "" ] ];
  71. var n = {};
  72. if (r) for (var i = 0; i < this.length; i++) {
  73. var l = this[i][0];
  74. if (null != l) n[l] = true;
  75. }
  76. for (var a = 0; a < e.length; a++) {
  77. var s = [].concat(e[a]);
  78. if (r && n[s[0]]) continue;
  79. if (o) if (!s[2]) s[2] = o; else s[2] = "".concat(o, " and ").concat(s[2]);
  80. t.push(s);
  81. }
  82. };
  83. return t;
  84. };
  85. }
  86. };
  87. var t = {};
  88. function __webpack_require__(o) {
  89. var r = t[o];
  90. if (void 0 !== r) return r.exports;
  91. var n = t[o] = {
  92. id: o,
  93. exports: {}
  94. };
  95. e[o](n, n.exports, __webpack_require__);
  96. return n.exports;
  97. }
  98. (() => {
  99. __webpack_require__.n = e => {
  100. var t = e && e.__esModule ? () => e["default"] : () => e;
  101. __webpack_require__.d(t, {
  102. a: t
  103. });
  104. return t;
  105. };
  106. })();
  107. (() => {
  108. __webpack_require__.d = (e, t) => {
  109. for (var o in t) if (__webpack_require__.o(t, o) && !__webpack_require__.o(e, o)) Object.defineProperty(e, o, {
  110. enumerable: true,
  111. get: t[o]
  112. });
  113. };
  114. })();
  115. (() => {
  116. __webpack_require__.o = (e, t) => Object.prototype.hasOwnProperty.call(e, t);
  117. })();
  118. var o = {};
  119. (() => {
  120. const e = {
  121. "www.jianshu.com": {
  122. name: "JianShu",
  123. blockModal: true,
  124. rules: [ {
  125. urlReg: /\/p\/\w+/i,
  126. contentGetter: ".main-view .content",
  127. contentHandler: e => {
  128. e.querySelectorAll("img").forEach((e => {
  129. if (!e.src) e.src = e.getAttribute("data-original-src");
  130. }));
  131. e.querySelectorAll('div[aria-label="3rd-ad"]').forEach((e => {
  132. e.parentNode.removeChild(e);
  133. }));
  134. }
  135. } ]
  136. },
  137. "www.zhihu.com": {
  138. name: "Zhihu",
  139. blockModal: true,
  140. rules: [ {
  141. urlReg: /\/question\/\d+\/answer\/\d+/i,
  142. titleGetter: ".QuestionHeader-title",
  143. contentGetter: ".Question-main .QuestionAnswer-content",
  144. contentHandler: e => {
  145. e.querySelectorAll(`\n .ContentItem-actions,\n .ModalWrap,\n .ModalLoading-content,\n .CommentItemV2-footer,\n .RichContent--unescapable.is-collapsed .ContentItem-rightButton,\n .ContentItem.AnswerItem button.Button--primary`).forEach((e => {
  146. e.parentNode.removeChild(e);
  147. }));
  148. e.querySelectorAll(".CommentItemV2").forEach((e => {
  149. const t = document.createElement("br");
  150. e.before(t);
  151. }));
  152. }
  153. }, {
  154. urlReg: /\/question\/\d+/i,
  155. titleGetter: ".QuestionHeader-title",
  156. contentGetter: ".Question-main .List-item",
  157. contentHandler: e => {
  158. e.querySelectorAll(`\n .ContentItem-actions,\n .ModalWrap,\n .ModalLoading-content,\n .CommentItemV2-footer,\n .RichContent--unescapable.is-collapsed .ContentItem-rightButton,\n .ContentItem.AnswerItem button.Button--primary`).forEach((e => {
  159. e.parentNode.removeChild(e);
  160. }));
  161. e.querySelectorAll(".CommentItemV2").forEach((e => {
  162. const t = document.createElement("br");
  163. e.before(t);
  164. }));
  165. }
  166. } ]
  167. },
  168. "zhuanlan.zhihu.com": {
  169. name: "Zhihu Zhuanlan",
  170. blockModal: true,
  171. rules: [ {
  172. urlReg: /\/p\/\d+/i,
  173. titleGetter: "h1.Post-Title",
  174. contentGetter: ".Post-RichTextContainer"
  175. } ]
  176. }
  177. };
  178. const t = e;
  179. const o = null && [ "EnterPage", "StartCard", "ReadingMode" ];
  180. const r = {
  181. redirect: [ "pushState", "replaceState", "popstate" ],
  182. sameSite: [ "pushState", "replaceState", "popstate", "alert", "confirm" ]
  183. };
  184. const valORnull = e => e ? e : null;
  185. const n = {
  186. state: {
  187. is_debug: 0,
  188. auto_reading_mode: 0,
  189. log: [],
  190. warn: [],
  191. el: {},
  192. restore: {},
  193. pos: {},
  194. rule: {},
  195. modal: [ "alert", "confirm" ],
  196. toc: []
  197. },
  198. get is_debug() {
  199. return this.state.is_debug;
  200. },
  201. get auto_reading_mode() {
  202. return this.state.auto_reading_mode;
  203. },
  204. get modal() {
  205. return this.state.modal;
  206. },
  207. log(e, t) {
  208. if (this.is_debug) this.state.log.push((new Date).toLocaleString() + (e ? " " + e : "") + ": " + ([ "string", "number" ].includes(typeof t) ? t : JSON.stringify(t)));
  209. },
  210. warn(e, t) {
  211. this.state.warn.push((new Date).toLocaleString() + (e ? " " + e : "") + ": " + ([ "string", "number" ].includes(typeof t) ? t : JSON.stringify(t)));
  212. },
  213. exposeState() {
  214. if (this.is_debug) this.log("State expose", "Debug: " + this.is_debug);
  215. if (this.is_debug) window.rmfmState = this.state;
  216. },
  217. setRestore(e, t = null) {
  218. if (this.is_debug) this.log("State set Restore", {
  219. name: e,
  220. method: t
  221. });
  222. if (t) {
  223. this.state.restore[e] = t;
  224. return;
  225. }
  226. delete this.state.restore[e];
  227. },
  228. getRestore(e) {
  229. if (this.is_debug) this.log("State get Restore", {
  230. name: e,
  231. el: valORnull(this.state.restore[e])
  232. });
  233. return valORnull(this.state.restore[e]);
  234. },
  235. restore(e = []) {
  236. if (this.is_debug) this.log("State restore", e);
  237. if ("string" === typeof e) e = r[e] ? r[e] : [];
  238. const t = this.state.restore;
  239. for (const o in t) {
  240. if (e.includes(o)) continue;
  241. this.getRestore(o)();
  242. this.setRestore(o);
  243. }
  244. },
  245. getKeys(e) {
  246. if (this.is_debug) this.log("State get keys", {
  247. name: e,
  248. keys: Object.keys(this.state[e])
  249. });
  250. return Object.keys(this.state[e]);
  251. },
  252. addToc(e) {
  253. if (this.is_debug) this.log("State set TOC", e);
  254. this.state.toc.push(e);
  255. },
  256. getToc() {
  257. if (this.is_debug) this.log("State get TOC", this.state.toc);
  258. return this.state.toc;
  259. },
  260. clearEls() {
  261. this.getKeys("el").forEach((e => {
  262. if ("el_root" === e) return;
  263. delete this.state.el[e];
  264. }));
  265. }
  266. };
  267. const i = {
  268. el: [ "root", "startCard", "readingMode", "main", "title", "content", "menu", "toc", "tocList" ],
  269. rule: [ "site", "default", "now" ],
  270. pos: [ "toc", "menu" ]
  271. };
  272. for (const e in i) for (const t of i[e]) {
  273. const o = e + "_" + t;
  274. Object.defineProperty(n, o, {
  275. get: function() {
  276. if (this.is_debug) this.log("Store " + e + " get", o);
  277. return this.state[e][o];
  278. },
  279. set: function(t) {
  280. if (this.is_debug) this.log("Store " + e + " set", o + " = " + t);
  281. this.state[e][o] = t;
  282. }
  283. });
  284. }
  285. n.exposeState();
  286. const l = n;
  287. var a = __webpack_require__(920);
  288. var s = '<div class="start-content"> <p class="rmfm-small-tip">此提示来自于脚本:</p> <p class="rmfm-small-tip"><strong>移动页面的阅读模式</strong></p> <p class="rmfm-small-tip">当前版本号: 0.0.6beta</p> <p class="rmfm-small-tip">只是希望能够稍微提高一点在移动端的阅读体验。</p> <p class="rmfm-small-tip">此提示会在 <span id="rmfm-countdown"></span> 秒之后隐藏,刷新页面可以重新显示此提示。</p> <div class="start-card"> <button id="rmfm-show-button">进入阅读模式</button> <button id="rmfm-hide-button">╳</button> </div> </div>';
  289. const d = s;
  290. var m = __webpack_require__(152);
  291. var c = '<article class="rmfm-main"> <div id="rmfm-menu"> <div class="rmfm-menu-top"> <div id="rmfm-close-button" class="rmfm-menu-item">关闭</div> <div id="rmfm-toc-button" class="rmfm-menu-item rmfm-menu-hidden">大纲</div> </div> <div class="rmfm-menu-bottom"> <div id="rmfm-top-button" class="rmfm-menu-item">返回顶部</div> </div> </div> <ul id="rmfm-toc-list"></ul> <h1 class="rmfm-title"></h1> <div class="rmfm-content"></div> </article>';
  292. const f = c;
  293. var u = __webpack_require__(863);
  294. const removeEl = (e, t = false) => {
  295. if (l.is_debug) l.log("removeEl", {
  296. el: e,
  297. force: t
  298. });
  299. try {
  300. e.parentNode.removeChild(e);
  301. } catch (o) {
  302. l.warn("Remove el", {
  303. parent: e.parentNode,
  304. el: e,
  305. error: o
  306. });
  307. if (t) l.el_root.innerHTML = "";
  308. }
  309. };
  310. const addRootEl = () => {
  311. if (l.is_debug) l.log("addRootEl", "Everyone in it");
  312. if (l.el_root) {
  313. l.warn("Add root el", "But here have a root el.");
  314. return;
  315. }
  316. l.el_root = document.createElement("div");
  317. l.el_root.id = "rmfm-root-box";
  318. document.querySelector("html").appendChild(l.el_root);
  319. };
  320. const exitScript = () => {
  321. if (l.is_debug) l.log("exitScript", "End.");
  322. l.restore("redirect");
  323. l.clearEls();
  324. };
  325. const getPostToShow = () => {
  326. if (l.is_debug) l.log("getPostToShow", "");
  327. const e = l.rule_now;
  328. if (e.style) l.el_readingMode.querySelector("style").innerHTML += "\n" + e.style;
  329. l.el_title.innerText = titleGetter(e.titleGetter);
  330. l.el_content.innerHTML = contentGetter(e.contentGetter);
  331. const t = e.contentHandler;
  332. if ("function" === typeof t) t(l.el_content);
  333. getToc();
  334. clearContent();
  335. highlightCode();
  336. };
  337. const titleGetter = e => {
  338. if (l.is_debug) l.log("titleGetter", {
  339. selector: e
  340. });
  341. if (e) {
  342. if ("string" === typeof e && e.length) return document.body.querySelector(e).innerText;
  343. if ("function" === typeof e) return e();
  344. }
  345. const t = document.body.querySelector("h1");
  346. if (t) return t.innerHTML;
  347. return document.title;
  348. };
  349. const contentGetter = e => {
  350. if (l.is_debug) l.log("contentGetter", {
  351. selector: e
  352. });
  353. const t = [];
  354. if (e) {
  355. if ("function" === typeof e) return e();
  356. if ("string" === typeof e && e.length) t.unshift(e);
  357. }
  358. for (const e of t) {
  359. const t = document.body.querySelectorAll(e);
  360. if (t) {
  361. let e = "";
  362. t.forEach((t => {
  363. e += `<div class="rmfm-section">` + t.innerHTML + `</div>`;
  364. }));
  365. return e;
  366. }
  367. }
  368. return document.body.innerHTML;
  369. };
  370. const getToc = () => {
  371. const e = l.rule_now.toc ? l.rule_now.toc : [ "h1", "h2", "h3", "h4", "h5", "h6" ];
  372. e.forEach(((e, t) => {
  373. l.el_content.querySelectorAll(e).forEach((e => {
  374. e.classList.add("rmfm-toc-title");
  375. e.setAttribute("data-rmfm-toc-level", t);
  376. }));
  377. }));
  378. const t = [];
  379. l.el_content.querySelectorAll(".rmfm-toc-title").forEach(((e, o) => {
  380. const r = e.getAttribute("data-rmfm-toc-level");
  381. e.setAttribute("data-rmfm-toc-mairk", o);
  382. l.addToc({
  383. name: e.innerText,
  384. level: r,
  385. mark: o
  386. });
  387. if (!t.includes(r)) t.push(r);
  388. }));
  389. t.sort();
  390. if (l.getToc().length) {
  391. l.el_toc = l.el_readingMode.querySelector("#rmfm-toc-button");
  392. l.el_tocList = l.el_readingMode.querySelector("#rmfm-toc-list");
  393. let e = 0;
  394. l.getToc().forEach(((o, r) => {
  395. const n = document.createElement("li");
  396. if (!r) e = t.indexOf(o.level); else if (e < o.level) e = 0;
  397. const i = t.indexOf(o.level) - e;
  398. n.id = "rmfm-toc-item-" + r;
  399. n.classList.add("rmfm-toc-item");
  400. n.classList.add("rmfm-toc-item-" + i);
  401. n.style.marginLeft = 2 * i + "em";
  402. n.innerHTML = "<span>" + o.name + "<span>";
  403. n.onclick = () => {
  404. l.el_readingMode.scrollTo({
  405. top: l.el_content.querySelector('[data-rmfm-toc-mairk="' + o.mark + '"]').offsetTop + l.el_content.offsetTop,
  406. behavior: "smooth"
  407. });
  408. if (l.el_main.style.marginLeft) {
  409. l.el_main.style.marginLeft = "";
  410. l.pos_menu();
  411. }
  412. };
  413. l.el_tocList.appendChild(n);
  414. }));
  415. let o = 0;
  416. let r = 0;
  417. l.pos_toc = () => {
  418. r = 0;
  419. l.el_tocList.querySelectorAll("li.rmfm-toc-item>span").forEach((e => {
  420. r = Math.max(r, e.offsetWidth + Number(window.getComputedStyle(e.parentNode).marginLeft.replace("px", "")));
  421. }));
  422. if (r) r += 64;
  423. o = l.el_main.offsetLeft - r;
  424. l.el_tocList.style.left = (o < 0 ? 0 : o) + "px";
  425. const e = window.getComputedStyle(l.el_main);
  426. if (o < 0 || +e.marginLeft.replace("px", "") > +e.marginRight.replace("px", "")) l.el_toc.classList.remove("rmfm-menu-hidden"); else {
  427. l.el_main.style.marginLeft = "";
  428. l.el_toc.classList.add("rmfm-menu-hidden");
  429. }
  430. };
  431. l.pos_toc();
  432. window.addEventListener("resize", l.pos_toc);
  433. l.setRestore("tocResetOffset", (() => {
  434. window.removeEventListener("resize", l.pos_toc);
  435. }));
  436. l.el_toc.onclick = () => {
  437. if (o >= 0) return;
  438. if (l.el_main.style.marginLeft) l.el_main.style.marginLeft = ""; else l.el_main.style.marginLeft = r + "px";
  439. l.pos_menu();
  440. };
  441. }
  442. };
  443. const clearContent = () => {
  444. if (l.is_debug) l.log("clearContent", "");
  445. l.el_content.querySelectorAll(".rmfm-section *").forEach((e => {
  446. if (/^(style|script|header|footer|aside|nav|meta)$/i.test(e.tagName)) {
  447. removeEl(e);
  448. return;
  449. }
  450. e.removeAttribute("class");
  451. e.removeAttribute("id");
  452. e.removeAttribute("style");
  453. }));
  454. l.el_content.querySelectorAll(".rmfm-section").forEach((e => {
  455. e.innerHTML = e.innerHTML.replace(/<\/?(div|span)[^>]*>/gi, "").replace(/<p>\s*(<br\s?\/?>\s*)*<\/p>/g, "").replace(/(<br\s?\/?>\s*){2,}/g, "<br />");
  456. }));
  457. };
  458. const highlightCode = () => {
  459. const e = l.el_content.querySelectorAll("pre");
  460. if (e) {
  461. e.forEach((e => {
  462. const t = e.querySelector("code");
  463. if ("undefined" !== typeof hljs) hljs.highlightBlock(t); else t.classList.add("hljs");
  464. setLineNumber(t);
  465. }));
  466. l.el_readingMode.querySelector("style").innerHTML = u.Z + "\n" + l.el_readingMode.querySelector("style").innerHTML;
  467. }
  468. };
  469. const generateLineNumber = (e, t) => {
  470. const o = document.createElement("canvas");
  471. const r = o.getContext("2d");
  472. const n = {
  473. font: t.fontSize + " " + (t.fontFamily ? t.fontFamily : window.getComputedStyle(document.body).fontFamily),
  474. textAlign: "right",
  475. fillStyle: "#999999"
  476. };
  477. for (const e in n) r[e] = n[e];
  478. t.width = r.measureText(e).width;
  479. t.height = Number(t.lineHeight.replace("px", ""));
  480. o.width = t.width;
  481. o.height = t.height;
  482. for (const e in n) r[e] = n[e];
  483. const i = t.height / 2 + Number(t.fontSize.replace("px", "")) / 2;
  484. r.fillText(e, t.width, i);
  485. return o.toDataURL("image/png");
  486. };
  487. const setLineNumber = e => {
  488. const t = e ? [ e ] : [];
  489. t.forEach((e => {
  490. const t = window.getComputedStyle(e);
  491. const o = {
  492. fontSize: t.fontSize,
  493. fontFamily: t.fontFamily,
  494. lineHeight: t.lineHeight
  495. };
  496. e.innerHTML = e.innerHTML.split("\n").map(((e, t) => {
  497. const r = t + 1;
  498. const n = generateLineNumber(r, o);
  499. return '<div class="rmfm-code-line"><div class="rmfm-code-line-num" date-line-num="' + r + '" style="background-image: url(' + n + ')"></div>' + e + "</div>";
  500. })).join("");
  501. }));
  502. };
  503. const pageRedirectEvent = () => {
  504. const e = new Event("pageRedirect", {
  505. bubbles: true,
  506. cancelable: true
  507. });
  508. e.arguments = arguments;
  509. window.dispatchEvent(e);
  510. };
  511. const methodChanger = (e, t = window, o) => {
  512. const r = t[e];
  513. t[e] = o ? function() {
  514. const e = r.apply(this, arguments);
  515. o(arguments);
  516. return e;
  517. } : function() {
  518. if (l.is_debug) l.log("Evevt Killer - " + e, JSON.stringify(arguments));
  519. };
  520. return function() {
  521. t[e] = r;
  522. };
  523. };
  524. const addPageRedirectTrigger = () => {
  525. [ "pushState", "replaceState" ].forEach((e => {
  526. l.setRestore(e, methodChanger(e, history, pageRedirectEvent));
  527. }));
  528. window.addEventListener("popstate", pageRedirectEvent);
  529. l.setRestore("popstate", (() => {
  530. window.removeEventListener("popstate", pageRedirectEvent);
  531. }));
  532. const pageRedirectListener = () => {
  533. if (window.rmfmState.pageUrl === window.location.href) return;
  534. };
  535. window.addEventListener("pageRedirect", pageRedirectListener);
  536. l.setRestore("pageRedirect", (() => {
  537. window.removeEventListener("pageRedirect", pageRedirectListener);
  538. }));
  539. };
  540. const enterPage = e => {
  541. if (l.is_debug) l.log("Page enter", "Start.");
  542. if (self != top) return;
  543. l.rule_site = e[window.location.host];
  544. if (!l.rule_site) return;
  545. addPageRedirectTrigger();
  546. l.rule_default = Object.assign({}, l.rule_site);
  547. delete l.rule_default.rules;
  548. if (l.rule_default.blockModal) l.modal.forEach((e => {
  549. l.setRestore(e, methodChanger(e));
  550. }));
  551. for (const e of l.rule_site.rules) if (e.urlReg.test(window.location.href)) {
  552. l.rule_now = Object.assign({}, l.rule_default, e);
  553. break;
  554. }
  555. if (!l.rule_now) {
  556. exitScript();
  557. return;
  558. }
  559. addRootEl();
  560. if (l.auto_reading_mode) {
  561. showReadingMode();
  562. return;
  563. }
  564. showStartCard();
  565. };
  566. const showStartCard = () => {
  567. if (l.is_debug) l.log("showStartCard", "");
  568. if (l.el_startCard) {
  569. l.warn("Add start el", "But here have a start el.");
  570. return;
  571. }
  572. l.el_startCard = document.createElement("div");
  573. l.el_startCard.id = "reading-mode-for-mobile-start-card";
  574. l.el_startCard.innerHTML = "<style>" + a.Z + "</style>\n" + d;
  575. l.el_root.appendChild(l.el_startCard);
  576. const closeStartCard = () => {
  577. window.clearInterval(o);
  578. removeEl(l.el_startCard, true);
  579. l.el_startCard = null;
  580. l.setRestore("closeStartCard");
  581. };
  582. l.setRestore("closeStartCard", closeStartCard);
  583. l.el_startCard.querySelector("#rmfm-hide-button").onclick = exitScript;
  584. l.el_startCard.querySelector("#rmfm-show-button").onclick = () => {
  585. closeStartCard();
  586. showReadingMode();
  587. };
  588. let e = 8;
  589. const t = l.el_startCard.querySelector("#rmfm-countdown");
  590. t.innerText = e;
  591. let o = window.setInterval((() => {
  592. e--;
  593. if (!e) closeStartCard();
  594. t.innerText = e;
  595. }), 1e3);
  596. };
  597. const showReadingMode = () => {
  598. if (l.is_debug) l.log("showReadingMode", "");
  599. const e = l.rule_now;
  600. if (l.el_readingMode) {
  601. l.warn("Add reading el", "But here have a reading el.");
  602. return;
  603. }
  604. l.el_readingMode = document.createElement("div");
  605. l.el_readingMode.id = "reading-mode-for-mobile";
  606. l.el_readingMode.innerHTML = "<style>" + m.Z + "</style>\n" + f;
  607. l.el_root.appendChild(l.el_readingMode);
  608. document.body.classList.add("rmfm-body-hidden");
  609. const closeReadingMode = () => {
  610. document.body.classList.remove("rmfm-body-hidden");
  611. removeEl(l.el_readingMode, true);
  612. document.removeEventListener("keydown", escCloseReadingMode);
  613. l.setRestore("closeReadingMode");
  614. };
  615. l.setRestore("closeReadingMode", closeReadingMode);
  616. const escCloseReadingMode = e => {
  617. if ("Escape" === e.code) exitScript();
  618. };
  619. document.addEventListener("keydown", escCloseReadingMode);
  620. l.el_main = l.el_readingMode.querySelector(".rmfm-main");
  621. l.el_title = l.el_readingMode.querySelector(".rmfm-title");
  622. l.el_content = l.el_readingMode.querySelector(".rmfm-content");
  623. l.el_menu = l.el_readingMode.querySelector("#rmfm-menu");
  624. l.pos_menu = () => {
  625. l.el_menu.style.marginLeft = l.el_main.offsetLeft + "px";
  626. };
  627. l.pos_menu();
  628. window.addEventListener("resize", l.pos_menu);
  629. l.setRestore("menuResetOffset", (() => {
  630. window.removeEventListener("resize", l.pos_menu);
  631. }));
  632. l.el_menu.querySelector("#rmfm-close-button").onclick = exitScript;
  633. l.el_menu.querySelector("#rmfm-top-button").onclick = () => {
  634. l.el_readingMode.scrollTo({
  635. top: 0,
  636. behavior: "smooth"
  637. });
  638. };
  639. if ("loading" === document.readyState) {
  640. l.el_content.innerHTML = `<div style="text-align: center">loading……</div>`;
  641. document.addEventListener("DOMContentLoaded", (() => {
  642. getPostToShow();
  643. }));
  644. } else getPostToShow();
  645. };
  646. if (l.is_debug) l.log("Script", "Now, script is loaded.");
  647. const g = {
  648. enterPage
  649. };
  650. if (l.is_debug) l.log("Script", "Now, script start.");
  651. g.enterPage(t);
  652. })();
  653. })();

QingJ © 2025

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