Sleazy Fork is available in English.

ExHentai/E-Hentai Infinite Pages / No Date Limit In Watched

Removes post limit when browsing watched tag posts

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください。
// ==UserScript==
// @name        ExHentai/E-Hentai Infinite Pages / No Date Limit In Watched
// @description Removes post limit when browsing watched tag posts
// @namespace   Violentmonkey Scripts
// @match       https://exhentai.org/watched
// @match       https://e-hentai.org/watched
// @version     1.0
// @author      shlsdv
// @icon        https://e-hentai.org/favicon.ico
// @license     MIT
// ==/UserScript==

var firstWatchedPage = null;
var firstWatchedDate = null;

const fullTag = {
  a: 'artist',
  c: 'character',
  char: 'character',
  cos: 'cosplayer',
  f: 'female',
  g: 'group',
  circle: 'group',
  l: 'language',
  lang: 'language',
  m: 'male',
  x: 'mixed',
  o: 'other',
  p: 'parody',
  series: 'parody',
  r: 'reclass'
}

function addFilterButton() {
  const fsearch = document.getElementById('f_search');
  const inputButton = document.createElement('input');
  inputButton.type = 'button';
  inputButton.value = 'Filter';

  inputButton.addEventListener('click', function() {
      sessionStorage.setItem('searchFilter',fsearch.value);
      applyFilter();
  });

  const searchBtn = fsearch.parentNode.querySelector('input[value="Search"]');

  searchBtn.addEventListener('mousedown', function() {
      sessionStorage.setItem('searchFilter','');
  });

  const clearBtn = fsearch.parentNode.querySelector('input[value="Clear"]');

  clearBtn.addEventListener('mousedown', function() {
      sessionStorage.setItem('searchFilter','');
  });

  if (fsearch) {
      const parentNode = fsearch.parentNode;
      parentNode.appendChild(inputButton);
  }
}

function parseFilterString(input) {
    if (!input) return {};

    let split = input.match(/([-]\b\w*:\s*"[^"]+"|[-]\b\w*:\s*\w+|-[^"]\w*\b(?=\s|$)|\b\w*:\s*"[^"]+"|\b\w*:\s*\w+|[^"]\w*\b(?=\s|$))/g);
    let result = {content: []};
    split.forEach(item => {
        let kv = item.trim().split(/:(.+)/);

        if (kv.length >= 2) {
            let x = kv[0].startsWith('-') ? kv[0].substring(1) : kv[0];
            if (x in fullTag) {
              kv[0] = (kv[0].startsWith('-') ? '-' : '') +  fullTag[x];
            }
            result[kv[0]] = kv[1].trim().replace(/["$]/g, '');
        } else {
            result['content'].push(kv[0]);
        }
    });

    result.content = result.content.join(' ');
    return result;
}

function setSearchBarToFilter() {
  var search = sessionStorage.getItem('searchFilter');
  if (search) {
   document.getElementById('f_search').value = search;
  }
}

function applyFilter() {
  var search = sessionStorage.getItem('searchFilter');
  var dict = parseFilterString(search);

  let elems = document.querySelectorAll('.glname');
  elems.forEach(elem => {
      let ancestor = elem.closest('tr') || elem.closest('.gl1t');
      if (!ancestor) return;
      ancestor.style.display = '';
      for (let key in dict) {
          let negation = key.startsWith('-');
          let adjustedKey = negation ? key.substring(1) : key;
          let containsKeyValue = ancestor.innerHTML.includes(adjustedKey + ':' + dict[key]);

          if ((negation && containsKeyValue) || (!negation && key === 'content' && ancestor.innerHTML.indexOf(dict[key]) === -1) ||
              (!negation && key !== 'content' && !containsKeyValue))
          {
              ancestor.style.display = 'none';
              break;
          }
      }
  });
}

function getDomain() {
  return window.location.href.includes('exhentai') ? 'exhentai.org' : 'e-hentai.org';
}

function getEarliestPostId() {
  const regex = new RegExp(`https://${getDomain()}/g/(\\d+)/.*`);
  const elements = document.querySelectorAll('a');
  for (let i = elements.length - 1; i >= 0; i--) {
      const match = elements[i].href.match(regex);
      if (match && match[1]) {
          return match[1];
      }
  }
  return null;
}

function initInfinitePages2() {
  const unext = document.querySelector('#unext');
  if (unext === null) {
    console.log('Infinite pages: unext does not exist in document (first page is probably empty).');
    return;
  }

  if (unext.tagName.toLowerCase() === 'span') {
    var id = getEarliestPostId();

    var nextUrl = '';
    var jump = 1;

    if (window.location.href.includes('&jump=')) {
      const urlParams = new URLSearchParams(window.location.search);
      jump = parseInt(urlParams.get('jump').replace(/\D/g, '')) + 1;
    }

    if (!window.location.href.includes('?next=') && id === null) {
      console.log("Infinite pages: url does not contain '?next=' and no post exists in document");
      return;
    }
    else if (id === null) {
      nextUrl = window.location.href.split('&jump=')[0];
      nextUrl += '&jump=' + jump;
    }
    else {
      var id = parseInt(id);
      nextUrl = `https://${getDomain()}/watched?next=${id}&jump=${jump}`;
    }

    console.log(nextUrl);

    const nextJumpLink = `<a id="unext" href="${nextUrl}">Jump &gt;</a>`;
    document.querySelector('#unext').parentNode.innerHTML = nextJumpLink;
    document.querySelector('#dnext').parentNode.innerHTML = nextJumpLink;
  }
}

(function() {
  initInfinitePages2();
  addFilterButton();
  applyFilter();
  setSearchBarToFilter();
})();