AniDub-CommentFinder

Поисковик комментов по id. Ищет комменты из топа на странице с анимой или из списка последних комментов любого пользователя.

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         AniDub-CommentFinder
// @namespace    MaxLevs
// @version      3.3.2
// @description  Поисковик комментов по id. Ищет комменты из топа на странице с анимой или из списка последних комментов любого пользователя.
// @author       MaxLevs
// @match        *://online.anidub.com/*
// @grant        none
// @noframes
// @run-at document-idle
// @licenses     https://raw.githubusercontent.com/MaxLevs/AniDub-CommentFinder/master/LICENSE
// @supportURL   https://github.com/MaxLevs/AniDub-CommentFinder/issues
// ==/UserScript==


(function(w) {
  'use strict';
  const _PAGE_CACHE = [];
  const _NEWS_CACHE = [];
  const _COMMENT_LIST_CACHE = [];
  const min = 1;
  const nav = w.document.getElementsByClassName('navigation')[0];
  const max = nav ? +nav.lastElementChild.innerHTML : 1;
  let bestComm;
  let news_id;
  let onLoadEvent = new Event("ad_finderonload");

  function Indicate(text = "ИЩЕМ?", dur = 1000) {
    this.link = document.createElement('div');
    this.link.id = 'ad-bcom-finder';
    this.link.align = 'center';
    this.link.textContent = text;
    this.link.style.cssText = `width: 100px;height: 20px;line-height: 20px;background-color: #c73f4c;color: #fff;font-weight: 600;border-radius: 10px;user-select: none;transition-property: background-color;transition-duration: ${dur}ms;cursor: pointer;`;

    this.animToken = null;

    this.animate = () => {
      this.animToken = setInterval((()=>{
        let state = false;
        return ()=>{
          if (state) {
            this.link.style.backgroundColor = '#c73f4c';
          } else {
            this.link.style.backgroundColor = '#565656';
          }
          state = !state;
        };
      })(), dur+1);
      this.link.textContent = "ПОИСК";
    };

    this.stopAnimate = (state) => {
      clearInterval(this.animToken);
      switch (state) {
        case 1:
          this.link.style.backgroundColor = "#c73f4c";
          this.link.textContent = "ОШИБКА";
          break;

        case 0:
        default:
          this.link.style.backgroundColor = "#6fae18";
          this.link.textContent = "НАЙДЕНО";
          break;
      }
    };
  }

  var ad_getCommentsList = (cstart, news_id) => {
    return new Promise((responsed) => {
      if (!_COMMENT_LIST_CACHE[cstart]){
        $.get(dle_root+"engine/ajax/comments.php", {cstart:cstart,news_id:news_id,skin:dle_skin}, (data) => {
          _COMMENT_LIST_CACHE[cstart] = data;
          responsed(data);
        },"json");
      } else {
        responsed(_COMMENT_LIST_CACHE[cstart]);
      }
    });
  };

  function ad_showComment(cstart, news_id, comm_id) {
    ad_getCommentsList(cstart, news_id).then(
      function(data){
        if(!isNaN(cstart)&&!isNaN(news_id)){
          $('#dle-comm-link').unbind('click');
          $('#dle-comm-link').bind('click',function(){CommentsPage(cstart,news_id);return false;});
        }
        $("#dle-comments-list").html(data.comments);
        $(".dle-comments-navigation").html(data.navigation);
        if (comm_id && /comment-id-\d+/.test(comm_id)) {
          document.getElementById("dle-comments-list").querySelector(`#${comm_id}`).scrollIntoView();
        }
        w.dispatchEvent(new Event('ad_oncommentdraw'));
      }
    );
    return false;
  }

  var ad_binarySearch = (id, n1, n2) => {
    return (Promise.all([ad_getCommentsList(n1, news_id), ad_getCommentsList(n2, news_id), ad_getCommentsList(Math.ceil((n1+n2)/2), news_id)])
        .then((data) => {
      data = data.map(el => {return el.comments;});
      if (n1 > n2) {
        return -1;
      }

      if(~data[0].search(new RegExp(`${id}\\D`))){
        return n1;
      }

      if(~data[1].search(new RegExp(`${id}\\D`))){
        return n2;
      }

      if(~data[2].search(new RegExp(`${id}\\D`))){
        return Math.ceil((n1+n2)/2);
      }

      if(+id.match(/\d+/)[0] < +data[2].match(/comment-id-\d+/g)[0].match(/\d+/)[0]){
        return ad_binarySearch(id, n1+1, Math.ceil((n1+n2)/2));
      } else {
        return ad_binarySearch(id, Math.ceil((n1+n2)/2), n2-1);
      }
    }).catch((err) => {
      return Promise.reject(err);
    }));
  };

  var searchError = (err)=>{
    console.error(err);
  };

  var ad_searchManager = (userIdList = null) => {
    userIdList = typeof userIdList === "string" ? [userIdList] : userIdList;
    return Promise.all((() => {
      let resP = [];
      if (userIdList && userIdList.length) {
        for (let i = 0; i < userIdList.length; ++i) {
          resP[i] = ad_binarySearch(userIdList[i], min, max).then(
            (page) => {
              if(~page){
                ad_showComment(page, news_id, userIdList[i]);
                console.log(`Page: ${page}`);
              } else {
                alert("Комментарий не найден...");
              }
              return page;
            }, searchError);
        }
      } else {
        for (let i = 0; i < bestComm.length; ++i) {
          resP[i] = ad_binarySearch(bestComm[i].id, min, max).then(
            (page) => {
              if(~page){
                bestComm[i].children[0].onclick = ()=>{ad_showComment(page, news_id, bestComm[i].id); return false;};
                bestComm[i].children[0].style.cursor = "pointer";
                console.log(`Page: ${page}`);
              } else {
                alert(`Комментарий #${i+1} не найден...`);
              }
              return page;
            }, searchError);
        }
      }
      return resP;
    })());
  };

  var ad_uri = w.location.href;
  if ((new RegExp('/[^/]+/[^/]+/[^/]+$')).test(ad_uri)) {
    //Вставляем индикатор
    let indicator = new Indicate("ИЩЕМ?");
    indicator.link.style.float = 'right';
    let refPoint = document.getElementById('ad-refPoint');
    refPoint = document.getElementsByClassName('comm_best')[0].previousElementSibling.previousElementSibling.previousElementSibling;
    refPoint.style.width = '400px';
    refPoint.style.float = 'left';
    refPoint.id = 'ad-refPoint';
    refPoint.style.marginBottom = '14px';
    refPoint.parentNode.insertBefore(indicator.link, refPoint.nextSibling);

    //Получаем нужные данные
    bestComm = w.document.getElementsByClassName('comm_best')[0].children;
    news_id = w.location.pathname.match(/\d*-/)[0].match(/\d*/)[0];

    //Алгоритмы работы
    var activateIndicator = () => {
      indicator.link.style.cursor = "default";
      indicator.animate();
      ad_searchManager().then((resp)=>{
        let state = 0;
        if(resp && ~resp.indexOf(-1)){
          state = 1;
        }
        indicator.stopAnimate(state);
        return resp;
      });
      indicator.link.removeEventListener('click', activateIndicator);
    };
    indicator.link.addEventListener('click', activateIndicator);

    //API
    w.ad_searchManager = ad_searchManager;
    w.ad_showComment = ad_showComment;
  }
  else if ((new RegExp('/index.php?[^/]*do=lastcomments[^/]*$')).test(ad_uri)) {
    var mar = 12;
    var list = document.getElementById("dle-comments-list").children;

    for (var point of list) {
      if (!(/comment-id-\d+/.test(point.id))) continue;

      var indicatorBox = document.createElement("div");
      var indicatorMar = document.createElement("div");
      let indicator = new Indicate("НАЙТИ");
      {
        indicatorMar.id = 'ad_indicatorMar';
        indicatorMar.style.height = `${mar}px`;
      }
      {
        indicatorBox.style.height = `${mar + (+indicator.link.style.height.match(/\d*/)[0])}px`;
        indicatorBox.style.backgroundColor = "#fff";
      }

      point.querySelector('.commleft').align = 'center';
      point.querySelector('.commleft').appendChild(indicatorBox);
      indicatorBox.appendChild(indicatorMar);
      indicatorBox.appendChild(indicator.link);

      function goToSearch(event){
        let indicator = this.indicator;
        let point = this.point;
        let href = point.querySelector('.comm_title').children[1].href;
        let targetPage = null;

        if (!_NEWS_CACHE[href]){
          targetPage = w.open(href);
          _NEWS_CACHE[href] = targetPage;
          setTimeout(function(){
            targetPage.document.title = `[ПОИСК] ${targetPage.document.title}`;
          }, 500);
          targetPage.onbeforeunload = function(){
            _NEWS_CACHE[href] = null;
          };
        } else {
          targetPage = _NEWS_CACHE[href];
        }

        if (!_PAGE_CACHE[point.id]){
          indicator.animate();
          if(!targetPage.ad_loaded){
            targetPage.addEventListener("ad_finderonload", doEv);
          } else {
            doEv();
          }
          function doEv() {
            targetPage.ad_loaded = true;
            targetPage.ad_searchManager(point.id).then((resp) => {
              let state = 0;
              if(resp && ~resp.indexOf(-1)){
                state = 1;
              }
              indicator.stopAnimate(state);
              return resp;
            }).then((resp)=>{
              _PAGE_CACHE[point.id] = resp[0];
            });
            targetPage.removeEventListener("ad_finderonload", doEv);
          };
        } else {
          if(!targetPage.ad_loaded){
            targetPage.addEventListener("ad_finderonload", doEv);
          } else {
            doEv();
          }
          function doEv() {
            targetPage.ad_loaded = true;
            targetPage.ad_showComment(_PAGE_CACHE[point.id], targetPage.location.pathname.match(/\d*-/)[0].match(/\d*/)[0], point.id);
            targetPage.removeEventListener("ad_finderonload", doEv);
          };
        }
      }

      indicator.link.addEventListener('click', {handleEvent: goToSearch, indicator:indicator, point:point});
    }
  }

  //API
  w.ad_getCommentsList = ad_getCommentsList;
  w.dispatchEvent(onLoadEvent);
})(window);