-
1.
// ==UserScript==
-
2.
// @name 4chan Post Preview
-
3.
// @namespace https://ponepaste.org/5555
-
4.
// @match https://boards.4channel.org/*/thread/*
-
5.
// @grant none
-
6.
// @version 1.21
-
7.
// @author Fillyanon
-
8.
// @description 1/30/2022, 1:37:00 PM
-
9.
// ==/UserScript==
-
10.
-
11.
const css = `
-
12.
.colorizer-preview {
-
13.
border-top: 1px solid #888;
-
14.
margin: 0;
-
15.
margin-top: 0.5rem;
-
16.
max-height: 300px;
-
17.
min-height: 80px;
-
18.
min-width: 300px;
-
19.
overflow-y: auto;
-
20.
word-wrap: break-word;
-
21.
}
-
22.
-
23.
.colorizer-quote {
-
24.
color: #789922;
-
25.
}
-
26.
-
27.
.colorizer-reference {
-
28.
color: #d00;
-
29.
}
-
30.
-
31.
.spoiler {
-
32.
background: #000;
-
33.
color: #fff;
-
34.
display: inline !important;
-
35.
}
-
36.
`;
-
37.
-
38.
const processPreview = (input) => {
-
39.
const patterns = [
-
40.
[/\[spoiler\]([\s\S]*?)\[\/spoiler\]?/mg, "<s>$1</s>"],
-
41.
[/>>(\d{8})/g, "<a class='quotelink' href='#p$1'>>>$1</a>"],
-
42.
[/(\n>.*)/g, "<span class='quote'>$1</span>"],
-
43.
[/\[spoiler\]([\s\S]*)/mg, "<s>$1</s>"]
-
44.
];
-
45.
-
46.
const replaced = patterns.reduce((accumulator, pattern) => {
-
47.
const [rgx, tag] = pattern;
-
48.
return accumulator.replaceAll(rgx, tag)
-
49.
}, input)
-
50.
-
51.
// First replace removes the \n I added as a hack for quote-detection.
-
52.
// The rest of the \n-s get converted into <br>-s
-
53.
return replaced.replace(/\n/, "").replaceAll(/\n/g, "<br>")
-
54.
}
-
55.
-
56.
/* YANKED FROM FLAG RANDOMIZER SCRIPT */
- 57.
-
58.
-
59.
-
60.
const creationObserver = (function () {
-
61.
const observedNodes = [];
-
62.
const callbacks = [];
-
63.
const executeCallback = (fn, node) => {
-
64.
if (observedNodes.includes(node))
-
65.
return;
-
66.
observedNodes.push(node);
-
67.
fn(node);
-
68.
};
-
69.
const obs = new MutationObserver(mutationRecords => {
-
70.
mutationRecords.forEach(mutation => {
-
71.
mutation.addedNodes.forEach(node => {
-
72.
if (!(node instanceof HTMLElement))
-
73.
return;
-
74.
callbacks.forEach(([selector, fn]) => {
-
75.
if (node.matches(selector))
-
76.
executeCallback(fn, node);
-
77.
node.querySelectorAll(selector).forEach(childNode => executeCallback(fn, childNode));
-
78.
});
-
79.
});
-
80.
});
-
81.
});
-
82.
obs.observe(document.body, { childList: true, subtree: true });
-
83.
return function (selector, fn) {
-
84.
document.querySelectorAll(selector).forEach(node => executeCallback(fn, node));
-
85.
callbacks.push([selector, fn]);
-
86.
};
-
87.
})();
-
88.
-
89.
const selectors = [
-
90.
'form[name="post"]', // 4chan default post
-
91.
'form[name="qrPost"]', // 4chanNX quick reply form
-
92.
'div#qr form', // 4chanX quick reply form
-
93.
].join(', ');
-
94.
-
95.
-
96.
/* YANKING ENDS HERE */
-
97.
-
98.
// Inject the style.
-
99.
const style = document.createElement("style")
-
100.
style.innerHTML = css
-
101.
document.head.appendChild(style)
-
102.
-
103.
creationObserver(selectors, form => {
-
104.
if (!(form instanceof HTMLFormElement))
-
105.
return;
-
106.
-
107.
const textArea = form.querySelector("textarea")
-
108.
const preview = document.createElement("blockquote")
-
109.
preview.className = "colorizer-preview"
-
110.
preview.width = textArea.width;
-
111.
-
112.
// Thanks >>38150841 !
-
113.
preview.addEventListener('mouseover', Main.onThreadMouseOver);
-
114.
preview.addEventListener('mouseout', Main.onThreadMouseOut);
-
115.
-
116.
form.appendChild(preview)
-
117.
-
118.
new ResizeObserver(() => {
-
119.
preview.style.width = textArea.offsetWidth + 'px';
-
120.
preview.style.maxWidth = (textArea.style.width == "" ? "296px" : textArea.style.width);
-
121.
}).observe(textArea)
-
122.
-
123.
"input,paste".split(",").forEach(ev => textArea.addEventListener(ev, () => {
-
124.
// "\n" + is a hack that simplifies the way I detect quotes.
-
125.
// Probably could be done in a better way, but it doesn't much matter.
-
126.
preview.innerHTML = processPreview("\n" + textArea.value);
-
127.
preview.width = textArea.width;
-
128.
}))
-
129.
});
369 3.83 KB 129
Post Previewer UserScript
By FillyanonCreated: 2022-01-30 14:21:34
Updated: 2022-01-31 15:02:31
Expiry: Never
by Fillyanon
by Fillyanon
by Fillyanon
by Fillyanon
by Fillyanon