html-validate 6.3.1 → 6.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/core.d.ts +102 -26
- package/dist/cjs/core.js +112 -49
- package/dist/cjs/core.js.map +1 -1
- package/dist/es/core.d.ts +102 -26
- package/dist/es/core.js +112 -49
- package/dist/es/core.js.map +1 -1
- package/package.json +21 -23
package/dist/cjs/core.d.ts
CHANGED
|
@@ -40,28 +40,95 @@ declare class EventHandler {
|
|
|
40
40
|
declare enum TokenType {
|
|
41
41
|
UNICODE_BOM = 1,
|
|
42
42
|
WHITESPACE = 2,
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
interface Token {
|
|
43
|
+
DOCTYPE_OPEN = 3,
|
|
44
|
+
DOCTYPE_VALUE = 4,
|
|
45
|
+
DOCTYPE_CLOSE = 5,
|
|
46
|
+
TAG_OPEN = 6,
|
|
47
|
+
TAG_CLOSE = 7,
|
|
48
|
+
ATTR_NAME = 8,
|
|
49
|
+
ATTR_VALUE = 9,
|
|
50
|
+
TEXT = 10,
|
|
51
|
+
TEMPLATING = 11,
|
|
52
|
+
SCRIPT = 12,
|
|
53
|
+
STYLE = 13,
|
|
54
|
+
COMMENT = 14,
|
|
55
|
+
CONDITIONAL = 15,
|
|
56
|
+
DIRECTIVE = 16,
|
|
57
|
+
EOF = 17
|
|
58
|
+
}
|
|
59
|
+
interface BaseToken {
|
|
61
60
|
type: TokenType;
|
|
62
61
|
location: Location;
|
|
63
|
-
data?: any;
|
|
64
62
|
}
|
|
63
|
+
interface UnicodeBOMToken extends BaseToken {
|
|
64
|
+
type: TokenType.UNICODE_BOM;
|
|
65
|
+
data: [bom: string];
|
|
66
|
+
}
|
|
67
|
+
interface WhitespaceToken extends BaseToken {
|
|
68
|
+
type: TokenType.WHITESPACE;
|
|
69
|
+
data: [text: string];
|
|
70
|
+
}
|
|
71
|
+
interface DoctypeOpenToken extends BaseToken {
|
|
72
|
+
type: TokenType.DOCTYPE_OPEN;
|
|
73
|
+
data: [text: string, tag: string];
|
|
74
|
+
}
|
|
75
|
+
interface DoctypeValueToken extends BaseToken {
|
|
76
|
+
type: TokenType.DOCTYPE_VALUE;
|
|
77
|
+
data: [text: string];
|
|
78
|
+
}
|
|
79
|
+
interface DoctypeCloseToken extends BaseToken {
|
|
80
|
+
type: TokenType.DOCTYPE_CLOSE;
|
|
81
|
+
data: [text: ">"];
|
|
82
|
+
}
|
|
83
|
+
interface TagOpenToken extends BaseToken {
|
|
84
|
+
type: TokenType.TAG_OPEN;
|
|
85
|
+
data: [text: string, close: "/" | "", tag: string];
|
|
86
|
+
}
|
|
87
|
+
interface TagCloseToken extends BaseToken {
|
|
88
|
+
type: TokenType.TAG_CLOSE;
|
|
89
|
+
data: [text: ">" | "/>"];
|
|
90
|
+
}
|
|
91
|
+
interface AttrNameToken extends BaseToken {
|
|
92
|
+
type: TokenType.ATTR_NAME;
|
|
93
|
+
data: [text: string, name: string];
|
|
94
|
+
}
|
|
95
|
+
interface AttrValueToken extends BaseToken {
|
|
96
|
+
type: TokenType.ATTR_VALUE;
|
|
97
|
+
data: [text: string, delimiter: string, value: string, quote?: '"' | "'"];
|
|
98
|
+
}
|
|
99
|
+
interface TextToken extends BaseToken {
|
|
100
|
+
type: TokenType.TEXT;
|
|
101
|
+
data: [text: string];
|
|
102
|
+
}
|
|
103
|
+
interface TemplatingToken extends BaseToken {
|
|
104
|
+
type: TokenType.TEMPLATING;
|
|
105
|
+
data: [text: string];
|
|
106
|
+
}
|
|
107
|
+
interface ScriptToken extends BaseToken {
|
|
108
|
+
type: TokenType.SCRIPT;
|
|
109
|
+
data: [text: string];
|
|
110
|
+
}
|
|
111
|
+
interface StyleToken extends BaseToken {
|
|
112
|
+
type: TokenType.STYLE;
|
|
113
|
+
data: [text: string];
|
|
114
|
+
}
|
|
115
|
+
interface CommentToken extends BaseToken {
|
|
116
|
+
type: TokenType.COMMENT;
|
|
117
|
+
data: [text: string, comment: string];
|
|
118
|
+
}
|
|
119
|
+
interface ConditionalToken extends BaseToken {
|
|
120
|
+
type: TokenType.CONDITIONAL;
|
|
121
|
+
data: [text: string, condition: string];
|
|
122
|
+
}
|
|
123
|
+
interface DirectiveToken extends BaseToken {
|
|
124
|
+
type: TokenType.DIRECTIVE;
|
|
125
|
+
data: [text: string, begin: "[", action: string, rest: string, end: "]" | ""];
|
|
126
|
+
}
|
|
127
|
+
interface EOFToken extends BaseToken {
|
|
128
|
+
type: TokenType.EOF;
|
|
129
|
+
data: [];
|
|
130
|
+
}
|
|
131
|
+
declare type Token = UnicodeBOMToken | WhitespaceToken | DoctypeOpenToken | DoctypeValueToken | DoctypeCloseToken | TagOpenToken | TagCloseToken | AttrNameToken | AttrValueToken | TextToken | TemplatingToken | ScriptToken | StyleToken | CommentToken | ConditionalToken | DirectiveToken | EOFToken;
|
|
65
132
|
|
|
66
133
|
declare type TokenStream = IterableIterator<Token>;
|
|
67
134
|
|
|
@@ -502,6 +569,8 @@ interface ConditionalEvent extends Event {
|
|
|
502
569
|
location: Location;
|
|
503
570
|
/** Condition including markers. */
|
|
504
571
|
condition: string;
|
|
572
|
+
/** The element containing the conditional, if any. */
|
|
573
|
+
parent: HtmlElement | null;
|
|
505
574
|
}
|
|
506
575
|
/**
|
|
507
576
|
* Event emitted when html-validate directives `<!-- [html-validate-...] -->`
|
|
@@ -625,14 +694,14 @@ declare class Parser {
|
|
|
625
694
|
* stack when is allowed to omit.
|
|
626
695
|
*/
|
|
627
696
|
private closeOptional;
|
|
628
|
-
protected consumeTag(source: Source, startToken:
|
|
697
|
+
protected consumeTag(source: Source, startToken: TagOpenToken, tokenStream: TokenStream): void;
|
|
629
698
|
protected closeElement(source: Source, node: HtmlElement | null, active: HtmlElement, location: Location): void;
|
|
630
699
|
private processElement;
|
|
631
700
|
/**
|
|
632
701
|
* Discard tokens until the end tag for the foreign element is found.
|
|
633
702
|
*/
|
|
634
703
|
protected discardForeignBody(source: Source, foreignTagName: string, tokenStream: TokenStream, errorLocation: Location): void;
|
|
635
|
-
protected consumeAttribute(source: Source, node: HtmlElement, token:
|
|
704
|
+
protected consumeAttribute(source: Source, node: HtmlElement, token: AttrNameToken, next?: Token): void;
|
|
636
705
|
/**
|
|
637
706
|
* Takes attribute key token an returns location.
|
|
638
707
|
*/
|
|
@@ -650,17 +719,24 @@ declare class Parser {
|
|
|
650
719
|
* an aggregate location covering key, quotes if present and value.
|
|
651
720
|
*/
|
|
652
721
|
private getAttributeLocation;
|
|
653
|
-
protected consumeDirective(token:
|
|
722
|
+
protected consumeDirective(token: DirectiveToken): void;
|
|
723
|
+
/**
|
|
724
|
+
* Consumes conditional comment in tag form.
|
|
725
|
+
*
|
|
726
|
+
* See also the related [[consumeCommend]] method.
|
|
727
|
+
*/
|
|
728
|
+
protected consumeConditional(token: ConditionalToken): void;
|
|
654
729
|
/**
|
|
655
730
|
* Consumes comment token.
|
|
656
731
|
*
|
|
657
|
-
* Tries to find IE conditional comments and emits conditional token if
|
|
732
|
+
* Tries to find IE conditional comments and emits conditional token if
|
|
733
|
+
* found. See also the related [[consumeConditional]] method.
|
|
658
734
|
*/
|
|
659
|
-
protected consumeComment(token:
|
|
735
|
+
protected consumeComment(token: CommentToken): void;
|
|
660
736
|
/**
|
|
661
737
|
* Consumes doctype tokens. Emits doctype event.
|
|
662
738
|
*/
|
|
663
|
-
protected consumeDoctype(startToken:
|
|
739
|
+
protected consumeDoctype(startToken: DoctypeOpenToken, tokenStream: TokenStream): void;
|
|
664
740
|
/**
|
|
665
741
|
* Return a list of tokens found until the expected token was found.
|
|
666
742
|
*
|
|
@@ -1145,7 +1221,7 @@ declare class HtmlElement extends DOMNode {
|
|
|
1145
1221
|
/**
|
|
1146
1222
|
* @internal
|
|
1147
1223
|
*/
|
|
1148
|
-
static fromTokens(startToken:
|
|
1224
|
+
static fromTokens(startToken: TagOpenToken, endToken: TagCloseToken, parent: HtmlElement | null, metaTable: MetaTable | null): HtmlElement;
|
|
1149
1225
|
/**
|
|
1150
1226
|
* Returns annotated name if set or defaults to `<tagName>`.
|
|
1151
1227
|
*
|
package/dist/cjs/core.js
CHANGED
|
@@ -1487,8 +1487,8 @@ class DOMTokenList extends Array {
|
|
|
1487
1487
|
constructor(value, location) {
|
|
1488
1488
|
if (value && typeof value === "string") {
|
|
1489
1489
|
/* replace all whitespace with a single space for easier parsing */
|
|
1490
|
-
const
|
|
1491
|
-
const { tokens, locations } = parse(
|
|
1490
|
+
const normalized = value.replace(/[\t\r\n]/g, " ");
|
|
1491
|
+
const { tokens, locations } = parse(normalized, location);
|
|
1492
1492
|
super(...tokens);
|
|
1493
1493
|
this.locations = locations;
|
|
1494
1494
|
}
|
|
@@ -2956,7 +2956,7 @@ var TRANSFORMER_API;
|
|
|
2956
2956
|
/** @public */
|
|
2957
2957
|
const name = "html-validate";
|
|
2958
2958
|
/** @public */
|
|
2959
|
-
const version = "6.
|
|
2959
|
+
const version = "6.5.0";
|
|
2960
2960
|
/** @public */
|
|
2961
2961
|
const homepage = "https://html-validate.org";
|
|
2962
2962
|
/** @public */
|
|
@@ -2995,6 +2995,42 @@ function parseSeverity(value) {
|
|
|
2995
2995
|
}
|
|
2996
2996
|
}
|
|
2997
2997
|
|
|
2998
|
+
function escape(value) {
|
|
2999
|
+
return value.replace(/'/g, "\\'");
|
|
3000
|
+
}
|
|
3001
|
+
function format(value, quote = false) {
|
|
3002
|
+
if (value === null) {
|
|
3003
|
+
return "null";
|
|
3004
|
+
}
|
|
3005
|
+
if (typeof value === "number") {
|
|
3006
|
+
return value.toString();
|
|
3007
|
+
}
|
|
3008
|
+
if (typeof value === "string") {
|
|
3009
|
+
return quote ? `'${escape(value)}'` : value;
|
|
3010
|
+
}
|
|
3011
|
+
if (Array.isArray(value)) {
|
|
3012
|
+
const content = value.map((it) => format(it, true)).join(", ");
|
|
3013
|
+
return `[ ${content} ]`;
|
|
3014
|
+
}
|
|
3015
|
+
if (typeof value === "object") {
|
|
3016
|
+
const content = Object.entries(value)
|
|
3017
|
+
.map(([key, nested]) => `${key}: ${format(nested, true)}`)
|
|
3018
|
+
.join(", ");
|
|
3019
|
+
return `{ ${content} }`;
|
|
3020
|
+
}
|
|
3021
|
+
return String(value);
|
|
3022
|
+
}
|
|
3023
|
+
/**
|
|
3024
|
+
* Replaces placeholder `{{ ... }}` with values from given object.
|
|
3025
|
+
*
|
|
3026
|
+
* @internal
|
|
3027
|
+
*/
|
|
3028
|
+
function interpolate(text, data) {
|
|
3029
|
+
return text.replace(/{{\s*([^\s]+)\s*}}/g, (match, key) => {
|
|
3030
|
+
return typeof data[key] !== "undefined" ? format(data[key]) : match;
|
|
3031
|
+
});
|
|
3032
|
+
}
|
|
3033
|
+
|
|
2998
3034
|
const remapEvents = {
|
|
2999
3035
|
"tag:open": "tag:start",
|
|
3000
3036
|
"tag:close": "tag:end",
|
|
@@ -3129,7 +3165,8 @@ class Rule {
|
|
|
3129
3165
|
report(node, message, location, context) {
|
|
3130
3166
|
if (this.isEnabled() && (!node || node.ruleEnabled(this.name))) {
|
|
3131
3167
|
const where = this.findLocation({ node, location, event: this.event });
|
|
3132
|
-
|
|
3168
|
+
const interpolated = interpolate(message, context !== null && context !== void 0 ? context : {});
|
|
3169
|
+
this.reporter.add(this, interpolated, this.severity, node, where, context);
|
|
3133
3170
|
}
|
|
3134
3171
|
}
|
|
3135
3172
|
findLocation(src) {
|
|
@@ -3236,7 +3273,8 @@ function ruleDocumentationUrl(filename) {
|
|
|
3236
3273
|
const p = path__default["default"].parse(filename);
|
|
3237
3274
|
const root = path__default["default"].join(distFolder, "rules");
|
|
3238
3275
|
const rel = path__default["default"].relative(root, path__default["default"].join(p.dir, p.name));
|
|
3239
|
-
|
|
3276
|
+
const normalized = rel.replace(/\\/g, "/");
|
|
3277
|
+
return `${homepage}/rules/${normalized}.html`;
|
|
3240
3278
|
}
|
|
3241
3279
|
|
|
3242
3280
|
const defaults$p = {
|
|
@@ -3653,22 +3691,21 @@ exports.TokenType = void 0;
|
|
|
3653
3691
|
(function (TokenType) {
|
|
3654
3692
|
TokenType[TokenType["UNICODE_BOM"] = 1] = "UNICODE_BOM";
|
|
3655
3693
|
TokenType[TokenType["WHITESPACE"] = 2] = "WHITESPACE";
|
|
3656
|
-
TokenType[TokenType["
|
|
3657
|
-
TokenType[TokenType["
|
|
3658
|
-
TokenType[TokenType["
|
|
3659
|
-
TokenType[TokenType["
|
|
3660
|
-
TokenType[TokenType["
|
|
3661
|
-
TokenType[TokenType["
|
|
3662
|
-
TokenType[TokenType["
|
|
3663
|
-
TokenType[TokenType["
|
|
3664
|
-
TokenType[TokenType["
|
|
3665
|
-
TokenType[TokenType["
|
|
3666
|
-
TokenType[TokenType["
|
|
3667
|
-
TokenType[TokenType["
|
|
3668
|
-
TokenType[TokenType["
|
|
3669
|
-
TokenType[TokenType["
|
|
3670
|
-
TokenType[TokenType["
|
|
3671
|
-
TokenType[TokenType["EOF"] = 18] = "EOF";
|
|
3694
|
+
TokenType[TokenType["DOCTYPE_OPEN"] = 3] = "DOCTYPE_OPEN";
|
|
3695
|
+
TokenType[TokenType["DOCTYPE_VALUE"] = 4] = "DOCTYPE_VALUE";
|
|
3696
|
+
TokenType[TokenType["DOCTYPE_CLOSE"] = 5] = "DOCTYPE_CLOSE";
|
|
3697
|
+
TokenType[TokenType["TAG_OPEN"] = 6] = "TAG_OPEN";
|
|
3698
|
+
TokenType[TokenType["TAG_CLOSE"] = 7] = "TAG_CLOSE";
|
|
3699
|
+
TokenType[TokenType["ATTR_NAME"] = 8] = "ATTR_NAME";
|
|
3700
|
+
TokenType[TokenType["ATTR_VALUE"] = 9] = "ATTR_VALUE";
|
|
3701
|
+
TokenType[TokenType["TEXT"] = 10] = "TEXT";
|
|
3702
|
+
TokenType[TokenType["TEMPLATING"] = 11] = "TEMPLATING";
|
|
3703
|
+
TokenType[TokenType["SCRIPT"] = 12] = "SCRIPT";
|
|
3704
|
+
TokenType[TokenType["STYLE"] = 13] = "STYLE";
|
|
3705
|
+
TokenType[TokenType["COMMENT"] = 14] = "COMMENT";
|
|
3706
|
+
TokenType[TokenType["CONDITIONAL"] = 15] = "CONDITIONAL";
|
|
3707
|
+
TokenType[TokenType["DIRECTIVE"] = 16] = "DIRECTIVE";
|
|
3708
|
+
TokenType[TokenType["EOF"] = 17] = "EOF";
|
|
3672
3709
|
})(exports.TokenType || (exports.TokenType = {}));
|
|
3673
3710
|
|
|
3674
3711
|
/* eslint-disable no-useless-escape */
|
|
@@ -3693,7 +3730,7 @@ const MATCH_SCRIPT_DATA = /^[^]*?(?=<\/script)/;
|
|
|
3693
3730
|
const MATCH_SCRIPT_END = /^<(\/)(script)/;
|
|
3694
3731
|
const MATCH_STYLE_DATA = /^[^]*?(?=<\/style)/;
|
|
3695
3732
|
const MATCH_STYLE_END = /^<(\/)(style)/;
|
|
3696
|
-
const MATCH_DIRECTIVE = /^<!--\s
|
|
3733
|
+
const MATCH_DIRECTIVE = /^<!--\s*(\[)html-validate-([a-z0-9-]+)\s*(.*?)(]?)\s*-->/;
|
|
3697
3734
|
const MATCH_COMMENT = /^<!--([^]*?)-->/;
|
|
3698
3735
|
const MATCH_CONDITIONAL = /^<!\[([^\]]*?)\]>/;
|
|
3699
3736
|
class InvalidTokenError extends Error {
|
|
@@ -3748,15 +3785,15 @@ class Lexer {
|
|
|
3748
3785
|
previousState = context.state;
|
|
3749
3786
|
previousLength = context.string.length;
|
|
3750
3787
|
}
|
|
3751
|
-
yield this.token(context, exports.TokenType.EOF);
|
|
3788
|
+
yield this.token(context, exports.TokenType.EOF, []);
|
|
3752
3789
|
}
|
|
3753
3790
|
token(context, type, data) {
|
|
3754
|
-
const size = data ? data[0].length : 0;
|
|
3791
|
+
const size = data.length > 0 ? data[0].length : 0;
|
|
3755
3792
|
const location = context.getLocation(size);
|
|
3756
3793
|
return {
|
|
3757
3794
|
type,
|
|
3758
3795
|
location,
|
|
3759
|
-
data:
|
|
3796
|
+
data: Array.from(data),
|
|
3760
3797
|
};
|
|
3761
3798
|
}
|
|
3762
3799
|
/* istanbul ignore next: used to provide a better error when an unhandled state happens */
|
|
@@ -3781,17 +3818,18 @@ class Lexer {
|
|
|
3781
3818
|
}
|
|
3782
3819
|
}
|
|
3783
3820
|
*match(context, tests, error) {
|
|
3784
|
-
let match = null;
|
|
3785
3821
|
const n = tests.length;
|
|
3786
3822
|
for (let i = 0; i < n; i++) {
|
|
3787
3823
|
const [regex, nextState, tokenType] = tests[i];
|
|
3788
|
-
|
|
3824
|
+
const match = regex ? context.string.match(regex) : [""];
|
|
3825
|
+
if (match) {
|
|
3789
3826
|
let token = null;
|
|
3790
3827
|
if (tokenType !== false) {
|
|
3791
|
-
|
|
3828
|
+
token = this.token(context, tokenType, match);
|
|
3829
|
+
yield token;
|
|
3792
3830
|
}
|
|
3793
3831
|
const state = this.evalNextState(nextState, token);
|
|
3794
|
-
context.consume(match
|
|
3832
|
+
context.consume(match, state);
|
|
3795
3833
|
this.enter(context, state, match);
|
|
3796
3834
|
return;
|
|
3797
3835
|
}
|
|
@@ -3838,18 +3876,19 @@ class Lexer {
|
|
|
3838
3876
|
*tokenizeTag(context) {
|
|
3839
3877
|
/* eslint-disable-next-line consistent-return -- exhaustive switch handled by typescript */
|
|
3840
3878
|
function nextState(token) {
|
|
3879
|
+
const tagCloseToken = token;
|
|
3841
3880
|
switch (context.contentModel) {
|
|
3842
3881
|
case ContentModel.TEXT:
|
|
3843
3882
|
return State.TEXT;
|
|
3844
3883
|
case ContentModel.SCRIPT:
|
|
3845
|
-
if (
|
|
3884
|
+
if (tagCloseToken && tagCloseToken.data[0][0] !== "/") {
|
|
3846
3885
|
return State.SCRIPT;
|
|
3847
3886
|
}
|
|
3848
3887
|
else {
|
|
3849
3888
|
return State.TEXT; /* <script/> (not legal but handle it anyway so the lexer doesn't choke on it) */
|
|
3850
3889
|
}
|
|
3851
3890
|
case ContentModel.STYLE:
|
|
3852
|
-
if (
|
|
3891
|
+
if (tagCloseToken && tagCloseToken.data[0][0] !== "/") {
|
|
3853
3892
|
return State.STYLE;
|
|
3854
3893
|
}
|
|
3855
3894
|
else {
|
|
@@ -5997,7 +6036,7 @@ class NoConditionalComment extends Rule {
|
|
|
5997
6036
|
}
|
|
5998
6037
|
setup() {
|
|
5999
6038
|
this.on("conditional", (event) => {
|
|
6000
|
-
this.report(
|
|
6039
|
+
this.report(event.parent, "Use of conditional comments are deprecated", event.location);
|
|
6001
6040
|
});
|
|
6002
6041
|
}
|
|
6003
6042
|
}
|
|
@@ -9770,7 +9809,9 @@ class ResolvedConfig {
|
|
|
9770
9809
|
* @returns A list of transformed sources ready for validation.
|
|
9771
9810
|
*/
|
|
9772
9811
|
transformFilename(filename) {
|
|
9773
|
-
const
|
|
9812
|
+
const stdin = 0;
|
|
9813
|
+
const src = filename !== "/dev/stdin" ? filename : stdin;
|
|
9814
|
+
const data = fs__default["default"].readFileSync(src, { encoding: "utf8" });
|
|
9774
9815
|
const source = {
|
|
9775
9816
|
data,
|
|
9776
9817
|
filename,
|
|
@@ -10421,6 +10462,9 @@ class ParserError extends Error {
|
|
|
10421
10462
|
}
|
|
10422
10463
|
}
|
|
10423
10464
|
|
|
10465
|
+
function isAttrValueToken(token) {
|
|
10466
|
+
return Boolean(token && token.type === exports.TokenType.ATTR_VALUE);
|
|
10467
|
+
}
|
|
10424
10468
|
/**
|
|
10425
10469
|
* Parse HTML document into a DOM tree.
|
|
10426
10470
|
*
|
|
@@ -10492,10 +10536,7 @@ class Parser {
|
|
|
10492
10536
|
this.consumeDirective(token);
|
|
10493
10537
|
break;
|
|
10494
10538
|
case exports.TokenType.CONDITIONAL:
|
|
10495
|
-
this.
|
|
10496
|
-
condition: token.data[1],
|
|
10497
|
-
location: token.location,
|
|
10498
|
-
});
|
|
10539
|
+
this.consumeConditional(token);
|
|
10499
10540
|
break;
|
|
10500
10541
|
case exports.TokenType.COMMENT:
|
|
10501
10542
|
this.consumeComment(token);
|
|
@@ -10505,7 +10546,7 @@ class Parser {
|
|
|
10505
10546
|
break;
|
|
10506
10547
|
case exports.TokenType.TEXT:
|
|
10507
10548
|
case exports.TokenType.TEMPLATING:
|
|
10508
|
-
this.appendText(token.data, token.location);
|
|
10549
|
+
this.appendText(token.data[0], token.location);
|
|
10509
10550
|
break;
|
|
10510
10551
|
case exports.TokenType.EOF:
|
|
10511
10552
|
this.closeTree(source, token.location);
|
|
@@ -10700,15 +10741,15 @@ class Parser {
|
|
|
10700
10741
|
const keyLocation = this.getAttributeKeyLocation(token);
|
|
10701
10742
|
const valueLocation = this.getAttributeValueLocation(next);
|
|
10702
10743
|
const location = this.getAttributeLocation(token, next);
|
|
10703
|
-
const haveValue = next
|
|
10744
|
+
const haveValue = isAttrValueToken(next);
|
|
10704
10745
|
const attrData = {
|
|
10705
10746
|
key: token.data[1],
|
|
10706
10747
|
value: null,
|
|
10707
10748
|
quote: null,
|
|
10708
10749
|
};
|
|
10709
|
-
if (
|
|
10750
|
+
if (haveValue) {
|
|
10710
10751
|
const [, , value, quote] = next.data;
|
|
10711
|
-
attrData.value = value
|
|
10752
|
+
attrData.value = value;
|
|
10712
10753
|
attrData.quote = quote !== null && quote !== void 0 ? quote : null;
|
|
10713
10754
|
}
|
|
10714
10755
|
/* get callback to process attributes, default is to just return attribute
|
|
@@ -10787,12 +10828,16 @@ class Parser {
|
|
|
10787
10828
|
};
|
|
10788
10829
|
}
|
|
10789
10830
|
consumeDirective(token) {
|
|
10790
|
-
const directive = token.data
|
|
10791
|
-
|
|
10831
|
+
const [text, , action, directive, end] = token.data;
|
|
10832
|
+
if (end === "") {
|
|
10833
|
+
throw new Error(`Missing end bracket "]" on directive "${text}"`);
|
|
10834
|
+
}
|
|
10835
|
+
const match = directive.match(/^(.*?)(?:\s*(?:--|:)\s*(.*))?$/);
|
|
10836
|
+
/* istanbul ignore next: should not be possible, would be emitted as comment token */
|
|
10792
10837
|
if (!match) {
|
|
10793
|
-
throw new Error(`Failed to parse directive "${
|
|
10838
|
+
throw new Error(`Failed to parse directive "${text}"`);
|
|
10794
10839
|
}
|
|
10795
|
-
const [,
|
|
10840
|
+
const [, data, comment] = match;
|
|
10796
10841
|
this.trigger("directive", {
|
|
10797
10842
|
action,
|
|
10798
10843
|
data,
|
|
@@ -10800,17 +10845,33 @@ class Parser {
|
|
|
10800
10845
|
location: token.location,
|
|
10801
10846
|
});
|
|
10802
10847
|
}
|
|
10848
|
+
/**
|
|
10849
|
+
* Consumes conditional comment in tag form.
|
|
10850
|
+
*
|
|
10851
|
+
* See also the related [[consumeCommend]] method.
|
|
10852
|
+
*/
|
|
10853
|
+
consumeConditional(token) {
|
|
10854
|
+
const element = this.dom.getActive();
|
|
10855
|
+
this.trigger("conditional", {
|
|
10856
|
+
condition: token.data[1],
|
|
10857
|
+
location: token.location,
|
|
10858
|
+
parent: element,
|
|
10859
|
+
});
|
|
10860
|
+
}
|
|
10803
10861
|
/**
|
|
10804
10862
|
* Consumes comment token.
|
|
10805
10863
|
*
|
|
10806
|
-
* Tries to find IE conditional comments and emits conditional token if
|
|
10864
|
+
* Tries to find IE conditional comments and emits conditional token if
|
|
10865
|
+
* found. See also the related [[consumeConditional]] method.
|
|
10807
10866
|
*/
|
|
10808
10867
|
consumeComment(token) {
|
|
10809
10868
|
const comment = token.data[0];
|
|
10869
|
+
const element = this.dom.getActive();
|
|
10810
10870
|
for (const conditional of parseConditionalComment(comment, token.location)) {
|
|
10811
10871
|
this.trigger("conditional", {
|
|
10812
10872
|
condition: conditional.expression,
|
|
10813
10873
|
location: conditional.location,
|
|
10874
|
+
parent: element,
|
|
10814
10875
|
});
|
|
10815
10876
|
}
|
|
10816
10877
|
}
|
|
@@ -10819,7 +10880,8 @@ class Parser {
|
|
|
10819
10880
|
*/
|
|
10820
10881
|
consumeDoctype(startToken, tokenStream) {
|
|
10821
10882
|
const tokens = Array.from(this.consumeUntil(tokenStream, exports.TokenType.DOCTYPE_CLOSE, startToken.location));
|
|
10822
|
-
|
|
10883
|
+
/* first token is the doctype, second is the closing ">" */
|
|
10884
|
+
const doctype = tokens[0];
|
|
10823
10885
|
const value = doctype.data[0];
|
|
10824
10886
|
this.dom.doctype = value;
|
|
10825
10887
|
this.trigger("doctype", {
|
|
@@ -10852,7 +10914,7 @@ class Parser {
|
|
|
10852
10914
|
this.trigger("token", {
|
|
10853
10915
|
location: token.location,
|
|
10854
10916
|
type: token.type,
|
|
10855
|
-
data:
|
|
10917
|
+
data: Array.from(token.data),
|
|
10856
10918
|
});
|
|
10857
10919
|
}
|
|
10858
10920
|
return it;
|
|
@@ -11112,11 +11174,12 @@ class Engine {
|
|
|
11112
11174
|
return lines;
|
|
11113
11175
|
}
|
|
11114
11176
|
dumpTokens(source) {
|
|
11177
|
+
var _a;
|
|
11115
11178
|
const lexer = new Lexer();
|
|
11116
11179
|
const lines = [];
|
|
11117
11180
|
for (const src of source) {
|
|
11118
11181
|
for (const token of lexer.tokenize(src)) {
|
|
11119
|
-
const data =
|
|
11182
|
+
const data = (_a = token.data[0]) !== null && _a !== void 0 ? _a : "";
|
|
11120
11183
|
lines.push({
|
|
11121
11184
|
token: exports.TokenType[token.type],
|
|
11122
11185
|
data,
|