Fix kbin Code Blocks

Fix for kbin code blocks federated from Lemmy. Strips out the weird <span> tags on each line.

当前为 2024-01-04 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Fix kbin Code Blocks
  3. // @namespace pamasich-kbin
  4. // @version 1.2.3
  5. // @description Fix for kbin code blocks federated from Lemmy. Strips out the weird <span> tags on each line.
  6. // @author Pamasich
  7. // @match https://kbin.social/*
  8. // @icon https://www.google.com/s2/favicons?sz=64&domain=kbin.social
  9. // @license MIT
  10. // @grant none
  11. // ==/UserScript==
  12.  
  13. /*
  14. This script fixes code blocks on kbin that originate from Lemmy.
  15. When federating code blocks, Lemmy includes additional <span> tags
  16. which kbin currently does not expect, so it just renders them in plaintext.
  17. The script removes those tags from code blocks.
  18. */
  19.  
  20. const testPattern = /^\n?<span style="color:#[0-9a-fA-F]{6};">(.+\n)+<\/span>\n?$/;
  21. const startTagPattern = /^\n?<span style="color:#[0-9a-fA-F]{6};">/;
  22. const endTagPattern = /\n<\/span>\n?$/;
  23. const combinedPattern = /<\/span><span style="color:#[0-9a-fA-F]{6};">/g;
  24.  
  25. function fixCodeBlock(code) {
  26. // used to avoid false positives, wouldn't want to strip out end span tags (</span>) from legit HTML code blocks
  27. if (testPattern.test(code.innerText)) {
  28. code.innerText = code.innerText
  29. .replace(startTagPattern, "")
  30. .replaceAll(combinedPattern, "")
  31. .replace(endTagPattern, "");
  32. }
  33. }
  34.  
  35. // the MutationObserver doesn't work well when the page is loaded from scratch (without navigating from another kbin page with turbo mode)
  36. document.querySelectorAll("pre code").forEach(fixCodeBlock);
  37.  
  38. const observer = new MutationObserver(mutations => {
  39. // the filter ensures the script only looks for new code blocks to fix if new comments were added or the user navigated to a different thread
  40. const codeBlocks = mutations.flatMap(mutation => Array.from(mutation.addedNodes))
  41. .filter(node => node.nodeName == "BLOCKQUOTE" || node.nodeName == "BODY")
  42. .flatMap(node => Array.from(node.querySelectorAll("pre code")));
  43. // codeBlocks at this point might contain the same node twice, so the Set constructor is used to get unique nodes
  44. new Set(codeBlocks).forEach(fixCodeBlock);
  45. });
  46. // observing the entire document because of turbo mode
  47. observer.observe(document, { childList: true, subtree: true });