保存百度文库中的文档,页面加载完后按Ctrl-S。

将百度文库中的文档保存为html。保存前需要滚动页面到底部,不要滚太快以确保页面加载成功,最好用键盘上的<Page Down>键。

当前为 2018-11-28 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @namespace ATGT
  3. // @name Save baidu wenku doc, press Ctrl-S after page load done.
  4. // @name:zh-CN 保存百度文库中的文档,页面加载完后按Ctrl-S。
  5. // @description Save baidu wenku doc as html.\n Need to Scroll down the web page to load all pages before press Ctrl-S to save, don't scroll too fast to ensure page of doc load complete, prefer use key <Page Down> on your keyboard.
  6. // @description:zh-CN 将百度文库中的文档保存为html。保存前需要滚动页面到底部,不要滚太快以确保页面加载成功,最好用键盘上的<Page Down>键。
  7. // @version 1.1
  8. // @icon https://www.baidu.com/cache/icon/favicon.ico
  9. // @include http*://wenku.baidu.com/*
  10.  
  11. // @run-at document-start
  12. // ==/UserScript==
  13.  
  14. /*
  15. ChangeLog:
  16. v1.1:
  17. 28 Nov 2018, remove copy limit.
  18. v1:
  19. 28 Nov 2018, Remove ads and show all pages.
  20. */
  21.  
  22. console.log("!!!!!!!!!!!!!!!!!!!!!save-baidu-wenku-doc!!!!!!!!!!!!!!!!!!!!!!!!");
  23. (function () {
  24.  
  25. function injectFunction(func) {
  26. var script = document.createElement('script');
  27. //script.className = "injectFunction";
  28. //script.appendChild(document.createTextNode('('+ func +')();'));
  29. script.appendChild(document.createTextNode('(function (){' + '(' + func + ')();' + '})();'));
  30. try {
  31. (document.body || document.head || document.documentElement).appendChild(script);
  32. } catch(e) {
  33. console.error("Can not inject function ", func);
  34. }
  35. }
  36. function injectFunctionContent(func) {
  37. var script = document.createElement('script');
  38. //script.className = "injectFunction";
  39. //script.appendChild(document.createTextNode('('+ func +')();'));
  40. var funcContent = func.toSource();
  41. if (/^function\s*[\w\d_$]*\(.*\)\s*\{/.test(funcContent)) {
  42. funcContent = funcContent.replace(/^function\s*[\w\d_$]*\(.*\)\s*\{/, '');
  43. funcContent = funcContent.replace(/}$/g, '');
  44. }
  45. script.appendChild(document.createTextNode(funcContent));
  46. (document.body || document.head || document.documentElement).appendChild(script);
  47. }
  48.  
  49. function saveConsole() {
  50. window.console_debug = console.debug;
  51. window.console_log = console.log;
  52. window.console_info = console.info;
  53. window.console_error = console.error;
  54.  
  55. }
  56. injectFunction(saveConsole);
  57.  
  58. function hookModJS() {
  59. console_info("--------> hookModJS");
  60. var require,
  61. define;
  62. !function (obj) {
  63. function create_async_script(script_src, load_fail_handler) {
  64. console_info("create_async_script", script_src);
  65. function load_ok() {
  66. clearTimeout(scriptLoadTimer)
  67. }
  68. if (!(script_src in async_script_list)) {
  69. async_script_list[script_src] = !0;
  70. var script = document.createElement('script');
  71. if (load_fail_handler) {
  72. var scriptLoadTimer = setTimeout(load_fail_handler, require.timeout);
  73. script.onerror = function () {
  74. clearTimeout(scriptLoadTimer),
  75. load_fail_handler()
  76. },
  77. 'onload' in script ? script.onload = load_ok : script.onreadystatechange = function () {
  78. ('loaded' == this.readyState || 'complete' == this.readyState) && load_ok()
  79. }
  80. }
  81. return script.type = 'text/javascript',
  82. script.src = script_src,
  83. head.appendChild(script),
  84. script
  85. }
  86. }
  87. function async_load_script(libName, fn_clean_up, fn_fail_handler) {
  88. var cleanUpHandlerList = libCleanUpHandlerList_Map[libName] || (libCleanUpHandlerList_Map[libName] = []);
  89. cleanUpHandlerList.push(fn_clean_up);
  90. var script_src,
  91. libAttr = libAttr_Map[libName] || {},
  92. pkg = libAttr.pkg;
  93. script_src = pkg ? libPkgNameList_Map[pkg].url : libAttr.url || libName,
  94. create_async_script(script_src, fn_fail_handler && function () {
  95. fn_fail_handler(libName)
  96. })
  97. }
  98. var head = document.getElementsByTagName('head')[0],
  99. libCleanUpHandlerList_Map = {
  100. },
  101. libFunc_Map = {
  102. },
  103. libMod_Map = {
  104. },
  105. async_script_list = {
  106. },
  107. libAttr_Map = {
  108. },
  109. libPkgNameList_Map = {
  110. };
  111. define = function (libName, func) {
  112. console_info("define ", libName);
  113. libFunc_Map[libName] = func;
  114. var cleanUpHandlerList = libCleanUpHandlerList_Map[libName];
  115. if (cleanUpHandlerList) {
  116. for (var n = 0, o = cleanUpHandlerList.length; o > n; n++)
  117. cleanUpHandlerList[n]();
  118. delete libCleanUpHandlerList_Map[libName]
  119. }
  120. },
  121. require = function (libName) {
  122. //console_info("require ", libName);
  123. if (libName && libName.splice) {
  124. //console_info("call require.async");
  125. return require.async.apply(this, arguments);
  126. }
  127. libName = require.alias(libName);
  128. //console_info("alias", libName);
  129. var module = libMod_Map[libName];
  130. if (module) {
  131. //console_info("found in libModMap, return.");
  132. return module.exports;
  133. }
  134. var modImplFunc = libFunc_Map[libName];
  135. if (!modImplFunc) {
  136. //console_info("Can not found module");
  137. throw '[ModJS] Cannot find module `' + libName + '`';
  138. }
  139. module = libMod_Map[libName] = {
  140. exports: {
  141. }
  142. };
  143. //console_info("modImplFunc", modImplFunc);
  144. var n = 'function' == typeof modImplFunc ? modImplFunc.apply(module, [
  145. require,
  146. module.exports,
  147. module
  148. ]) : modImplFunc;
  149. //console_info("n", n, "module", module);
  150. if (libName === 'wkcommon:widget/ui/reader/view/doc/view.js') {
  151. console_info('++++++++++++++++++ hook doc/view.js');
  152. module.exports.view.prototype._recycleView = function(e) {
  153. console_info("hooked _recycleView called");
  154. };
  155. } else if (libName == "wkcommon:widget/ui/reader_plugin/copylimit/copylimit.js") {
  156. console_info('++++++++++++++++++ hook copylimit/copylimit.js');
  157. module.exports.prototype.isCanCopy = function(e) {
  158. console_info("hooked isCanCopy called");
  159. return true;
  160. };
  161. }
  162. return n && (module.exports = n),
  163. module.exports
  164. },
  165. require.async = function (libList_param, fn_clean_up_handler, fn_fail_handler) {
  166. function async_load_script_list(libList_tmp) {
  167. for (var r = 0, n = libList_tmp.length; n > r; r++) {
  168. var libName = libList_tmp[r];
  169. if (libName in libFunc_Map) {
  170. var libAttr = libAttr_Map[libName];
  171. libAttr && 'deps' in libAttr && async_load_script_list(libAttr.deps)
  172. } else if (!(libName in loading_status)) {
  173. loading_status[libName] = !0,
  174. load_cnt++ ,
  175. async_load_script(libName, fn_clean_up, fn_fail_handler);
  176. var libAttr = libAttr_Map[libName];
  177. libAttr && 'deps' in libAttr && async_load_script_list(libAttr.deps)
  178. }
  179. }
  180. }
  181. function fn_clean_up() {
  182. if (0 == load_cnt--) {
  183. for (var modList = [], i = 0, a = libList_param.length; a > i; i++)
  184. modList[i] = require(libList_param[i]);
  185. fn_clean_up_handler && fn_clean_up_handler.apply(obj, modList)
  186. }
  187. }
  188. 'string' == typeof libList_param && (libList_param = [libList_param]);
  189. for (var c = 0, f = libList_param.length; f > c; c++)
  190. libList_param[c] = require.alias(libList_param[c]);
  191. var loading_status = {},
  192. load_cnt = 0;
  193. async_load_script_list(libList_param),
  194. fn_clean_up()
  195. },
  196. require.resourceMap = function (resMap) {
  197. var r,
  198. tmp_list;
  199. tmp_list = resMap.res;
  200. for (r in tmp_list)
  201. tmp_list.hasOwnProperty(r) && (libAttr_Map[r] = tmp_list[r]);
  202. tmp_list = resMap.pkg;
  203. for (r in tmp_list)
  204. tmp_list.hasOwnProperty(r) && (libPkgNameList_Map[r] = tmp_list[r])
  205. },
  206. require.loadJs = function (e) {
  207. create_async_script(e)
  208. },
  209. require.loadCss = function (e) {
  210. if (e.content) {
  211. var style = document.createElement('style');
  212. style.type = 'text/css',
  213. style.styleSheet ? style.styleSheet.cssText = e.content : style.innerHTML = e.content,
  214. head.appendChild(style)
  215. } else if (e.url) {
  216. var link = document.createElement('link');
  217. link.href = e.url,
  218. link.rel = 'stylesheet',
  219. link.type = 'text/css',
  220. head.appendChild(link)
  221. }
  222. },
  223. require.alias = function (libName) {
  224. return libName
  225. },
  226. require.timeout = 5000
  227. }(this);
  228. Object.defineProperty(window, 'require', {
  229. get: function () { return require; },
  230. set: function (v) {
  231. //console_info('RO Value! New value: ' + v);
  232. }
  233. });
  234. Object.defineProperty(window, 'define', {
  235. get: function () { return define; },
  236. set: function (v) {
  237. //console_info('RO Value! New value: ' + v);
  238. }
  239. });
  240. /* IMPORTANT
  241. * must freeze `require', otherwize require.alias/.async/.resouceMap will be modified.
  242. */
  243. Object.freeze(define);
  244. Object.freeze(require);
  245. }
  246. injectFunction(hookModJS);
  247.  
  248. function tunePage() {
  249. function continueRead() {
  250. try {
  251. /* _recycleView hooked in hookModJS() */
  252. var v = require('wkcommon:widget/ui/reader/view/doc/view.js').view.prototype._recycleView;
  253. } catch(e) {
  254. console_error(e.toString());
  255. var v = e.toString();
  256. }
  257. console_info("doc/view.js ... _recycleView:", v.toSource());
  258. console_info("continueRead >>> ");
  259. $('.doc-reader').attr('oncopy', "");
  260. $(".goBtn").click();
  261. }
  262.  
  263. function removeUseless() {
  264. var rmNodes = [
  265. '.fix-searchbar-wrap',
  266. '.doc-tag',
  267. '.reader-tools-bar-wrap',
  268. '#Zuniqueid__3',
  269. '[id^=html-reader-AD]',
  270. '.banner-core-wrap',
  271. '.fc-container',
  272. '.fc-ppt',
  273. '#ggbtm-ads',
  274. '.banner-ad',
  275. ];
  276. for (var node of rmNodes) {
  277. var tmpNodes = $(node);
  278. if (tmpNodes.length == 0)
  279. console_info("No node found for " + node);
  280. else {
  281. $(node).hide();
  282. $(node).remove();
  283. }
  284. }
  285. }
  286.  
  287. window.addEventListener("load", function () {
  288. console_info("ready!");
  289. continueRead();
  290. removeUseless();
  291. });
  292. };
  293. injectFunction(tunePage);
  294. })();
  295.  
  296. console.log("!!!!!!!!!!!!!!!!!!!!!/save-baidu-wenku-doc!!!!!!!!!!!!!!!!!!!!!!!!");