Commit 37c2f46d authored by Robert Knight's avatar Robert Knight

Convert `src/sidebar/{media-embedder.js, render-markdown.js}` to TypeScript

Convert these modules to TS and improve the docs of several functions.
parent 0e6df86a
...@@ -14,18 +14,15 @@ DOMPurify.addHook('afterSanitizeAttributes', node => { ...@@ -14,18 +14,15 @@ DOMPurify.addHook('afterSanitizeAttributes', node => {
}); });
function targetBlank() { function targetBlank() {
/** @param {string} text */ function filter(text: string) {
function filter(text) {
return text.replace(/<a href=/g, '<a target="_blank" href='); return text.replace(/<a href=/g, '<a target="_blank" href=');
} }
return [{ type: 'output', filter }]; return [{ type: 'output', filter }];
} }
/** @type {showdown.Converter} */ let converter: showdown.Converter;
let converter;
/** @param {string} markdown */ function renderMarkdown(markdown: string) {
function renderMarkdown(markdown) {
if (!converter) { if (!converter) {
// see https://github.com/showdownjs/showdown#valid-options // see https://github.com/showdownjs/showdown#valid-options
converter = new showdown.Converter({ converter = new showdown.Converter({
...@@ -44,30 +41,27 @@ function renderMarkdown(markdown) { ...@@ -44,30 +41,27 @@ function renderMarkdown(markdown) {
return converter.makeHtml(markdown); return converter.makeHtml(markdown);
} }
/** @param {number} id */ function mathPlaceholder(id: number) {
function mathPlaceholder(id) {
return '{math:' + id.toString() + '}'; return '{math:' + id.toString() + '}';
} }
/** type MathBlock = {
* @typedef MathBlock id: number;
* @prop {number} id inline: boolean;
* @prop {boolean} inline expression: string;
* @prop {string} expression };
*/
/** /**
* Parses a string containing mixed markdown and LaTeX in between * Parses a string containing mixed markdown and LaTeX in between
* '$$..$$' or '\( ... \)' delimiters and returns an object containing a * '$$..$$' or '\( ... \)' delimiters and returns an object containing a
* list of math blocks found in the string, plus the input string with math * list of math blocks found in the string, plus the input string with math
* blocks replaced by placeholders. * blocks replaced by placeholders.
*
* @param {string} content
* @return {{ content: string, mathBlocks: MathBlock[]}}
*/ */
function extractMath(content) { function extractMath(content: string): {
/** @type {MathBlock[]} */ content: string;
const mathBlocks = []; mathBlocks: MathBlock[];
} {
const mathBlocks: MathBlock[] = [];
let pos = 0; let pos = 0;
let replacedContent = content; let replacedContent = content;
...@@ -129,11 +123,7 @@ function extractMath(content) { ...@@ -129,11 +123,7 @@ function extractMath(content) {
}; };
} }
/** function insertMath(html: string, mathBlocks: MathBlock[]) {
* @param {string} html
* @param {MathBlock[]} mathBlocks
*/
function insertMath(html, mathBlocks) {
return mathBlocks.reduce((html, block) => { return mathBlocks.reduce((html, block) => {
let renderedMath; let renderedMath;
try { try {
...@@ -152,9 +142,15 @@ function insertMath(html, mathBlocks) { ...@@ -152,9 +142,15 @@ function insertMath(html, mathBlocks) {
} }
/** /**
* @param {string} markdown * Convert a string of markdown and math into sanitized HTML.
*
* Math expressions in the input are written as LaTeX and must be enclosed in
* `$$ .. $$` or `\( .. \)` delimiters to indicate block or inline math
* expressions. These expressions are extracted and rendered using KaTeX.
*
* @return - A string of sanitized HTML.
*/ */
export function renderMathAndMarkdown(markdown) { export function renderMathAndMarkdown(markdown: string): string {
// KaTeX takes care of escaping its input, so we want to avoid passing its // KaTeX takes care of escaping its input, so we want to avoid passing its
// output through the HTML sanitizer. Therefore we first extract the math // output through the HTML sanitizer. Therefore we first extract the math
// blocks from the input, render and sanitize the remaining markdown and then // blocks from the input, render and sanitize the remaining markdown and then
......
import * as mediaEmbedder from '../media-embedder.js'; import * as mediaEmbedder from '../media-embedder';
describe('sidebar/media-embedder', () => { describe('sidebar/media-embedder', () => {
function domElement(html) { function domElement(html) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment