有章PDF下载

下载有章文档

  1. // ==UserScript==
  2. // @name 有章PDF下载
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.0.4
  5. // @description 下载有章文档
  6. // @author JoyofFire
  7. // @match https://www.ilawpress.com/assets/plugin/pdfviewer/web/viewer.html
  8. // @icon https://www.google.com/s2/favicons?sz=64&domain=ilawpress.com
  9. // @grant none
  10. // @run-at document-start
  11. // @license GPL-3.0-only
  12. // ==/UserScript==
  13.  
  14.  
  15. (function() {
  16. 'use strict';
  17.  
  18.  
  19. // 全局常量
  20. const DL_PDF_API = "download_pdf";
  21. const DL_BTN = `<button id="dl-pdf" class="extend-navbar-btn fa fa-download" title="下载PDF" style="margin-right:1.1em;color:red" onclick="${DL_PDF_API}()"><span>下载PDF</span></button>`; //`<button id="dl-pdf" class="extend-navbar-btn fa fa-download" title="下载PDF" style="position:fixed;right: 2em;color:red" onclick="${DL_PDF_API}()"><span>下载PDF</span></button>`
  22. const make_blob_url = get_fn_call(URL, "createObjectURL");
  23. const insert_html_elem = get_fn_call(Element.prototype, "insertAdjacentHTML");
  24.  
  25. function print(...args) {
  26. const time = new Date().toTimeString().slice(0, 8);
  27. console.info(`[wk ${time}]`, ...args);
  28. }
  29.  
  30. function get_fn_call(obj, fn_name) {
  31. const fn = obj[fn_name];
  32. const call = fn.call.bind(fn);
  33. print(`got bound ${fn_name}.call:`, call);
  34. return call;
  35. }
  36.  
  37. /**
  38. * @param {string} selectors
  39. * @returns {HTMLElement}
  40. */
  41. function $(selectors) {
  42. return document.querySelector(selectors);
  43. }
  44.  
  45.  
  46. function add_dl_btn() {
  47. insert_html_elem($("#toolbarViewerRight"), "afterbegin", DL_BTN);
  48. print("btn added");
  49. }
  50.  
  51. function on_data(data) {
  52. const blob = new Blob([data], { type: "application/pdf" });
  53. const url = make_blob_url(URL, blob);
  54. window.data = data;
  55. window.url = url;
  56. window[DL_PDF_API] = () => open(url);
  57.  
  58. print("data:", data);
  59. print("url:", window.url);
  60. }
  61.  
  62. function hook_then() {
  63. print("entered hook_then");
  64.  
  65. const { then } = Promise.prototype;
  66. Promise.prototype.then = function(...args) {
  67. for (const [i, arg] of args.entries()) {
  68. if (String(arg).includes("(pdfDocument) {")) {
  69. print(...args);
  70.  
  71. args[i] = function(doc) {
  72. print("doc:", doc);
  73. doc.getData().then(on_data);
  74. return arg.call(this, doc);
  75. };
  76. break;
  77. }
  78. }
  79. return then.apply(this, args);
  80. };
  81. }
  82.  
  83. function on_dom_loaded() {
  84. print("dom loaded");
  85. add_dl_btn();
  86. }
  87.  
  88. function hook_fetch() {
  89. const myfetch = get_fn_call(window, "fetch");
  90.  
  91. window.fetch = function(url, ...args) {
  92. //debugger;
  93. const aim = /[/]pdf[/]trybook[/][0-9]+/;
  94. const _url = `${url}`;
  95. const replaced = aim.test(_url)
  96. ? _url.replace("/trybook/", "/book/")
  97. : url;
  98. //debugger;
  99. const ret_val = myfetch(this, replaced, ...args);
  100. return ret_val;
  101.  
  102. //return myfetch(this, url, ...args);
  103. };
  104. print("fetch hooked:", window.fetch);
  105. }
  106.  
  107. function main() {
  108. print("entered main");
  109.  
  110. document.addEventListener("DOMContentLoaded", on_dom_loaded);
  111. hook_fetch();
  112. hook_then();
  113. }
  114.  
  115. main();
  116. })();

QingJ © 2025

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