re-render markdown with marked.js and highlight codeblocks with highlight.js
当前为
// ==UserScript== // @name Old Reddit Better Codeblocks // @namespace http://tampermonkey.net/ // @version 0.3.1 // @license MIT // @description re-render markdown with marked.js and highlight codeblocks with highlight.js // @author cultab // @match http*://*.reddit.com/* // @exclude http*://new.reddit.com/* // @icon https://www.google.com/s2/favicons?sz=64&domain=reddit.com // @grant GM_addStyle // @grant GM_getResourceText // @require https://cdn.jsdelivr.net/npm/@violentmonkey/dom@2 // @require https://cdn.jsdelivr.net/npm/[email protected]/lib/marked.umd.min.js // @require https://cdn.jsdelivr.net/npm/[email protected]/dist/purify.min.js // @require https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js // @resource hljs https://cdn.jsdelivr.net/gh/highlightjs/[email protected]/build/styles/github-dark.min.css // ==/UserScript== /* global VM hljs DOMPurify marked */ function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } function until(conditionFunction) { const poll = resolve => { if(conditionFunction()) resolve(); else setTimeout(_ => poll(resolve), 400); } return new Promise(poll); } function parse(md) { md = md.replace('/ /g', ' '); md = DOMPurify.sanitize(marked.parse(md)); md = md.replace(/</g,'<').replace(/>/g,'>').replace(/&/g,'&'); return md; } const stoyle = GM_getResourceText("hljs"); GM_addStyle(stoyle); const disconnect = VM.observe(document.body, () => { // all posts/comments const entries = document.getElementsByClassName("entry"); // barrier for callback completion let barrier = entries.length; for (const entry of entries) { // find view source button and if exists click it twice let btn = entry.querySelector(".viewSource"); if (btn == null) { continue; } btn.children[0].click(); // yes twice btn.children[0].click(); // when source is loaded, use it to replace post content with marked.js markdown VM.observe(entry, () => { /* intended shared reference to barrier*/ let source = entry.querySelector("textarea").innerHTML; let post = entry.querySelector(".usertext-body"); if (post == null) { console.log("entry: ", entry); } else { post.children[0].innerHTML = parse(source); } barrier--; return true }) } (async() => { // wait until all posts have been re-parsed await until(() => { return barrier == 0; }); // highlight all codeblocks hljs.highlightAll(); // create a div with class hlhs let hl = document.createElement("div"); hl.classList.add('hljs'); hl.setAttribute("id", "hljshack"); document.querySelector("body").append(hl); // use it to get the style of hljs classes let ready_and_styled = document.getElementById("hljshack"); let wanted_styles = window.getComputedStyle(ready_and_styled); // force hljs styles on code and pre blocks let code_blocks = document.querySelectorAll("code"); for (let blk of code_blocks) { blk.style.backgroundColor = wanted_styles.backgroundColor; blk.style.color = wanted_styles.color; } let pre_elems = document.querySelectorAll("pre"); for (let pre of pre_elems) { pre.style.backgroundColor = wanted_styles.backgroundColor; pre.style.borderColor = wanted_styles.color; } })(); return true; });