Sleazy Fork is available in English.

hitomi.la 助手

下载加速,分包下载,优化在线阅读,标签汉化,本子列表标题自动换行,点击本子列表预览图新标签页打开,非搜索增加选页功能,本子列表标签支持展开(默认显示10个),本子列表显示本子总页数

  1. // ==UserScript==
  2. // @name hitomi.la 助手
  3. // @namespace https://greasyfork.org/zh-CN/users/200067#1
  4. // @version 1.97
  5. // @description 下载加速,分包下载,优化在线阅读,标签汉化,本子列表标题自动换行,点击本子列表预览图新标签页打开,非搜索增加选页功能,本子列表标签支持展开(默认显示10个),本子列表显示本子总页数
  6. // @author 不会英语会写点代码的小白
  7. // @match http*://hitomi.la/*
  8. // @run-at document-start
  9. // @grant unsafeWindow
  10. // @grant GM_getValue
  11. // @grant GM_setValue
  12. // @grant GM_listValues
  13. // @grant GM_deleteValue
  14. // @grant GM_xmlhttpRequest
  15. // @grant GM_addStyle
  16. // @connect *
  17. // @connect hub.gitmirror.com
  18. // @connect ghp.ci
  19. // @connect github.com
  20. // @connect githubusercontent.com
  21. // ==/UserScript==
  22. /******/ (() => {
  23. // webpackBootstrap
  24. /******/ "use strict";
  25. const location_hash = location.hash.startsWith("#VIEW#") ? location.hash : void 0;
  26. let json, is_limitLists = !1, translate_lock = !1;
  27. load_db: {
  28. if (location.pathname.startsWith("/reader/")) break load_db;
  29. const gx = 3;
  30. if (GM_getValue("更新", 0) != gx) {
  31. GM_getValue("db_update_time", 0) > 0 && localStorage.setItem("db_js", GM_getValue("db_js"));
  32. const list = GM_listValues();
  33. for (const key of list) GM_deleteValue(key);
  34. GM_setValue("更新", gx);
  35. }
  36. unsafeWindow.load_ehtagtranslation_db_text = db => {
  37. const data = db.data;
  38. db = {
  39. TMap: {
  40. tags: "标签",
  41. artists: "艺术家",
  42. series: "原作",
  43. characters: "角色",
  44. language: "语言",
  45. type: "类型",
  46. group: "团队"
  47. },
  48. aliasMap: {
  49. // 标签
  50. loli: "lolicon",
  51. shota: "shotacon",
  52. // 类型
  53. "artist CG": "artistcg",
  54. "game CG": "gamecg",
  55. "image set": "imageset"
  56. },
  57. alias(str) {
  58. return this.aliasMap[str] || str.toLowerCase();
  59. }
  60. };
  61. for (const j of data) db[j.namespace] = j;
  62. is_limitLists && !translate_lock ? (translate_lock = !0, json = db, translate(),
  63. translate_lock = !1) : json = db;
  64. };
  65. let is_add_script = !0;
  66. const xhr_onload = r => {
  67. if (200 !== r.status) return xhr.onerror(r), null;
  68. if (4 === r.readyState) {
  69. const responseText = r.responseText;
  70. if (!responseText.includes("load_ehtagtranslation_db_")) return xhr.onerror(r),
  71. null;
  72. localStorage.setItem("db_update_time", (new Date).getTime() + 864e5 + ""), localStorage.setItem("db_js", responseText);
  73. }
  74. if (is_add_script) {
  75. if (!document.head) return r.readyState = 0, void setTimeout(xhr_onload, 100, r);
  76. is_add_script = !1;
  77. const script = document.createElement("script");
  78. script.src = URL.createObjectURL(r.response), document.head.appendChild(script);
  79. }
  80. }, db_js = localStorage.getItem("db_js") || "";
  81. if (db_js.includes("load_ehtagtranslation_db_") && (xhr_onload({
  82. status: 200,
  83. response: new Blob([ db_js ], {
  84. type: "application/x-javascript"
  85. })
  86. }), parseInt(localStorage.getItem("db_update_time") || "0") > (new Date).getTime())) break load_db;
  87. let index = 0;
  88. const urls = [ "https://github.com/EhTagTranslation/Database/releases/latest/download/db.text.js", "https://ghp.ci/https://github.com/EhTagTranslation/Database/releases/latest/download/db.text.js", "https://hub.gitmirror.com/https://github.com/EhTagTranslation/Database/releases/latest/download/db.text.js" ], xhr_onerror = er => {
  89. console.error(`status:${er.status || 0}, url:${xhr.url} index:${index}`), index >= 2 * urls.length ? is_add_script && alert("用于汉化标签的数据库加载失败,请确保网络可以访问github.com后刷新网页重试") : xhr_send();
  90. }, xhr = {
  91. url: "",
  92. method: "GET",
  93. timeout: 1e4,
  94. responseType: "blob",
  95. onload: xhr_onload,
  96. onerror: xhr_onerror,
  97. ontimeout: xhr_onerror,
  98. onabort: xhr_onerror
  99. }, xhr_send = () => {
  100. xhr.url = urls[index++ % urls.length], GM_xmlhttpRequest(xhr);
  101. };
  102. xhr_send();
  103. }
  104. let main = () => {
  105. console.log("main()");
  106. {
  107. let limit;
  108. GM_addStyle("\n#lang > a {\n padding: 10px 70px 10px 15px;\n}\n.gallery-content > div > h1.lillie {\n white-space: normal; //标题换行显示\n}\n");
  109. let _onresizeT, each_fun = function() {
  110. const el = $(this);
  111. el.index() >= limit && el.addClass("hidden-list-item");
  112. }, onclick = function() {
  113. let el = $(this);
  114. const is = "展开>" === el.html();
  115. el.html(is ? "收起<" : "展开>"), el = el.parent().nextAll(), is ? el.removeClass("hidden-list-item") : el.addClass("hidden-list-item");
  116. }, each_fun2 = function() {
  117. let el = $(this).children();
  118. if (el.length > limit) {
  119. const ex = $('<li><a style="cursor: pointer; color:aqua">展开&gt;</a></li>');
  120. ex.children().on("click", onclick), el.eq(9).after(ex), el = el.last(), "..." === el.text() && el.remove();
  121. }
  122. };
  123. // 修复标题换行显示后预览图错位
  124. const onresize = () => {
  125. _onresizeT = void 0;
  126. const is = document.body.clientWidth > 768, p = 768 == document.body.clientWidth ? 30 : 15, dom = $(".gallery-content > div");
  127. return dom.each((function() {
  128. const img = this.firstElementChild, imgD = img.firstElementChild;
  129. let top;
  130. if (is) top = (this.offsetHeight - imgD.offsetHeight) / 2 + 18 + "px"; else {
  131. const title = img.nextElementSibling, artist = title.nextElementSibling;
  132. top = title.offsetHeight + artist.offsetHeight + p + "px";
  133. }
  134. imgD.style.top = top;
  135. })), dom;
  136. };
  137. unsafeWindow.addEventListener("resize", (() => {
  138. null != _onresizeT && clearTimeout(_onresizeT), _onresizeT = setTimeout(onresize, 10);
  139. }));
  140. //去除顶部广告被屏蔽后的空白
  141. const el = document.querySelector(".content > div, .top-content > div");
  142. el && !el.className.match("list-title|cover-column") && el.remove(), (main = () => {
  143. limit = 10, $(".relatedtags li, .series-list li").each(each_fun), $(".relatedtags ul, .series-list ul").each(each_fun2),
  144. limit = 5, $(".artist-list li").each(each_fun), $(".artist-list ul").each(each_fun2);
  145. const dom = onresize();
  146. dom.length && dom.find("a.lillie").attr("target", "_blank");
  147. })();
  148. }
  149. if (!unsafeWindow.galleryinfo) return;
  150. const files = unsafeWindow.galleryinfo.files;
  151. // 阅读页
  152. // 下载按钮扩展
  153. {
  154. const dlbt = $("#dl-button");
  155. dlbt.removeAttr("href").css("cursor", "pointer").children().html("下载"), GM_addStyle('\n.cover > a , #dl_options {\n text-align: center;\n display: block;\n}\n#dl_options input[type="radio"] {\n margin: 0 2px 0 4px;\n}\n#dl_options span, #dl_options label, #dl_options input {\n vertical-align: middle;\n font-size: 14px;\n}\n.gallery-info > table {\n table-layout: fixed; /*限制tag长度*/\n}\n');
  156. const dl_options = $(`\n<div id="dl_options" style="line-height: 25px;">\n <label>下载并发数:<input type="number" style="width:38px" name="dl_thread" value="${GM_getValue("dl_thread", "6")}"></label>\n <label><input type="radio" name="dl_mode" value="2">不打包下载</label>\n <br>\n <label>\n <input type="radio" name="dl_mode" value="1">按大小分包:\n <input type="number" style="width:55px" name="zip_max_length" value="${GM_getValue("zip_max_length", "1024")}">M\n </label>\n <br>\n 图片格式:\n <label><input type="radio" name="img_type" value="webp">webp</label>\n <label><input type="radio" name="img_type" value="avif">avif</label>\n</div>\n`);
  157. dl_options.find("input[name=dl_mode][value=" + GM_getValue("dl_mode", "1") + "]").attr("checked", "checked"),
  158. dl_options.find("input[name=img_type][value=" + GM_getValue("img_type", "webp") + "]").attr("checked", "checked"),
  159. dl_options.find("input[type]").on("change", (e => {
  160. const target = e.target, name = target.name;
  161. name && GM_setValue(name, target.value);
  162. }));
  163. const dlt = $('<span style="position:absolute;left:0px;right:0px;vertical-align:middle;"/>'), progressbar = $("#progressbar");
  164. progressbar.append(dlt), progressbar.css({
  165. "text-align": "center",
  166. position: "relative"
  167. }), progressbar.after(dl_options), unsafeWindow.download_gallery = name => {
  168. let obj;
  169. const files_length = files.length, dl_fun = {
  170. mode1(xhr) {
  171. let zip, zip_i = 0;
  172. do {
  173. if ((zip = obj.zips[zip_i]) || (zip = obj.zips[zip_i] = new JSZip, zip_i > 0 && (zip.index = obj.zips[zip_i - 1].max_index + 1)),
  174. xhr.dl_index > zip.max_index) {
  175. if (zip.next_zip) continue;
  176. files_length - xhr.dl_index < 20 ? zip.max_index = files_length : zip.max_index = xhr.dl_index;
  177. }
  178. break;
  179. } while (++zip_i);
  180. zip.file(files[xhr.dl_index].name, xhr.response), zip.index++;
  181. const is_dl_finish = obj.dl_index_finish === files_length;
  182. if (is_dl_finish || (zip.next_zip = (zip.byteLength += xhr.response.byteLength) > obj.zip_max_byteLength) && zip.index > zip.max_index) {
  183. const zip_name = zip_i > 0 ? obj.gallery_name + " (" + zip_i + ")" : obj.gallery_name;
  184. zip.generateAsync({
  185. type: "blob"
  186. }).then((data => saveAs(data, zip_name + ".zip")));
  187. }
  188. is_dl_finish && this.finish();
  189. },
  190. mode2(xhr) {
  191. let datas = obj.bolbs;
  192. datas || (datas = obj.bolbs = []), xhr.response.dl_index = xhr.dl_index, datas.push(xhr.response),
  193. obj.itv_id || (obj.itv_id = setInterval(this.mode2_itv.bind(this), 200));
  194. },
  195. mode2_itv() {
  196. const blob = obj.bolbs.shift();
  197. blob && obj ? saveAs(blob, obj.gallery_name + "_" + files[blob.dl_index].name) : (clearInterval(obj.itv_id),
  198. obj.itv_id = 0, obj.dl_index_finish === files_length && this.finish());
  199. },
  200. finish() {
  201. progressbar.hide(), dlbt.children().text("下载"), obj = null;
  202. }
  203. };
  204. function xhr_onreadystatechange() {
  205. if (4 === this.readyState) {
  206. if (!obj) return;
  207. 200 === this.status ? (dlt.html(++obj.dl_index_finish + "/" + files_length), progressbar.progressbar("value", obj.dl_index_finish / files_length * 100),
  208. obj.dl_mode_fun(this), obj && obj.dl_index < files_length && (xhr_init(this), xhr_send.bind(this)())) : (this.status >= 500 && this.status < 600 || --this.dl_retry) && setTimeout(xhr_send.bind(this), 500);
  209. }
  210. }
  211. function xhr_init(xhr) {
  212. const image = files[obj.dl_index];
  213. let img_type = obj.img_type;
  214. "avif" !== img_type || image.hasavif || (img_type = "webp"), image.name = image.name.replace(/[^.]*$/, img_type),
  215. xhr.dl_url = unsafeWindow.url_from_url_from_hash(unsafeWindow.galleryid, image, img_type, void 0, "a"),
  216. xhr.dl_index = obj.dl_index++, xhr.dl_retry = 100;
  217. }
  218. function xhr_send() {
  219. this.open("GET", this.dl_url, !0), this.send();
  220. }
  221. const JSZip = unsafeWindow.JSZip;
  222. JSZip.prototype.byteLength = 0, JSZip.prototype.index = 0, JSZip.prototype.max_index = 0,
  223. JSZip.prototype.next_zip = !1, (unsafeWindow.download_gallery = name => {
  224. if (null != obj) {
  225. for (const xhr of obj.xhrs) xhr.abort();
  226. return void dl_fun.finish();
  227. }
  228. dlbt.children().text("取消下载"), dlt.html("0/" + files_length), progressbar.show(),
  229. progressbar.progressbar({
  230. value: !1
  231. }), obj = {}, obj.gallery_name = name || "hitomi", obj.dl_index = 0, obj.dl_index_finish = 0,
  232. obj.img_type = GM_getValue("img_type", "webp");
  233. const dl_mode = GM_getValue("dl_mode", "1");
  234. obj.dl_mode_fun = dl_fun["mode" + dl_mode].bind(dl_fun);
  235. let xhr_responseType, dl_thread = parseInt(GM_getValue("dl_thread", "6"));
  236. // 线程 1-6,超过6会出现503错误
  237. if (dl_thread = dl_thread < 1 ? 1 : dl_thread > 6 ? 6 : dl_thread, "1" === dl_mode) {
  238. const max_length = parseInt(GM_getValue("zip_max_length", "1024"));
  239. obj.zip_max_byteLength = 1048576 * (max_length < 100 ? 100 : max_length > 2048 ? 2048 : max_length),
  240. // 限制大小100M-2048M
  241. xhr_responseType = "arraybuffer", obj.zips = [];
  242. } else "2" === dl_mode && (xhr_responseType = "blob");
  243. obj.xhrs = [];
  244. for (let xhr, thread = 0; thread < dl_thread && obj.dl_index < files_length; thread++) obj.xhrs.push(xhr = new XMLHttpRequest),
  245. xhr.onreadystatechange = xhr_onreadystatechange, xhr.responseType = xhr_responseType,
  246. xhr_init(xhr), xhr_send.bind(xhr)();
  247. })(name);
  248. };
  249. }
  250. // 在线阅读
  251. {
  252. let titleA = $("#gallery-brand > a");
  253. titleA.length && titleA.before("(" + files.length + ")"), GM_addStyle('\n#_VIEW_ {\n height: 100%;\n width: 100%;\n position: fixed;\n z-index: 99998;\n}\n#_VIEW_ > iframe {\n height: 100%;\n width: 100%;\n}\n#_VIEW_ > .lum-close-button {\n cursor: pointer;\n position: absolute;\n right: 5px;\n top: 3px;\n width: 32px;\n height: 32px;\n z-index: 99999;\n opacity: 1\n}\n#_VIEW_ > .lum-close-button:hover {\n opacity: .7\n}\n#_VIEW_ > .lum-close-button:after,.lum-close-button:before {\n position: absolute;\n left: 15px;\n content: " ";\n height: 33px;\n width: 2px;\n background-color: #fff;\n}\n#_VIEW_ > .lum-close-button:before {\n transform: rotate(45deg)\n}\n#_VIEW_ > .lum-close-button:after {\n transform: rotate(-45deg)\n}\n');
  254. const ro = $("#read-online-button > :eq(0)");
  255. ro.html("在线阅读");
  256. const reader_href = ro.parent().attr("href"), view = $(`\n<div tabindex="1" style="display: none;">\n<div id="_VIEW_">\n <iframe src="${reader_href}#1"/>\n <div class="lum-close-button"/>\n </div>\n</div>\n`);
  257. document.body.prepend(view[0]);
  258. const hideView = e => {
  259. view.hide(), void 0 !== e && (unsafeWindow.history.back(), e.stopPropagation(),
  260. e.preventDefault());
  261. };
  262. view.find(".lum-close-button").on("click", hideView);
  263. const _get_pagenum_hash = unsafeWindow.get_pagenum_hash;
  264. unsafeWindow.get_pagenum_hash = function(...args) {
  265. if (location.hash.startsWith("#VIEW#")) {
  266. const iframe = view.find("#_VIEW_>iframe")[0];
  267. view.is(":hidden") && (view.show(), iframe.focus({
  268. preventScroll: !0
  269. }));
  270. const page = location.hash.substring(6);
  271. ro.html("继续阅读第" + page + "页");
  272. const iframe_hash = reader_href + "#" + page;
  273. return $("#read-online-button, #gallery-brand > a").attr("href", iframe_hash), iframe.contentWindow?.location.replace(iframe_hash),
  274. $(".simplePagerNav a").length + 1;
  275. }
  276. return view.is(":hidden") || hideView(void 0), _get_pagenum_hash.apply(this, args);
  277. }, $("#read-online-button, #gallery-brand > a, .thumbnail-container > a").on("click", (function(e) {
  278. const match = this.href.match(/#([0-9-]+)$/), hash = "#VIEW#" + (match ? match[1] : "1");
  279. view.is(":hidden") ? location.hash = hash : location.replace(hash), e.stopPropagation(),
  280. e.preventDefault();
  281. })), unsafeWindow.addEventListener("message", (e => {
  282. const data = e.data;
  283. data.startsWith("#") && location.replace(location.pathname + data.replace("#", "#VIEW#"));
  284. }), !1), location_hash && (location.hash = location_hash);
  285. }
  286. }, translate = () => {
  287. let translateList;
  288. function each_fun() {
  289. let map, str;
  290. const mat = /^(.+)( [♀♂])/.exec(this.innerHTML);
  291. if (mat) {
  292. if (str = " ♀" === mat[2] ? "female" : "male", map = json[str].data[json.alias(mat[1])],
  293. map) return this.title = map.intro, void (this.innerHTML = map.name + mat[2]);
  294. this.innerHTML = mat[1];
  295. }
  296. const str2 = json.alias(this.innerHTML);
  297. for (const val of translateList) if (val !== str && (map = json[val].data[str2],
  298. map)) {
  299. this.title = map.intro, this.innerHTML = map.name + (str || ("female" === val ? "♀" : "male" === val ? "♂" : ""));
  300. break;
  301. }
  302. }
  303. function each_fun2() {
  304. this.title = this.innerHTML;
  305. const str = json.TMap[this.innerHTML.toLowerCase()];
  306. str && (this.innerHTML = str);
  307. }
  308. function each_fun3() {
  309. const str = json.alias(this.innerHTML);
  310. let map;
  311. for (const val of translateList) if (map = json[val].data[str], map) {
  312. this.innerHTML = map.name, this.title = map.intro;
  313. break;
  314. }
  315. }
  316. const is = null != unsafeWindow.galleryinfo, lang = $("nav > ul > li#lang > a");
  317. // 工具栏
  318. if ($("nav > ul > li > a[href]").each(each_fun2), lang.length) {
  319. $("nav > ul #lang-list").children() ? (lang.html(lang.children()[0]), lang.prepend("语言 ")) : lang.parent().hide();
  320. }
  321. (translate = () => {
  322. if (translateList = [ "female", "male", "other", "mixed", "artist", "character", "cosplayer", "group", "parody" ],
  323. $(".dj-content td.relatedtags a").each(each_fun), // 列表的标签
  324. $(".dj-content tr > td:nth-of-type(1)").each(each_fun2), // 列表的行名
  325. is && ($(".gallery-info ul#tags a").each(each_fun), // 详情页的标签
  326. // translateList.splice(5, 1);
  327. // translateList.unshift('character');
  328. translateList = [ "character" ], $(".gallery-info ul#characters a").each(each_fun),
  329. // 详情页的角色
  330. $(".gallery-info tr > td:nth-of-type(1)").each(each_fun2)),
  331. // 原作
  332. translateList = [ "parody" ], $(".dj-content tr:nth-of-type(1) > td:nth-of-type(2) a").each(each_fun3),
  333. is && ($(".gallery-info tr:nth-of-type(4) > td:nth-of-type(2) a").each(each_fun3),
  334. translateList = [ "group" ], // 团队
  335. $(".gallery-info tr:nth-of-type(1) > td:nth-of-type(2) a").each(each_fun3)),
  336. // 类型
  337. translateList = [ "reclass" ], $(".dj-content tr:nth-of-type(2) > td:nth-of-type(2) a").each(each_fun3),
  338. is) {
  339. // el.html('<a href="/type/' + el.text() + '-all.html">' + el.text() + '</a>')
  340. $(".gallery-info tr:nth-of-type(2) > td:nth-of-type(2)").find("a").each(each_fun3);
  341. }
  342. })();
  343. }, $ = unsafeWindow.jQuery;
  344. {
  345. let get_galleryinfo_l = 0, galleryinfo_datas = [];
  346. const galleryinfos = {}, get_galleryinfo_fnish = () => {
  347. $(".gallery-content > div > h1.lillie > a").each(each_fun);
  348. }, get_galleryinfo = (url, retry) => {
  349. $.ajax({
  350. type: "get",
  351. url,
  352. dataType: "text",
  353. success: response => {
  354. galleryinfo_datas.push(response.replace(/.*?galleryinfo *=/, "galleryinfos[" + url.replace(/.*\/([0-9]+).js$/, "'$1'") + "]= ")),
  355. --get_galleryinfo_l || (new Function("galleryinfos", galleryinfo_datas.join("\n"))(galleryinfos),
  356. galleryinfo_datas = [], get_galleryinfo_fnish());
  357. },
  358. error: () => retry && setTimeout(get_galleryinfo, 500, url, retry - 1)
  359. });
  360. }, each_fun = function() {
  361. const match = this.href.match(/-([0-9]+)\.html/);
  362. if (!match) return;
  363. const galleryinfo = galleryinfos[match[1]];
  364. galleryinfo && $(this).before("(" + galleryinfo.files.length + ")");
  365. }, each_fun2 = function() {
  366. const match = this.href.match(/-([0-9]+)\.html/);
  367. match && !galleryinfos[match[1]] && (get_galleryinfo_l++, get_galleryinfo("//" + unsafeWindow.domain + "/galleries/" + match[1] + ".js", 10));
  368. }, _limitLists = (el = $(".gallery-content > div > h1.lillie > a")) => {
  369. el.length && (el.each(each_fun2), get_galleryinfo_l || get_galleryinfo_fnish(),
  370. json && !translate_lock && (translate_lock = !0, translate(), translate_lock = !1),
  371. is_limitLists = !0, main());
  372. };
  373. let _$ = () => {
  374. if (!$) return;
  375. _$ = () => $, console.log("开始劫持 limitLists()"), unsafeWindow.limitLists ? unsafeWindow.limitLists = _limitLists : Object.defineProperty(unsafeWindow, "limitLists", {
  376. get: () => _limitLists,
  377. set() {}
  378. });
  379. const el = $(".gallery-content > div > h1.lillie > a");
  380. return el.length && _limitLists(el), $;
  381. };
  382. unsafeWindow.jQuery ? (console.warn("脚本被延迟加载"), _$()) : Object.defineProperty(unsafeWindow, "$", {
  383. get: () => _$(),
  384. set(value) {
  385. $ = value;
  386. }
  387. });
  388. }
  389. function saveAs(blob, filename) {
  390. const url = URL.createObjectURL(blob), save_link = document.createElement("a");
  391. save_link.href = url, save_link.download = filename, document.body.appendChild(save_link),
  392. save_link.click(), save_link.remove();
  393. }
  394. if (location.pathname.startsWith("/reader/")) {
  395. function end() {
  396. console.log("end()");
  397. // 改变hash不添加历史
  398. const script = document.createElement("script");
  399. script.type = "text/javascript";
  400. const fns = [ "singlePageChange", "mobile_singlePageChange", "twoPageChange", "mobile_twoPageChange" ];
  401. for (const index in fns) fns[index] = unsafeWindow[fns[index]].toString().replace(/location.hash *= *([A-z]*);/g, "location.replace(location.pathname+'#'+$1);");
  402. script.innerHTML = "'use strict'\n" + fns.join("\n"), document.body.appendChild(script);
  403. // 取消在图片上隐藏鼠标指针
  404. const make_image_element_ = unsafeWindow.make_image_element;
  405. unsafeWindow.make_image_element = function(...args) {
  406. return args.length > 4 && (
  407. // 取消 img.onmouseover 事件
  408. args[4] = void 0), make_image_element_.apply(this, args);
  409. };
  410. // 修复 preventDefault报错
  411. const addEventListener_ = document.addEventListener;
  412. if (document.addEventListener = function(...args) {
  413. return "touchmove" === args[0] && (2 == args.length && args.push({
  414. passive: !1
  415. }), document.addEventListener = addEventListener_), addEventListener_.apply(this, args);
  416. }, GM_addStyle("\n#comicImages.fitVertical > picture {\n display: contents;\n}\n#comicImages.fitVertical {\n height: calc(100% - 41px);\n display: flex;\n align-items: center;\n justify-content: center;\n}\n#comicImages.fitVertical img {\n max-height: 100%;\n width: auto;\n height: auto;\n max-width: calc(100% - 4px);\n}\n#mobileImages.fitVertical {\n height: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n#mobileImages.fitVertical img {\n max-height: 100%;\n width: auto;\n height: auto;\n max-width: 100%;\n}\n"),
  417. unsafeWindow.mobile_fitHorizontal = unsafeWindow.mobile_fitVertical, unsafeWindow.parent === unsafeWindow) return;
  418. // iframe
  419. $(".mobile-navbar-inner>.gallery-link").remove(), $(".mobile-navbar-inner>.mobile-nav-right").css("float", "left"),
  420. $(".container>a.brand").remove(), $(".container>.btn-navbar").css("float", "left"),
  421. $("ul.pull-right").css("float", "left");
  422. unsafeWindow.addEventListener("hashchange", (() => {
  423. const hash = location.hash;
  424. unsafeWindow.parent.postMessage("" === hash ? "#1" : hash);
  425. } // 向父页面发送消息
  426. ), !1);
  427. }
  428. "loading" !== document.readyState ? (console.warn(document.readyState), end()) : document.addEventListener("DOMContentLoaded", end, {
  429. capture: !0,
  430. once: !0
  431. });
  432. }
  433. /******/})();