Вакаба-разметка для vk.com

Включает вакаба-разметку в сообщениях ВК.

< Feedback on Вакаба-разметка для vk.com

Review: OK - script works, but has bugs

§
Posted: 09/01/2018
Edited: 09/01/2018

Говнокод

Доброе время суток!

Прошу Вас обратить внимание, что любое сообщение, содержащее буквосочетание wak в себе Вашим скриптом игнорируется из-за if (string.indexOf('wak') == -1). Кроме того, запускать его десять раз в секунду очень накладно для больших объёмов текста на неторопливых после Meltdown машинах. Смотрите тут и там примеры решений.

Кроме того, на мой взгляд, лучше вынести замену в функции repl(str) и её вызов из markUp() в циклах. Так проще дополнять и редактировать правила. Во второй функции, кстати, нагляднее было бы определить длину массивов document.getElementsByClassName('…') перед for (…), что также позволит не вычислять эти массивы по два раза за итерацию. Наконец, есть конструкция for … of (справка).

Да, забыл, посмотрите использование "use strict"; — пригодится.

Успехов!

§
Posted: 10/01/2018
Edited: 10/01/2018

Вот примерно это я предлагаю:

// ==UserScript==
// @name          Wakaba Markup
// @author      Anza Nyanza
// @namespace   vk.com/nyanza
// @version     0.0.1
// @description Enables Wakaba markup
// @match       *://*/*
// @exclude     *://regexr.com/*
// ==/UserScript==

"use strict";

var actualCode = '(' + function() {
    "use strict";
  function repl(str){
      var tuples = [
        [/(?:\*{2})([^\*<]+?)(?:\*{2})/gim,                          '<b>$1</b>'],                                // **bold**
        [/([\n\t>\s]|^)(?:\*|_)([^\*_<]+?)(?:\*|_)([\s<\n\t]|$)/gim, '$1<i>$2</i>$3'],                            // _italic_, *italic*
        [/\[b\](.*?)\[\/b\]/gim,                                     '<b>$1</b>'],                                // [b]bold[/b]
        [/\[i\](.*?)\[\/i\]/gim,                                     '<i>$1</i>'],                                // [i]italic[/i]
        [/(?:\%{2})([^\%<]+?)(?:\%{2})/gim,                          '<details>$1</details>'],                    // %%spoiler%%
        [/(^|[\s\n\t>])>([^<\n\t]+)/gim,                             '$1<q class="wakaba-quote">$2</q>'],         // >quote
        [/\[s\](.*?)\[\/s\]/gim,                                     '<s>$1</s>'],                                // [s]deleted[\s]
        [/\[sub\](.*?)\[\/sub\]/gim,                                 '<sub>$1</sub>'],                            // [sub]subscript[/sub]
        [/\[sup\](.*?)\[\/sup\]/gim,                                 '<sup>$1</sup>'],                            // [sup]superscript[/sup]
        [/\[u\](.*?)\[\/u\]/gim,                                     '<u>$1</u>'],                                // [u]underlined[/u]
        [/\[o\](.*?)\[\/o\]/gim,                                     '<span class="wakaba-overline">$1</span>'],  // [o]overlined[/o]
        [/\`{3}(.*?)\`{3}/gim,                                       '<code class="wakaba-code">$1</code>'],      // ```source code```
        [/~{3}(.*?)~{3}/gim,                                         '<mark>$1</mark>'],                          // ~~~highlighted~~~
        [/(?:[\s\n]|^)---/gim,                                       ' —'],                                       //
        [/~{2}/gim,                                                  '≈']                                         //
      ];
      for (let t of tuples) {
        str = str.replace(t[0], t[1]);
      }
      return str;
  }

    var selectors = [
        "div:not([wakabaed])",
        "span:not([wakabaed])"
    ];
  var isRunning = false;
    function wakaba() {
    if (isRunning) {
      return;
    }
    isRunning = true;
        for (let s of selectors) {
            var divs = document.querySelectorAll(s);
            for (let d of divs) {
        var innerHTML = "";
        for (let n of d.childNodes) {
          if (n.nodeName === "#text" && n.nodeValue !== undefined) {
            innerHTML += repl(n.nodeValue);
            //console.log(repl(n.nodeValue));
          }
          else {
            if (n.outerHTML !== undefined) {
              innerHTML += n.outerHTML;
            }
          }
        }
        d.innerHTML = innerHTML;
        d.setAttribute('wakabaed', 'true');
            }
      console.log("ran over", divs.length, s);
        }
    isRunning = false;
    }
    wakaba();
    // see http://stackoverflow.com/a/14570614
    var observeDOM = (function() {
        var MutationObserver = window.MutationObserver || window.WebKitMutationObserver,
            eventListenerSupported = window.addEventListener;

        return function(obj, callback) {
            if (MutationObserver) {
                // define a new observer
                var obs = new MutationObserver(function(mutations) {
                    if (mutations[0].addedNodes.length || mutations[0].removedNodes.length) {
                        callback();
                    }
                });
                // have the observer observe foo for changes in children
                obs.observe(obj, {childList: true, subtree: true});
            }
            else if (eventListenerSupported) {
                obj.addEventListener('DOMNodeInserted', callback, false);
                obj.addEventListener('DOMNodeRemoved', callback, false);
            }
        };
    })();
    var containers = document.querySelectorAll('body');
    for (let c of containers) {
        observeDOM(c, wakaba);
    }
} + ')();';

var script = document.createElement('script');
script.textContent = actualCode;
(document.body||document.documentElement).appendChild(script);

var css = document.createElement('style');
css.setAttribute('type', 'text/css');
css.innerHTML = '                                                    \
  div[wakabaed] q.wakaba-quote, span[wakabaed] q.wakaba-quote {      \
    opacity: 0.6;                                                    \
    border-left: 3px solid;                                          \
    padding-left: 3px;                                               \
  }                                                                  \
  div[wakabaed] .wakaba-overline, span[wakabaed] .wakaba-overline {  \
    text-decoration: overline;                                       \
  }                                                                  \
  div[wakabaed] code.wakaba-code, span[wakabaed] code.wakaba-code {  \
    border: 1px solid #aaa;                                          \
    border-radius: 0.2em;                                            \
    padding: 1px 4px;                                                \
  }                                                                  \
';
(document.body||document.documentElement).appendChild(css);

Но это иногда приводит к зависанию сайтов — отсюда @exclude.

Post reply

Sign in to post a reply.