Skip to content

Commit 3739935

Browse files
committed
feat(pat-markdown): Switch to marked as markdown library to support better syntax highlight libraries.
1 parent 81c4e14 commit 3739935

File tree

3 files changed

+11
-29
lines changed

3 files changed

+11
-29
lines changed

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,14 @@
1414
"@fullcalendar/timegrid": "^5.11.3",
1515
"@juggle/resize-observer": "^3.4.0",
1616
"@stomp/stompjs": "^6.1.2",
17+
"dompurify": "^2.4.0",
1718
"google-code-prettify": "^1.0.5",
1819
"imagesloaded": "^4.1.4",
1920
"intersection-observer": "^0.12.2",
2021
"jquery": "^3.6.1",
2122
"jquery-jcrop": "^0.9.13",
2223
"luxon": "2.4.0",
24+
"marked": "^4.1.0",
2325
"masonry-layout": "^4.2.2",
2426
"moment": "^2.29.4",
2527
"moment-timezone": "^0.5.37",

src/pat/markdown/markdown.js

Lines changed: 5 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -27,33 +27,13 @@ const Markdown = Base.extend({
2727
},
2828

2929
async render(text) {
30-
const Showdown = (await import("showdown")).default;
31-
32-
// Add support for syntax highlighting via pat-syntax-highlight
33-
Showdown.extensions.prettify = function () {
34-
return [
35-
{
36-
type: "output",
37-
filter: function (source) {
38-
return source.replace(/(<pre>)?<code>/gi, function (match, pre) {
39-
if (pre) {
40-
return '<pre class="pat-syntax-highlight" tabIndex="0"><code data-inner="1">';
41-
} else {
42-
return '<code class="pat-syntax-highlight">';
43-
}
44-
});
45-
},
46-
},
47-
];
48-
};
30+
const marked = (await import("marked")).marked;
31+
const DOMPurify = (await import("dompurify")).default;
32+
await import("../syntax-highlight/syntax-highlight").default;
4933

5034
const wrapper = document.createElement("div");
51-
const converter = new Showdown.Converter({
52-
tables: true,
53-
extensions: ["prettify"],
54-
});
55-
const html = converter.makeHtml(text);
56-
wrapper.innerHTML = html;
35+
const parsed = DOMPurify.sanitize(marked.parse(text));
36+
wrapper.innerHTML = parsed;
5737
return $(wrapper);
5838
},
5939

src/pat/markdown/markdown.test.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,18 @@ describe("pat-markdown", function () {
1616
afterEach(() => {
1717
jest.restoreAllMocks();
1818
});
19-
it("replaces the DOM element with the rendered Markdown content.", async function () {
19+
it("It renders content for elements with the pattern trigger.", async function () {
2020
var $el = $('<p class="pat-markdown"></p>');
2121
$el.appendTo("#lab");
2222
jest.spyOn(pattern.prototype, "render").mockImplementation(() => {
2323
return $("<p>Rendering</p>");
2424
});
2525
pattern.init($el);
2626
await utils.timeout(1); // wait a tick for async to settle.
27-
expect($("#lab").html()).toBe("<p>Rendering</p>");
27+
expect($("#lab").html()).toBe('<p class="pat-markdown">Rendering</p>');
2828
});
2929

30-
it("does not replace the DOM element if it doesn't have the pattern trigger", function () {
30+
it("It does not render when the DOM element doesn't have the pattern trigger", function () {
3131
var $el = $("<p></p>");
3232
$el.appendTo("#lab");
3333
jest.spyOn(pattern.prototype, "render").mockImplementation(() => {
@@ -70,7 +70,7 @@ describe("pat-markdown", function () {
7070

7171
it("converts markdown into HTML", async function () {
7272
const $rendering = await pattern.prototype.render("*This is markdown*");
73-
expect($rendering.html()).toBe("<p><em>This is markdown</em></p>");
73+
expect($rendering.html()).toBe(`<p><em>This is markdown</em></p>\n`);
7474
});
7575
});
7676

0 commit comments

Comments
 (0)