Last active
January 6, 2024 14:29
-
-
Save EtienneDG/fe32d3213d87f79e0da0f829e73ee4ab to your computer and use it in GitHub Desktop.
Trello syntax highlighting
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Trello syntax highlighting | |
// @namespace http://tampermonkey.net/ | |
// @version 2024-01-05 | |
// @description Add some code syntax highlighting for trello cards description | |
// @author EtienneDG | |
// @match https://trello.com/* | |
// @icon https://www.google.com/s2/favicons?sz=64&domain=trello.com | |
// @grant GM_addStyle | |
// @grant GM_getResourceText | |
// @resource CSS https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism-solarizedlight.min.css | |
// @require https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/prism.min.js | |
// @require https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-bash.min.js | |
// @require https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-javascript.min.js | |
// @require https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-python.min.js | |
// @require https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-rust.min.js | |
// @updateURL https://gist.githubusercontent.com/EtienneDG/fe32d3213d87f79e0da0f829e73ee4ab/raw/trello.js | |
// @downloadURL https://gist.githubusercontent.com/EtienneDG/fe32d3213d87f79e0da0f829e73ee4ab/raw/trello.js | |
// ==/UserScript== | |
(function() { | |
'use strict'; | |
const CARD_MODAL_SELECTOR = ".window-overlay" | |
const DESCIPTION_SELECTOR = "div.current.markeddown.hide-on-edit.js-desc.js-show-with-desc" | |
// "// PRISM=foo" or "//PRISM=foo" or "# PRISM=foo" or "#PRISM=foo" | |
const LANG_REGEX = [/#\s{0,1}PRISM=(.*)\n/g, /\/\/\s{0,1}PRISM=(.*)\n/g] | |
function debounce(func, delay) { | |
let debounceTimer | |
return function() { | |
const context = this | |
const args = arguments | |
clearTimeout(debounceTimer) | |
debounceTimer = setTimeout(() => func.apply(context, args), delay) | |
}; | |
}; | |
function initPrism() { | |
// inject Prism's CSS | |
const cssAsText = GM_getResourceText("CSS") | |
GM_addStyle(cssAsText) | |
} | |
function getLang(text) { | |
for (let regex of LANG_REGEX) { | |
const matches = regex.exec(text) | |
if (Array.isArray(matches) && matches.length > 1) return matches[1] | |
} | |
return null | |
} | |
function setUpLangClass(element, lang) { | |
element.classList.add(`language-${lang}`) | |
} | |
// Used in MutationObserver => debounced by default to avoid multiple consecutive highlights | |
const highlightAll = debounce(() => { | |
const codeTags = document.querySelectorAll("code") | |
for (const node of codeTags) { | |
const lang = getLang(node.innerText) | |
setUpLangClass(node, lang) | |
} | |
// eslint-disable-next-line no-undef | |
Prism.highlightAll() | |
}, 100) | |
function initCardOpenObserver() { | |
const observer = new MutationObserver((mutations) => { | |
const description = document.querySelector(DESCIPTION_SELECTOR) | |
for (const mutation of mutations) { | |
for (const node of mutation.addedNodes) { | |
if (node.contains(description)) { | |
highlightAll() | |
} | |
} | |
} | |
}) | |
observer.observe(document.querySelector(CARD_MODAL_SELECTOR), { | |
childList: true, | |
subtree: true | |
}) | |
} | |
function initDescEditObserver() { | |
const observer = new MutationObserver((mutationList) => { | |
const description = document.querySelector(DESCIPTION_SELECTOR) | |
for (const mutation of mutationList) { | |
if (mutation.target === description) { | |
highlightAll() | |
} | |
} | |
}) | |
const target = document.querySelector(CARD_MODAL_SELECTOR) | |
observer.observe(target, {attributes: true, childList: true, subtree: true }); | |
} | |
document.onreadystatechange = () => { | |
if (document.readyState === "complete") { | |
initPrism() | |
highlightAll() | |
initCardOpenObserver() | |
initDescEditObserver() | |
} | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment