Skip to content

Commit a4bb1de

Browse files
authored
fix: fix <noframes> parsing (#1277)
* fix: fix `<noframes>` parsing Fixes #972
1 parent 6da70b3 commit a4bb1de

File tree

2 files changed

+41
-6
lines changed

2 files changed

+41
-6
lines changed

packages/parse5/lib/parser/index.test.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { parseFragment, parse } from 'parse5';
33
import { jest } from '@jest/globals';
44
import { generateParsingTests } from 'parse5-test-utils/utils/generate-parsing-tests.js';
55
import { treeAdapters } from 'parse5-test-utils/utils/common.js';
6+
import type { Element, TextNode } from '../tree-adapters/default.js';
67

78
generateParsingTests(
89
'parser',
@@ -110,4 +111,37 @@ describe('parser', () => {
110111
expect(onItemPop).toHaveBeenLastCalledWith(bodyElement.childNodes[0], bodyElement);
111112
});
112113
});
114+
115+
describe('rawtext parsing', () => {
116+
it.each([
117+
['iframe'],
118+
['noembed'],
119+
['noframes'],
120+
['noscript'],
121+
['script'],
122+
['style'],
123+
['textarea'],
124+
['title'],
125+
['xmp'],
126+
])('<%s>', (tagName) => {
127+
const html = `<r><${tagName}><math id="</${tagName}><b>should be outside</b>">`;
128+
const fragment = parseFragment(html);
129+
130+
expect(fragment.childNodes.length).toBe(1);
131+
const r = fragment.childNodes[0] as Element;
132+
expect(r.nodeName).toBe('r');
133+
expect(r.childNodes).toHaveLength(3);
134+
expect(r.childNodes.map((_) => _.nodeName)).toEqual([tagName, 'b', '#text']);
135+
136+
const target = r.childNodes[0] as Element;
137+
expect(target.childNodes).toHaveLength(1);
138+
expect(target.childNodes[0].nodeName).toBe('#text');
139+
expect((target.childNodes[0] as TextNode).value).toBe('<math id="');
140+
141+
const b = r.childNodes[1] as Element;
142+
expect(b.childNodes).toHaveLength(1);
143+
expect(b.childNodes[0].nodeName).toBe('#text');
144+
expect((b.childNodes[0] as TextNode).value).toBe('should be outside');
145+
});
146+
});
113147
});

packages/parse5/lib/parser/index.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2195,9 +2195,9 @@ function iframeStartTagInBody<T extends TreeAdapterTypeMap>(p: Parser<T>, token:
21952195
p._switchToTextParsing(token, TokenizerMode.RAWTEXT);
21962196
}
21972197

2198-
//NOTE: here we assume that we always act as an user agent with enabled plugins, so we parse
2199-
//<noembed> as rawtext.
2200-
function noembedStartTagInBody<T extends TreeAdapterTypeMap>(p: Parser<T>, token: TagToken): void {
2198+
//NOTE: here we assume that we always act as a user agent with enabled plugins/frames, so we parse
2199+
//<noembed>/<noframes> as rawtext.
2200+
function rawTextStartTagInBody<T extends TreeAdapterTypeMap>(p: Parser<T>, token: TagToken): void {
22012201
p._switchToTextParsing(token, TokenizerMode.RAWTEXT);
22022202
}
22032203

@@ -2449,8 +2449,9 @@ function startTagInBody<T extends TreeAdapterTypeMap>(p: Parser<T>, token: TagTo
24492449
optgroupStartTagInBody(p, token);
24502450
break;
24512451
}
2452-
case $.NOEMBED: {
2453-
noembedStartTagInBody(p, token);
2452+
case $.NOEMBED:
2453+
case $.NOFRAMES: {
2454+
rawTextStartTagInBody(p, token);
24542455
break;
24552456
}
24562457
case $.FRAMESET: {
@@ -2463,7 +2464,7 @@ function startTagInBody<T extends TreeAdapterTypeMap>(p: Parser<T>, token: TagTo
24632464
}
24642465
case $.NOSCRIPT: {
24652466
if (p.options.scriptingEnabled) {
2466-
noembedStartTagInBody(p, token);
2467+
rawTextStartTagInBody(p, token);
24672468
} else {
24682469
genericStartTagInBody(p, token);
24692470
}

0 commit comments

Comments
 (0)