Greasy Fork is available in English.

MiaouDTC - DansTonChat.com

Improves browsing of quotes and comments on DansTonChat.com (also known as DTC). Miaou... Miaou... MiaouDTC

2018-07-01 يوللانغان نەشرى. ئەڭ يېڭى نەشرىنى كۆرۈش.

// ==UserScript==
// @name            MiaouDTC - DansTonChat.com
// @name:fr         MiaouDTC - DansTonChat.com
// @namespace       jlgrall_UserScripts
// @version         1.2
// @description     Improves browsing of quotes and comments on DansTonChat.com (also known as DTC). Miaou... Miaou... MiaouDTC
// @description:fr  Améliore la navigation des quotes et des commentaires sur DansTonChat.com (DTC pour les intimes). Miaou... Miaou... MiaouDTC
// @homepage        https://greasyfork.org/en/scripts/369900-miaoudtc-danstonchat-com
// @supportURL      https://greasyfork.org/en/scripts/369900-miaoudtc-danstonchat-com/feedback
// @contributionURL https://www.tipeee.com/danstonchat
// @author          jlgrall
// @license         MIT License
// @match           https://danstonchat.com/*
// @exclude         https://danstonchat.com/user/login*
// @exclude         https://danstonchat.com/myaccount*
// @grant           none
// ==/UserScript==

