From b25e3c13d055639c6e34300c155145811f82306a Mon Sep 17 00:00:00 2001 From: hiro98 Date: Thu, 9 Apr 2020 14:31:27 +0200 Subject: [PATCH] init --- .gitignore | 1 + README.md | 11 ++++++++ manifest.json | 26 ++++++++++++++++++ package-lock.json | 24 +++++++++++++++++ riot-katex.js | 68 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 130 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 manifest.json create mode 100644 package-lock.json create mode 100644 riot-katex.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/README.md b/README.md new file mode 100644 index 0000000..25fb43c --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +# Riot KaTeX + +This extension injects KaTeX into the `Riot` chat client for +`matrix`. This currently works for just one domain +(matrix.tu-dresden.de). If you want to use it, you have to adjust the +`manifest.json`. + +## Writing LaTeX + - `$$x^2$$` renders math block style + - `\(x^2\)` renders math inline + diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..84edb28 --- /dev/null +++ b/manifest.json @@ -0,0 +1,26 @@ +{ + "manifest_version": 2, + "name": "Riot KaTeX", + "version": "1.0", + + "description": "Renders formulars in Riot chats using KaTeX.", + + "icons": { + "48": "icons/border-48.png" + }, + "permissions": [ + "activeTab" + ], + "content_scripts": [ + { + "matches": ["*://matrix.tu-dresden.de/*"], + "js": ["node_modules/katex/dist/katex.js", + "node_modules/katex/dist/contrib/auto-render.js", + "node_modules/observable-slim/observable-slim.js", + "riot-katex.js"], + "css": ["node_modules/katex/dist/katex.css"], + "all_frames": true, + "run_at": "document_idle" + } + ] +} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..d0bc1fa --- /dev/null +++ b/package-lock.json @@ -0,0 +1,24 @@ +{ + "requires": true, + "lockfileVersion": 1, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "katex": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/katex/-/katex-0.11.1.tgz", + "integrity": "sha512-5oANDICCTX0NqYIyAiFCCwjQ7ERu3DQG2JFHLbYOf+fXaMoH8eg/zOq5WSYJsKMi/QebW+Eh3gSM+oss1H/bww==", + "requires": { + "commander": "^2.19.0" + } + }, + "observable-slim": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/observable-slim/-/observable-slim-0.1.5.tgz", + "integrity": "sha512-xhDK4EjwM6ehZ6KhTtDc0z5kqBhqoBQPP9pq2n1c+RXA4IcyLIm68ipDwS3nZVXhrCssoKu4LcHDUT1tl0kP9A==" + } + } +} diff --git a/riot-katex.js b/riot-katex.js new file mode 100644 index 0000000..94888e0 --- /dev/null +++ b/riot-katex.js @@ -0,0 +1,68 @@ +(function() { + /** + * Check and set a global guard variable. + * If this content script is injected into the same page again, + * it will do nothing next time. + */ + if (window.hasRun) { + return; + } + window.hasRun = true; + + const math_config = [ + {left: "$$", right: "$$", display: true}, + {left: "\\(", right: "\\)", display: false}, + {left: "\\[", right: "\\]", display: true} + ] + + function init() { + const header = document.querySelector('.mx_RoomList'); + let chat_observer = listen_on_chat_element(); + function listen_on_chat_element() { + const chat_elem = document.querySelector('.mx_RoomView_MessageList'); + renderMathInElement(chat_elem, math_config); + + const config = { attributes: true, childList: true, subtree: true }; + const callback = function(mutationsList, observer) { + // Use traditional 'for loops' for IE 11 + for(let mutation of mutationsList) { + if (mutation.type === 'childList' && mutation.addedNodes.length > 0) { + for(let node of mutation.addedNodes) { + renderMathInElement(node, math_config); + } + } + } + }; + // Create an observer instance linked to the callback function + const observer = new MutationObserver(callback); + + // Start observing the target node for configured mutations + observer.observe(chat_elem, config); + return observer; + } + + function change_chat_element(mutationsList, observer) { + if (chat_observer) { + chat_observer.disconnect(); + } + + chat_observer = listen_on_chat_element(); + } + + const header_obs = new MutationObserver(change_chat_element) + const config = { attributes: true, childList: true, subtree: true }; + header_obs.observe(header, config); + } + + let = window.wrappedJSObject; + + function wait_for_matrix() { + if(!('matrixChat' in window.wrappedJSObject + && window.wrappedJSObject.matrixChat.firstSyncComplete)) + return setTimeout(wait_for_matrix, 500); + + init(); + } + + wait_for_matrix(); +})();