From c1310bcd9f11faeb5414443cc9ece721582e19eb Mon Sep 17 00:00:00 2001
From: David Baker <dave@matrix.org>
Date: Thu, 1 Jul 2021 21:31:17 +0100
Subject: [PATCH] Better types

---
 package.json    |  1 +
 src/Markdown.ts | 26 ++++++++++++++++----------
 yarn.lock       |  5 +++++
 3 files changed, 22 insertions(+), 10 deletions(-)

diff --git a/package.json b/package.json
index 4ad585ba7d..c505e16dce 100644
--- a/package.json
+++ b/package.json
@@ -54,6 +54,7 @@
   },
   "dependencies": {
     "@babel/runtime": "^7.12.5",
+    "@types/commonmark": "^0.27.4",
     "await-lock": "^2.1.0",
     "browser-encrypt-attachment": "^0.3.0",
     "browser-request": "^0.3.3",
diff --git a/src/Markdown.ts b/src/Markdown.ts
index 64037369db..bb6d6d8df0 100644
--- a/src/Markdown.ts
+++ b/src/Markdown.ts
@@ -23,7 +23,15 @@ const ALLOWED_HTML_TAGS = ['sub', 'sup', 'del', 'u'];
 // These types of node are definitely text
 const TEXT_NODES = ['text', 'softbreak', 'linebreak', 'paragraph', 'document'];
 
-function isAllowedHtmlTag(node: any) {
+// As far as @types/commonmark is concerned, these are not public, so add them
+interface CommonmarkHtmlRendererInternal extends commonmark.HtmlRenderer {
+    paragraph: (node: commonmark.Node, entering: boolean) => void;
+    link: (node: commonmark.Node, entering: boolean) => void;
+    html_inline: (node: commonmark.Node) => void; // eslint-disable-line camelcase
+    html_block: (node: commonmark.Node) => void; // eslint-disable-line camelcase
+}
+
+function isAllowedHtmlTag(node: commonmark.Node): boolean {
     if (node.literal != null &&
         node.literal.match('^<((div|span) data-mx-maths="[^"]*"|/(div|span))>$') != null) {
         return true;
@@ -45,7 +53,7 @@ function isAllowedHtmlTag(node: any) {
  * comprises multiple block level elements (ie. lines),
  * or false if it is only a single line.
  */
-function isMultiLine(node) {
+function isMultiLine(node: commonmark.Node): boolean {
     let par = node;
     while (par.parent) {
         par = par.parent;
@@ -57,12 +65,10 @@ function isMultiLine(node) {
  * Class that wraps commonmark, adding the ability to see whether
  * a given message actually uses any markdown syntax or whether
  * it's plain text.
- *
- * Types are a bit of a struggle here as commonmark doesn't have types
  */
 export default class Markdown {
     private input: string;
-    private parsed: any;
+    private parsed: commonmark.Node;
 
     constructor(input) {
         this.input = input;
@@ -71,7 +77,7 @@ export default class Markdown {
         this.parsed = parser.parse(this.input);
     }
 
-    isPlainText() {
+    isPlainText(): boolean {
         const walker = this.parsed.walker();
 
         let ev;
@@ -94,7 +100,7 @@ export default class Markdown {
         return true;
     }
 
-    toHTML({ externalLinks = false } = {}) {
+    toHTML({ externalLinks = false } = {}): string {
         const renderer = new commonmark.HtmlRenderer({
             safe: false,
 
@@ -104,7 +110,7 @@ export default class Markdown {
             // block quote ends up all on one line
             // (https://github.com/vector-im/element-web/issues/3154)
             softbreak: '<br />',
-        });
+        }) as CommonmarkHtmlRendererInternal;
 
         // Trying to strip out the wrapping <p/> causes a lot more complication
         // than it's worth, i think.  For instance, this code will go and strip
@@ -181,8 +187,8 @@ export default class Markdown {
      * N.B. this does **NOT** render arbitrary MD to plain text - only MD
      * which has no formatting.  Otherwise it emits HTML(!).
      */
-    toPlaintext() {
-        const renderer = new commonmark.HtmlRenderer({ safe: false });
+    toPlaintext(): string {
+        const renderer = new commonmark.HtmlRenderer({ safe: false }) as CommonmarkHtmlRendererInternal;
 
         renderer.paragraph = function(node, entering) {
             // as with toHTML, only append lines to paragraphs if there are
diff --git a/yarn.lock b/yarn.lock
index 6f08372e18..d59dc9d79f 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1478,6 +1478,11 @@
   resolved "https://registry.yarnpkg.com/@types/classnames/-/classnames-2.2.11.tgz#2521cc86f69d15c5b90664e4829d84566052c1cf"
   integrity sha512-2koNhpWm3DgWRp5tpkiJ8JGc1xTn2q0l+jUNUE7oMKXUf5NpI9AIdC4kbjGNFBdHtcxBD18LAksoudAVhFKCjw==
 
+"@types/commonmark@^0.27.4":
+  version "0.27.4"
+  resolved "https://registry.yarnpkg.com/@types/commonmark/-/commonmark-0.27.4.tgz#8f42990e5cf3b6b95bd99eaa452e157aab679b82"
+  integrity sha512-7koSjp08QxKoS1/+3T15+kD7+vqOUvZRHvM8PutF3Xsk5aAEkdlIGRsHJ3/XsC3izoqTwBdRW/vH7rzCKkIicA==
+
 "@types/counterpart@^0.18.1":
   version "0.18.1"
   resolved "https://registry.yarnpkg.com/@types/counterpart/-/counterpart-0.18.1.tgz#b1b784d9e54d9879f0a8cb12f2caedab65430fe8"