Skip to content

Commit 24e2831

Browse files
authored
fix: prefilter html but warn about invalid html (#1211)
* fix: prefilter html but warn about invalid html Closes: #1210 * chore: fix eslint errors * chore: update nodejs-ci config * chore: remove console.log eslint error * fix: add testcase and fix edge case
1 parent 9c8536f commit 24e2831

File tree

9 files changed

+510
-89
lines changed

9 files changed

+510
-89
lines changed

.github/workflows/nodejs.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,6 @@ jobs:
1212
uses: zakodium/workflows/.github/workflows/nodejs.yml@nodejs-v1
1313
with:
1414
lint-check-types: false
15-
disable-tests: true
1615
disable-test-package: true
16+
upload-coverage: false
17+
node-version-matrix: '[24]'

package-lock.json

Lines changed: 19 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919
"prerelease": "grunt bump:prerelease",
2020
"prettier": "prettier --check src",
2121
"prettier-write": "prettier --write src",
22-
"test": "npm run eslint && npm run prettier",
22+
"test": "npm run eslint && npm run prettier && npm run test-only",
23+
"test-only": "node --test tests/**",
2324
"release:minor": "npm run test && grunt bump:minor --release",
2425
"release:patch": "npm run test && grunt bump:patch --release"
2526
},
@@ -44,6 +45,7 @@
4445
"@rollup/plugin-commonjs": "^29.0.0",
4546
"@rollup/plugin-json": "^6.1.0",
4647
"@rollup/plugin-node-resolve": "^16.0.3",
48+
"@types/node": "^24.10.13",
4749
"add-stream": "^1.0.0",
4850
"bower": "^1.8.14",
4951
"conventional-changelog": "^6.0.0",
@@ -61,6 +63,7 @@
6163
"lodash": "^4.17.23",
6264
"mkpath": "^1.0.0",
6365
"prettier": "^3.8.1",
66+
"requirejs": "^2.3.8",
6467
"rollup": "^4.59.0",
6568
"rollup-plugin-polyfill-node": "^0.13.0",
6669
"tempfile": "^3.0.0",

src/modules/module.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -221,10 +221,10 @@ define([
221221
toolbar[i].title || ''
222222
}">`;
223223
if (toolbar[i].icon) {
224-
html += `<div style="color=${color}"><i src="${toolbar[i].icon}"/></div>`;
224+
html += `<div style="color=${color}"><i src="${toolbar[i].icon}"></i></div>`;
225225
}
226226
if (toolbar[i].cssClass) {
227-
html += `<span style="color: ${color};" class="${toolbar[i].cssClass}"/>`;
227+
html += `<span style="color: ${color};" class="${toolbar[i].cssClass}"></span>`;
228228
}
229229
html += '</li>';
230230
}

src/src/main/entrypoint.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
define([
44
'jquery',
55
'lodash',
6+
'src/util/jquery_prefilter',
67
'src/header/header',
78
'src/util/repository',
89
'src/main/grid',
@@ -25,6 +26,7 @@ define([
2526
], function (
2627
$,
2728
_,
29+
jqueryPrefilter,
2830
Header,
2931
Repository,
3032
Grid,
@@ -42,6 +44,20 @@ define([
4244
Config,
4345
Sandbox,
4446
) {
47+
jQuery.htmlPrefilter = (preHtml) => {
48+
const { warn, html } = jqueryPrefilter(preHtml);
49+
if (warn) {
50+
// eslint-disable-next-line no-console
51+
console.warn(
52+
'jQuery.htmlPrefilter modified invalid html, make sure to update your html markup',
53+
{
54+
before: preHtml,
55+
after: html,
56+
},
57+
);
58+
}
59+
return html;
60+
};
4561
var _viewLoaded, _dataLoaded, _modulesSet;
4662

4763
var RepositoryData = new Repository(),

src/src/util/jquery_prefilter.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
'use strict';
2+
3+
define(() => {
4+
// https://jquery.com/upgrade-guide/3.5/
5+
const rxhtmlTag =
6+
/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^/\0>\u0020\t\r\n\f]*)[^>]*)\/>/gi;
7+
8+
return function jqueryPrefilter(html) {
9+
// Self-closing tags are invalid except for void elements like input
10+
const filteredHtml = html.replaceAll(rxhtmlTag, '<$1></$2>');
11+
if (filteredHtml !== html) {
12+
// Ignore svg content because it is actually XML
13+
const cleanedHtml = html.replaceAll(/<svg[^>]*>(.*?)<\/svg>/g, '').trim();
14+
15+
const result = rxhtmlTag.exec(cleanedHtml);
16+
if (cleanedHtml && result && result[0] !== cleanedHtml) {
17+
return {
18+
html: filteredHtml,
19+
warn: true,
20+
};
21+
}
22+
}
23+
return {
24+
html,
25+
warn: false,
26+
};
27+
};
28+
});

0 commit comments

Comments
 (0)