(function($) {
  'use strict';
  
  var $empty = $();
  
  var Miaou = window.Miaou = {
    // CSS rules:
    styleContent: [
      // GENERAL:
      'div.cls-cookie { display: none; }',
      
      // scoreRatio:
      'span.miaouScoreRatio { float: left; margin-left: -20px; }',
      
      // miaouComments Header:
      '.miaouComments-header { float: left; background: #ddd; }',
      '.miaouComments-header:hover { background: #ccc; }',
      '.miaouComments-header > span,',
      '.miaouComments-header > a { padding: 11px 10px 12px; font-size: 1.1em; _font-weight: bold; display: inline-block; color: #222; }',
      '@media (max-width: 530px) {',
      '  .miaouComments-header > a { text-indent: -9999px; line-height: 0; }', // Idea from: https://stackoverflow.com/questions/7896402/how-can-i-replace-text-with-css/22054588#22054588
      '  .miaouComments-header > a:after { content: "Comms"; text-indent: 0; line-height: initial; display: block; }',
      '}',
      '@media (max-width: 350px) {',
      '  .miaouComments-header > a { padding: 5px; }',
      '  .miaouComments-header > a:after { content: "C"; font-size: 1.4em; }',
      '}',
      
      // miaouComments Wrapper and Body:
      '.miaouComments-wrapper { border-left: 10px solid #ddd; border-bottom: 10px solid #ddd; padding-left: 6px; }',
      '.miaouComments-body { max-height: 500px; overflow: auto; resize: vertical; padding-top: 6px; }',
      '@media (max-height: 660px) { .miaouComments-body { max-height: 74vh; } }',
      '@media (max-height: 570px) { .miaouComments-body { max-height: 68vh; } }',
      '@media (max-height: 480px) { .miaouComments-body { max-height: 60vh; } }',
      '.miaouItem.miaouComments-hide .miaouComments-wrapper { display: none; }',
      
      // Linkified quotes:
      '.item-content a.miaou-linkifiedQuoteRef { display: unset; max-width: unset; color: #8cbd6a; }',
      '.item-content a.miaou-linkifiedQuoteRef:hover { color: #add095; }',
    ],
    
    // Comments loading states:
    COMMENTS_UNLOADED: 0,
    COMMENTS_LOADING: 1,
    COMMENTS_LOADED: 2,
    COMMENTS_ERROR: 3,
    getCommentsStateForItem: function($item) {
      var state = $item.data('data-miaou-commentsState');
      return state === undefined ? Miaou.COMMENTS_UNLOADED : state;
    },
    setCommentsStateForItem: function($item, state) {
      $item.data('data-miaou-commentsState', state);
    },
    
    itemsById: {},
    extractItemId: function($item) { // itemId is always a string (it should not be converted to a number)
      var item = $item[0];
      for (var i = 0; i < item.classList.length; i++) {
        var name = item.classList.item(i);
        if (name !== 'item') {
          var match = name.match(/^item(\d{1,9})$/);
          if (match) return match[1];
        }
      }
      return undefined;
    },
    initItem: function($item) {
      var itemId = Miaou.extractItemId($item);
      var itemURL = $item.find('div.item-content > a').attr('href');
      var $score = $item.find('span.score');
      var scoreMatch = $score.text().match(/(\d{1,6})\s*\/\s*(\d{1,6})/);
      var scoreRatio = scoreMatch ? (scoreMatch[1] / scoreMatch[2]).toFixed(1) : NaN;
      var nbComments = parseInt($item.find('span.comments').text(), 10);
      
      Miaou.itemsById[itemId] = (Miaou.itemsById[itemId] || $empty).add($item);

      var $scoreRatio = $('<span class="miaouScoreRatio"> = ' + scoreRatio + '</span>');

      $item.data({
        'miaou-itemId': itemId,
        'miaou-itemURL': itemURL,
        'miaou-nbComments': nbComments,
        'miaou-$scoreRatio': $scoreRatio,
      });
      
      $item.addClass('miaouItem miaouItem' + itemId);
      
      $scoreRatio.insertAfter($score);
      
      if ($item.closest('.items, .item-listing').length > 0) Miaou._initItemComments($item);
      
      return $item;
    },
    _initItemComments: function($item) {
      var $commentsHeader = $('<div class="miaouComments-header"></div>');
      var $commentsWrapper = $('<div class="miaouComments-wrapper"></div>');
      var $commentsBody = $('<div class="miaouComments-body"></div>');
      
      $item.data({
        'miaou-$commentsHeader': $commentsHeader,
        'miaou-$commentsWrapper': $commentsWrapper,
        'miaou-$commentsBody': $commentsBody,
      });
      
      $item.addClass('miaouComments-hide'); // TODO: use 'miaouComments-show' instead ?
      $commentsHeader.insertBefore($item.find('.meta-bar .vote-plus'));
      $commentsWrapper.append($commentsBody).appendTo($item);
      
      Miaou.updateCommentsUI($item, Miaou.COMMENTS_UNLOADED);
      
      return $item;
    },
    updateCommentsUI: function($item, state) {
      if (state === undefined) {
        state = Miaou.getCommentsStateForItem($item);
      }
      else {
        Miaou.setCommentsStateForItem($item, state);
      }
      var itemId = $item.data('miaou-itemId');
      var nbComments = $item.data('miaou-nbComments');
      var $commentsHeader = $item.data('miaou-$commentsHeader');
      
      switch(state) {
        case Miaou.COMMENTS_UNLOADED:
          var hrefUnloaded = 'javascript:Miaou.loadCommentsForItemId(\'' + itemId + '\')';
          $commentsHeader.html('<a href="' + hrefUnloaded + '">Afficher les commentaires (' +  nbComments + ')</a>');
          break;
          
        case Miaou.COMMENTS_LOADING:
          $commentsHeader.html('<span>Chargement des commentaires...</span>');
          break;
          
        case Miaou.COMMENTS_LOADED:
          var hidden = $item.hasClass('miaouComments-hide');
          if (hidden) {
            var hrefLoadedHidden = 'javascript:Miaou.showCommentsForItemId(\'' + itemId + '\')';
            $commentsHeader.html('<a href="' + hrefLoadedHidden + '">Afficher les commentaires (' +  nbComments + ')</a>');
          }
          else {
            var hrefLoadedShown = 'javascript:Miaou.hideCommentsForItemId(\'' + itemId + '\')';
            $commentsHeader.html('<a href="' + hrefLoadedShown + '">Masquer les commentaires (' +  nbComments + ')</a>');
          }
          break;
          
        case Miaou.COMMENTS_ERROR:
          var hrefError = 'javascript:Miaou.loadCommentsForItemId(\'' + itemId + '\')';
          $commentsHeader.html('<a href="' + hrefError + '">Recharger les commentaires</a>');
          break;
      }
      
      return $item;
    },
    loadCommentsForItemId: function(itemId) {
      var $items = Miaou.itemsById[itemId] || $empty;
      if ($items.length === 0) return console.error('Could not find element item with id: ' + itemId);
      
      var itemURL = undefined;
      $items.each(function(i, item) {
        var $item = $(item);
        if (Miaou.getCommentsStateForItem($item) === Miaou.COMMENTS_LOADING) return;
        
        Miaou.updateCommentsUI($item, Miaou.COMMENTS_LOADING);
        
        itemURL = $item.data('miaou-itemURL');
      });
      if (!itemURL) return; // Probably already loading.
      
      $.get(itemURL, 'html').then(function(data) {
        var $comments = $($.parseHTML(data)).find('.comment-list').remove('script, style, link');
        if ($comments.length > 0) {
          var nbComments = $comments.find('.comment').length;
          return {$comments: Miaou.linkifyQuoteRefs($comments), state: Miaou.COMMENTS_LOADED, nbComments: nbComments};
        }
        else {
          $comments = $.parse('<div class="comment-list">Erreur: commentaires non trouvés.</div>');
          return $.Deffered().rejectWith(data, {$comments: $comments, state: Miaou.COMMENTS_ERROR});
        }
      }, function(jqXHR) {
        var $comments = $.parse('<div class="comment-list">Erreur: status = "' + jqXHR.statusText + '"</div>');
        return {$comments: $comments, state: Miaou.COMMENTS_ERROR};
      }).always(function(data) {
        // In case content of page was modified during xhr:
        var $items = Miaou.itemsById[itemId] || $empty;
        if ($items.length === 0) return;
        
        $items.each(function(i, item) {
          var $item = $(item);
          
          if ('nbComments' in data) $item.data('miaou-nbComments', data.nbComments);
          
          var $commentsBody = $item.data('miaou-$commentsBody');
          $commentsBody.empty().append(data.$comments);
          
          Miaou.updateCommentsUI($item, data.state);

          Miaou.showCommentsForItemId(itemId);
        });
      });
    },
    showCommentsForItemId: function(itemId) {
      var $items = Miaou.itemsById[itemId] || $empty;
      $items.each(function(i, item) {
        var $item = $(item);
        var state = Miaou.getCommentsStateForItem($item);
        if (state === Miaou.COMMENTS_UNLOADED) Miaou.loadCommentsForItemId(itemId);
        $item.removeClass('miaouComments-hide');
        Miaou.updateCommentsUI($item);
      });
    },
    hideCommentsForItemId: function(itemId) {
      var $items = Miaou.itemsById[itemId] || $empty;
      $items.each(function(i, item) {
        var $item = $(item);
        $item.addClass('miaouComments-hide');
        Miaou.updateCommentsUI($item);
      });
    },
    toggleCommentsForItemId: function(itemId) {
      var $items = Miaou.itemsById[itemId] || $empty;
      if ($items.filter(':not(.miaouComments-hide)').length > 0) {
        Miaou.hideCommentsForItemId(itemId);
      }
      else {
        Miaou.showCommentsForItemId(itemId);
      }
    },
    showCommentsForAllItems: function() {
      for (var itemId in Miaou.itemsById) Miaou.showCommentsForItemId(itemId);
    },
    hideCommentsForAllItems: function() {
      for (var itemId in Miaou.itemsById) Miaou.hideCommentsForItemId(itemId);
    },
    toggleCommentsForAllItems: function() {
      for (var itemId in Miaou.itemsById) Miaou.toggleCommentsForItemId(itemId);
    },
    linkifyQuoteRefs: function(node) {
      if (node.each) { // node is a jQuery object
        node.each(function(i, node) {
          Miaou.linkifyQuoteRefs(node);
        });
      }
      else if (node.hasChildNodes()) {
        for (var i = 0; i < node.childNodes.length; i++){
           Miaou.linkifyQuoteRefs(node.childNodes[i]);
        }
      }
      else if (node.nodeType === Node.TEXT_NODE
            && node.textContent.indexOf('#') > -1 // Quick test speeds up the process.
            && !node.parentNode.classList.contains('miaou-linkifiedQuoteRef')) {
        // Regex to find a DTC quote reference: a '#' followed by up to 9 digits,
        // and the reference must be separated from other words.
        var newHTML = node.textContent.replace(/\B#(\d{1,9})\b/g, '<a href="/$1.html" class="miaou-linkifiedQuoteRef">$&</a>');
        $(node).replaceWith(newHTML);
      }
      return node;
    },
  };
  
  
  
  
// MAIN:
  
  Miaou.pageHasItemsList = document.querySelector('div.items, div.item-listing') !== null;
  
  Miaou.$style = $('<style/>', {html: Miaou.styleContent.join('\n'), 'id': 'Miaou.$style'}).appendTo(document.head);
  
  $('.item').each(function(i, item) {
    Miaou.initItem($(item));
  });
  
  //Miaou.allowActionLoadAll = true;
  if (Miaou.pageHasItemsList && Miaou.allowActionLoadAll) {
    var $showAllComments = $('<a href="javascript:Miaou.showCommentsForAllItems()" class="miaouShowAllComments"><span>Afficher tous les commentaires</span></a>');
    $showAllComments.insertAfter('div.contenu a.submit.android');
    
    var $hideAllComments = $('<a href="javascript:Miaou.hideCommentsForAllItems()" class="miaouHideAllComments"><span>Masquer tous les commentaires</span></a>');
    $hideAllComments.insertAfter($showAllComments);
  }
  
  Miaou.linkifyQuoteRefs($('.item-content, .comment-content'));
  
})(window.jQuery);