Skip to content

Commit 2dd9bfe

Browse files
Fix false positive parsing error (#8)
1 parent d08d03c commit 2dd9bfe

File tree

2 files changed

+35
-11
lines changed

2 files changed

+35
-11
lines changed

src/syntax/index.js

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -90,17 +90,21 @@ const numberOrSelector = {
9090
* @see {@link https://github.com/csstree/csstree/blob/master/lib/syntax/pseudo/index.js}
9191
*/
9292
parse() {
93-
return this.createSingleNodeList(
94-
// If the next token is a number, parse it as a number,
95-
// otherwise parse it as a selector as fallback
96-
// * PLEASE NOTE: If the number parsing is failed, CSSTree
97-
// * will throw an "internal error" via "onParsingError"
98-
// * callback.
99-
// * See: https://github.com/csstree/csstree/blob/master/docs/parsing.md#onparseerror
100-
// * This not a breaking issue, because the parsing will
101-
// * continue its work.
102-
this.parseWithFallback(this.Number, this.Selector),
103-
);
93+
// Save the current token index
94+
const startToken = this.tokenIndex;
95+
96+
// Don't use "parseWithFallback" here, because we don't want to
97+
// throw parsing error, if just the number parsing fails.
98+
try {
99+
// Try to parse :upward()'s argument as a number, but if it fails,
100+
// that's not a problem, because we can try to parse it as a selector.
101+
return this.createSingleNodeList(this.Number.call(this));
102+
} catch (error) {
103+
// If the number parsing fails, then we try to parse a selector.
104+
// If the selector parsing fails, then an error will be thrown,
105+
// because the argument is invalid.
106+
return this.createSingleNodeList(this.Selector.call(this, startToken));
107+
}
104108
},
105109
};
106110

test/syntax/upward.test.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,4 +220,24 @@ describe(':upward()', () => {
220220
'div:upward(.something+#another)',
221221
);
222222
});
223+
224+
test('no false positive parsing errors', () => {
225+
// "Local" parser config for this test
226+
const localParserConfig = {
227+
...parserConfig,
228+
onParseError: (error) => {
229+
throw error;
230+
},
231+
};
232+
233+
expect(() => parse('div:upward(0)', localParserConfig)).not.toThrow();
234+
expect(() => parse('div:upward(42)', localParserConfig)).not.toThrow();
235+
expect(() => parse('div:upward(.something + #another)', localParserConfig)).not.toThrow();
236+
expect(
237+
() => parse(
238+
'div:upward(div + :-abp-has(> a[href^="https://example.com/"]) + div)',
239+
localParserConfig,
240+
),
241+
).not.toThrow();
242+
});
223243
});

0 commit comments

Comments
 (0)