// ==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;
}))
});