JAVBUS larger thumbnails

replace thumbnails of javbus,javdb and avmoo with source images

ของเมื่อวันที่ 04-04-2021 ดู เวอร์ชันล่าสุด

  1. // ==UserScript==
  2. // @name JAVBUS larger thumbnails
  3. // @name:zh-CN JAVBUS封面大图
  4. // @namespace https://github.com/kygo233/tkjs
  5. // @version 20210403
  6. // @author kygo233
  7. // @description replace thumbnails of javbus,javdb and avmoo with source images
  8. // @description:zh-CN javbus,javdb,avmoo替换封面为源图
  9.  
  10. // @include /^.*(javbus|busfan|fanbus|buscdn|cdnbus|dmmsee|seedmm|busdmm|busjav)\..*$/
  11. // @include /^.*(javdb)[0-9]?\..*$/
  12. // @include /^.*(avmoo)\..*$/
  13.  
  14. // @require https://cdn.jsdelivr.net/npm/vanilla-lazyload@17.3.0/dist/lazyload.min.js
  15.  
  16. // @grant GM_addStyle
  17. // @grant GM_xmlhttpRequest
  18. // @grant GM_getValue
  19. // @grant GM_setValue
  20. // @grant GM_download
  21. // @grant GM_setClipboard
  22. // @connect *
  23.  
  24. // 2021-04-03 适配JAVDB;点击图片弹出新窗口;标题默认显示一行;调整样式;增加英文显示
  25. // 2021-03-09 恢复高清字幕图标的显示
  26. // 2021-02-06 新增图片懒加载插件;重调样式;优化按钮效果,切换样式不刷新页面;磁力界面新增演员表样品图显示;
  27. // 2021-01-18 适配AVMOO网站;无码页面屏蔽竖图模式;调整域名匹配规则
  28. // 2021-01-01 新增宽度调整功能;
  29. // 2020-12-29 解决半图模式下 竖图显示不全的问题;
  30. // 2020-10-16 解决功能开关取默认值为undefined的bug
  31. // 2020-10-16 解决和"JAV老司机"同时运行时样式冲突问题,需关闭老司机的瀑布流
  32. // 2020-10-14 收藏界面只匹配影片;下载图片文件名添加标题;新增复制番号、标题功能;视频截图文件下载;封面显示半图;增加样式开关
  33. // 2020-09-20 收藏界面的适配
  34. // 2020-08-27 适配更多界面
  35. // 2020-08-26 修复查询结果为1个时,item宽度为100%的问题
  36. // 2020-08-26 添加瀑布流
  37. // 2020-08-24 第一版:封面大图、下载封面、查看视频截图
  38. // ==/UserScript==
  39.  
  40. //vue
  41. (function () {
  42. 'use strict';
  43. let statusDefault = {
  44. autoPage: false,
  45. copyBtn :true,
  46. toolBar: true,
  47. avInfo:true,
  48. itemTag:true,
  49. halfImg:false,
  50. waterfallWidth:100,
  51. columnNumFull:3,
  52. columnNumHalf:4
  53. };
  54. const IMG_SUFFIX = "-screenshot-tag";
  55. const AVINFO_SUFFIX = "-avInfo-tag";
  56. const blogjavSelector= "#content .title2>h1>a";
  57.  
  58. const copy_Svg = `<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" width="16" height="16" viewBox="0 0 16 16"><path d="M2 2a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v13.5a.5.5 0 0 1-.777.416L8 13.101l-5.223 2.815A.5.5 0 0 1 2 15.5V2zm2-1a1 1 0 0 0-1 1v12.566l4.723-2.482a.5.5 0 0 1 .554 0L13 14.566V2a1 1 0 0 0-1-1H4z"/></svg>`;
  59. const download_Svg = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" class="tool-svg" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M1 8a7 7 0 1 0 14 0A7 7 0 0 0 1 8zm15 0A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM8.5 4.5a.5.5 0 0 0-1 0v5.793L5.354 8.146a.5.5 0 1 0-.708.708l3 3a.5.5 0 0 0 .708 0l3-3a.5.5 0 0 0-.708-.708L8.5 10.293V4.5z"/></svg>`;
  60. const picture_Svg = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" class="tool-svg" viewBox="0 0 16 16"><path d="M6.002 5.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z"/><path d="M2.002 1a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2h-12zm12 1a1 1 0 0 1 1 1v6.5l-3.777-1.947a.5.5 0 0 0-.577.093l-3.71 3.71-2.66-1.772a.5.5 0 0 0-.63.062L1.002 12V3a1 1 0 0 1 1-1h12z"/></svg>`;
  61. const magnet_Svg = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" class="tool-svg" x="0px" y="0px" viewBox="0 0 1000 1000" ><g><g transform="translate(0.000000,460.000000) scale(0.100000,-0.100000)"><path d="M4171.6,3994c-183.9-13.4-515.3-67.1-706.9-113c-770.2-187.7-1448.4-563.3-2021.2-1118.8c-707-685.9-1130.3-1494.4-1299-2481c-59.4-358.3-59.4-1002,0-1360.2c157.1-923.4,546-1705.1,1172.5-2354.6c695.4-722.3,1534.6-1159.1,2548.1-1325.7c174.4-28.7,388.9-34.5,1643.8-40.2l1440.7-7.7v1302.8v1302.8l-1354.5,7.6c-1207,5.7-1369.8,9.6-1480.9,40.2c-448.3,116.9-785.5,335.3-1036.5,666.7c-252.9,339.1-364,666.7-364,1088.2s111.1,749.1,364,1088.2c241.4,318,595.8,551.8,1000.1,659.1c157.1,40.2,191.6,42.1,1517.3,47.9l1354.5,7.7v1302.8v1300.9l-1344.9-3.8C4863.3,4001.6,4219.5,3997.8,4171.6,3994z"/><path d="M7620.1,2704.6V1401.8h1139.9H9900v1302.8v1302.8H8760.1H7620.1V2704.6z"/><path d="M7620.1-3502.7v-1302.8h1139.9H9900v1302.8v1302.8H8760.1H7620.1V-3502.7z"/></g></g></svg>`;
  62.  
  63. const LOCALE = {
  64. zh: {
  65. menuText :'设置',
  66. menu_autoPage: '鼠标滚轮翻页',
  67. menu_copyBtn :'复制图标',
  68. menu_toolBar: '功能图标',
  69. menu_avInfo:'弹窗中的演员和样品图',
  70. menu_itemTag:'高清&字幕图标',
  71. menu_halfImg:'竖图模式',
  72. menu_columnNum:'列',
  73. copyButton:'复制',
  74. copySuccess:'复制成功',
  75. getAvImg_loading:'加载中。。。',
  76. getAvImg_norespond:'blogjav.net网站暂时无法响应',
  77. getAvImg_none:'未搜索到',
  78. tool_magnetTip:'磁力',
  79. tool_downloadTip:'下载封面',
  80. tool_pictureTip:'视频截图(blogjav.net)'
  81. },
  82. en: {
  83. menuText :'Settings',
  84. menu_autoPage:'turn pages by mouse wheel',
  85. menu_copyBtn:'copy icon',
  86. menu_toolBar:'tools icon',
  87. menu_avInfo:'actors and sample images in pop-ups',
  88. menu_itemTag:'HD & subtitle icon',
  89. menu_halfImg:'Vertical image mode',
  90. menu_columnNum:'columns',
  91. copyButton:'Copy',
  92. copySuccess:'Copy successful',
  93. getAvImg_loading:'Loading. . .',
  94. getAvImg_norespond:'blogjav.net is temporarily unable to respond',
  95. getAvImg_none:'Not found',
  96. tool_magnetTip:'Magnet',
  97. tool_downloadTip:'Download cover',
  98. tool_pictureTip:'Video screenshot from blogjav.net'
  99. }
  100. }
  101. let getlanguage = () => {
  102. let local= navigator.language;
  103. local = local.toLowerCase().replace('_', '-');
  104. if (local in LOCALE){
  105. return LOCALE[local];
  106. }else if (local.split('-')[0] in LOCALE){
  107. return LOCALE[local.split('-')[0]];
  108. }else {
  109. return LOCALE.en;
  110. }
  111. }
  112. let lang = getlanguage();
  113.  
  114. function showAlert(msg){
  115. var $alert=$(`<div class="alert-zdy" ></div>`);
  116. $('body').append($alert);
  117. $alert.text(msg);
  118. $alert.show({start:function(){
  119. $(this).css({'margin-top': -$(this).height() / 2 });
  120. $(this).css({'margin-left': -$(this).width() / 2 });
  121. }}).delay(3000).fadeOut();
  122. }
  123.  
  124. let tool_Func = {
  125. autoPage: function () {
  126. window.location.reload();
  127. },
  128. copyBtn: function () {
  129. $("#waterfall-zdy .copy-svg").toggle();
  130. },
  131. itemTag: function () {
  132. $("#waterfall-zdy .item-tag").toggle();
  133. },
  134. toolBar: function () {
  135. $("#waterfall-zdy .func-div").toggle();
  136. },
  137. halfImg:function () {
  138. var removeClassName = "halfImgCSS";
  139. var addClassName = "fullImgCSS";
  140. if (Status.isHalfImg()) {
  141. removeClassName = "fullImgCSS";
  142. addClassName = "halfImgCSS";
  143. }
  144. $("#waterfall-zdy .movie-box-b img").each(function () {
  145. //高大于宽的图片 不变化
  146. if (!(this.height >= this.width)) {
  147. $(this).removeClass(removeClassName).addClass(addClassName);
  148. }
  149. });
  150. var columnNum = Status.getColumnNum();
  151. GM_addStyle('#waterfall-zdy .item{ width: ' + 100 / columnNum + '%;}');
  152. $("#columnNum_range").val(columnNum);
  153. $("#columnNum_range+span").text(columnNum);
  154. },
  155. avInfo: function () { },
  156. columnNum: function (columnNum) {
  157. GM_addStyle('#waterfall-zdy .item{ width: ' + 100 / columnNum + '%;}');
  158. },
  159. waterfallWidth: function (width) {
  160. var widthSelctor=currentObj.widthSelector;
  161. $(widthSelctor).css("width", width + "%");
  162. $(widthSelctor).css("margin", "0 " + (width>100?(100-width)/2+"%":"auto"));
  163. }
  164. };
  165.  
  166. let Status = {
  167. halfImg_block:false,
  168. set : function(key,value){
  169. if(key=="columnNum") {
  170. key=key+(this.isHalfImg()?"Half":"Full");
  171. }else if(key=="waterfallWidth"){
  172. key=key+"_"+currentWeb;
  173. }
  174. return GM_setValue(key, value);
  175. },
  176. get : function(key){
  177. return GM_getValue(key=="waterfallWidth"?(key+"_"+currentWeb):key, statusDefault[key]);
  178. },
  179. isHalfImg: function () {
  180. return this.get("halfImg") && (!this.halfImg_block);
  181. },
  182. getColumnNum: function () {
  183. var key= 'columnNum'+(this.isHalfImg()?"Half":"Full");
  184. return this.get(key);
  185. }
  186. };
  187.  
  188. class Popover{
  189. show(){
  190. document.documentElement.classList.add("scrollBarHide");
  191. this.element.show({duration:0,start:function(){
  192. var t=$(this).find('#modal-div');
  193. t.css({'margin-top': Math.max(0, ($(window).height() - t.height()) / 2) });
  194. }});
  195. }
  196. hide(){
  197. document.documentElement.classList.remove("scrollBarHide");
  198. this.element.hide();
  199. this.element.find('.pop-up-tag').hide();
  200. }
  201. init(){
  202. var me=this;
  203. me.element = $('<div id="myModal"><div id="modal-div" > </div></div>');
  204. me.element.on('click',function(e){
  205. if($(e.target).closest("#modal-div").length==0){
  206. me.hide();
  207. }
  208. });
  209. me.scrollBarWidth = me.getScrollBarWidth();
  210. GM_addStyle('.scrollBarHide{ padding-right: ' + me.scrollBarWidth + 'px;overflow:hidden;}');
  211. $('body').append(me.element);
  212. if(currentWeb=="javbus"){
  213. me.element.magnificPopup({
  214. delegate: 'a.sample-box-zdy:visible',
  215. type: 'image',
  216. closeOnContentClick: false,
  217. closeBtnInside: false,
  218. mainClass: 'mfp-with-zoom mfp-img-mobile',
  219. image: {
  220. verticalFit: true
  221. },
  222. gallery: {
  223. enabled: true
  224. },
  225. zoom: {
  226. enabled: true,
  227. duration: 300,
  228. opener: function (element) {
  229. return element.find('img');
  230. }
  231. }
  232. });
  233. }
  234. }
  235. append(elem){
  236. if(!this.element){ this.init();}
  237. this.element.find("#modal-div").append(elem);
  238. }
  239. getScrollBarWidth() {
  240. var el = document.createElement("p");
  241. var styles = {width: "100px",height: "100px",overflowY: "scroll" };
  242. for (var i in styles) {
  243. el.style[i] = styles[i];
  244. }
  245. document.body.appendChild(el);
  246. var scrollBarWidth = el.offsetWidth - el.clientWidth;
  247. el.remove();
  248. return scrollBarWidth;
  249. }
  250. }
  251.  
  252. function addMenu() {
  253. var columnNum = Status.getColumnNum();
  254. var $menu = $('<div id="menu-div" ></div>');
  255. $menu.append(creatCheckbox("autoPage", lang.menu_autoPage));
  256. $menu.append(creatCheckbox("copyBtn", lang.menu_copyBtn));
  257. $menu.append(creatCheckbox("itemTag", lang.menu_itemTag));
  258. $menu.append(creatCheckbox("toolBar", lang.menu_toolBar));
  259. $menu.append(creatCheckbox("halfImg", lang.menu_halfImg,Status.halfImg_block));
  260. if (currentWeb == 'javbus') {
  261. $menu.append(creatCheckbox("avInfo", lang.menu_avInfo));
  262. }
  263. $menu.append(creatRange("columnNum", lang.menu_columnNum, columnNum, 8));
  264. $menu.append(creatRange("waterfallWidth", '%', waterfallWidth, currentObj.maxWidth?currentObj.maxWidth:100));
  265. var $spanner = $(currentObj.menu.html);
  266. $spanner.append($menu);
  267. $spanner.mouseenter(()=>$menu.show()).mouseleave(()=>$menu.hide());
  268. $(currentObj.menu.position).append($spanner);
  269. }
  270.  
  271. function creatCheckbox(tagName, name,disabled) {
  272. var $checkbox = $(`<div class="switch-div"><input ${disabled?'disabled="disabled"':''} type="checkbox" id="${tagName}_checkbox" /><label for="${tagName}_checkbox" >${name}</label></div>`);
  273. $checkbox.find("input")[0].checked = Status.get(tagName);
  274. $checkbox.find("input").eq(0).click(function () {
  275. Status.set(tagName, this.checked);
  276. tool_Func[tagName]();
  277. });
  278. return $checkbox;
  279. }
  280. function creatRange(tagName, name, value, max) {
  281. var $range = $(`<div class="range-div"><input type="range" id="${tagName}_range" min="1" max="${max}" step="1" value="${value}" /><span name="value">${value}</span><span>${name}</span></div>`);
  282. $range.bind('input propertychange', function () {
  283. var val = $(this).find("input").eq(0).val();
  284. $(this).find("span[name=value]").html(val);
  285. Status.set(tagName, val);
  286. tool_Func[tagName](val);
  287. });
  288. return $range;
  289. }
  290.  
  291. function showMagnetTable(avid, src) {
  292. let $el=$(`.pop-up-tag[name=${avid}${AVINFO_SUFFIX}]`);
  293. if ($el.length > 0) {
  294. $el.show();
  295. myModal.show();
  296. } else {
  297. getMagnet(avid, src).then(avInfo_c => {
  298. myModal.append(avInfo_c.avatar_waterfall);
  299. myModal.append(avInfo_c.sample_waterfall);
  300. myModal.append(avInfo_c.magnetTable);
  301. myModal.show();
  302. });
  303. }
  304. }
  305. function getMagnet(avid, src) {
  306. //有码和欧美 0 无码 1
  307. var uc_code = location.pathname.search(/(uncensored|mod=uc)/) < 1 ? 0 : 1;
  308. return avInfofetch(avid).then(avInfo_c => {
  309. var gid = avInfo_c.gid;
  310. var url = `${location.protocol}//${location.hostname}/ajax/uncledatoolsbyajax.php?gid=${gid}&lang=zh&img=${src}&uc=${uc_code}&floor=` + Math.floor(Math.random() * 1e3 + 1);
  311. return fetch(url).then(response => response.text())
  312. .then(doc => {
  313. var table_html = doc.substring(0, doc.indexOf('<script')).trim();
  314. var name = avid + AVINFO_SUFFIX;
  315. var table_tag = $('<table class="table pop-up-tag" name="' + name + '" style="background-color:#FFFFFF;" ></table>');
  316. table_tag.append($(table_html));
  317. table_tag.find("tr").each(function (i) { // 遍历 tr
  318. var me = this;
  319. if ($(me).find('a').length == 0) {
  320. return true;
  321. }
  322. var magent_url = $(me).find('a')[0].href;
  323. addCopybutton(me, magent_url);
  324. });
  325. avInfo_c.magnetTable = table_tag;
  326. return avInfo_c;
  327. })
  328. });
  329. };
  330.  
  331. function avInfofetch(avid) {
  332. return fetch(`${location.protocol}//${location.hostname}/`+avid) .then(response => response.text())
  333. .then(doc => {
  334. var str = /var\s+gid\s+=\s+(\d{1,})/.exec(doc);
  335. var gid = str[1];
  336. var avInfo_c={avid:avid};
  337. avInfo_c.gid=gid;
  338. if(Status.get("avInfo")){
  339. var sample_waterfall = $($.parseHTML(doc)).find("#sample-waterfall");
  340. var avatar_waterfall = $($.parseHTML(doc)).find("#avatar-waterfall");
  341. if(sample_waterfall.length>0){
  342. sample_waterfall[0].id = "";
  343. sample_waterfall.addClass("pop-up-tag");
  344. sample_waterfall.attr("name",avid + AVINFO_SUFFIX);
  345. sample_waterfall.find(".sample-box").removeClass("sample-box").addClass("sample-box-zdy");
  346. }
  347. if(avatar_waterfall.length>0){
  348. avatar_waterfall[0].id = "";
  349. avatar_waterfall.addClass("pop-up-tag");
  350. avatar_waterfall.attr("name",avid + AVINFO_SUFFIX);
  351. avatar_waterfall.find("a.avatar-box").attr("target","_blank").removeClass("avatar-box").addClass("avatar-box-zdy");
  352. }
  353. avInfo_c.sample_waterfall=sample_waterfall;
  354. avInfo_c.avatar_waterfall=avatar_waterfall;
  355. }
  356. return avInfo_c;
  357. }).catch(err => alert(err));
  358. };
  359.  
  360. function addCopybutton(tag, text) {
  361. var copyButton = $(`<button class="center-block">${lang.copyButton}</button>`);
  362. copyButton.click(function () {
  363. var btn = this;
  364. GM_setClipboard(text);
  365. showAlert(lang.copySuccess);
  366. });
  367. var td_tag = $('<td></td>');
  368. td_tag.append(copyButton);
  369. $(tag).prepend(td_tag);
  370. }
  371.  
  372. function showBigImg(avid,elem) {
  373. let $selector = $(`#${avid}${IMG_SUFFIX}`);
  374. if ($selector.length > 0) {
  375. $selector.show();
  376. myModal.show();
  377. } else {
  378. getAvImg(avid,elem);
  379. }
  380. }
  381.  
  382. function getAvImg(avid, elem) {
  383. if (elem.click_lock) {
  384. showAlert(lang.getAvImg_loading);
  385. return;
  386. }
  387. elem.click_lock = true;
  388. GM_xmlhttpRequest({
  389. method: "GET",
  390. url: 'http://blogjav.net/?s=' + avid,
  391. onload: function (result) {
  392. if (result.status !== 200) {
  393. showAlert(lang.getAvImg_norespond);
  394. elem.click_lock = false;
  395. return;
  396. }
  397. var doc = result.responseText;
  398. let a_array = $(doc).find(blogjavSelector);
  399. let imgUrl;
  400. for (let i = 0; i < a_array.length; i++) {
  401. imgUrl = a_array[i].href;
  402. var fhd_idx = a_array[i].href.search(/FHD/g);
  403. if (fhd_idx > 0) {
  404. break;
  405. }
  406. }
  407. if (!imgUrl) {
  408. showAlert(lang.getAvImg_none);
  409. elem.click_lock = false;
  410. return;
  411. }
  412. GM_xmlhttpRequest({
  413. method: "GET",
  414. url: imgUrl,
  415. headers: {
  416. referrer: "http://pixhost.to/"
  417. },
  418. onload: function (XMLHttpRequest) {
  419. var bodyStr = XMLHttpRequest.responseText;
  420. var img_src_arr = /<img .*src="https*:\/\/.*pixhost.to\/thumbs\/.*>/.exec(bodyStr);
  421. if (img_src_arr) {
  422. var src = $(img_src_arr[0]).attr("src").replace('thumbs', 'images').replace('//t', '//img').replace('"', '');
  423. console.log(src);
  424. var height = $(window).height();
  425. var img_tag = $('<div id="' + avid + IMG_SUFFIX + '" class="pop-up-tag" ><img style="min-height:' + height + 'px;width:100%" src="' + src + '" /></div>');
  426. var downloadBtn = $('<span class="download-icon" >'+download_Svg+'</span>');
  427. downloadBtn.click(function () {
  428. GM_download(src, avid + ".jpg");
  429. });
  430. $(img_tag).prepend(downloadBtn);
  431. myModal.append(img_tag);
  432. myModal.show();
  433. }else if(bodyStr.match("404 Not Found")){
  434. showAlert(lang.getAvImg_norespond);
  435. }
  436. elem.click_lock = false;
  437. }
  438. });
  439. }
  440. });
  441. };
  442.  
  443. let myModal;
  444. let currentWeb ;
  445. let currentObj ;
  446. let ConstCode = {
  447. javbus: {
  448. domainReg: /(javbus|busfan|fanbus|buscdn|cdnbus|dmmsee|seedmm|busdmm|busjav)\./i,
  449. excludePages: ['/actresses', 'mdl=favor&sort=1', 'mdl=favor&sort=2', 'mdl=favor&sort=3', 'mdl=favor&sort=4', 'searchstar'],
  450. halfImg_block_Pages:['/uncensored','javbus.one','mod=uc'],
  451. menu:{
  452. position:'#navbar ul:first',
  453. html:`<li class='dropdown'><a class='dropdown-toggle'>${lang.menuText}</a></li>`
  454. },
  455. gridSelector: 'div#waterfall',
  456. itemSelector: 'div#waterfall div.item',
  457. widthSelector : '#waterfall-zdy',
  458. pageNext:'a#next',
  459. pageSelector:'.pagination',
  460. getAvItem: function (elem) {
  461. var photoDiv = elem.find("div.photo-frame")[0];
  462. var href = elem.find("a")[0].href;
  463. var img = $(photoDiv).children("img")[0];
  464. var src = img.src;
  465. if (src.match(/pics.dmm.co.jp/)) {
  466. src = src.replace(/ps.jpg/, "pl.jpg");
  467. } else {
  468. src = src.replace(/thumbs/, "cover").replace(/thumb/, "cover").replace(/.jpg/, "_b.jpg");
  469. }
  470. var title = img.title;
  471. var AVID = elem.find("date").eq(0).text().replace(/\./g, '-');
  472. var date = elem.find("date").eq(1).text();
  473. var itemTag = "";elem.find("div.photo-info .btn").toArray().forEach( x=> itemTag+=x.outerHTML);
  474. return {AVID: AVID,href: href,src: src,title: title,date: date,itemTag:itemTag};
  475. }
  476. },
  477. javdb: {
  478. domainReg: /(javdb)[0-9]?\./i,
  479. excludePages: ['/users/'],
  480. halfImg_block_Pages:['/uncensored','/western','/video_uncensored','/video_western'],
  481. menu:{
  482. position:'#navbar-menu-hero .navbar-start',
  483. html:`<div class='navbar-item' >${lang.menuText}</div>`
  484. },
  485. gridSelector: 'div#videos>.grid',
  486. itemSelector: 'div#videos>.grid div.grid-item',
  487. widthSelector : '#waterfall-zdy',
  488. pageNext: 'a.pagination-next',
  489. pageSelector:'.pagination-list',
  490. init_Style: function(){
  491. var local_color=$(".box").css("background-color");
  492. if(local_color=="rgb(18, 18, 18)"){
  493. GM_addStyle(`#waterfall-zdy .movie-box-b{background-color:${local_color};}.alert-zdy {color: black;background-color: white;}`);
  494. }
  495. },
  496. maxWidth: 150,
  497. getAvItem: function (elem) {
  498. var href = elem.find("a")[0].href;
  499. var img = elem.find("div.item-image>img").eq(0);
  500. var src = img.attr("data-src").replace(/thumbs/, "covers") ;
  501. var title = elem.find("div.video-title").eq(0).text();
  502. if(!title) {title = elem.find("div.video-title2").eq(0).text()};
  503. var AVID = elem.find("div.uid").eq(0).text().replace(/\./g, '-');
  504. if(!AVID) {AVID = elem.find("div.uid2").eq(0).text()};
  505. var date = elem.find("div.meta").eq(0).text();
  506. var itemTag = elem.find(".tags.has-addons").html();
  507. return {AVID: AVID,href: href,src: src,title: title,date: date,itemTag:itemTag};
  508. },
  509. init: function(){
  510. // if(location.href.includes("/users/")){ this.widthSelector="div.section";}
  511. }
  512. },
  513. avmoo: {
  514. domainReg: /avmoo\./i,
  515. excludePages: ['/actresses'],
  516. menu:{
  517. position:'#navbar ul:first',
  518. html:`<li class='dropdown'><a class='dropdown-toggle'>${lang.menuText}</a></li>`
  519. },
  520. gridSelector: 'div#waterfall',
  521. itemSelector: 'div#waterfall div.item',
  522. widthSelector : '#waterfall-zdy',
  523. pageNext: 'a[name="nextpage"]',
  524. pageSelector:'.pagination',
  525. getAvItem: function (elem) {
  526. var photoDiv = elem.find("div.photo-frame")[0];
  527. var href = elem.find("a")[0].href;
  528. var img = $(photoDiv).children("img")[0];
  529. var src = img.src.replace(/ps.jpg/, "pl.jpg");
  530. var title = img.title;
  531. var AVID = elem.find("date").eq(0).text().replace(/\./g, '-');
  532. var date = elem.find("date").eq(1).text();
  533. var itemTag = "";elem.find("div.photo-info .btn").toArray().forEach( x=> itemTag+=x.outerHTML);
  534. return {AVID: AVID,href: href,src: src,title: title,date: date,itemTag:itemTag};
  535. }
  536. }
  537. };
  538. function pageInit() {
  539. for (var key in ConstCode) {
  540. var domainReg = ConstCode[key].domainReg;
  541. if (domainReg && domainReg.test(location.href)) {
  542. currentWeb = key;
  543. currentObj = ConstCode[key];
  544. //排除页面的判断
  545. if (ConstCode[key].excludePages) {
  546. for (var page of ConstCode[key].excludePages) {
  547. if (location.pathname.includes(page)) return;
  548. }
  549. }
  550. //调用初始化方法
  551. if (ConstCode[key].init) {
  552. ConstCode[key].init();
  553. }
  554. //屏蔽竖图模式的页面判断
  555. if (ConstCode[key].halfImg_block_Pages) {
  556. for (var blockPage of ConstCode[key].halfImg_block_Pages) {
  557. if (location.href.includes(blockPage)) {
  558. Status.halfImg_block = true;
  559. break;
  560. };
  561. }
  562. }
  563. break;
  564. }
  565. }
  566. let $items = $(currentObj.itemSelector);
  567. if (currentWeb && $items.length) {
  568. if(['javbus','avmoo'].includes(currentWeb)){ //屏蔽老司机脚本,改写id
  569. let $waterfall = $('#waterfall');
  570. if($waterfall.length){
  571. $waterfall.get(0).id = "waterfall-destroy";
  572. }
  573. if($waterfall.find("#waterfall").length){ //javbus首页有2个'waterfall' ID
  574. $waterfall.find("#waterfall").get(0).id = "";
  575. }
  576. let $waterfall_h= $('#waterfall_h');
  577. if ($waterfall_h.length) {
  578. $waterfall_h.get(0).id = "waterfall-destroy";
  579. }
  580. if(location.pathname.search(/search/) > 0){//解决"改写id后,搜索页面自动跳转到无码页面"的bug
  581. $('body').append('<div id="waterfall"></div>');
  582. }
  583. currentObj.gridSelector = "#waterfall-destroy";
  584. }
  585. $(currentObj.gridSelector).hide();
  586. var waterfall=$(`<div id= 'waterfall-zdy'></div>`);
  587. $(currentObj.gridSelector).eq(0).before(waterfall);
  588. addStyle();//全局样式
  589. if(currentObj.init_Style){currentObj.init_Style()};
  590. addMenu(); //添加菜单
  591. myModal = new Popover();//弹出插件
  592. //加载图片懒加载插件
  593. let lazyLoad = new LazyLoad({
  594. callback_loaded: function (bigimg) {
  595. //加载时的回调,本身为竖图的不做变化
  596. if (Status.isHalfImg() && bigimg.height >= bigimg.width) {
  597. $(bigimg).removeClass("halfImgCSS");
  598. $(bigimg).addClass("fullImgCSS");
  599. }
  600. }
  601. });
  602. let elems=getItems($items);
  603. waterfall.append(elems);
  604. lazyLoad.update();
  605. if(Status.get("autoPage") && $(currentObj.pageSelector).length ){
  606. let scroller=new ScrollerPlugin(waterfall,lazyLoad);
  607. }
  608. }
  609. }
  610. class ScrollerPlugin{
  611. constructor(waterfall,lazyLoad){
  612. let me=this;
  613. me.waterfall=waterfall;
  614. me.lazyLoad=lazyLoad;
  615. let $pageNext=$(currentObj.pageNext);
  616. me.nextURL = $pageNext.attr('href');
  617. me.scroller_status=$(`<div class = "scroller-status" style="text-align:center;display:none"><h2 class="scroll-request">●●●</h2><h2 class="scroll-last">End</h2></div>`);
  618. me.waterfall.after(me.scroller_status);
  619. me.locked=false;
  620. me.canLoad=true;
  621. let $page=$(currentObj.pageSelector);
  622. document.addEventListener('wheel', function(){
  623. if ($page.get(0).getBoundingClientRect().top - $(window).height() < 300 && (!me.locked) && (me.canLoad)) {
  624. me.locked=true;
  625. me.loadNextPage(me.nextURL).then(()=>{me.locked=false});
  626. }
  627. });
  628. }
  629. async loadNextPage(url){
  630. this.showStatus('request');
  631. console.log(url);
  632. let respondText = await fetch(url, { credentials: 'same-origin' }).then(respond=>respond.text());
  633. let $body = $(new DOMParser().parseFromString(respondText, 'text/html'));
  634. let elems = getItems($body.find(currentObj.itemSelector));
  635. if (currentWeb != "javdb" && location.pathname.includes('/star/') && elems) {
  636. elems=elems.slice(1);
  637. }
  638. this.scroller_status.hide();
  639. this.waterfall.append(elems);
  640. this.lazyLoad.update();
  641. this.nextURL = $body.find(currentObj.pageNext).attr('href');
  642. if(!this.nextURL){
  643. this.canLoad=false;
  644. this.showStatus("last");
  645. }
  646. }
  647. showStatus(status){
  648. this.scroller_status.children().each( (i,e)=>{$(e).hide()});
  649. this.scroller_status.find(`.scroll-${status}`).show();
  650. this.scroller_status.show();
  651. }
  652. }
  653.  
  654. function getItems(elems) {
  655. var elemsHtml = "";
  656. var className = Status.isHalfImg() ? "halfImgCSS" : "fullImgCSS";
  657. var parseFunc = currentObj.getAvItem;
  658. for (let i = 0; i < elems.length; i++) {
  659. elemsHtml = elemsHtml + getItem(elems.eq(i), parseFunc,className);
  660. }
  661. var $elems = $(elemsHtml);
  662. if (!Status.get("toolBar")) {
  663. $elems.find(".func-div").css("display","none");
  664. }
  665. if(!(currentWeb=="javbus")){
  666. $elems.find(".func-div span[name='magnet']").remove();
  667. }
  668. if (!Status.get("copyBtn")) {
  669. $elems.find(".copy-svg").css("display","none");
  670. }
  671.  
  672. if (!Status.get("itemTag")) {
  673. $elems.find(".item-tag").css("display","none");
  674. }
  675. $elems.find("span[name='copy']").click(function () {
  676. GM_setClipboard($(this).next().text());
  677. showAlert(lang.copySuccess);
  678. return false;
  679. });
  680. $elems.find(".func-div span[name='download']").click(function () {
  681. GM_download($(this).attr("src"), $(this).attr("src-title")+".jpg");
  682. });
  683. $elems.find(".func-div span[name='magnet']").click(function () {
  684. showMagnetTable($(this).attr("AVID"));
  685. });
  686. $elems.find(".func-div span[name='picture']").click(function () {
  687. showBigImg($(this).attr("AVID"),this);
  688. });
  689. return $elems;
  690. }
  691.  
  692. function getItem(tag,parseFunc,className) {
  693. if (currentWeb!="javdb" && tag.find(".avatar-box").length) {
  694. tag.find(".avatar-box").addClass("avatar-box-b").removeClass("avatar-box");
  695. return `<div class='item'>${tag.html()}</div>`;
  696. }
  697. var AvItem = parseFunc(tag);
  698. return `<div class="item">
  699. <div class="movie-box-b">
  700. <div class="photo-frame-b">
  701. <a href="${AvItem.href}" target="_blank"><img class="lazy ${className}" data-src="${AvItem.src}" ></a>
  702. </div>
  703. <div class="photo-info-b">
  704. <a name="av-title" href="${AvItem.href}" target="_blank" title="${AvItem.title}" class="titleNowrap"><span class="svg-span copy-svg" name="copy">${copy_Svg}</span> <span>${AvItem.title}</span></a>
  705. <div class="info-bottom">
  706. <div class="info-bottom-one">
  707. <span class="svg-span copy-svg" name="copy">${copy_Svg}</span><date name="avid">${AvItem.AVID}</date> / <date>${AvItem.date}</date>
  708. </div>
  709. <div class="info-bottom-two">
  710. <div class="item-tag">${AvItem.itemTag}</div>
  711. <div class="func-div">
  712. <span name="magnet" class="svg-span" title="${lang.tool_magnetTip}" AVID="${AvItem.AVID}" >${magnet_Svg}</span>
  713. <span name="download" class="svg-span" title="${lang.tool_downloadTip}" src="${AvItem.src}" src-title="${AvItem.AVID} ${AvItem.title}">${download_Svg}</span>
  714. <span name="picture" class="svg-span" title="${lang.tool_pictureTip}" AVID="${AvItem.AVID}" >${picture_Svg}</span>
  715. </div>
  716. </div>
  717. </div>
  718. </div>
  719. </div>
  720. </div>`;
  721. }
  722.  
  723. let waterfallWidth = 100;
  724. function addStyle() {
  725. var columnNum = Status.getColumnNum();
  726. waterfallWidth=Status.get("waterfallWidth");
  727. var css_waterfall = `
  728. ${currentObj.widthSelector}{
  729. width:${waterfallWidth}%;
  730. margin:0 ${waterfallWidth>100?(100-waterfallWidth)/2+'%':'auto'};
  731. transition:.5s ;
  732. }
  733. #waterfall-zdy{
  734. display:flex;
  735. flex-direction:row;
  736. flex-wrap:wrap;
  737. }
  738. #waterfall-zdy .item{
  739. padding:5px;
  740. width:${100 / columnNum}%;
  741. transition:.5s ;
  742. /* animation: itemShow .5s;*/
  743. }
  744. #waterfall-zdy .movie-box-b {
  745. border-radius: 5px;
  746. background-color:white;
  747. border: 1px solid rgba(0, 0, 0, 0.2);
  748. box-shadow: 0 2px 3px 0 rgba(0, 0, 0, 0.1);
  749. overflow: hidden;
  750. }
  751. #waterfall-zdy .movie-box-b .photo-frame-b a {
  752. display: block;
  753. }
  754. #waterfall-zdy .movie-box-b .photo-info-b {
  755. padding: 7px;
  756. }
  757. #waterfall-zdy .movie-box-b .photo-info-b a {
  758. color: inherit;
  759. display: block;
  760. }
  761. #waterfall-zdy .info-bottom,.info-bottom-two{
  762. display: flex;
  763. justify-content: space-between;
  764. align-items: center;
  765. flex-wrap: wrap;
  766. }
  767. #waterfall-zdy .avatar-box-b {
  768. display: flex;
  769. flex-direction: column;
  770. background-color:white;
  771. border-radius: 5px;
  772. align-items: center;
  773. border: 1px solid rgba(0, 0, 0, 0.2);
  774. }
  775. #waterfall-zdy .avatar-box-b p {
  776. margin: 0 !important
  777. }
  778. #waterfall-zdy date:first-of-type {
  779. font-size: 18px !important
  780. }
  781. #waterfall-zdy .func-div {
  782. float: right;padding: 2px;
  783. white-space:nowrap;
  784. }
  785. #waterfall-zdy .func-div span {
  786. margin-right: 2px;
  787. }
  788. #waterfall-zdy .copy-svg {
  789. vertical-align: middle;
  790. display: inline-block
  791. }
  792. #waterfall-zdy span.svg-span {
  793. cursor: pointer;
  794. opacity: .3;
  795. }
  796. #waterfall-zdy span.svg-span:hover {
  797. opacity: 1
  798. }
  799. #waterfall-zdy .item-tag {
  800. display: inline-block;
  801. white-space:nowrap;
  802. }
  803. img.fullImgCSS {
  804. width: 100% !important;
  805. height: 100% !important;
  806. }
  807. img.halfImgCSS {
  808. position: relative;
  809. left: -112%;
  810. width: 212% !important;
  811. height: 100% !important;
  812. max-width: 212%
  813. }
  814. #myModal {
  815. overflow-x: hidden;
  816. overflow-y: auto;
  817. display: none;
  818. position: fixed;
  819. top: 0;
  820. left: 0;
  821. right: 0;
  822. bottom: 0;
  823. z-index: 1050;
  824. background-color: rgba(0, 0, 0, 0.5);
  825. }
  826. #myModal #modal-div {
  827. position: relative;
  828. width: 80%;
  829. margin: 0 auto;
  830. background-color: rgb(6 6 6 / 50%);
  831. border-radius: 8px;
  832. animation: fadeInDown .5s;
  833. }
  834. #modal-div .pop-up-tag {
  835. border-radius: 8px;
  836. overflow: hidden
  837. }
  838. #modal-div .sample-box-zdy,.avatar-box-zdy {
  839. display: inline-block;
  840. border-radius: 8px;
  841. background-color: #fff;
  842. overflow: hidden;
  843. margin: 5px;
  844. width: 140px
  845. }
  846. #modal-div .sample-box-zdy .photo-frame {
  847. overflow: hidden;
  848. margin: 10px
  849. }
  850. #modal-div .sample-box-zdy img {
  851. height: 90px
  852. }
  853. #modal-div .avatar-box-zdy .photo-frame {
  854. overflow: hidden;
  855. height: 120px;
  856. margin: 10px
  857. }
  858. #modal-div .avatar-box-zdy img {
  859. height: 120px
  860. }
  861. #modal-div .avatar-box-zdy span {
  862. font-weight: bold;
  863. text-align: center;
  864. word-wrap: break-word;
  865. display: block;
  866. padding: 10px;
  867. line-height: 22px;
  868. color: #333;
  869. background-color: #fafafa;
  870. border-top: 1px solid #f2f2f2
  871. }
  872. svg.tool-svg {
  873. fill: currentColor;
  874. width: 22px;
  875. height: 22px;
  876. vertical-align: middle
  877. }
  878. #menu-div {
  879. white-space: nowrap;
  880. background-color: white;
  881. color:black;
  882. display: none;
  883. min-width: 200px;
  884. position: absolute;
  885. top: 100%;
  886. border-radius: 5px;
  887. padding: 5px;
  888. box-shadow: 0 10px 20px 0 rgb(0 0 0 / 50%)
  889. }
  890. #menu-div .switch-div,#menu-div .switch-div *{
  891. margin: 3px;
  892. }
  893. #menu-div .switch-div label{
  894. display: inline;
  895. }
  896. #menu-div .range-div {
  897. display: flex;
  898. flex-direction: row;
  899. flex-wrap: nowrap;
  900. }
  901. #menu-div .range-div input {
  902. cursor: pointer;
  903. width: 80%;max-width:200px;
  904. }
  905. .alert-zdy {
  906. position: fixed;
  907. top: 50%;
  908. left: 50%;
  909. padding: 12px 20px;
  910. font-size: 20px;
  911. color: white;
  912. background-color: rgb(0,0,0,.75);
  913. border-radius: 4px;
  914. border: 1px solid black;
  915. animation: itemShow .4s;
  916. z-index: 1051;
  917. }
  918. .titleNowrap{
  919. white-space:nowrap;text-overflow: ellipsis;overflow:hidden;
  920. }
  921. .download-icon {
  922. position: absolute;
  923. right: 0;
  924. z-index: 2;
  925. cursor: pointer
  926. }
  927. .download-icon>svg {
  928. width: 30px;
  929. height: 30px;
  930. fill: aliceblue;
  931. }
  932. @keyframes fadeInDown {
  933. 0% {transform: translate3d(0, -100%, 0);opacity: 0; }
  934. 100% {transform: none; opacity: 1;}
  935. }
  936. @keyframes itemShow {
  937. 0% {transform:scale(0);}
  938. 100% {transform:scale(1);}
  939. }
  940. `;
  941. GM_addStyle(css_waterfall);
  942. }
  943. pageInit();
  944. })();