// ==UserScript== // @name 4chan Post Preview // @namespace https://ponepaste.org/5555 // @match https://boards.4channel.org/*/thread/* // @grant none // @version 1.21 // @author Fillyanon // @description 1/30/2022, 1:37:00 PM // ==/UserScript== const css = ` .colorizer-preview { border-top: 1px solid #888; margin: 0; margin-top: 0.5rem; max-height: 300px; min-height: 80px; min-width: 300px; overflow-y: auto; word-wrap: break-word; } .colorizer-quote { color: #789922; } .colorizer-reference { color: #d00; } .spoiler { background: #000; color: #fff; display: inline !important; } `; const processPreview = (input) => { const patterns = [ [/\[spoiler\]([\s\S]*?)\[\/spoiler\]?/mg, "$1"], [/>>(\d{8})/g, ">>$1"], [/(\n>.*)/g, "$1"], [/\[spoiler\]([\s\S]*)/mg, "$1"] ]; const replaced = patterns.reduce((accumulator, pattern) => { const [rgx, tag] = pattern; return accumulator.replaceAll(rgx, tag) }, input) // First replace removes the \n I added as a hack for quote-detection. // The rest of the \n-s get converted into
-s return replaced.replace(/\n/, "").replaceAll(/\n/g, "
") } /* YANKED FROM FLAG RANDOMIZER SCRIPT */ // https://ponepaste.org/6796 const creationObserver = (function () { const observedNodes = []; const callbacks = []; const executeCallback = (fn, node) => { if (observedNodes.includes(node)) return; observedNodes.push(node); fn(node); }; const obs = new MutationObserver(mutationRecords => { mutationRecords.forEach(mutation => { mutation.addedNodes.forEach(node => { if (!(node instanceof HTMLElement)) return; callbacks.forEach(([selector, fn]) => { if (node.matches(selector)) executeCallback(fn, node); node.querySelectorAll(selector).forEach(childNode => executeCallback(fn, childNode)); }); }); }); }); obs.observe(document.body, { childList: true, subtree: true }); return function (selector, fn) { document.querySelectorAll(selector).forEach(node => executeCallback(fn, node)); callbacks.push([selector, fn]); }; })(); const selectors = [ 'form[name="post"]', // 4chan default post 'form[name="qrPost"]', // 4chanNX quick reply form 'div#qr form', // 4chanX quick reply form ].join(', '); /* YANKING ENDS HERE */ // Inject the style. const style = document.createElement("style") style.innerHTML = css document.head.appendChild(style) creationObserver(selectors, form => { if (!(form instanceof HTMLFormElement)) return; const textArea = form.querySelector("textarea") const preview = document.createElement("blockquote") preview.className = "colorizer-preview" preview.width = textArea.width; // Thanks >>38150841 ! preview.addEventListener('mouseover', Main.onThreadMouseOver); preview.addEventListener('mouseout', Main.onThreadMouseOut); form.appendChild(preview) new ResizeObserver(() => { preview.style.width = textArea.offsetWidth + 'px'; preview.style.maxWidth = (textArea.style.width == "" ? "296px" : textArea.style.width); }).observe(textArea) "input,paste".split(",").forEach(ev => textArea.addEventListener(ev, () => { // "\n" + is a hack that simplifies the way I detect quotes. // Probably could be done in a better way, but it doesn't much matter. preview.innerHTML = processPreview("\n" + textArea.value); preview.width = textArea.width; })) });