Skip to content

Commit df0e2b7

Browse files
idlebergnetomi
andauthored
Add support for GfM alerts (#1535)
* chore: install markdown-it plugin for gfm alerts * feat: initialize alert plugin * feat: add styling for alerts * add changelog entry and add icons to alerts --------- Co-authored-by: Thomas Neidhart <thomas.neidhart@gmail.com>
1 parent 62a53cc commit df0e2b7

File tree

4 files changed

+156
-51
lines changed

4 files changed

+156
-51
lines changed

webui/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ This change log covers only the frontend library (webui) of Open VSX.
77
### Added
88

99
- Support removing reviews by admins ([#1403](https://github.com/eclipse/openvsx/pull/1403))
10+
- Support for GitHub flavored markdown alerts ([#1535](https://github.com/eclipse/openvsx/pull/1535))
1011

1112
## [v0.17.1] (Jan. 2026)
1213

webui/package.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
"dependencies": {
3939
"@emotion/react": "^11.11.1",
4040
"@emotion/styled": "^11.11.0",
41+
"@mdit/plugin-alert": "^0.22.3",
4142
"@mui/base": "^5.0.0-beta.9",
4243
"@mui/icons-material": "^5.13.7",
4344
"@mui/material": "^5.13.7",
@@ -46,8 +47,8 @@
4647
"dompurify": "^3.0.4",
4748
"fetch-retry": "^5.0.6",
4849
"lodash": "^4.17.21",
49-
"markdown-it": "^13.0.1",
50-
"markdown-it-anchor": "^8.6.7",
50+
"markdown-it": "^14.1.0",
51+
"markdown-it-anchor": "^9.2.0",
5152
"prop-types": "^15.8.1",
5253
"punycode": "^2.3.0",
5354
"react": "^18.2.0",
@@ -74,7 +75,7 @@
7475
"@types/dompurify": "^3.0.2",
7576
"@types/express": "^4.17.21",
7677
"@types/lodash": "^4.14.195",
77-
"@types/markdown-it": "^13.0.1",
78+
"@types/markdown-it": "^14",
7879
"@types/mocha": "^10.0.9",
7980
"@types/node": "^20.4.0",
8081
"@types/prop-types": "^15.7.5",

webui/src/components/sanitized-markdown.tsx

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@
99
********************************************************************************/
1010

1111
import React, { FunctionComponent, useEffect } from 'react';
12-
import * as MarkdownIt from 'markdown-it';
12+
import MarkdownIt from 'markdown-it';
1313
import * as MarkdownItAnchor from 'markdown-it-anchor';
14+
import { alert } from '@mdit/plugin-alert';
1415
import DOMPurify from 'dompurify';
1516
import { Theme, styled } from '@mui/material/styles';
1617
import linkIcon from './link-icon';
@@ -75,6 +76,82 @@ const Markdown = styled('div')(({ theme }: { theme: Theme }) => ({
7576
textAlign: 'start',
7677
background: theme.palette.neutral.dark
7778
}
79+
},
80+
'& .markdown-alert': {
81+
padding: '8px 16px',
82+
marginBottom: 16,
83+
borderLeft: '4px solid',
84+
borderRadius: 4,
85+
'& .markdown-alert-title': {
86+
display: 'flex',
87+
alignItems: 'center',
88+
fontWeight: 600,
89+
marginBottom: 4,
90+
'& svg': {
91+
marginRight: 8,
92+
width: 16,
93+
height: 16
94+
}
95+
},
96+
'& .markdown-alert-title:before': {
97+
content: " ",
98+
width: '16px',
99+
height: '16px',
100+
marginRight: '8px',
101+
},
102+
'& p': {
103+
margin: 0
104+
}
105+
},
106+
'& .markdown-alert-note': {
107+
borderColor: '#2f81f7',
108+
backgroundColor: 'rgba(47, 129, 247, 0.1)',
109+
'& .markdown-alert-title': {
110+
color: '#2f81f7'
111+
},
112+
'& .markdown-alert-title::before': {
113+
content: `url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='%232f81f7' d='M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z'/%3E%3C/svg%3E")`
114+
}
115+
},
116+
'& .markdown-alert-tip': {
117+
borderColor: '#3fb950',
118+
backgroundColor: 'rgba(63, 185, 80, 0.1)',
119+
'& .markdown-alert-title': {
120+
color: '#3fb950'
121+
},
122+
'& .markdown-alert-title::before': {
123+
content: `url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='%233fb950' d='M8 1.5c-2.363 0-4 1.69-4 3.75 0 .984.424 1.625.984 2.304l.214.253c.223.264.47.556.673.848.284.411.537.896.621 1.49a.75.75 0 0 1-1.484.211c-.04-.282-.163-.547-.37-.847a8.456 8.456 0 0 0-.542-.68c-.084-.1-.173-.205-.268-.32C3.201 7.75 2.5 6.766 2.5 5.25 2.5 2.31 4.863 0 8 0s5.5 2.31 5.5 5.25c0 1.516-.701 2.5-1.328 3.259-.095.115-.184.22-.268.319-.207.245-.383.453-.541.681-.208.3-.33.565-.37.847a.751.751 0 0 1-1.485-.212c.084-.593.337-1.078.621-1.489.203-.292.45-.584.673-.848.075-.088.147-.173.213-.253.561-.679.985-1.32.985-2.304 0-2.06-1.637-3.75-4-3.75ZM5.75 12h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1 0-1.5ZM6 15.25a.75.75 0 0 1 .75-.75h2.5a.75.75 0 0 1 0 1.5h-2.5a.75.75 0 0 1-.75-.75Z'/%3E%3C/svg%3E")`
124+
}
125+
},
126+
'& .markdown-alert-important': {
127+
borderColor: '#a371f7',
128+
backgroundColor: 'rgba(163, 113, 247, 0.1)',
129+
'& .markdown-alert-title': {
130+
color: '#a371f7'
131+
},
132+
'& .markdown-alert-title::before': {
133+
content: `url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='%23a371f7' d='M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v9.5A1.75 1.75 0 0 1 14.25 13H8.06l-2.573 2.573A1.458 1.458 0 0 1 3 14.543V13H1.75A1.75 1.75 0 0 1 0 11.25Zm1.75-.25a.25.25 0 0 0-.25.25v9.5c0 .138.112.25.25.25h2a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h6.5a.25.25 0 0 0 .25-.25v-9.5a.25.25 0 0 0-.25-.25Zm7 2.25v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 9a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z'/%3E%3C/svg%3E ")`
134+
}
135+
},
136+
'& .markdown-alert-warning': {
137+
borderColor: '#d29922',
138+
backgroundColor: 'rgba(210, 153, 34, 0.1)',
139+
'& .markdown-alert-title': {
140+
color: '#d29922'
141+
},
142+
'& .markdown-alert-title::before': {
143+
content: `url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='%23d29922' d='M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z'/%3E%3C/svg%3E")`
144+
}
145+
},
146+
'& .markdown-alert-caution': {
147+
borderColor: '#f85149',
148+
backgroundColor: 'rgba(248, 81, 73, 0.1)',
149+
'& .markdown-alert-title': {
150+
color: '#f85149'
151+
},
152+
'& .markdown-alert-title::before': {
153+
content: `url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='%23f85149' d='M4.47.22A.749.749 0 0 1 5 0h6c.199 0 .389.079.53.22l4.25 4.25c.141.14.22.331.22.53v6a.749.749 0 0 1-.22.53l-4.25 4.25A.749.749 0 0 1 11 16H5a.749.749 0 0 1-.53-.22L.22 11.53A.749.749 0 0 1 0 11V5c0-.199.079-.389.22-.53Zm.84 1.28L1.5 5.31v5.38l3.81 3.81h5.38l3.81-3.81V5.31L10.69 1.5ZM8 4a.75.75 0 0 1 .75.75v3.5a.75.75 0 0 1-1.5 0v-3.5A.75.75 0 0 1 8 4Zm0 8a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z'/%3E%3C/svg%3E")`
154+
}
78155
}
79156
}));
80157

@@ -85,6 +162,9 @@ export const SanitizedMarkdown: FunctionComponent<SanitizedMarkdownProps> = ({ c
85162
linkify: true,
86163
typographer: true
87164
});
165+
166+
markdownIt.use(alert);
167+
88168
if (linkify === undefined || linkify) {
89169
const anchor = MarkdownItAnchor.default;
90170
markdownIt.use(anchor, {

webui/yarn.lock

Lines changed: 70 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -752,6 +752,20 @@ __metadata:
752752
languageName: node
753753
linkType: hard
754754

755+
"@mdit/plugin-alert@npm:^0.22.3":
756+
version: 0.22.3
757+
resolution: "@mdit/plugin-alert@npm:0.22.3"
758+
dependencies:
759+
"@types/markdown-it": "npm:^14.1.2"
760+
peerDependencies:
761+
markdown-it: ^14.1.0
762+
peerDependenciesMeta:
763+
markdown-it:
764+
optional: true
765+
checksum: 10/59215807519c878d56cfdf09a86153b25702dfb08da89489ecdfc23b6dceec864a30f772588e14cb40c439fc18d3fad3fdc13e4a28ae8137859eca8ad7d032b6
766+
languageName: node
767+
linkType: hard
768+
755769
"@mui/base@npm:5.0.0-beta.40":
756770
version: 5.0.0-beta.40
757771
resolution: "@mui/base@npm:5.0.0-beta.40"
@@ -1225,10 +1239,10 @@ __metadata:
12251239
languageName: node
12261240
linkType: hard
12271241

1228-
"@types/linkify-it@npm:^3":
1229-
version: 3.0.5
1230-
resolution: "@types/linkify-it@npm:3.0.5"
1231-
checksum: 10/fac28f41a6e576282300a459d70ea0d33aab70dbb77c3d09582bb0335bb00d862b6de69585792a4d590aae4173fbab0bf28861e2d90ca7b2b1439b52688e9ff6
1242+
"@types/linkify-it@npm:^5":
1243+
version: 5.0.0
1244+
resolution: "@types/linkify-it@npm:5.0.0"
1245+
checksum: 10/c3919044d4876f9d71d037e861745cd2485c95ac8c36a4fa67b132d4e60eb1d067e123cc7965c9cf5110eea351517d767f0d306af5e9147d6d0af87bc374ddcf
12321246
languageName: node
12331247
linkType: hard
12341248

@@ -1239,20 +1253,20 @@ __metadata:
12391253
languageName: node
12401254
linkType: hard
12411255

1242-
"@types/markdown-it@npm:^13.0.1":
1243-
version: 13.0.8
1244-
resolution: "@types/markdown-it@npm:13.0.8"
1256+
"@types/markdown-it@npm:^14, @types/markdown-it@npm:^14.1.2":
1257+
version: 14.1.2
1258+
resolution: "@types/markdown-it@npm:14.1.2"
12451259
dependencies:
1246-
"@types/linkify-it": "npm:^3"
1247-
"@types/mdurl": "npm:^1"
1248-
checksum: 10/0e1d2ac44bb6dda78707dcec2eb1bf617a37f1654a4710aef3ae92295db7689349b51900ff76f0ce307c1485eecad52971dfc0ec71fc8b125fc0ddcf05584691
1260+
"@types/linkify-it": "npm:^5"
1261+
"@types/mdurl": "npm:^2"
1262+
checksum: 10/ca2f239c8d59610b9f936fd40261a6ccf2fa1ae27a21816c031e5712542dcf9ee01e2fe29b31118df90716e11ade54e47d92a498e9b6488800e77ca8827255a2
12491263
languageName: node
12501264
linkType: hard
12511265

1252-
"@types/mdurl@npm:^1":
1253-
version: 1.0.5
1254-
resolution: "@types/mdurl@npm:1.0.5"
1255-
checksum: 10/e8e872e8da8f517a9c748b06cec61c947cb73fd3069e8aeb0926670ec5dfac5d30549b3d0f1634950401633e812f9b7263f2d5dbe7e98fce12bcb2c659aa4b21
1266+
"@types/mdurl@npm:^2":
1267+
version: 2.0.0
1268+
resolution: "@types/mdurl@npm:2.0.0"
1269+
checksum: 10/78746e96c655ceed63db06382da466fd52c7e9dc54d60b12973dfdd110cae06b9439c4b90e17bb8d4461109184b3ea9f3e9f96b3e4bf4aa9fe18b6ac35f283c8
12561270
languageName: node
12571271
linkType: hard
12581272

@@ -2829,10 +2843,10 @@ __metadata:
28292843
languageName: node
28302844
linkType: hard
28312845

2832-
"entities@npm:~3.0.1":
2833-
version: 3.0.1
2834-
resolution: "entities@npm:3.0.1"
2835-
checksum: 10/3706e0292ea3f3679720b3d3b1ed6290b164aaeb11116691a922a3acea144503871e0de2170b47671c3b735549b8b7f4741d0d3c2987e8f985ccaa0dd3762eba
2846+
"entities@npm:^4.4.0":
2847+
version: 4.5.0
2848+
resolution: "entities@npm:4.5.0"
2849+
checksum: 10/ede2a35c9bce1aeccd055a1b445d41c75a14a2bb1cd22e242f20cf04d236cdcd7f9c859eb83f76885327bfae0c25bf03303665ee1ce3d47c5927b98b0e3e3d48
28362850
languageName: node
28372851
linkType: hard
28382852

@@ -4475,12 +4489,12 @@ __metadata:
44754489
languageName: node
44764490
linkType: hard
44774491

4478-
"linkify-it@npm:^4.0.1":
4479-
version: 4.0.1
4480-
resolution: "linkify-it@npm:4.0.1"
4492+
"linkify-it@npm:^5.0.0":
4493+
version: 5.0.0
4494+
resolution: "linkify-it@npm:5.0.0"
44814495
dependencies:
4482-
uc.micro: "npm:^1.0.1"
4483-
checksum: 10/d0a786d2e3f02f46b6f4a9b466af9eb936fb68e86b7cd305933d5457b12fdc53a4d0e0b697b02dc2e7d84a51d2425d719598bb7b47af7e01911e492e07a97957
4496+
uc.micro: "npm:^2.0.0"
4497+
checksum: 10/ef3b7609dda6ec0c0be8a7b879cea195f0d36387b0011660cd6711bba0ad82137f59b458b7e703ec74f11d88e7c1328e2ad9b855a8500c0ded67461a8c4519e6
44844498
languageName: node
44854499
linkType: hard
44864500

@@ -4610,28 +4624,29 @@ __metadata:
46104624
languageName: node
46114625
linkType: hard
46124626

4613-
"markdown-it-anchor@npm:^8.6.7":
4614-
version: 8.6.7
4615-
resolution: "markdown-it-anchor@npm:8.6.7"
4627+
"markdown-it-anchor@npm:^9.2.0":
4628+
version: 9.2.0
4629+
resolution: "markdown-it-anchor@npm:9.2.0"
46164630
peerDependencies:
46174631
"@types/markdown-it": "*"
46184632
markdown-it: "*"
4619-
checksum: 10/1b061e9c8fb093dab6040725f9f3cedae7da1160a14ee8f29d144534be7ee5c788f02a4de4019f55eb8514cae5f12d350baaa7d08732c26a62abc60e5e66c7f7
4633+
checksum: 10/ececb857a621946be9da08a9abdec98b954fa2f14493261293bf1868146f840d419042be7028317851940ecb7f6d2db318916d13bd38c9d398507c7802d6f70f
46204634
languageName: node
46214635
linkType: hard
46224636

4623-
"markdown-it@npm:^13.0.1":
4624-
version: 13.0.2
4625-
resolution: "markdown-it@npm:13.0.2"
4637+
"markdown-it@npm:^14.1.0":
4638+
version: 14.1.0
4639+
resolution: "markdown-it@npm:14.1.0"
46264640
dependencies:
46274641
argparse: "npm:^2.0.1"
4628-
entities: "npm:~3.0.1"
4629-
linkify-it: "npm:^4.0.1"
4630-
mdurl: "npm:^1.0.1"
4631-
uc.micro: "npm:^1.0.5"
4642+
entities: "npm:^4.4.0"
4643+
linkify-it: "npm:^5.0.0"
4644+
mdurl: "npm:^2.0.0"
4645+
punycode.js: "npm:^2.3.1"
4646+
uc.micro: "npm:^2.1.0"
46324647
bin:
4633-
markdown-it: bin/markdown-it.js
4634-
checksum: 10/4f48271bbd44d16502efd4148d7c05ca1fb4b50719a07d34c91e8d16f8d065c558fed0fafe07cd13ca5958096bfe295b37cd4f042add7ec49f73c70154e75f58
4648+
markdown-it: bin/markdown-it.mjs
4649+
checksum: 10/f34f921be178ed0607ba9e3e27c733642be445e9bb6b1dba88da7aafe8ba1bc5d2f1c3aa8f3fc33b49a902da4e4c08c2feadfafb290b8c7dda766208bb6483a9
46354650
languageName: node
46364651
linkType: hard
46374652

@@ -4642,10 +4657,10 @@ __metadata:
46424657
languageName: node
46434658
linkType: hard
46444659

4645-
"mdurl@npm:^1.0.1":
4646-
version: 1.0.1
4647-
resolution: "mdurl@npm:1.0.1"
4648-
checksum: 10/ada367d01c9e81d07328101f187d5bd8641b71f33eab075df4caed935a24fa679e625f07108801d8250a5e4a99e5cd4be7679957a11424a3aa3e740d2bb2d5cb
4660+
"mdurl@npm:^2.0.0":
4661+
version: 2.0.0
4662+
resolution: "mdurl@npm:2.0.0"
4663+
checksum: 10/1720349d4a53e401aa993241368e35c0ad13d816ad0b28388928c58ca9faa0cf755fa45f18ccbf64f4ce54a845a50ddce5c84e4016897b513096a68dac4b0158
46494664
languageName: node
46504665
linkType: hard
46514666

@@ -5068,6 +5083,7 @@ __metadata:
50685083
"@emotion/styled": "npm:^11.11.0"
50695084
"@eslint/eslintrc": "npm:^3.2.0"
50705085
"@eslint/js": "npm:^9.15.0"
5086+
"@mdit/plugin-alert": "npm:^0.22.3"
50715087
"@mui/base": "npm:^5.0.0-beta.9"
50725088
"@mui/icons-material": "npm:^5.13.7"
50735089
"@mui/material": "npm:^5.13.7"
@@ -5078,7 +5094,7 @@ __metadata:
50785094
"@types/dompurify": "npm:^3.0.2"
50795095
"@types/express": "npm:^4.17.21"
50805096
"@types/lodash": "npm:^4.14.195"
5081-
"@types/markdown-it": "npm:^13.0.1"
5097+
"@types/markdown-it": "npm:^14"
50825098
"@types/mocha": "npm:^10.0.9"
50835099
"@types/node": "npm:^20.4.0"
50845100
"@types/prop-types": "npm:^15.7.5"
@@ -5102,8 +5118,8 @@ __metadata:
51025118
express-rate-limit: "npm:^7.4.0"
51035119
fetch-retry: "npm:^5.0.6"
51045120
lodash: "npm:^4.17.21"
5105-
markdown-it: "npm:^13.0.1"
5106-
markdown-it-anchor: "npm:^8.6.7"
5121+
markdown-it: "npm:^14.1.0"
5122+
markdown-it-anchor: "npm:^9.2.0"
51075123
mocha: "npm:^11.7.5"
51085124
prop-types: "npm:^15.8.1"
51095125
punycode: "npm:^2.3.0"
@@ -5481,6 +5497,13 @@ __metadata:
54815497
languageName: node
54825498
linkType: hard
54835499

5500+
"punycode.js@npm:^2.3.1":
5501+
version: 2.3.1
5502+
resolution: "punycode.js@npm:2.3.1"
5503+
checksum: 10/f0e946d1edf063f9e3d30a32ca86d8ff90ed13ca40dad9c75d37510a04473340cfc98db23a905cc1e517b1e9deb0f6021dce6f422ace235c60d3c9ac47c5a16a
5504+
languageName: node
5505+
linkType: hard
5506+
54845507
"punycode@npm:^2.1.0, punycode@npm:^2.3.0":
54855508
version: 2.3.1
54865509
resolution: "punycode@npm:2.3.1"
@@ -6607,10 +6630,10 @@ __metadata:
66076630
languageName: node
66086631
linkType: hard
66096632

6610-
"uc.micro@npm:^1.0.1, uc.micro@npm:^1.0.5":
6611-
version: 1.0.6
6612-
resolution: "uc.micro@npm:1.0.6"
6613-
checksum: 10/6898bb556319a38e9cf175e3628689347bd26fec15fc6b29fa38e0045af63075ff3fea4cf1fdba9db46c9f0cbf07f2348cd8844889dd31ebd288c29fe0d27e7a
6633+
"uc.micro@npm:^2.0.0, uc.micro@npm:^2.1.0":
6634+
version: 2.1.0
6635+
resolution: "uc.micro@npm:2.1.0"
6636+
checksum: 10/37197358242eb9afe367502d4638ac8c5838b78792ab218eafe48287b0ed28aaca268ec0392cc5729f6c90266744de32c06ae938549aee041fc93b0f9672d6b2
66146637
languageName: node
66156638
linkType: hard
66166639

0 commit comments

Comments
 (0)