Pixiv Previewer

显示大图预览,按热门度排序(pixiv_sk)。Show Preview, ands sort by bookmark count.

目前为 2019-12-01 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Pixiv Previewer
  3. // @namespace https://github.com/Ocrosoft/PixivPreviewer
  4. // @version 3.0.8
  5. // @description 显示大图预览,按热门度排序(pixiv_sk)。Show Preview, ands sort by bookmark count.
  6. // @author Ocrosoft
  7. // @match *://www.pixiv.net/*
  8. // @grant none
  9. // @compatible Chrome
  10. // require https://unpkg.com/jelly-switch@0.2.3/lib/index.min.js
  11. // ==/UserScript==
  12.  
  13. // 测试 JQuery,如果不支持就插入
  14. //var $ = function () { };
  15. try {
  16. $();
  17. } catch (e) {
  18. var script = document.createElement('script');
  19. script.src = 'https://code.jquery.com/jquery-2.2.4.min.js';
  20. document.head.appendChild(script);
  21. }
  22.  
  23. var Languages = {
  24. // 中文-中国大陆
  25. zh_CN: 0,
  26. // 英语-美国
  27. en_US: 1,
  28. };
  29. var LogLevel = {
  30. None: 0,
  31. Error: 1,
  32. Warning: 2,
  33. Info: 3,
  34. Elements: 4,
  35. };
  36. function DoLog(level, msgOrElement) {
  37. if (level <= g_logLevel) {
  38. var prefix = '%c';
  39. var param = '';
  40.  
  41. if (level == LogLevel.Error) {
  42. prefix += '[Error]';
  43. param = 'color:#ff0000';
  44. } else if (level == LogLevel.Warning) {
  45. prefix += '[Warning]';
  46. param = 'color:#ffa500';
  47. } else if (level == LogLevel.Info) {
  48. prefix += '[Info]';
  49. param = 'color:#000000';
  50. } else if (level == LogLevel.Elements) {
  51. prefix += 'Elements';
  52. param = 'color:#000000';
  53. }
  54.  
  55. if (level != LogLevel.Elements) {
  56. console.log(prefix + msgOrElement, param);
  57. } else {
  58. console.log(msgOrElement);
  59. }
  60.  
  61. if (++g_logCount > 512) {
  62. console.clear();
  63. g_logCount = 0;
  64. }
  65. }
  66. }
  67.  
  68. // 版本号,第三位不需要跟脚本的版本号对上,第三位更新只有需要弹更新提示的时候才需要更新这里
  69. var g_version = '3.0.6';
  70. // 添加收藏需要这个
  71. var g_csrfToken = '';
  72. // 打的日志数量,超过一定数值清空控制台
  73. var g_logCount = 0;
  74. // 当前页面类型
  75. var g_pageType = -1;
  76. // 图片详情页的链接,使用时替换 #id#
  77. var g_artworkUrl = '/artworks/#id#';
  78. // 获取图片链接的链接
  79. var g_getArtworkUrl = '/ajax/illust/#id#/pages';
  80. // 获取动图下载链接的链接
  81. var g_getUgoiraUrl = '/ajax/illust/#id#/ugoira_meta';
  82. // 鼠标位置
  83. var g_mousePos = { x: 0, y: 0 };
  84. // 加载中图片
  85. var g_loadingImage = 'https://pp-1252089172.cos.ap-chengdu.myqcloud.com/loading.gif';
  86. // 页面打开时的 url
  87. var initialUrl = location.href;
  88. // 默认设置,仅用于首次脚本初始化
  89. var g_defaultSettings = {
  90. 'enablePreview': 1,
  91. 'enableSort': 1,
  92. 'enableAnimeDownload': 1,
  93. 'original': 0,
  94. 'pageCount': 2,
  95. 'favFilter': 0,
  96. 'hideFavorite': 0,
  97. 'linkBlank': 1,
  98. 'pageByKey': 0,
  99. 'version': g_version,
  100. };
  101. // 设置
  102. var g_settings;
  103. // 日志等级
  104. var g_logLevel = LogLevel.Elements;
  105. // 排序时同时请求收藏量的 Request 数量,没必要太多,并不会加快速度
  106. var g_maxXhr = 10;
  107.  
  108. // 页面相关的一些预定义,包括处理页面元素等
  109. var PageType = {
  110. // 搜索
  111. Search: 0,
  112. // 关注的新作品
  113. BookMarkNew: 1,
  114. // 发现
  115. Discovery: 2,
  116. // 用户主页
  117. Member: 3,
  118. // 首页
  119. Home: 4,
  120. // 排行榜
  121. Ranking: 5,
  122. // 大家的新作品
  123. NewIllust: 6,
  124. // R18
  125. R18: 7,
  126. // 自己的收藏页
  127. BookMark: 8,
  128. // 动态
  129. Stacc: 9,
  130. // 作品详情页(处理动图预览及下载)
  131. Artwork: 10,
  132.  
  133. // 总数
  134. PageTypeCount: 11,
  135. };
  136. var Pages = {};
  137. /* Pages 必须实现的函数
  138. * PageTypeString: string,字符串形式的 PageType
  139. * bool CheckUrl: function(string url),用于检查一个 url 是否是当前页面的目标 url
  140. * ReturnMap ProcessPageElements: function(),处理页面(寻找图片元素、添加属性等),返回 ReturnMap
  141. * ReturnMap GetProcessedPageElements: function(), 返回上一次 ProcessPageElements 的返回值(如果没有上次调用则调用一次)
  142. * Object GetToolBar: function(), 返回工具栏元素(右下角那个,用来放设置按钮)
  143. * HasAutoLoad: bool,表示这个页面是否有自动加载功能
  144. */
  145. var ReturnMapSample = {
  146. // 页面是否加载完成,false 意味着后面的成员无效
  147. loadingComplete: false,
  148. // 控制元素,每个图片的鼠标响应元素
  149. controlElements: [],
  150. };
  151. var ControlElementsAttributesSample = {
  152. // 图片信息,内容如下:
  153. // [必需] 图片 id
  154. illustId: 0,
  155. // [必需] 图片类型(0:普通图片,2:动图)
  156. illustType: 0,
  157. // [必需] 页数
  158. pageCount: 1,
  159. // [可选] 标题
  160. title: '',
  161. // [可选] 作者 id
  162. userId: 0,
  163. // [可选] 作者昵称
  164. userName: '',
  165. // [可选] 收藏数
  166. bookmarkCount: 0,
  167. };
  168.  
  169. Pages[PageType.Search] = {
  170. PageTypeString: 'SearchPage',
  171. CheckUrl: function (url) {
  172. return /^https?:\/\/www.pixiv.net\/tags\/.*\/artworks/.test(url);
  173. //return /^https?:\/\/www.pixiv.net\/search.php.*/.test(url);
  174. },
  175. ProcessPageElements: function () {
  176. var returnMap = {
  177. loadingComplete: false,
  178. controlElements: [],
  179. };
  180.  
  181. var sections = $('section');
  182. DoLog(LogLevel.Info, 'Page has ' + sections.length + ' <section>.');
  183. DoLog(LogLevel.Elements, sections);
  184. // 先对 section 进行评分
  185. var sectionIndex = -1;
  186. var bestScore = -99;
  187. sections.each(function (i, e) {
  188. var section = $(e);
  189. var score = 0;
  190. if (section.find('ul').length > 0) {
  191. var childrenCount = section.children().length;
  192. if (childrenCount != 2) {
  193. DoLog(LogLevel.Warning, '<ul> was found in this <section>, but it has ' + childrenCount + ' children!');
  194. score--;
  195. }
  196. var ul = section.find('ul');
  197. if (ul.length > 1) {
  198. DoLog(LogLevel.Warning, 'This section has more than one <ul>?');
  199. score--;
  200. }
  201. if ($(ul.parent().get(0)).css('display') == 'none' || $(ul.get(0)).css('display') == 'none') {
  202. DoLog(LogLevel.Info, '<ul> or it\'s parentNode is not visible now, continue waiting.');
  203. sectionIndex = -1;
  204. bestScore = 999;
  205. return false;
  206. }
  207. if ($(ul.get(0)).next().length === 0) {
  208. DoLog(LogLevel.Info, 'Page selector not exists, continue waiting.');
  209. sectionIndex = -1;
  210. bestScore = 999;
  211. return false;
  212. }
  213. var lis = ul.find('li');
  214. if (lis.length === 0) {
  215. DoLog(LogLevel.Info, 'This <ul> has 0 children, will be skipped.');
  216. return false;
  217. }
  218. if ($(lis.get(0)).find('figure').length > 0) {
  219. DoLog(LogLevel.Warning, '<figure> was found in the first <li>, continue waiting.');
  220. sectionIndex = -1;
  221. bestScore = 999;
  222. return false;
  223. }
  224. if (lis.length > 4) {
  225. score += 5;
  226. }
  227. if (score > bestScore) {
  228. bestScore = score;
  229. sectionIndex = i;
  230. }
  231. } else {
  232. DoLog(LogLevel.Info, 'This section(' + i + ' is not has <ul>, will be skipped.');
  233. }
  234. });
  235.  
  236. if (sectionIndex == -1) {
  237. if (bestScore < 100) {
  238. DoLog(LogLevel.Error, 'No suitable <section>!');
  239. }
  240. return returnMap;
  241. }
  242.  
  243. var lis = $(sections[sectionIndex]).find('ul').find('li');
  244. lis.each(function (i, e) {
  245. var li = $(e);
  246. var control = li.children('div:first');
  247.  
  248. // 只填充必须的几个,其他的目前用不着
  249. var ctlAttrs = {
  250. illustId: 0,
  251. illustType: 0,
  252. pageCount: 1,
  253. };
  254.  
  255. var img = $(li.find('img').get(0));
  256. var imageLink = img.parent().parent();
  257. var additionDiv = img.parent().prev();
  258. var animationSvg = img.parent().find('svg');
  259. var pageCountSpan = additionDiv.find('span');
  260.  
  261. if (img == null || imageLink == null) {
  262. DoLog(LogLevel.Warning, 'Can not found img or imageLink, skip this.');
  263. return;
  264. }
  265.  
  266. var link = imageLink.attr('href');
  267. if (link == null) {
  268. DoLog(LogLevel.Warning, 'Invalid href, skip this.');
  269. return;
  270. }
  271. var linkMatched = link.match(/artworks\/(\d+)/);
  272. var illustId = '';
  273. if (linkMatched) {
  274. ctlAttrs.illustId = linkMatched[1];
  275. } else {
  276. DoLog(LogLevel.Error, 'Get illustId failed, skip this list item!');
  277. return;
  278. }
  279. if (animationSvg.length > 0) {
  280. ctlAttrs.illustType = 2;
  281. }
  282. if (pageCountSpan.length > 0) {
  283. ctlAttrs.pageCount = parseInt(pageCountSpan.text());
  284. }
  285.  
  286. // 添加 attr
  287. li.attr({
  288. 'illustId': ctlAttrs.illustId,
  289. 'illustType': ctlAttrs.illustType,
  290. 'pageCount': ctlAttrs.pageCount
  291. });
  292.  
  293. li.addClass('pp-control');
  294. });
  295. returnMap.controlElements = $('.pp-control');
  296. this.private.pageSelector = $($(sections[sectionIndex]).find('ul').get(0)).next().get(0);
  297. returnMap.loadingComplete = true;
  298. this.private.imageListConrainer = $(sections[sectionIndex]).find('ul').get(0);
  299.  
  300. DoLog(LogLevel.Info, 'Process page elements complete.');
  301. DoLog(LogLevel.Elements, returnMap);
  302.  
  303. this.private.returnMap = returnMap;
  304. return returnMap;
  305. },
  306. GetProcessedPageElements: function () {
  307. if (this.private.returnMap == null) {
  308. return this.ProcessPageElements();
  309. }
  310. return this.private.returnMap;
  311. },
  312. GetToolBar: function () {
  313. return $('#root').children('div:last').prev().find('li:first').parent().get(0);
  314. },
  315. HasAutoLoad: false,
  316. GetImageListContainer: function () {
  317. return this.private.imageListConrainer;
  318. },
  319. GetFirstImageElement: function () {
  320. return $(this.private.imageListConrainer).find('li').get(0);
  321. },
  322. GetPageSelector: function () {
  323. return this.private.pageSelector;
  324. },
  325. private: {
  326. imageListContainer: null,
  327. pageSelector: null,
  328. returnMap: null,
  329. },
  330. };
  331. Pages[PageType.BookMarkNew] = {
  332. PageTypeString: 'BookMarkNewPage',
  333. CheckUrl: function (url) {
  334. return /^https:\/\/www.pixiv.net\/bookmark_new_illust.php.*/.test(url);
  335. },
  336. ProcessPageElements: function () {
  337. var returnMap = {
  338. loadingComplete: false,
  339. controlElements: [],
  340. };
  341.  
  342. var containerDiv = $('#js-mount-point-latest-following').children('div:first');
  343. if (containerDiv.length > 0) {
  344. DoLog(LogLevel.Info, 'Found container div.');
  345. DoLog(LogLevel.Elements, containerDiv);
  346. } else {
  347. DoLog(LogLevel.Error, 'Can not found container div.');
  348. return returnMap;
  349. }
  350.  
  351. containerDiv.children().each(function (i, e) {
  352. var _this = $(e);
  353.  
  354. var figure = _this.find('figure');
  355. if (figure.length === 0) {
  356. DoLog(LogLevel.Warning, 'Can not found <fingure>, skip this element.');
  357. return;
  358. }
  359.  
  360. var link = figure.children('div:first').children('a:first');
  361. if (link.length === 0) {
  362. DoLog(LogLevel.Warning, 'Can not found <a>, skip this element.');
  363. return;
  364. }
  365.  
  366. var ctlAttrs = {
  367. illustId: 0,
  368. illustType: 0,
  369. pageCount: 1,
  370. };
  371.  
  372. var href = link.attr('href');
  373. if (href == null || href === '') {
  374. DoLog(LogLevel.Warning, 'No href found, skip.');
  375. return;
  376. } else {
  377. var matched = href.match(/artworks\/(\d+)/);
  378. if (matched) {
  379. ctlAttrs.illustId = matched[1];
  380. } else {
  381. DoLog(LogLevel.Warning, 'Can not found illust id, skip.');
  382. return;
  383. }
  384. }
  385.  
  386. if (link.children().length > 1) {
  387. if (link.children('div:first').find('span').length > 0) {
  388. var span = link.children('div:first').children('span:first');
  389. if (span.length === 0) {
  390. DoLog(LogLevel.Warning, 'Can not found <span>, skip this element.');
  391. return;
  392. }
  393. ctlAttrs.pageCount = span.text();
  394. } else {
  395. ctlAttrs.illustType = 2;
  396. }
  397. }
  398.  
  399. _this.attr({
  400. 'illustId': ctlAttrs.illustId,
  401. 'illustType': ctlAttrs.illustType,
  402. 'pageCount': ctlAttrs.pageCount
  403. });
  404.  
  405. returnMap.controlElements.push(e);
  406. });
  407.  
  408. DoLog(LogLevel.Info, 'Process page elements complete.');
  409. DoLog(LogLevel.Elements, returnMap);
  410.  
  411. returnMap.loadingComplete = true;
  412. this.private.returnMap = returnMap;
  413. return returnMap;
  414. },
  415. GetProcessedPageElements: function () {
  416. if (this.private.returnMap == null) {
  417. return this.ProcessPageElements();
  418. }
  419. return this.private.returnMap;
  420. },
  421. GetToolBar: function () {
  422. return $('._toolmenu').get(0);
  423. },
  424. HasAutoLoad: false,
  425. private: {
  426. returnMap: null,
  427. },
  428. };
  429. Pages[PageType.Discovery] = {
  430. PageTypeString: 'DiscoveryPage',
  431. CheckUrl: function (url) {
  432. return /^https?:\/\/www.pixiv.net\/discovery.*/.test(url);
  433. },
  434. ProcessPageElements: function () {
  435. var returnMap = {
  436. loadingComplete: false,
  437. controlElements: [],
  438. };
  439.  
  440. var containerDiv = $('.gtm-illust-recommend-zone');
  441. if (containerDiv.length > 0) {
  442. DoLog(LogLevel.Info, 'Found container div.');
  443. DoLog(LogLevel.Elements, containerDiv);
  444. } else {
  445. DoLog(LogLevel.Error, 'Can not found container div.');
  446. return returnMap;
  447. }
  448.  
  449. containerDiv.children().each(function (i, e) {
  450. var _this = $(e);
  451.  
  452. var figure = _this.find('figure');
  453. if (figure.length === 0) {
  454. DoLog(LogLevel.Warning, 'Can not found <fingure>, skip this element.');
  455. return;
  456. }
  457.  
  458. var link = figure.children('div:first').children('a:first');
  459. if (link.length === 0) {
  460. DoLog(LogLevel.Warning, 'Can not found <a>, skip this element.');
  461. return;
  462. }
  463.  
  464. var ctlAttrs = {
  465. illustId: 0,
  466. illustType: 0,
  467. pageCount: 1,
  468. };
  469.  
  470. var href = link.attr('href');
  471. if (href == null || href === '') {
  472. DoLog(LogLevel.Warning, 'No href found, skip.');
  473. return;
  474. } else {
  475. var matched = href.match(/artworks\/(\d+)/);
  476. if (matched) {
  477. ctlAttrs.illustId = matched[1];
  478. } else {
  479. DoLog(LogLevel.Warning, 'Can not found illust id, skip.');
  480. return;
  481. }
  482. }
  483.  
  484. if (link.children().length > 1) {
  485. if (link.children('div:first').find('span').length > 0) {
  486. var span = link.children('div:first').children('span:first');
  487. if (span.length === 0) {
  488. DoLog(LogLevel.Warning, 'Can not found <span>, skip this element.');
  489. return;
  490. }
  491. ctlAttrs.pageCount = span.text();
  492. } else if (link.children('div:last').find('svg').length > 0) {
  493. ctlAttrs.illustType = 2;
  494. }
  495. }
  496.  
  497. _this.attr({
  498. 'illustId': ctlAttrs.illustId,
  499. 'illustType': ctlAttrs.illustType,
  500. 'pageCount': ctlAttrs.pageCount
  501. });
  502.  
  503. returnMap.controlElements.push(e);
  504. });
  505.  
  506. DoLog(LogLevel.Info, 'Process page elements complete.');
  507. DoLog(LogLevel.Elements, returnMap);
  508.  
  509. returnMap.loadingComplete = true;
  510. this.private.returnMap = returnMap;
  511. return returnMap;
  512. },
  513. GetProcessedPageElements: function () {
  514. if (this.private.returnMap == null) {
  515. return this.ProcessPageElements();
  516. }
  517. return this.private.returnMap;
  518. },
  519. GetToolBar: function () {
  520. return $('._toolmenu').get(0);
  521. },
  522. HasAutoLoad: true,
  523. private: {
  524. returnMap: null,
  525. },
  526. };
  527. Pages[PageType.Member] = {
  528. PageTypeString: 'MemberPage/MemberIllustPage/MemberBookMark',
  529. CheckUrl: function (url) {
  530. return /^https?:\/\/www.pixiv.net\/member.php\?id=.*/.test(url) ||
  531. /^https:\/\/www.pixiv.net\/member_illust.php.*/.test(url) ||
  532. /^https:\/\/www.pixiv.net\/bookmark.php\?.*/.test(url);
  533. },
  534. ProcessPageElements: function () {
  535. var returnMap = {
  536. loadingComplete: false,
  537. controlElements: [],
  538. };
  539.  
  540. var sections = $('section');
  541. DoLog(LogLevel.Info, 'Page has ' + sections.length + ' <section>.');
  542. DoLog(LogLevel.Elements, sections);
  543.  
  544. var lis = sections.find('ul').find('li');
  545. lis.each(function (i, e) {
  546. var li = $(e);
  547. var control = li.children('div:first');
  548.  
  549. // 只填充必须的几个,其他的目前用不着
  550. var ctlAttrs = {
  551. illustId: 0,
  552. illustType: 0,
  553. pageCount: 1,
  554. };
  555.  
  556. // 有 figure 的是 lazy load,读取不到数据
  557. if (li.find('figure').length === 0) {
  558. var img = $(li.find('img').get(0));
  559. var imageLink = img.parent().parent();
  560. var additionDiv = img.parent().prev();
  561. var animationSvg = img.parent().find('svg');
  562. var pageCountSpan = additionDiv.find('span');
  563.  
  564. var link = imageLink.attr('href');
  565. if (link == null || link === '') {
  566. DoLog(LogLevel.Warning, 'Can not found illust id, skip this.');
  567. return;
  568. }
  569.  
  570. var linkMatched = link.match(/artworks\/(\d+)/);
  571. var illustId = '';
  572. if (linkMatched) {
  573. ctlAttrs.illustId = linkMatched[1];
  574. } else {
  575. DoLog(LogLevel.Error, 'Get illustId failed, skip this list item!');
  576. return;
  577. }
  578. if (animationSvg.length > 0) {
  579. ctlAttrs.illustType = 2;
  580. }
  581. if (pageCountSpan.length > 0) {
  582. ctlAttrs.pageCount = parseInt(pageCountSpan.text());
  583. }
  584.  
  585. // 添加 attr
  586. li.attr({
  587. 'illustId': ctlAttrs.illustId,
  588. 'illustType': ctlAttrs.illustType,
  589. 'pageCount': ctlAttrs.pageCount
  590. });
  591. }
  592.  
  593. li.addClass('pp-control');
  594. });
  595. returnMap.controlElements = $('.pp-control');
  596. returnMap.loadingComplete = true;
  597.  
  598. DoLog(LogLevel.Info, 'Process page elements complete.');
  599. DoLog(LogLevel.Elements, returnMap);
  600.  
  601. this.private.returnMap = returnMap;
  602. return returnMap;
  603. },
  604. GetProcessedPageElements: function () {
  605. if (this.private.returnMap == null) {
  606. return this.ProcessPageElements();
  607. }
  608. return this.private.returnMap;
  609. },
  610. GetToolBar: function () {
  611. var div = $('#root').children('div');
  612. for (var i = div.length - 1; i >= 0; i--) {
  613. if ($(div.get(i)).children('ul').length > 0) {
  614. return $(div.get(i)).children('ul').get(0);
  615. }
  616. }
  617. },
  618. HasAutoLoad: false,
  619. private: {
  620. returnMap: null,
  621. },
  622. };
  623. Pages[PageType.Home] = {
  624. PageTypeString: 'HomePage',
  625. CheckUrl: function (url) {
  626. var patterns = [
  627. /https?:\/\/www.pixiv.net\/$/,
  628. /https?:\/\/www.pixiv.net$/,
  629. /https?:\/\/www.pixiv.net\?.*/,
  630. /https?:\/\/www.pixiv.net\/\?.*/,
  631. ];
  632. for (var i = 0; i < patterns.length; i++) {
  633. if (patterns[i].test(url)) {
  634. return true;
  635. }
  636. }
  637. return false;
  638. },
  639. ProcessPageElements: function () {
  640. var returnMap = {
  641. loadingComplete: false,
  642. controlElements: [],
  643. };
  644.  
  645. var uls = $('._image-items');
  646.  
  647. DoLog(LogLevel.Info, 'This page has ' + uls.length + ' <ul>.');
  648. if (uls.length < 1) {
  649. DoLog(LogLevel.Warning, 'Less than 1 <ul>, continue waiting.');
  650. return returnMap;
  651. } else if (uls.length != 4) {
  652. DoLog(LogLevel.Warning, 'Normaly, should found 4 <ul>.');
  653. }
  654.  
  655. uls.each(function (i, e) {
  656. var _this = $(e);
  657.  
  658. var li = _this.find('.image-item');
  659. if (li.length < 1) {
  660. DoLog(LogLevel.Warning, 'This <ul> has 0 <li>, will be skipped.');
  661. return;
  662. }
  663.  
  664. li.each(function (j, ee) {
  665. var __this = $(ee);
  666.  
  667. var ctlAttrs = {
  668. illustId: 0,
  669. illustType: 0,
  670. pageCount: 1,
  671. };
  672.  
  673. var illustId = __this.find('a:first').attr('data-gtm-recommend-illust-id') || __this.find('img:first').attr('data-id');
  674. if (illustId == null) {
  675. DoLog(LogLevel.Warning, 'Can not found illust id of this image, skip.');
  676. return;
  677. } else {
  678. ctlAttrs.illustId = illustId;
  679. }
  680. var pageCount = __this.find('.page-count');
  681. if (pageCount.length > 0) {
  682. pageCount = parseInt(pageCount.find('span').text());
  683. }
  684. if (__this.find('a:first').hasClass('ugoku-illust')) {
  685. ctlAttrs.illustType = 2;
  686. }
  687.  
  688. __this.attr({
  689. 'illustId': ctlAttrs.illustId,
  690. 'illustType': ctlAttrs.illustType,
  691. 'pageCount': ctlAttrs.pageCount
  692. });
  693.  
  694. returnMap.controlElements.push(ee);
  695. });
  696. });
  697.  
  698. DoLog(LogLevel.Info, 'Process page elements complete.');
  699. DoLog(LogLevel.Elements, returnMap);
  700.  
  701. returnMap.loadingComplete = true;
  702. this.private.returnMap = returnMap;
  703. return returnMap;
  704. },
  705. GetProcessedPageElements: function () {
  706. if (this.private.returnMap == null) {
  707. return this.ProcessPageElements();
  708. }
  709. return this.private.returnMap;
  710. },
  711. GetToolBar: function () {
  712. return $('._toolmenu').get(0);
  713. },
  714. HasAutoLoad: false,
  715. private: {
  716. returnMap: null,
  717. },
  718. };
  719. Pages[PageType.Ranking] = {
  720. PageTypeString: 'RankingPage',
  721. CheckUrl: function (url) {
  722. return /^https?:\/\/www.pixiv.net\/ranking.php.*/.test(url);
  723. },
  724. ProcessPageElements: function () {
  725. var returnMap = {
  726. loadingComplete: false,
  727. controlElements: [],
  728. };
  729.  
  730. var works = $('._work');
  731.  
  732. DoLog(LogLevel.Info, 'Found .work, length: ' + works.length);
  733. DoLog(LogLevel.Elements, works);
  734.  
  735. works.each(function (i, e) {
  736. var _this = $(e);
  737.  
  738. var ctlAttrs = {
  739. illustId: 0,
  740. illustType: 0,
  741. pageCount: 1,
  742. };
  743.  
  744. var href = _this.attr('href');
  745.  
  746. if (href == null || href === '') {
  747. DoLog('Can not found illust id, skip this.');
  748. return;
  749. }
  750.  
  751. var matched = href.match(/artworks\/(\d+)/);
  752. if (matched) {
  753. ctlAttrs.illustId = matched[1];
  754. } else {
  755. DoLog('Can not found illust id, skip this.');
  756. return;
  757. }
  758.  
  759. if (_this.hasClass('multiple')) {
  760. ctlAttrs.pageCount = _this.find('.page-count').find('span').text();
  761. }
  762.  
  763. if (_this.hasClass('ugoku-illust')) {
  764. ctlAttrs.illustType = 2;
  765. }
  766.  
  767. // 添加 attr
  768. _this.attr({
  769. 'illustId': ctlAttrs.illustId,
  770. 'illustType': ctlAttrs.illustType,
  771. 'pageCount': ctlAttrs.pageCount
  772. });
  773.  
  774. returnMap.controlElements.push(e);
  775. });
  776.  
  777. returnMap.loadingComplete = true;
  778.  
  779. DoLog(LogLevel.Info, 'Process page elements complete.');
  780. DoLog(LogLevel.Elements, returnMap);
  781.  
  782. this.private.returnMap = returnMap;
  783. return returnMap;
  784. },
  785. GetProcessedPageElements: function () {
  786. if (this.private.returnMap == null) {
  787. return this.ProcessPageElements();
  788. }
  789. return this.private.returnMap;
  790. },
  791. GetToolBar: function () {
  792. return $('._toolmenu').get(0);
  793. },
  794. HasAutoLoad: false,
  795. private: {
  796. returnMap: null,
  797. },
  798. };
  799. Pages[PageType.NewIllust] = {
  800. PageTypeString: 'NewIllustPage',
  801. CheckUrl: function (url) {
  802. return /^https?:\/\/www.pixiv.net\/new_illust.php.*/.test(url);
  803. },
  804. ProcessPageElements: function () {
  805. var returnMap = {
  806. loadingComplete: false,
  807. controlElements: [],
  808. };
  809.  
  810. var firstDiv = $('#root').children('div:first');
  811. if (firstDiv.length === 0) {
  812. DoLog(LogLevel.Error, 'Can not found images\' container div!');
  813. return returnMap;
  814. }
  815.  
  816. var ul = firstDiv.children('div:last').find('ul');
  817. if (ul.length === 0) {
  818. DoLog(LogLevel.Error, 'Can not found <ul>!');
  819. return returnMap;
  820. }
  821.  
  822. ul.find('li').each(function (i, e) {
  823. var _this = $(e);
  824.  
  825. var link = _this.find('a:first');
  826. var href = link.attr('href');
  827. if (href == null || href === '') {
  828. DoLog(LogLevel.Error, 'Can not found illust id, skip this.');
  829. return;
  830. }
  831.  
  832. var ctlAttrs = {
  833. illustId: 0,
  834. illustType: 0,
  835. pageCount: 1,
  836. };
  837.  
  838. var matched = href.match(/artworks\/(\d+)/);
  839. if (matched) {
  840. ctlAttrs.illustId = matched[1];
  841. } else {
  842. DoLog(LogLevel.Warning, 'Can not found illust id, skip this.');
  843. return;
  844. }
  845.  
  846. if (link.children().length > 1) {
  847. var span = link.find('svg').next();
  848. if (span.length > 0) {
  849. ctlAttrs.pageCount = span.text();
  850. } else if (link.find('svg').length > 0) {
  851. ctlAttrs.illustType = 2;
  852. }
  853. }
  854.  
  855. _this.attr({
  856. 'illustId': ctlAttrs.illustId,
  857. 'illustType': ctlAttrs.illustType,
  858. 'pageCount': ctlAttrs.pageCount
  859. });
  860.  
  861. returnMap.controlElements.push(e);
  862. });
  863.  
  864. returnMap.loadingComplete = true;
  865.  
  866. DoLog(LogLevel.Info, 'Process page elements complete.');
  867. DoLog(LogLevel.Elements, returnMap);
  868.  
  869. this.private.returnMap = returnMap;
  870. return returnMap;
  871. },
  872. GetProcessedPageElements: function () {
  873. if (this.private.returnMap == null) {
  874. return this.ProcessPageElements();
  875. }
  876. return this.private.returnMap;
  877. },
  878. GetToolBar: function () {
  879. var div = $('#root').children('div');
  880. for (var i = div.length - 1; i >= 0; i--) {
  881. if ($(div.get(i)).children('ul').length > 0) {
  882. return $(div.get(i)).children('ul').get(0);
  883. }
  884. }
  885. },
  886. HasAutoLoad: true,
  887. private: {
  888. returnMap: null,
  889. },
  890. };
  891. Pages[PageType.R18] = {
  892. PageTypeString: 'R18Page',
  893. CheckUrl: function (url) {
  894. return /^https?:\/\/www.pixiv.net\/cate_r18.php.*/.test(url);
  895. },
  896. ProcessPageElements: function () {
  897. //
  898. },
  899. GetToolBar: function () {
  900. //
  901. },
  902. HasAutoLoad: false,
  903. };
  904. Pages[PageType.BookMark] = {
  905. PageTypeString: 'BookMarkPage',
  906. CheckUrl: function (url) {
  907. return /^https:\/\/www.pixiv.net\/bookmark.php\/?$/.test(url);
  908. },
  909. ProcessPageElements: function () {
  910. var returnMap = {
  911. loadingComplete: false,
  912. controlElements: [],
  913. };
  914.  
  915. var images = $('.image-item');
  916. DoLog(LogLevel.Info, 'Found images, length: ' + images.length);
  917. DoLog(LogLevel.Elements, images);
  918.  
  919. images.each(function (i, e) {
  920. var _this = $(e);
  921.  
  922. var work = _this.find('._work');
  923. if (work.length === 0) {
  924. DoLog(LogLevel.Warning, 'Can not found ._work, skip this.');
  925. return;
  926. }
  927.  
  928. var ctlAttrs = {
  929. illustId: 0,
  930. illustType: 0,
  931. pageCount: 1,
  932. };
  933.  
  934. var href = work.attr('href');
  935. if (href == null || href === '') {
  936. DoLog(LogLevel.Warning, 'Can not found illust id, skip this.');
  937. return;
  938. }
  939.  
  940. var matched = href.match(/illust_id=(\d+)/);
  941. if (matched) {
  942. ctlAttrs.illustId = matched[1];
  943. } else {
  944. DoLog(LogLevel.Warning, 'Can not found illust id, skip this.');
  945. return;
  946. }
  947.  
  948. if (work.hasClass('multiple')) {
  949. ctlAttrs.pageCount = _this.find('.page-count').find('span').text();
  950. }
  951.  
  952. if (work.hasClass('ugoku-illust')) {
  953. ctlAttrs.illustType = 2;
  954. }
  955.  
  956. // 添加 attr
  957. _this.attr({
  958. 'illustId': ctlAttrs.illustId,
  959. 'illustType': ctlAttrs.illustType,
  960. 'pageCount': ctlAttrs.pageCount
  961. });
  962.  
  963. returnMap.controlElements.push(e);
  964. });
  965.  
  966. returnMap.loadingComplete = true;
  967.  
  968. DoLog(LogLevel.Info, 'Process page elements complete.');
  969. DoLog(LogLevel.Elements, returnMap);
  970.  
  971. this.private.returnMap = returnMap;
  972. return returnMap;
  973. },
  974. GetProcessedPageElements: function () {
  975. if (this.private.returnMap == null) {
  976. return this.ProcessPageElements();
  977. }
  978. return this.private.returnMap;
  979. },
  980. GetToolBar: function () {
  981. return $('._toolmenu').get(0);
  982. },
  983. HasAutoLoad: false,
  984. private: {
  985. returnMap: null,
  986. },
  987. };
  988. Pages[PageType.Stacc] = {
  989. PageTypeString: 'StaccPage',
  990. CheckUrl: function (url) {
  991. return /^https:\/\/www.pixiv.net\/stacc.*/.test(url);
  992. },
  993. ProcessPageElements: function () {
  994. var returnMap = {
  995. loadingComplete: false,
  996. controlElements: [],
  997. };
  998.  
  999. var works = $('._work');
  1000.  
  1001. DoLog(LogLevel.Info, 'Found .work, length: ' + works.length);
  1002. DoLog(LogLevel.Elements, works);
  1003.  
  1004. works.each(function (i, e) {
  1005. var _this = $(e);
  1006.  
  1007. var ctlAttrs = {
  1008. illustId: 0,
  1009. illustType: 0,
  1010. pageCount: 1,
  1011. };
  1012.  
  1013. var href = _this.attr('href');
  1014.  
  1015. if (href == null || href === '') {
  1016. DoLog('Can not found illust id, skip this.');
  1017. return;
  1018. }
  1019.  
  1020. var matched = href.match(/illust_id=(\d+)/);
  1021. if (matched) {
  1022. ctlAttrs.illustId = matched[1];
  1023. } else {
  1024. DoLog('Can not found illust id, skip this.');
  1025. return;
  1026. }
  1027.  
  1028. if (_this.hasClass('multiple')) {
  1029. ctlAttrs.pageCount = _this.find('.page-count').find('span').text();
  1030. }
  1031.  
  1032. if (_this.hasClass('ugoku-illust')) {
  1033. ctlAttrs.illustType = 2;
  1034. }
  1035.  
  1036. // 添加 attr
  1037. _this.attr({
  1038. 'illustId': ctlAttrs.illustId,
  1039. 'illustType': ctlAttrs.illustType,
  1040. 'pageCount': ctlAttrs.pageCount
  1041. });
  1042.  
  1043. returnMap.controlElements.push(e);
  1044. });
  1045.  
  1046. returnMap.loadingComplete = true;
  1047.  
  1048. DoLog(LogLevel.Info, 'Process page elements complete.');
  1049. DoLog(LogLevel.Elements, returnMap);
  1050.  
  1051. this.private.returnMap = returnMap;
  1052. return returnMap;
  1053. },
  1054. GetProcessedPageElements: function () {
  1055. if (this.private.returnMap == null) {
  1056. return this.ProcessPageElements();
  1057. }
  1058. return this.private.returnMap;
  1059. },
  1060. GetToolBar: function () {
  1061. return $('._toolmenu').get(0);
  1062. },
  1063. HasAutoLoad: true,
  1064. private: {
  1065. returnMap: null,
  1066. },
  1067. };
  1068. Pages[PageType.Artwork] = {
  1069. PageTypeString: 'ArtworkPage',
  1070. CheckUrl: function (url) {
  1071. return /^https:\/\/www.pixiv.net\/artworks\/.*/.test(url);
  1072. },
  1073. ProcessPageElements: function () {
  1074. var returnMap = {
  1075. loadingComplete: false,
  1076. controlElements: [],
  1077. };
  1078.  
  1079. // 是动图
  1080. var canvas = $('main').find('figure').find('canvas');
  1081. if ($('main').find('figure').find('canvas').length > 0) {
  1082. this.private.needProcess = true;
  1083. canvas.addClass('pp-canvas');
  1084. }
  1085.  
  1086. returnMap.loadingComplete = true;
  1087. return returnMap;
  1088. },
  1089. GetToolBar: function () {
  1090. var div = $('#root').children('div');
  1091. for (var i = div.length - 1; i >= 0; i--) {
  1092. if ($(div.get(i)).children('ul').length > 0) {
  1093. return $(div.get(i)).children('ul').get(0);
  1094. }
  1095. }
  1096. },
  1097. HasAutoLoad: false,
  1098. Work: function () {
  1099. function AddDownloadButton(div, button, offsetToOffsetTop) {
  1100. if (!g_settings.enableAnimeDownload) {
  1101. return;
  1102. }
  1103.  
  1104. var cloneButton = button.clone().css({ 'bottom': '50px', 'margin': 0, 'padding': 0, 'width': '48px', 'height': '48px', 'opacity': '0.4', 'cursor': 'pointer' });
  1105. cloneButton.get(0).innerHTML = '<svg viewBox="0 0 120 120" style="width: 40px; height: 40px; stroke-width: 10; stroke-linecap: round; stroke-linejoin: round; border-radius: 24px; background-color: black; stroke: limegreen; fill: none;" class="_3Fo0Hjg"><polyline points="60,30 60,90"></polyline><polyline points="30,60 60,90 90,60"></polyline></svg></button>';
  1106.  
  1107. function MoveButton() {
  1108. function getOffset(e) {
  1109. if (e.offsetParent) {
  1110. var offset = getOffset(e.offsetParent);
  1111. return {
  1112. offsetTop: e.offsetTop + offset.offsetTop,
  1113. offsetLeft: e.offsetLeft + offset.offsetLeft,
  1114. };
  1115. } else {
  1116. return {
  1117. offsetTop: e.offsetTop,
  1118. offsetLeft: e.offsetLeft,
  1119. };
  1120. }
  1121. }
  1122.  
  1123. var offset = getOffset(button.get(0));
  1124. DoLog(LogLevel.Info, 'offset of download button: ' + offset.offsetTop + ', ' + offset.offsetLeft);
  1125. DoLog(LogLevel.Elements, offset);
  1126.  
  1127. cloneButton.css({ 'position': 'absolute', 'left': offset.offsetLeft, 'top': offset.offsetTop - 50 - offsetToOffsetTop }).show();
  1128. }
  1129.  
  1130. MoveButton();
  1131. $(window).on('resize', MoveButton);
  1132. div.append(cloneButton);
  1133.  
  1134. cloneButton.mouseover(function () {
  1135. $(this).css('opacity', '0.2');
  1136. }).mouseleave(function () {
  1137. $(this).css('opacity', '0.4');
  1138. }).click(function () {
  1139. var illustId = '';
  1140.  
  1141. var matched = location.href.match(/artworks\/(\d+)/);
  1142. if (matched) {
  1143. illustId = matched[1];
  1144. DoLog(LogLevel.Info, 'IllustId=' + illustId);
  1145. } else {
  1146. DoLog(LogLevel.Error, 'Can not found illust id!');
  1147. return;
  1148. }
  1149.  
  1150. $.ajax(g_getUgoiraUrl.replace('#id#', illustId), {
  1151. method: 'GET',
  1152. success: function (json) {
  1153. DoLog(LogLevel.Elements, json);
  1154.  
  1155. if (json.error == true) {
  1156. DoLog(LogLevel.Error, 'Server response an error: ' + json.message);
  1157. return;
  1158. }
  1159.  
  1160. // 因为浏览器会拦截不同域的 open 操作,绕一下
  1161. var newWindow = window.open('_blank');
  1162. newWindow.location = json.body.originalSrc;
  1163. },
  1164. error: function () {
  1165. DoLog(LogLevel.Error, 'Request zip file failed!');
  1166. }
  1167. });
  1168. });
  1169. }
  1170.  
  1171. if (this.private.needProcess) {
  1172. var canvas = $('.pp-canvas');
  1173.  
  1174. // 预览模式,需要调成全屏,并且添加下载按钮到全屏播放的 div 里
  1175. if (location.href.indexOf('#preview') != -1) {
  1176. canvas.click();
  1177.  
  1178. $('#root').remove();
  1179.  
  1180. var callbackInterval = setInterval(function () {
  1181. var div = $('div[role="presentation"]');
  1182. if (div.length < 1) {
  1183. return;
  1184. }
  1185.  
  1186. DoLog(LogLevel.Info, 'found <div>, continue to next step.');
  1187.  
  1188. clearInterval(callbackInterval);
  1189.  
  1190. var presentationCanvas = div.find('canvas');
  1191. if (presentationCanvas.length < 1) {
  1192. DoLog(LogLevel.Error, 'Can not found canvas in the presentation div.');
  1193. return;
  1194. }
  1195.  
  1196. var width = 0, height = 0;
  1197. var tWidth = presentationCanvas.attr('width');
  1198. var tHeight = presentationCanvas.attr('height');
  1199. if (tWidth && tHeight) {
  1200. width = parseInt(tWidth);
  1201. height = parseInt(tHeight);
  1202. } else {
  1203. tWidth = presentationCanvas.css('width');
  1204. tHeight = presentationCanvas.css('height');
  1205. width = parseInt(tWidth);
  1206. height = parseInt(this);
  1207. }
  1208.  
  1209. var parent = presentationCanvas.parent();
  1210. for (var i = 0; i < 3; i++) {
  1211. parent.get(0).className = '';
  1212. parent = parent.parent();
  1213. }
  1214. presentationCanvas.css({ 'width': width + 'px', 'height': height + 'px', 'cursor': 'default' }).addClass('pp-presentationCanvas');
  1215. var divForStopClick = $('<div class="pp-disableClick"></div>').css({
  1216. 'width': width + 'px', 'height': height + 'px',
  1217. 'opacity': 0,
  1218. 'position': 'absolute', 'top': '0px', 'left': '0px', 'z-index': 99999,
  1219. });
  1220. div.append(divForStopClick);
  1221. div.append(presentationCanvas.next().css('z-index', 99999));
  1222. presentationCanvas.next().remove();
  1223. // 防止预览图消失
  1224. $('html').addClass('pp-main');
  1225.  
  1226. // 调整 canvas 大小的函数
  1227. window.ResizeCanvas = function (newWidth, newHeight) {
  1228. DoLog(LogLevel.Info, 'Resize canvas: ' + newWidth + 'x' + newHeight);
  1229. $('.pp-disableClick').css({ 'width': newWidth, 'height': newHeight });
  1230. $('.pp-presentationCanvas').css({ 'width': newWidth, 'height': newHeight });
  1231. };
  1232. window.GetCanvasSize = function () {
  1233. return {
  1234. width: width,
  1235. height: height,
  1236. };
  1237. }
  1238.  
  1239. // 添加下载按钮
  1240. AddDownloadButton(div, divForStopClick.next(), 0);
  1241.  
  1242. window.parent.PreviewCallback(width, height);
  1243. }, 500);
  1244. }
  1245. // 普通模式,只需要添加下载按钮到内嵌模式的 div 里
  1246. else {
  1247. var div = $('div[role="presentation"]');
  1248. var button = div.find('button');
  1249.  
  1250. var headerRealHeight = parseInt($('header').css('height')) +
  1251. parseInt($('header').css('padding-top')) + parseInt($('header').css('padding-bottom')) +
  1252. parseInt($('header').css('margin-top')) + parseInt($('header').css('margin-bottom')) +
  1253. parseInt($('header').css('border-bottom-width')) + parseInt($('header').css('border-top-width'));
  1254.  
  1255. AddDownloadButton(div, button, headerRealHeight);
  1256. }
  1257. }
  1258. },
  1259. private: {
  1260. needProcess: false,
  1261. },
  1262. };
  1263.  
  1264. function CheckUrlTest() {
  1265. var urls = [
  1266. 'http://www.pixiv.net',
  1267. 'http://www.pixiv.net',
  1268. 'https://www.pixiv.net',
  1269. 'https://www.pixiv.net/',
  1270. 'https://www.pixiv.net/?lang=en',
  1271. 'https://www.pixiv.net/search.php?s_mode=s_tag&word=miku',
  1272. 'https://www.pixiv.net/search.php?word=VOCALOID&s_mode=s_tag_full',
  1273. 'https://www.pixiv.net/discovery',
  1274. 'https://www.pixiv.net/discovery?x=1',
  1275. 'https://www.pixiv.net/member.php?id=3207350',
  1276. 'https://www.pixiv.net/member_illust.php?id=3207350&type=illust',
  1277. 'https://www.pixiv.net/bookmark.php?id=3207350&rest=show',
  1278. 'https://www.pixiv.net/ranking.php?mode=daily&content=ugoira',
  1279. 'https://www.pixiv.net/ranking.php?mode=daily',
  1280. 'https://www.pixiv.net/new_illust.php',
  1281. 'https://www.pixiv.net/new_illust.php?x=1',
  1282. 'https://www.pixiv.net/cate_r18.php',
  1283. 'https://www.pixiv.net/cate_r18.php?x=1',
  1284. 'https://www.pixiv.net/bookmark.php',
  1285. 'https://www.pixiv.net/bookmark.php?x=1',
  1286. 'https://www.pixiv.net/stacc?mode=unify',
  1287. 'https://www.pixiv.net/artworks/77996773',
  1288. 'https://www.pixiv.net/artworks/77996773#preview',
  1289. ];
  1290.  
  1291. for (var j = 0; j < urls.length; j++) {
  1292. for (var i = 0; i < PageType.PageTypeCount; i++) {
  1293. if (Pages[i].CheckUrl(urls[j])) {
  1294. console.log(urls[j]);
  1295. console.log('[' + j + '] is ' + Pages[i].PageTypeString);
  1296. }
  1297. }
  1298. }
  1299. }
  1300.  
  1301. /* ---------------------------------------- 预览 ---------------------------------------- */
  1302. function PixivPreview() {
  1303. var autoLoadInterval = null;
  1304.  
  1305. // 开启预览功能
  1306. function ActivePreview() {
  1307. var returnMap = Pages[g_pageType].GetProcessedPageElements();
  1308. if (!returnMap.loadingComplete) {
  1309. DoLog(LogLevel.Error, 'Page not load, should not call Preview!');
  1310. return;
  1311. }
  1312.  
  1313. // 鼠标进入
  1314. $(returnMap.controlElements).mouseenter(function (e) {
  1315. // 按住 Ctrl键 不显示预览图
  1316. if (e.ctrlKey) {
  1317. return;
  1318. }
  1319.  
  1320. var _this = $(this);
  1321. var illustId = _this.attr('illustId');
  1322. var illustType = _this.attr('illustType');
  1323. var pageCount = _this.attr('pageCount');
  1324.  
  1325. if (illustId == null) {
  1326. DoLog(LogLevel.Error, 'Can not found illustId in this element\'s attrbutes.');
  1327. return;
  1328. }
  1329. if (illustType == null) {
  1330. DoLog(LogLevel.Error, 'Can not found illustType in this element\'s attrbutes.');
  1331. return;
  1332. }
  1333. if (pageCount == null) {
  1334. DoLog(LogLevel.Error, 'Can not found pageCount in this element\'s attrbutes.');
  1335. return;
  1336. }
  1337.  
  1338. // 鼠标位置
  1339. g_mousePos = { x: e.pageX, y: e.pageY };
  1340. // 预览 Div
  1341. var previewDiv = $(document.createElement('div')).addClass('pp-main').attr('illustId', illustId)
  1342. .css({
  1343. 'position': 'absolute', 'z-index': '999999', 'left': g_mousePos.x + 'px', 'top': g_mousePos.y + 'px',
  1344. 'border-style': 'solid', 'border-color': '#6495ed', 'border-width': '2px', 'border-radius': '20px',
  1345. 'width': '48px', 'height': '48px',
  1346. 'background-image': 'url(https://pp-1252089172.cos.ap-chengdu.myqcloud.com/transparent.png)',
  1347. });
  1348. // 添加到 body
  1349. $('.pp-main').remove();
  1350. $('body').append(previewDiv);
  1351.  
  1352. // 加载中图片
  1353. var loadingImg = $(new Image()).addClass('pp-loading').attr('src', g_loadingImage).css({
  1354. 'position': 'absolute', 'border-radius': '20px',
  1355. });
  1356. previewDiv.append(loadingImg);
  1357.  
  1358. // 要显示的预览图节点
  1359. var loadImg = $(new Image()).addClass('pp-image').css({ 'height': '0px', 'width': '0px', 'display': 'none', 'border-radius': '20px' });
  1360. previewDiv.append(loadImg);
  1361.  
  1362. // 原图(笑脸)图标
  1363. var originIcon = $(new Image()).addClass('pp-original').attr('src', 'https://source.pixiv.net/www/images/pixivcomic-favorite.png')
  1364. .css({ 'position': 'absolute', 'bottom': '5px', 'right': '5px', 'display': 'none' });
  1365. previewDiv.append(originIcon);
  1366.  
  1367. // 点击图标新网页打开原图
  1368. originIcon.click(function () {
  1369. window.open($(previewDiv).children('img')[1].src);
  1370. });
  1371.  
  1372. // 右上角张数标记
  1373. var pageCountHTML = '<div class="pp-pageCount" style="display: flex;-webkit-box-align: center;align-items: center;box-sizing: border-box;margin-left: auto;height: 20px;color: rgb(255, 255, 255);font-size: 10px;line-height: 12px;font-weight: bold;flex: 0 0 auto;padding: 4px 6px;background: rgba(0, 0, 0, 0.32);border-radius: 10px;margin-top:5px;margin-right:5px;">\<svg viewBox="0 0 9 10" width="9" height="10" style="stroke: none;line-height: 0;font-size: 0px;fill: currentcolor;"><path d="M8,3 C8.55228475,3 9,3.44771525 9,4 L9,9 C9,9.55228475 8.55228475,10 8,10 L3,10 C2.44771525,10 2,9.55228475 2,9 L6,9 C7.1045695,9 8,8.1045695 8,7 L8,3 Z M1,1 L6,1 C6.55228475,1 7,1.44771525 7,2 L7,7 C7,7.55228475 6.55228475,8 6,8 L1,8 C0.44771525,8 0,7.55228475 0,7 L0,2 C0,1.44771525 0.44771525,1 1,1 Z"></path></svg><span style="margin-left:2px;" class="pp-page">0/0</span></div>';
  1374. var pageCountDiv = $(pageCountHTML)
  1375. .css({ 'position': 'absolute', 'top': '0px', 'display': 'none', 'right': '0px', 'display': 'none' });
  1376. previewDiv.append(pageCountDiv);
  1377.  
  1378. $('.pp-main').mouseleave(function (e) {
  1379. $(this).remove();
  1380. });
  1381.  
  1382. var url = '';
  1383. if (illustType == 2) {
  1384. // 动图
  1385. var screenWidth = document.documentElement.clientWidth;
  1386. var screenHeight = document.documentElement.clientHeight;
  1387. previewDiv.get(0).innerHTML = '<iframe class="pp-iframe" style="width: 48px; height: 48px; display: none; border-radius: 20px;" src="https://www.pixiv.net/artworks/' + illustId + '#preview" />';
  1388. previewDiv.append(loadingImg);
  1389. } else {
  1390. url = g_getArtworkUrl.replace('#id#', illustId);
  1391.  
  1392. // 获取图片链接
  1393. $.ajax(url, {
  1394. method: 'GET',
  1395. success: function (json) {
  1396. DoLog(LogLevel.Info, 'Got artwork urls:');
  1397. DoLog(LogLevel.Elements, json);
  1398.  
  1399. if (json.error === true) {
  1400. DoLog(LogLevel.Error, 'Server responsed an error: ' + json.message);
  1401. return;
  1402. }
  1403.  
  1404. var regular = [];
  1405. var original = [];
  1406. for (var i = 0; i < json.body.length; i++) {
  1407. regular.push(json.body[i].urls.regular);
  1408. original.push(json.body[i].urls.original);
  1409. }
  1410.  
  1411. DoLog(LogLevel.Info, 'Process urls complete.');
  1412. DoLog(LogLevel.Elements, regular);
  1413. DoLog(LogLevel.Elements, original);
  1414.  
  1415. ViewImages(regular, 0, original, g_settings.original);
  1416. },
  1417. error: function (data) {
  1418. DoLog(LogLevel.Error, 'Request image urls failed!');
  1419. if (data) {
  1420. DoLog(LogLevel.Elements, data);
  1421. }
  1422. }
  1423. });
  1424. }
  1425. });
  1426.  
  1427. // 鼠标移出图片
  1428. $(returnMap.controlElements).mouseleave(function (e) {
  1429. var _this = $(this);
  1430. var illustId = _this.attr('illustId');
  1431. var illustType = _this.attr('illustType');
  1432. var pageCount = _this.attr('pageCount');
  1433.  
  1434. var moveToElement = $(e.relatedTarget);
  1435. var isMoveToPreviewElement = false;
  1436. // 鼠标移动到预览图上
  1437. while (true) {
  1438. if (moveToElement.hasClass('pp-main') && moveToElement.attr('illustId') == illustId) {
  1439. isMoveToPreviewElement = true;
  1440. }
  1441.  
  1442. if (moveToElement.parent().length < 1) {
  1443. break;
  1444. }
  1445.  
  1446. moveToElement = moveToElement.parent();
  1447. }
  1448. if (!isMoveToPreviewElement) {
  1449. // 非预览图上
  1450. $('.pp-main').remove();
  1451. }
  1452. });
  1453.  
  1454. // 鼠标移动,调整位置
  1455. $(returnMap.controlElements).mousemove(function (e) {
  1456. // Ctrl 和 中键 都可以禁止预览图移动,这样就可以单手操作了
  1457. if (e.ctrlKey || e.buttons & 4) {
  1458. return;
  1459. }
  1460. var screenWidth = document.documentElement.clientWidth;
  1461. var screenHeight = document.documentElement.clientHeight;
  1462. g_mousePos.x = e.pageX; g_mousePos.y = e.pageY;
  1463.  
  1464. AdjustDivPosition();
  1465. });
  1466.  
  1467. // 这个页面有自动加载
  1468. if (Pages[g_pageType].HasAutoLoad && autoLoadInterval == null) {
  1469. autoLoadInterval = setInterval(ProcessAutoLoad, 1000);
  1470. DoLog(LogLevel.Info, 'Auto load interval set.');
  1471. }
  1472.  
  1473. // 插一段回调函数
  1474. window.PreviewCallback = PreviewCallback;
  1475. DoLog(LogLevel.Info, 'Callback function was inserted.');
  1476. DoLog(LogLevel.Elements, window.PreviewCallback);
  1477.  
  1478. DoLog(LogLevel.Info, 'Preview enable succeed!');
  1479. }
  1480.  
  1481. // 关闭预览功能,不是给外部用的
  1482. function DeactivePreview() {
  1483. var returnMap = Pages[g_pageType].GetProcessedPageElements();
  1484. if (!returnMap.loadingComplete) {
  1485. DoLog(LogLevel.Error, 'Page not load, should not call Preview!');
  1486. return;
  1487. }
  1488.  
  1489. // 只需要取消绑定事件, attrs 以及回调都不需要删除
  1490. $(returnMap.controlElements).unbind('mouseenter').unbind('mouseleave').unbind('mousemove');
  1491.  
  1492. if (autoLoadInterval) {
  1493. clearInterval(autoLoadInterval);
  1494. autoLoadInterval = null;
  1495. }
  1496.  
  1497. DoLog(LogLevel.Info, 'Preview disable succeed!');
  1498. }
  1499.  
  1500. // iframe 的回调函数
  1501. function PreviewCallback(canvasWidth, canvasHeight) {
  1502. DoLog(LogLevel.Info, 'iframe callback, width: ' + canvasWidth + ', height: ' + canvasHeight);
  1503.  
  1504. var size = AdjustDivPosition();
  1505.  
  1506. $('.pp-loading').hide();
  1507. $('.pp-iframe').css({ 'width': size.width, 'height': size.height }).show();
  1508. }
  1509.  
  1510. // 调整预览 Div 的位置
  1511. function AdjustDivPosition() {
  1512. // 鼠标到预览图的距离
  1513. var fromMouseToDiv = 30;
  1514.  
  1515. var screenWidth = document.documentElement.clientWidth;
  1516. var screenHeight = document.documentElement.clientHeight;
  1517. var left = 0;
  1518. var top = document.body.scrollTop + document.documentElement.scrollTop;
  1519.  
  1520. var width = 0, height = 0;
  1521. if ($('.pp-main').find('iframe').length > 0) {
  1522. var iframe = $('.pp-main').find('iframe').get(0);
  1523. if (iframe.contentWindow.GetCanvasSize) {
  1524. var canvasSize = iframe.contentWindow.GetCanvasSize();
  1525. width = canvasSize.width;
  1526. height = canvasSize.height;
  1527. } else {
  1528. width = 0;
  1529. height = 0;
  1530. }
  1531. } else {
  1532. $('.pp-image').css({ 'width': '', 'height': '' });
  1533. width = $('.pp-image').get(0) == null ? 0 : $('.pp-image').get(0).width;
  1534. height = $('.pp-image').get(0) == null ? 0 : $('.pp-image').get(0).height;
  1535. }
  1536.  
  1537. var isShowOnLeft = g_mousePos.x > screenWidth / 2;
  1538.  
  1539. var newWidth = 48, newHeight = 48;
  1540. if (width > 0 && height > 0) {
  1541. newWidth = isShowOnLeft ? g_mousePos.x - fromMouseToDiv : screenWidth - g_mousePos.x - fromMouseToDiv;
  1542. newHeight = height / width * newWidth;
  1543. // 高度不足以完整显示,只能让两侧留空了
  1544. if (newHeight > screenHeight) {
  1545. newHeight = screenHeight;
  1546. newWidth = newHeight / height * width;
  1547. }
  1548. newWidth -= 5;
  1549. newHeight -= 5;
  1550.  
  1551. // 设置新的宽高
  1552. if ($('.pp-main').find('iframe').length > 0) {
  1553. var iframe = $('.pp-main').find('iframe');
  1554. iframe.get(0).contentWindow.ResizeCanvas(newWidth, newHeight);
  1555. iframe.css({ 'width': newWidth, 'height': newHeight });
  1556. }
  1557. else {
  1558. $('.pp-image').css({ 'height': newHeight + 'px', 'width': newWidth + 'px' });
  1559. }
  1560.  
  1561. // 调整下一次 loading 出现的位置
  1562. $('.pp-loading').css({ 'left': newWidth / 2 - 24 + 'px', 'top': newHeight / 2 - 24 + 'px' });
  1563. }
  1564.  
  1565. // 图片宽度大于高度很多时,会显示在页面顶部,鼠标碰不到,把它移动到下面
  1566. if (top + newHeight <= g_mousePos.y) {
  1567. top = (g_mousePos.y - newHeight - fromMouseToDiv);
  1568. }
  1569. // 调整DIV的位置
  1570. left = isShowOnLeft ? g_mousePos.x - newWidth - fromMouseToDiv : g_mousePos.x + fromMouseToDiv;
  1571.  
  1572. $('.pp-main').css({ 'left': left + 'px', 'top': top + 'px', 'width': newWidth, 'height': newHeight });
  1573.  
  1574. // 返回新的宽高
  1575. return {
  1576. width: newWidth,
  1577. height: newHeight,
  1578. };
  1579. }
  1580.  
  1581. // 显示预览图
  1582. function ViewImages(regular, index, original, isShowOriginal) {
  1583. if (!regular || regular.length === 0) {
  1584. DoLog(LogLevel.Error, 'Regular url array is null, can not view images!');
  1585. return;
  1586. }
  1587. if (index == null || index < 0 || index >= regular.length) {
  1588. DoLog(LogLevel.Error, 'Index(' + index + ') out of range, can not view images!');
  1589. return;
  1590. }
  1591. if (original == null || original.length === 0) {
  1592. DoLog(LogLevel.Warning, 'Original array is null, replace it with regular array.');
  1593. original = regular;
  1594. }
  1595. if (original.length < regular) {
  1596. DoLog(LogLevel.Warning, 'Original array\'s length is less than regular array, replace it with regular array.');
  1597. original = regular;
  1598. }
  1599. if (isShowOriginal == null) {
  1600. isShowOriginal = false;
  1601. }
  1602.  
  1603. if (original.length > 1) {
  1604. $('.pp-page').text((index + 1) + '/' + regular.length);
  1605. $('.pp-pageCount').show();
  1606. }
  1607. if (isShowOriginal) {
  1608. $('.pp-image').addClass('original');
  1609. } else {
  1610. $('.pp-image').removeClass('original');
  1611. }
  1612. g_settings.original = isShowOriginal ? 1 : 0;
  1613.  
  1614. // 隐藏页数和原图标签
  1615. $('.pp-original, .pp-pageCount').hide();
  1616.  
  1617. // 第一次需要绑定事件
  1618. if ($('.pp-image').attr('index') == null) {
  1619. // 绑定点击事件,Ctrl+左键 单击切换原图
  1620. $('.pp-image').on('click', function (ev) {
  1621. var _this = $(this);
  1622. var isOriginal = _this.hasClass('original');
  1623. var index = _this.attr('index');
  1624. if (index == null) {
  1625. index = 0;
  1626. } else {
  1627. index = parseInt(index);
  1628. }
  1629.  
  1630. if (ev.ctrlKey) {
  1631. // 按住 Ctrl 来回切换原图
  1632. isOriginal = !isOriginal;
  1633. ViewImages(regular, index, original, isOriginal);
  1634. }
  1635. else if (ev.shiftKey) {
  1636. // 按住 Shift 点击图片新标签页打开原图
  1637. window.open(original[index]);
  1638. } else {
  1639. if (regular.length == 1) {
  1640. return;
  1641. }
  1642. // 如果是多图,点击切换下一张
  1643. if (++index >= regular.length) {
  1644. index = 0;
  1645. }
  1646. ViewImages(regular, index, original, isOriginal);
  1647. // 预加载
  1648. for (var i = index + 1; i < regular.length && i <= index + 3; i++) {
  1649. var image = new Image();
  1650. image.src = isOriginal ? original[i] : regular[i];;
  1651. }
  1652. }
  1653. });
  1654.  
  1655. // 图片预加载完成
  1656. $('.pp-image').on('load', function () {
  1657. // 调整图片位置和大小
  1658. var _this = $(this);
  1659. var size = AdjustDivPosition();
  1660. var isShowOriginal = _this.hasClass('original');
  1661.  
  1662. $('.pp-loading').css('display', 'none');
  1663. // 显示图像、页数、原图标签
  1664. $('.pp-image').css('display', '');
  1665. if (regular.length > 1) {
  1666. $('.pp-pageCount').show();
  1667. }
  1668. if (isShowOriginal) {
  1669. $('.pp-original').show();
  1670. }
  1671.  
  1672. // 预加载
  1673. for (var i = index + 1; i < regular.length && i <= index + 3; i++) {
  1674. var image = new Image();
  1675. image.src = isShowOriginal ? original[i] : regular[i];;
  1676. }
  1677. }).on('error', function () {
  1678. DoLog(LogLevel.Error, 'Load image failed!');
  1679. });
  1680. }
  1681.  
  1682. $('.pp-image').attr('src', isShowOriginal ? original[index] : regular[index]).attr('index', index);
  1683. }
  1684.  
  1685. // 处理自动加载
  1686. function ProcessAutoLoad() {
  1687. if (Pages[g_pageType].GetProcessedPageElements() == null) {
  1688. DoLog(LogLevel.Error, 'Call ProcessPageElements first!');
  1689. return;
  1690. }
  1691.  
  1692. var oldReturnMap = Pages[g_pageType].GetProcessedPageElements();
  1693. var newReturnMap = Pages[g_pageType].ProcessPageElements();
  1694.  
  1695. if (newReturnMap.loadingComplete) {
  1696. if (oldReturnMap.controlElements.length < newReturnMap.controlElements.length) {
  1697. DoLog(LogLevel.Info, 'Page loaded ' + (newReturnMap.controlElements.length - oldReturnMap.controlElements.length) + ' new work(s).');
  1698.  
  1699. if (g_settings.linkBlank) {
  1700. $(newReturnMap.controlElements).find('a').attr('target', '_blank');
  1701. }
  1702.  
  1703. DeactivePreview();
  1704. ActivePreview();
  1705.  
  1706. return;
  1707. } else if (oldReturnMap.controlElements.length > newReturnMap.controlElements.length) {
  1708. DoLog(LogLevel.Warning, 'works become less?');
  1709.  
  1710. Pages[g_pageType].private.returnMap = oldReturnMap;
  1711.  
  1712. return;
  1713. }
  1714. }
  1715.  
  1716. DoLog(LogLevel.Info, 'Page not change.');
  1717. }
  1718.  
  1719. // 开启预览
  1720. ActivePreview();
  1721. }
  1722. /* ---------------------------------------- 排序 ---------------------------------------- */
  1723. function PixivSK(callback) {
  1724. // 不合理的设定
  1725. if (g_settings.pageCount < 1 || g_settings.favFilter < 0) {
  1726. g_settings.pageCount = 1;
  1727. g_settings.favFilter = 0;
  1728. }
  1729. // 当前已经取得的页面数量
  1730. var currentGettingPageCount = 0;
  1731. // 当前加载的页面 URL
  1732. var currentUrl = 'https://www.pixiv.net/ajax/search/artworks/';
  1733. // 当前加载的是第几张页面
  1734. var currentPage = 0;
  1735. // 获取到的作品
  1736. var works = [];
  1737.  
  1738. // 仅搜索页启用
  1739. if (g_pageType != PageType.Search) {
  1740. return;
  1741. }
  1742.  
  1743. // 获取第 currentPage 页的作品
  1744. var getWorks = function (onloadCallback) {
  1745. currentUrl = currentUrl.replace(/p=\d+/, 'p=' + currentPage);
  1746. DoLog(LogLevel.Info, 'Current url: ' + currentUrl);
  1747.  
  1748. var req = new XMLHttpRequest();
  1749. req.open('GET', currentUrl, true);
  1750. req.onload = function (event) {
  1751. onloadCallback(req);
  1752. };
  1753. req.onerror = function (event) {
  1754. DoLog(LogLevel.Error, 'Request search page error!');
  1755. };
  1756.  
  1757. req.send(null);
  1758. };
  1759.  
  1760. // 排序和筛选
  1761. var filterAndSort = function () {
  1762. DoLog(LogLevel.Info, 'Start sort.');
  1763. DoLog(LogLevel.Elements, works);
  1764. // 收藏量低于 FAV_FILTER 的作品不显示
  1765. var tmp = [];
  1766. $(works).each(function (i, work) {
  1767. var bookmarkCount = work.bookmarkCount ? work.bookmarkCount : 0;
  1768. if (bookmarkCount >= g_settings.favFilter && !(g_settings.hideFavorite && work.bookmarkData)) {
  1769. tmp.push(work);
  1770. }
  1771. });
  1772. works = tmp;
  1773.  
  1774. // 排序
  1775. works.sort(function (a, b) {
  1776. var favA = a.bookmarkCount;
  1777. var favB = b.bookmarkCount;
  1778. if (!favA) {
  1779. favA = 0;
  1780. }
  1781. if (!favB) {
  1782. favB = 0;
  1783. }
  1784. if (favA > favB) {
  1785. return -1;
  1786. }
  1787. if (favA < favB) {
  1788. return 1;
  1789. }
  1790. return 0;
  1791. });
  1792. DoLog(LogLevel.Info, 'Sort complete.');
  1793. DoLog(LogLevel.Elements, works);
  1794. };
  1795.  
  1796. if (currentPage === 0) {
  1797. var url = location.href;
  1798.  
  1799. if (url.indexOf('&p=') == -1 && url.indexOf('?p=') == -1) {
  1800. DoLog(LogLevel.Warning, 'Can not found page in url.');
  1801. if (url.indexOf('?') == -1) {
  1802. url += '?p=1';
  1803. DoLog(LogLevel.Info, 'Add "?p=1": ' + url);
  1804. } else {
  1805. url += '&p=1';
  1806. DoLog(LogLevel.Info, 'Add "&p=1": ' + url);
  1807. }
  1808. }
  1809. var wordMatch = url.match(/\/tags\/([^/]*)\/artworks/);
  1810. var searchWord = '';
  1811. if (wordMatch) {
  1812. DoLog(LogLevel.Info, 'Search key word: ' + searchWord);
  1813. searchWord = wordMatch[1];
  1814. } else {
  1815. DoLog(LogLevel.Error, 'Can not found search key word!');
  1816. return;
  1817. }
  1818.  
  1819. // page
  1820. var page = url.match(/p=(\d*)/)[1];
  1821. currentPage = parseInt(page);
  1822. DoLog(LogLevel.Info, 'Current page: ' + currentPage);
  1823.  
  1824. currentUrl += searchWord + '?word=' + searchWord + '&p=' + currentPage;
  1825. DoLog(LogLevel.Info, 'Current url: ' + currentUrl);
  1826. } else {
  1827. DoLog(LogLevel.Error, '???');
  1828. }
  1829.  
  1830. var imageContainer = Pages[PageType.Search].GetImageListContainer();
  1831. // loading
  1832. $(imageContainer).hide().before('<div id="loading" style="width:50px;margin-left:auto;margin-right:auto;"><img src="' + g_loadingImage + '" /><p id="progress" style="text-align: center;font-size: large;font-weight: bold;padding-top: 10px;">0%</p></div>');
  1833.  
  1834. // page
  1835. if (true) {
  1836. var pageSelectorDiv = Pages[PageType.Search].GetPageSelector();
  1837. if (pageSelectorDiv == null) {
  1838. DoLog(LogLevel.Error, 'Can not found page selector!');
  1839. return;
  1840. }
  1841.  
  1842. if ($(pageSelectorDiv).find('a').length > 2) {
  1843. var pageButton = $(pageSelectorDiv).find('a').get(1);
  1844. var newPageButtons = [];
  1845. var pageButtonString = 'Previewer';
  1846. for (var i = 0; i < 9; i++) {
  1847. var newPageButton = pageButton.cloneNode(true);
  1848. $(newPageButton).find('span').text(pageButtonString[i]);
  1849. newPageButtons.push(newPageButton);
  1850. }
  1851.  
  1852. $(pageSelectorDiv).find('button').remove();
  1853. while ($(pageSelectorDiv).find('a').length > 2) {
  1854. $(pageSelectorDiv).find('a:first').next().remove();
  1855. }
  1856.  
  1857. for (i = 0; i < 9; i++) {
  1858. $(pageSelectorDiv).find('a:last').before(newPageButtons[i]);
  1859. }
  1860.  
  1861. $(pageSelectorDiv).find('a').attr('href', 'javascript:;');
  1862.  
  1863. var pageUrl = location.href;
  1864. if (pageUrl.indexOf('&p=') == -1 && pageUrl.indexOf('?p=') == -1) {
  1865. if (pageUrl.indexOf('?') == -1) {
  1866. pageUrl += '?p=1';
  1867. } else {
  1868. pageUrl += '&p=1';
  1869. }
  1870. }
  1871. var prevPageUrl = pageUrl.replace(/p=\d+/, 'p=' + (currentPage - g_settings.pageCount > 1 ? currentPage - g_settings.pageCount : 1));
  1872. var nextPageUrl = pageUrl.replace(/p=\d+/, 'p=' + (currentPage + g_settings.pageCount));
  1873. DoLog(LogLevel.Info, 'Previous page url: ' + prevPageUrl);
  1874. DoLog(LogLevel.Info, 'Next page url: ' + nextPageUrl);
  1875. // 重新插入一遍清除事件绑定
  1876. var prevButton = $(pageSelectorDiv).find('a:first');
  1877. prevButton.before(prevButton.clone());
  1878. prevButton.remove();
  1879. var nextButton = $(pageSelectorDiv).find('a:last');
  1880. nextButton.before(nextButton.clone());
  1881. nextButton.remove();
  1882. $(pageSelectorDiv).find('a:first').attr('href', prevPageUrl).addClass('pp-prevPage');
  1883. $(pageSelectorDiv).find('a:last').attr('href', nextPageUrl).addClass('pp-nextPage');
  1884. }
  1885.  
  1886. var onloadCallback = function (req) {
  1887. try {
  1888. var json = JSON.parse(req.responseText);
  1889. if (json.hasOwnProperty('error')) {
  1890. if (json.error === false) {
  1891. var data = json.body.illustManga.data;
  1892. works = works.concat(data);
  1893. } else {
  1894. DoLog(LogLevel.Error, 'ajax error!');
  1895. return;
  1896. }
  1897. } else {
  1898. DoLog(LogLevel.Error, 'Key "error" not found!');
  1899. return;
  1900. }
  1901. } catch (e) {
  1902. DoLog(LogLevel.Error, 'A invalid json string!');
  1903. DoLog(LogLevel.Info, req.responseText);
  1904. }
  1905.  
  1906. currentPage++;
  1907. currentGettingPageCount++;
  1908. // 设定数量的页面加载完成
  1909. if (currentGettingPageCount == g_settings.pageCount) {
  1910. DoLog(LogLevel.Info, 'Load complete, start to load bookmark count.');
  1911. DoLog(LogLevel.Elements, works);
  1912.  
  1913. // 获取到的作品里面可能有广告,先删掉,否则后面一些处理需要做判断
  1914. var tempWorks = [];
  1915. for (var i = 0; i < works.length; i++) {
  1916. if (works[i].illustId) {
  1917. tempWorks.push(works[i]);
  1918. }
  1919. }
  1920. works = tempWorks;
  1921. DoLog(LogLevel.Info, 'Clear ad container complete.');
  1922. DoLog(LogLevel.Elements, works);
  1923.  
  1924. GetBookmarkCount(0);
  1925. } else {
  1926. getWorks(onloadCallback);
  1927. }
  1928. };
  1929.  
  1930. getWorks(onloadCallback);
  1931. }
  1932.  
  1933. var xhrs = [];
  1934. var currentRequestGroupMinimumIndex = 0;
  1935. function FillXhrsArray() {
  1936. xhrs.length = 0;
  1937. var onloadFunc = function (event) {
  1938. var matched = event.currentTarget.responseText.match(/bookmarkCount":(\d+)/);
  1939. if (matched) {
  1940. var bookmarkCount = matched[1];
  1941. var illustId = '';
  1942. var illustIdMatched = event.currentTarget.responseURL.match(/artworks\/(\d+)/);
  1943. if (illustIdMatched) {
  1944. illustId = illustIdMatched[1];
  1945. } else {
  1946. DoLog(LogLevel.Error, 'Can not get illust id from url!');
  1947. return;
  1948. }
  1949. var indexOfThisRequest = -1;
  1950. for (var j = 0; j < g_maxXhr; j++) {
  1951. if (xhrs[j].illustId == illustId) {
  1952. indexOfThisRequest = j;
  1953. break;
  1954. }
  1955. }
  1956. if (indexOfThisRequest == -1) {
  1957. DoLog('This url not match any request!');
  1958. return;
  1959. }
  1960. xhrs[indexOfThisRequest].complete = true;
  1961.  
  1962. works[currentRequestGroupMinimumIndex + indexOfThisRequest].bookmarkCount = parseInt(bookmarkCount);
  1963. DoLog(LogLevel.Info, 'IllustId: ' + illustId + ', bookmarkCount: ' + bookmarkCount);
  1964.  
  1965. var completeCount = 0;
  1966. for (j = 0; j < g_maxXhr; j++) {
  1967. if (xhrs[j].complete) {
  1968. completeCount++;
  1969. }
  1970. }
  1971. if (completeCount == g_maxXhr) {
  1972. $('#loading').find('#progress').text(parseInt((currentRequestGroupMinimumIndex + 1) * 1.0 / works.length * 100) + '%');
  1973. currentRequestGroupMinimumIndex += g_maxXhr;
  1974. GetBookmarkCount(currentRequestGroupMinimumIndex);
  1975. }
  1976. }
  1977. };
  1978. var onerrorFunc = function (event) {
  1979. var illustId = '';
  1980. var illustIdMatched = event.currentTarget.responseUrl.match(/artworks\/(\d+)/);
  1981. if (illustIdMatched) {
  1982. illustId = illustIdMatched[1];
  1983. } else {
  1984. DoLog(LogLevel.Error, 'Can not get illust id from url!');
  1985. return;
  1986. }
  1987.  
  1988. DoLog(LogLevel.Error, 'Send request failed, set this illust(' + illustId + ')\'s bookmark count to 0!');
  1989.  
  1990. var indexOfThisRequest = -1;
  1991. for (var j = 0; j < g_maxXhr; j++) {
  1992. if (xhrs[j].illustId == illustId) {
  1993. indexOfThisRequest = j;
  1994. break;
  1995. }
  1996. }
  1997. if (indexOfThisRequest == -1) {
  1998. DoLog('This url not match any request!');
  1999. return;
  2000. }
  2001. xhrs[indexOfThisRequest].complete = true;
  2002.  
  2003. var completeCount = 0;
  2004. for (j = 0; j < g_maxXhr; j++) {
  2005. if (xhrs[j].complete) {
  2006. completeCount++;
  2007. }
  2008. }
  2009. if (completeCount == g_maxXhr) {
  2010. $('#loading').find('#progress').text(parseInt((currentRequestGroupMinimumIndex + 1) * 1.0 / works.length * 100) + '%');
  2011. GetBookmarkCount(currentRequestGroupMinimumIndex + g_maxXhr);
  2012. }
  2013. };
  2014. for (var i = 0; i < g_maxXhr; i++) {
  2015. xhrs.push({
  2016. xhr: new XMLHttpRequest(),
  2017. illustId: '',
  2018. complete: false,
  2019. });
  2020. xhrs[i].xhr.onload = onloadFunc;
  2021. xhrs[i].xhr.onerror = onerrorFunc;
  2022. }
  2023. }
  2024.  
  2025. var GetBookmarkCount = function (index) {
  2026. if (index >= works.length) {
  2027. clearAndUpdateWorks();
  2028. return;
  2029. }
  2030.  
  2031. if (xhrs.length === 0) {
  2032. FillXhrsArray();
  2033. }
  2034.  
  2035. for (var i = 0; i < g_maxXhr; i++) {
  2036. if (index + i >= works.length) {
  2037. xhrs[i].complete = true;
  2038. continue;
  2039. }
  2040.  
  2041. var illustId = works[index + i].illustId;
  2042. var url = 'https://www.pixiv.net/artworks/' + illustId;
  2043. xhrs[i].illustId = illustId;
  2044. xhrs[i].complete = false;
  2045. xhrs[i].xhr.open('GET', url, true);
  2046. xhrs[i].xhr.send(null);
  2047. }
  2048. };
  2049.  
  2050. /*
  2051. li
  2052. -div
  2053. --div
  2054. ---div
  2055. ----div
  2056. -----div
  2057. ------a
  2058. -------div: 多图标签、R18标签
  2059. -------div: 里面是 img (以及 svg 动图标签)
  2060. ------div: 里面是 like 相关的元素
  2061. ---a: 作品标题,跳转链接
  2062. ---div: 作者头像和昵称
  2063. */
  2064. var clearAndUpdateWorks = function () {
  2065. filterAndSort();
  2066.  
  2067. var container = Pages[PageType.Search].GetImageListContainer();
  2068. var firstImageElement = Pages[PageType.Search].GetFirstImageElement();
  2069. var imageElementTemplate = firstImageElement.cloneNode(true);
  2070. // 清理模板
  2071. if (true) {
  2072. // image
  2073. var img = $($(imageElementTemplate).find('img').get(0));
  2074. var imageDiv = img.parent();
  2075. var imageLink = imageDiv.parent();
  2076. var imageLinkDiv = imageLink.parent();
  2077. var titleLink = imageLinkDiv.parent().next();
  2078. if (img == null || imageDiv == null || imageLink == null || imageLinkDiv == null || titleLink == null) {
  2079. DoLog(LogLevel.Error, 'Can not found some elements!');
  2080. }
  2081.  
  2082. // author
  2083. var authorDiv = titleLink.next();
  2084. var authorLinks = authorDiv.find('a'); // 点击头像和昵称都可以
  2085. var authorName = $(authorLinks.children('div'));
  2086. authorName.each(function (i, e) {
  2087. if ($(e).children().length === 0) {
  2088. authorName = $(e);
  2089. return false;
  2090. }
  2091. });
  2092. var authorImage = $(authorDiv.find('img').get(0));
  2093.  
  2094. // others
  2095. var bookmarkDiv = imageLink.next();
  2096. var bookmarkSvg = bookmarkDiv.find('svg');
  2097. var additionTagDiv = imageDiv.prev();
  2098. var animationTag = imageDiv.find('svg');
  2099.  
  2100. var bookmarkCountDiv = additionTagDiv.clone();
  2101. bookmarkCountDiv.css({ 'top': 'auto', 'bottom': '0px', 'width': '50%' });
  2102. additionTagDiv.parent().append(bookmarkCountDiv);
  2103.  
  2104. // 添加 class,方便后面修改内容
  2105. img.addClass('ppImg');
  2106. imageLink.addClass('ppImageLink');
  2107. titleLink.addClass('ppTitleLink');
  2108. authorLinks.addClass('ppAuthorLink');
  2109. authorName.addClass('ppAuthorName');
  2110. authorImage.addClass('ppAuthorImage');
  2111. bookmarkSvg.addClass('ppBookmarkSvg');
  2112. additionTagDiv.addClass('ppAdditionTag');
  2113. bookmarkCountDiv.addClass('ppBookmarkCount');
  2114.  
  2115. img.attr('src', '');
  2116. additionTagDiv.empty();
  2117. bookmarkCountDiv.empty();
  2118. animationTag.remove();
  2119. bookmarkSvg.find('path:first').css('fill', 'rgb(31, 31, 31)');
  2120. bookmarkSvg.find('path:last').css('fill', 'rgb(255, 255, 255)');
  2121.  
  2122. if (g_settings.linkBlank) {
  2123. imageLink.attr('target', '_blank');
  2124. titleLink.attr('target', '_blank');
  2125. authorLinks.attr('target', '_blank');
  2126. }
  2127. }
  2128.  
  2129. $(container).empty();
  2130. for (var i = 0; i < works.length; i++) {
  2131. var li = $(imageElementTemplate.cloneNode(true));
  2132.  
  2133. li.find('.ppImg').attr('src', works[i].url);
  2134. li.find('.ppImageLink').attr('href', '/artworks/' + works[i].illustId);
  2135. li.find('.ppTitleLink').attr('href', '/artworks/' + works[i].illustId).text(works[i].title);
  2136. li.find('.ppAuthorLink').attr('href', '/member.php?id=' + works[i].userId);
  2137. li.find('.ppAuthorName').text(works[i].userName);
  2138. li.find('.ppAuthorImage').attr('src', works[i].profileImageUrl);
  2139. li.find('.ppBookmarkSvg').attr('illustId', works[i].illustId);
  2140. if (works[i].bookmarkData) {
  2141. li.find('.ppBookmarkSvg').find('path').css('fill', 'rgb(255, 64, 96)');
  2142. li.find('.ppBookmarkSvg').attr('bookmarkId', works[i].bookmarkData.id);
  2143. }
  2144. if (works[i].xRestrict !== 0) {
  2145. var R18HTML = '<div style="margin-top: 2px; margin-left: 2px;"><div style="color: rgb(255, 255, 255);font-weight: bold;font-size: 10px;line-height: 1;padding: 3px 6px;border-radius: 3px;background: rgb(255, 64, 96);">R-18</div></div>';
  2146. li.find('.ppAdditionTag').append(R18HTML);
  2147. }
  2148. if (works[i].pageCount > 1) {
  2149. var pageCountHTML = '<div style="display: flex;-webkit-box-align: center;align-items: center;box-sizing: border-box;margin-left: auto;height: 20px;color: rgb(255, 255, 255);font-size: 10px;line-height: 12px;font-weight: bold;flex: 0 0 auto;padding: 4px 6px;background: rgba(0, 0, 0, 0.32);border-radius: 10px;">\<svg viewBox="0 0 9 10" width="9" height="10" style="stroke: none;line-height: 0;font-size: 0px;fill: currentcolor;"><path d="M8,3 C8.55228475,3 9,3.44771525 9,4 L9,9 C9,9.55228475 8.55228475,10 8,10 L3,10 C2.44771525,10 2,9.55228475 2,9 L6,9 C7.1045695,9 8,8.1045695 8,7 L8,3 Z M1,1 L6,1 C6.55228475,1 7,1.44771525 7,2 L7,7 C7,7.55228475 6.55228475,8 6,8 L1,8 C0.44771525,8 0,7.55228475 0,7 L0,2 C0,1.44771525 0.44771525,1 1,1 Z"></path></svg><span class="sc-fzXfOw bAzGJW">' + works[i].pageCount + '</span></div>';
  2150. li.find('.ppAdditionTag').append(pageCountHTML);
  2151. }
  2152. var bookmarkCountHTML = '<div style="margin-bottom: 6px; margin-left: 2px;"><div style="color: rgb(7, 95, 166);font-weight: bold;font-size: 13px;line-height: 1;padding: 3px 6px;border-radius: 3px;background: rgb(204, 236, 255);">' + works[i].bookmarkCount + ' likes</div></div>';
  2153. li.find('.ppBookmarkCount').append(bookmarkCountHTML);
  2154. if (works[i].illustType == 2) {
  2155. var animationHTML = '<svg viewBox="0 0 24 24" style="width: 48px; height: 48px;stroke: none;fill: rgb(255, 255, 255);line-height: 0;font-size: 0px;vertical-align: middle;position:absolute;"><circle cx="12" cy="12" r="10" style="fill: rgb(0, 0, 0);fill-opacity: 0.4;"></circle><path d="M9,8.74841664 L9,15.2515834 C9,15.8038681 9.44771525,16.2515834 10,16.2515834 C10.1782928,16.2515834 10.3533435,16.2039156 10.5070201,16.1135176 L16.0347118,12.8619342 C16.510745,12.5819147 16.6696454,11.969013 16.3896259,11.4929799 C16.3034179,11.3464262 16.1812655,11.2242738 16.0347118,11.1380658 L10.5070201,7.88648243 C10.030987,7.60646294 9.41808527,7.76536339 9.13806578,8.24139652 C9.04766776,8.39507316 9,8.57012386 9,8.74841664 Z"></path></svg>';
  2156. li.find('.ppImg').after(animationHTML);
  2157. }
  2158.  
  2159. $(container).append(li);
  2160. }
  2161.  
  2162. // 监听加入书签点击事件,监听父节点,但是按照 <svg> 节点处理
  2163. $('.ppBookmarkSvg').parent().on('click', function () {
  2164. if (g_csrfToken == '') {
  2165. DoLog(LogLevel.Error, 'No g_csrfToken, failed to add bookmark!');
  2166. alert('获取 Token 失败,无法添加,请到详情页操作。');
  2167. return;
  2168. }
  2169.  
  2170. var _this = $(this).children('svg:first');
  2171. var illustId = _this.attr('illustId');
  2172. var bookmarkId = _this.attr('bookmarkId');
  2173. if (bookmarkId == null || bookmarkId == '') {
  2174. DoLog(LogLevel.Info, 'Add bookmark, illustId: ' + illustId);
  2175. $.ajax('/ajax/illusts/bookmarks/add', {
  2176. method: 'POST',
  2177. contentType: 'application/json;charset=utf-8',
  2178. headers: { 'x-csrf-token': g_csrfToken },
  2179. data: '{"illust_id":"' + illustId + '","restrict":0,"comment":"","tags":[]}',
  2180. success: function (data) {
  2181. DoLog(LogLevel.Info, 'addBookmark result: ');
  2182. DoLog(LogLevel.Elements, data);
  2183. if (data.error) {
  2184. DoLog(LogLevel.Error, 'Server returned an error: ' + data.message);
  2185. return;
  2186. }
  2187. var bookmarkId = data.body.last_bookmark_id;
  2188. DoLog(LogLevel.Info, 'Add bookmark success, bookmarkId is ' + bookmarkId);
  2189. _this.attr('bookmarkId', bookmarkId);
  2190. _this.find('path').css('fill', 'rgb(255, 64, 96)');
  2191. }
  2192. });
  2193. } else {
  2194. DoLog(LogLevel.Info, 'Delete bookmark, bookmarkId: ' + bookmarkId);
  2195. $.ajax('/rpc/index.php', {
  2196. method: 'POST',
  2197. headers: { 'x-csrf-token': g_csrfToken },
  2198. data: { "mode": "delete_illust_bookmark", "bookmark_id": bookmarkId },
  2199. success: function (data) {
  2200. DoLog(LogLevel.Info, 'addBookmark result: ');
  2201. DoLog(LogLevel.Elements, data);
  2202. if (data.error) {
  2203. DoLog(LogLevel.Error, 'Server returned an error: ' + data.message);
  2204. return;
  2205. }
  2206. DoLog(LogLevel.Info, 'Delete bookmark success.');
  2207. _this.attr('bookmarkId', '');
  2208. _this.find('path:first').css('fill', 'rgb(31, 31, 31)');
  2209. _this.find('path:last').css('fill', 'rgb(255, 255, 255)');
  2210. }
  2211. });
  2212. }
  2213.  
  2214. _this.parent().focus();
  2215. });
  2216.  
  2217. if (works.length === 0) {
  2218. $('.column-search-result')[0].innerHTML = '<div class="_no-item">未找到任何相关结果</div>';
  2219. }
  2220.  
  2221. // 恢复显示
  2222. $('#loading').remove();
  2223. $(container).show();
  2224.  
  2225. Pages[PageType.Search].ProcessPageElements();
  2226.  
  2227. // 监听键盘的左右键,用来翻页
  2228. $(document).keydown(function(e) {
  2229. if (e.keyCode == 39) {
  2230. var btn = $('.pp-nextPage');
  2231. if (btn.length < 1 || btn.attr('hidden') == 'hidden') {
  2232. return;
  2233. }
  2234. // 很奇怪不能用 click()
  2235. location.href = btn.attr('href');
  2236. } else if (e.keyCode == 37) {
  2237. var btn = $('.pp-prevPage');
  2238. if (btn.length < 1 || btn.attr('hidden') == 'hidden') {
  2239. return;
  2240. }
  2241. location.href = btn.attr('href');
  2242. }
  2243. });
  2244.  
  2245. if (callback) {
  2246. callback();
  2247. }
  2248. }
  2249. }
  2250. /* ---------------------------------------- 设置 ---------------------------------------- */
  2251. function SetCookie(name, value) {
  2252. var Days = 180;
  2253. var exp = new Date();
  2254. exp.setTime(exp.getTime() + Days * 24 * 60 * 60 * 1000);
  2255. var str = JSON.stringify(value);
  2256. document.cookie = name + "=" + str + ";expires=" + exp.toGMTString() + ';path=\/';
  2257. }
  2258. function GetCookie(name) {
  2259. var arr, reg = new RegExp("(^| )" + name + "=([^;]*)(;|$)");
  2260. if (arr = document.cookie.match(reg)) {
  2261. return unescape(arr[2]);
  2262. }
  2263. else {
  2264. return null;
  2265. }
  2266. }
  2267. function ShowInstallMessage() {
  2268. $('#pp-bg').remove();
  2269. var bg = $('<div id="pp-bg"></div>').css({
  2270. 'width': document.documentElement.clientWidth + 'px', 'height': document.documentElement.clientHeight + 'px', 'position': 'fixed',
  2271. 'z-index': 999999, 'background-color': 'rgba(0,0,0,0.8)',
  2272. 'left': '0px', 'top': '0px'
  2273. });
  2274. $('body').append(bg);
  2275.  
  2276. bg.get(0).innerHTML = '<img id="pps-close"src="https://pp-1252089172.cos.ap-chengdu.myqcloud.com/Close.png"style="position: absolute; right: 35px; top: 20px; width: 32px; height: 32px; cursor: pointer;"><div style="position: absolute;width: 40%;left: 30%;top: 25%;font-size: 25px; text-align: center; color: white;">欢迎使用 PixivPreviewer v' + g_version + '</div><br><div style="position: absolute;width: 40%;left: 30%;top: 30%;font-size: 20px; color: white;"><p style="text-indent: 2em;">小版本更新(v3.0.6),排序后的页面现在可以使用键盘的←→键进行翻页,默认关闭,需要在设置中开启。</p><p style="text-indent: 2em;"> v3.0.x 是对 v2.08 进行了大量改动后的版本,因此可能不稳定,如果发现问题,请到<a style="color: green;" href="https://greasyfork.org/zh-CN/scripts/30766-pixiv-previewer/feedback" target="_blank"> 反馈页面 </a>反馈,我会尽快修复,也欢迎提出建议,非常感谢!</p><p style="text-indent: 2em;">排序功能会比之前的版本慢,具体时间视Pixiv的加载速度而定,原因是新的搜索页面不会再显示排序所必须的收藏量。</p><p style="text-indent: 2em;">如果您是第一次使用,推荐到<a style="color: green;" href="https://greasyfork.org/zh-CN/scripts/30766-pixiv-previewer" target="_blank"> 详情页 </a>查看脚本介绍。</p></div>';
  2277. $('#pps-close').click(function () {
  2278. $('#pp-bg').remove();
  2279. });
  2280. }
  2281. function GetSettings() {
  2282. var settings;
  2283.  
  2284. var cookie = GetCookie('PixivPreview');
  2285. // 新安装
  2286. if (cookie == null || cookie == 'null') {
  2287. settings = g_defaultSettings;
  2288. SetCookie('PixivPreview', settings);
  2289.  
  2290. ShowInstallMessage();
  2291. } else {
  2292. settings = JSON.parse(cookie);
  2293. }
  2294.  
  2295. // 升级
  2296. if (settings.version != g_version) {
  2297. ShowInstallMessage();
  2298. }
  2299.  
  2300. if (settings.version == null || settings.version != g_version) {
  2301. settings.version = g_version;
  2302. SetCookie('PixivPreview', settings);
  2303. }
  2304.  
  2305. return settings;
  2306. }
  2307. function ShowSetting() {
  2308. var screenWidth = document.documentElement.clientWidth;
  2309. var screenHeight = document.documentElement.clientHeight;
  2310.  
  2311. $('#pp-bg').remove();
  2312. var bg = $('<div id="pp-bg"></div>').css({
  2313. 'width': screenWidth + 'px', 'height': screenHeight + 'px', 'position': 'fixed',
  2314. 'z-index': 999999, 'background-color': 'rgba(0,0,0,0.8)',
  2315. 'left': '0px', 'top': '0px'
  2316. });
  2317. $('body').append(bg);
  2318.  
  2319. var settings = GetSettings();
  2320.  
  2321. var settingHTML = '<div style="color: white; font-size: 1em;"><img id="pps-close" src="https://pp-1252089172.cos.ap-chengdu.myqcloud.com/Close.png" style="position: absolute; right: 35px; top: 20px; width: 32px; height: 32px; cursor: pointer;"><div style="position: absolute; width: 30%; left: 30%; top: 25%;"><ul style="list-style: none; padding: 0; margin: 0;"><li style="height: 32px; font-size: 25px;">预览</li><li style="height: 32px; font-size: 25px;">排序(仅搜索页生效)</li><li style="height: 32px; font-size: 25px;">动图下载(动图预览及详情页生效)</li><li style="height: 32px; font-size: 25px;">预览时优先显示原图(慢)</li><li style="height: 32px; font-size: 25px;"></li><li style="height: 32px; font-size: 25px;">每次排序时统计的最大页数</li><li style="height: 32px; font-size: 25px;">隐藏收藏数少于设定值的作品</li><li style="height: 32px; font-size: 25px;">排序时隐藏已收藏的作品</li><li style="height: 32px; font-size: 25px;">使用新标签页打开作品详情页</li><li style="height: 32px; font-size: 25px;">使用键盘←→进行翻页(排序后的搜索页)</li></ul></div><div id="pps-right" style="position: absolute; width: 10%; right: 30%; text-align: right; top: 25%;"><ul style="list-style: none; padding: 0; margin: 0;"><li style="height: 32px;"><img id="pps-preview" src="https://pp-1252089172.cos.ap-chengdu.myqcloud.com/On.png" style="height: 32px; cursor: pointer;"></li><li style="height: 32px;"><img id="pps-sort" src="https://pp-1252089172.cos.ap-chengdu.myqcloud.com/On.png" style="height: 32px; cursor: pointer;"></li><li style="height: 32px;"><img id="pps-anime" src="https://pp-1252089172.cos.ap-chengdu.myqcloud.com/On.png" style="height: 32px; cursor: pointer;"></li><li style="height: 32px;"><img id="pps-original" src="https://pp-1252089172.cos.ap-chengdu.myqcloud.com/On.png" style="height: 32px; cursor: pointer;"></li><li style="height: 32px;"></li><li style="height: 32px;"><input id="pps-maxPage" style="height: 28px; font-size: 24px; padding: 0px; margin: 0px; border-width: 0px; width: 64px; text-align: center;"></li><li style="height: 32px;"><input id="pps-hideLess" style="height: 28px; font-size: 24px; padding: 0px; margin: 0px; border-width: 0px; width: 64px; text-align: center;"></li><li style="height: 32px;"><img id="pps-hideBookmarked" src="https://pp-1252089172.cos.ap-chengdu.myqcloud.com/On.png" style="height: 32px; cursor: pointer;"></li><li style="height: 32px;"><img id="pps-newTab" src="https://pp-1252089172.cos.ap-chengdu.myqcloud.com/On.png" style="height: 32px; cursor: pointer;"></li><li style="height: 32px;"><img id="pps-pageKey" src="https://pp-1252089172.cos.ap-chengdu.myqcloud.com/On.png" style="height: 32px; cursor: pointer;"></li></ul></div><div style="margin-top: 10px;position: absolute;bottom: 30%;width: 100%;text-align: center;"><button id="pps-save" style="font-size: 25px;border-radius: 15px;height: 48px;width: 128px;background-color: green;color: white;margin: 0 32px 0 32px;cursor: pointer;border: none;">保存设置</button><button id="pps-reset" style="font-size: 25px;border-radius: 15px;height: 48px;width: 128px;background-color: darkred;color: white;margin: 0 32px 0 32px;cursor: pointer;border: none;">重置脚本</button></div></div>';
  2322.  
  2323. bg.get(0).innerHTML = settingHTML;
  2324.  
  2325. var imgOn = 'https://pp-1252089172.cos.ap-chengdu.myqcloud.com/On.png';
  2326. var imgOff = 'https://pp-1252089172.cos.ap-chengdu.myqcloud.com/Off.png'
  2327. $('#pps-preview').attr('src', settings.enablePreview ? imgOn : imgOff).addClass(settings.enablePreview ? 'on' : 'off');
  2328. $('#pps-sort').attr('src', settings.enableSort ? imgOn : imgOff).addClass(settings.enableSort ? 'on' : 'off');
  2329. $('#pps-anime').attr('src', settings.enableAnimeDownload ? imgOn : imgOff).addClass(settings.enableAnimeDownload ? 'on' : 'off');
  2330. $('#pps-original').attr('src', settings.original ? imgOn : imgOff).addClass(settings.original ? 'on' : 'off');
  2331. $('#pps-maxPage').val(settings.pageCount);
  2332. $('#pps-hideLess').val(settings.favFilter);
  2333. $('#pps-hideBookmarked').attr('src', settings.hideFavorite ? imgOn : imgOff).addClass(settings.hideFavorite ? 'on' : 'off');
  2334. $('#pps-newTab').attr('src', settings.linkBlank ? imgOn : imgOff).addClass(settings.linkBlank ? 'on' : 'off');
  2335. $('#pps-pageKey').attr('src', settings.pageByKey ? imgOn : imgOff).addClass(settings.pageByKey ? 'on' : 'off');
  2336.  
  2337. $('#pps-right').find('img').click(function () {
  2338. var _this = $(this);
  2339.  
  2340. if (_this.hasClass('on')) {
  2341. _this.attr('src', imgOff).removeClass('on').addClass('off');
  2342. } else {
  2343. _this.attr('src', imgOn).removeClass('off').addClass('on');
  2344. }
  2345. });
  2346.  
  2347. $('#pps-save').click(function () {
  2348. if ($('#pps-maxPage').val() === '') {
  2349. $('#pps-maxPage').val(g_defaultSettings.pageCount);
  2350. }
  2351. if ($('#pps-hideLess').val() == '') {
  2352. $('#pps-hideLess').val(g_defaultSettings.favFilter);
  2353. }
  2354.  
  2355. var settings = {
  2356. 'enablePreview': $('#pps-preview').hasClass('on') ? 1 : 0,
  2357. 'enableSort': $('#pps-sort').hasClass('on') ? 1 : 0,
  2358. 'enableAnimeDownload': $('#pps-anime').hasClass('on') ? 1 : 0,
  2359. 'original': $('#pps-original').hasClass('on') ? 1 : 0,
  2360. 'pageCount': parseInt($('#pps-maxPage').val()),
  2361. 'favFilter': parseInt($('#pps-hideLess').val()),
  2362. 'hideFavorite': $('#pps-hideBookmarked').hasClass('on') ? 1 : 0,
  2363. 'linkBlank': $('#pps-newTab').hasClass('on') ? 1 : 0,
  2364. 'pageBytKey': $('#pps-pageKey').hasClass('on') ? 1 : 0,
  2365. 'version': g_version,
  2366. }
  2367.  
  2368. SetCookie('PixivPreview', settings);
  2369.  
  2370. location.href = location.href;
  2371. });
  2372.  
  2373. $('#pps-reset').click(function () {
  2374. var comfirmText = "这会删除所有设置,相当于重新安装脚本,确定要重置吗?";
  2375. if (confirm(comfirmText)) {
  2376. SetCookie('PixivPreview', null);
  2377. location.href = location.href;
  2378. }
  2379. });
  2380.  
  2381. $('#pps-close').click(function () {
  2382. $('#pp-bg').remove();
  2383. });
  2384. }
  2385. /* --------------------------------------- 主函数 --------------------------------------- */
  2386. var loadInterval = setInterval(function () {
  2387. // 匹配当前页面
  2388. for (var i = 0; i < PageType.PageTypeCount; i++) {
  2389. if (Pages[i].CheckUrl(location.href)) {
  2390. g_pageType = i;
  2391. break;
  2392. }
  2393. }
  2394. if (g_pageType >= 0) {
  2395. DoLog(LogLevel.Info, 'Current page is ' + Pages[g_pageType].PageTypeString);
  2396. } else {
  2397. DoLog(LogLevel.Info, 'Unsupported page.');
  2398. clearInterval(loadInterval);
  2399. return;
  2400. }
  2401.  
  2402. // 设置按钮
  2403. var toolBar = Pages[g_pageType].GetToolBar();
  2404. if (toolBar) {
  2405. DoLog(LogLevel.Elements, toolBar);
  2406. clearInterval(loadInterval);
  2407. } else {
  2408. DoLog(LogLevel.Warning, 'Get toolbar failed.');
  2409. return;
  2410. }
  2411.  
  2412. toolBar.appendChild(toolBar.firstChild.cloneNode(true));
  2413. toolBar.lastChild.outerHTML = '<button style="background-color: rgb(0, 0, 0);margin-top: 5px;opacity: 0.8;cursor: pointer;border: none;padding: 12px;border-radius: 24px;width: 48px;height: 48px;"><svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 1000 1000" enable-background="new 0 0 1000 1000" xml:space="preserve" style="fill: white;"><metadata> Svg Vector Icons : http://www.sfont.cn </metadata><g><path d="M377.5,500c0,67.7,54.8,122.5,122.5,122.5S622.5,567.7,622.5,500S567.7,377.5,500,377.5S377.5,432.3,377.5,500z"></path><path d="M990,546v-94.8L856.2,411c-8.9-35.8-23-69.4-41.6-100.2L879,186L812,119L689,185.2c-30.8-18.5-64.4-32.6-100.2-41.5L545.9,10h-94.8L411,143.8c-35.8,8.9-69.5,23-100.2,41.5L186.1,121l-67,66.9L185.2,311c-18.6,30.8-32.6,64.4-41.5,100.3L10,454v94.8L143.8,589c8.9,35.8,23,69.4,41.6,100.2L121,814l67,67l123-66.2c30.8,18.6,64.5,32.6,100.3,41.5L454,990h94.8L589,856.2c35.8-8.9,69.4-23,100.2-41.6L814,879l67-67l-66.2-123.1c18.6-30.7,32.6-64.4,41.5-100.2L990,546z M500,745c-135.3,0-245-109.7-245-245c0-135.3,109.7-245,245-245s245,109.7,245,245C745,635.3,635.3,745,500,745z"></path></g></svg></button>';
  2414. $(toolBar.lastChild).css('margin-top', '10px');
  2415. $(toolBar.lastChild).css('opacity', '0.8');
  2416. $(toolBar.lastChild).click(function () {
  2417. ShowSetting();
  2418. });
  2419.  
  2420. // 读取设置
  2421. g_settings = GetSettings();
  2422.  
  2423. // g_csrfToken
  2424. if (g_pageType == PageType.Search) {
  2425. $.get(location.href, function (data) {
  2426. var matched = data.match(/token":"([a-z0-9]{32})/);
  2427. if (matched.length > 0) {
  2428. g_csrfToken = matched[1];
  2429. DoLog(LogLevel.Info, 'Got g_csrfToken: ' + g_csrfToken);
  2430. } else {
  2431. DoLog(LogLevel.Error, 'Can not get g_csrfToken, so you can not add works to bookmark when sorting has enabled.');
  2432. }
  2433. });
  2434. }
  2435.  
  2436. // 现在 P站点击一些按钮不会重新加载页面了,脚本也不会重新加载,会导致一些问题。如果检测到 url 变了,就刷新一下
  2437. setInterval(function () {
  2438. if (location.href != initialUrl) {
  2439. location.href = location.href;
  2440. }
  2441. }, 1000);
  2442.  
  2443. // 排序、预览
  2444. var itv = setInterval(function () {
  2445. var returnMap = Pages[g_pageType].ProcessPageElements();
  2446. if (!returnMap.loadingComplete) {
  2447. return;
  2448. }
  2449.  
  2450. DoLog(LogLevel.Info, 'Process page comlete, sorting and prevewing begin.');
  2451. DoLog(LogLevel.Elements, returnMap);
  2452.  
  2453. clearInterval(itv);
  2454.  
  2455. if (g_settings.linkBlank) {
  2456. $(returnMap.controlElements).find('a').attr('target', '_blank');
  2457. }
  2458.  
  2459. try {
  2460. if (g_pageType == PageType.Artwork) {
  2461. Pages[g_pageType].Work();
  2462. }
  2463. else if (g_pageType == PageType.Search) {
  2464. if (g_settings.enableSort) {
  2465. PixivSK(g_settings.enablePreview ? PixivPreview : null);
  2466. } else if (g_settings.enablePreview) {
  2467. PixivPreview();
  2468. }
  2469. } else if (g_settings.enablePreview) {
  2470. PixivPreview();
  2471. }
  2472. }
  2473. catch (e) {
  2474. DoLog(LogLevel.Error, 'Unknown error: ' + e);
  2475. }
  2476. }, 500);
  2477. }, 1000);