@typed/template 0.2.0 → 0.3.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.
Files changed (213) hide show
  1. package/dist/cjs/Directive.js +1 -1
  2. package/dist/cjs/Directive.js.map +1 -1
  3. package/dist/cjs/ElementRef.js +23 -13
  4. package/dist/cjs/ElementRef.js.map +1 -1
  5. package/dist/cjs/ElementSource.js +16 -18
  6. package/dist/cjs/ElementSource.js.map +1 -1
  7. package/dist/cjs/EventHandler.js +1 -1
  8. package/dist/cjs/EventHandler.js.map +1 -1
  9. package/dist/cjs/Html.js +31 -32
  10. package/dist/cjs/Html.js.map +1 -1
  11. package/dist/cjs/HtmlChunk.js +4 -1
  12. package/dist/cjs/HtmlChunk.js.map +1 -1
  13. package/dist/cjs/Hydrate.js +1 -1
  14. package/dist/cjs/Hydrate.js.map +1 -1
  15. package/dist/cjs/Many.js +14 -13
  16. package/dist/cjs/Many.js.map +1 -1
  17. package/dist/cjs/Parser.js +11 -323
  18. package/dist/cjs/Parser.js.map +1 -1
  19. package/dist/cjs/Placeholder.js +3 -3
  20. package/dist/cjs/Placeholder.js.map +1 -1
  21. package/dist/cjs/Platform.js +4 -4
  22. package/dist/cjs/Platform.js.map +1 -1
  23. package/dist/cjs/Render.js +1 -1
  24. package/dist/cjs/Render.js.map +1 -1
  25. package/dist/cjs/RenderContext.js +48 -27
  26. package/dist/cjs/RenderContext.js.map +1 -1
  27. package/dist/cjs/RenderTemplate.js +2 -17
  28. package/dist/cjs/RenderTemplate.js.map +1 -1
  29. package/dist/cjs/Template.js +27 -1
  30. package/dist/cjs/Template.js.map +1 -1
  31. package/dist/cjs/TemplateInstance.js +2 -2
  32. package/dist/cjs/TemplateInstance.js.map +1 -1
  33. package/dist/cjs/Test.js +20 -7
  34. package/dist/cjs/Test.js.map +1 -1
  35. package/dist/cjs/index.js +0 -12
  36. package/dist/cjs/index.js.map +1 -1
  37. package/dist/cjs/internal/EventSource.js +95 -0
  38. package/dist/cjs/internal/EventSource.js.map +1 -0
  39. package/dist/cjs/internal/browser.js +11 -11
  40. package/dist/cjs/internal/browser.js.map +1 -1
  41. package/dist/cjs/internal/hydrate.js +49 -50
  42. package/dist/cjs/internal/hydrate.js.map +1 -1
  43. package/dist/cjs/internal/indexRefCounter.js +49 -2
  44. package/dist/cjs/internal/indexRefCounter.js.map +1 -1
  45. package/dist/cjs/internal/parser.js +60 -17
  46. package/dist/cjs/internal/parser.js.map +1 -1
  47. package/dist/cjs/internal/parts.js +128 -28
  48. package/dist/cjs/internal/parts.js.map +1 -1
  49. package/dist/cjs/internal/render.js +486 -53
  50. package/dist/cjs/internal/render.js.map +1 -1
  51. package/dist/cjs/internal/server.js +5 -2
  52. package/dist/cjs/internal/server.js.map +1 -1
  53. package/dist/dts/Directive.d.ts.map +1 -1
  54. package/dist/dts/ElementRef.d.ts +4 -2
  55. package/dist/dts/ElementRef.d.ts.map +1 -1
  56. package/dist/dts/ElementSource.d.ts +10 -5
  57. package/dist/dts/ElementSource.d.ts.map +1 -1
  58. package/dist/dts/EventHandler.d.ts.map +1 -1
  59. package/dist/dts/Html.d.ts +1 -1
  60. package/dist/dts/Html.d.ts.map +1 -1
  61. package/dist/dts/HtmlChunk.d.ts.map +1 -1
  62. package/dist/dts/Many.d.ts +13 -11
  63. package/dist/dts/Many.d.ts.map +1 -1
  64. package/dist/dts/Parser.d.ts +3 -6
  65. package/dist/dts/Parser.d.ts.map +1 -1
  66. package/dist/dts/Part.d.ts +13 -3
  67. package/dist/dts/Part.d.ts.map +1 -1
  68. package/dist/dts/Placeholder.d.ts +2 -2
  69. package/dist/dts/Placeholder.d.ts.map +1 -1
  70. package/dist/dts/Render.d.ts +2 -1
  71. package/dist/dts/Render.d.ts.map +1 -1
  72. package/dist/dts/RenderContext.d.ts +5 -4
  73. package/dist/dts/RenderContext.d.ts.map +1 -1
  74. package/dist/dts/RenderTemplate.d.ts +2 -16
  75. package/dist/dts/RenderTemplate.d.ts.map +1 -1
  76. package/dist/dts/Renderable.d.ts +2 -2
  77. package/dist/dts/Renderable.d.ts.map +1 -1
  78. package/dist/dts/Template.d.ts +21 -3
  79. package/dist/dts/Template.d.ts.map +1 -1
  80. package/dist/dts/TemplateInstance.d.ts +3 -2
  81. package/dist/dts/TemplateInstance.d.ts.map +1 -1
  82. package/dist/dts/Test.d.ts +4 -6
  83. package/dist/dts/Test.d.ts.map +1 -1
  84. package/dist/dts/index.d.ts +0 -4
  85. package/dist/dts/index.d.ts.map +1 -1
  86. package/dist/dts/internal/EventSource.d.ts +12 -0
  87. package/dist/dts/internal/EventSource.d.ts.map +1 -0
  88. package/dist/dts/internal/browser.d.ts.map +1 -1
  89. package/dist/dts/internal/hydrate.d.ts +5 -5
  90. package/dist/dts/internal/hydrate.d.ts.map +1 -1
  91. package/dist/dts/internal/indexRefCounter.d.ts +5 -0
  92. package/dist/dts/internal/indexRefCounter.d.ts.map +1 -1
  93. package/dist/dts/internal/module-augmentation.d.ts +0 -4
  94. package/dist/dts/internal/module-augmentation.d.ts.map +1 -1
  95. package/dist/dts/internal/parser.d.ts +8 -0
  96. package/dist/dts/internal/parser.d.ts.map +1 -1
  97. package/dist/dts/internal/parts.d.ts +66 -56
  98. package/dist/dts/internal/parts.d.ts.map +1 -1
  99. package/dist/dts/internal/render.d.ts +7 -7
  100. package/dist/dts/internal/render.d.ts.map +1 -1
  101. package/dist/dts/internal/server.d.ts.map +1 -1
  102. package/dist/esm/Directive.js +1 -1
  103. package/dist/esm/Directive.js.map +1 -1
  104. package/dist/esm/ElementRef.js +12 -7
  105. package/dist/esm/ElementRef.js.map +1 -1
  106. package/dist/esm/ElementSource.js +16 -13
  107. package/dist/esm/ElementSource.js.map +1 -1
  108. package/dist/esm/EventHandler.js +1 -1
  109. package/dist/esm/EventHandler.js.map +1 -1
  110. package/dist/esm/Html.js +29 -24
  111. package/dist/esm/Html.js.map +1 -1
  112. package/dist/esm/HtmlChunk.js +6 -1
  113. package/dist/esm/HtmlChunk.js.map +1 -1
  114. package/dist/esm/Hydrate.js +1 -1
  115. package/dist/esm/Hydrate.js.map +1 -1
  116. package/dist/esm/Many.js +14 -10
  117. package/dist/esm/Many.js.map +1 -1
  118. package/dist/esm/Parser.js +6 -335
  119. package/dist/esm/Parser.js.map +1 -1
  120. package/dist/esm/Placeholder.js +2 -2
  121. package/dist/esm/Placeholder.js.map +1 -1
  122. package/dist/esm/Platform.js +2 -2
  123. package/dist/esm/Platform.js.map +1 -1
  124. package/dist/esm/Render.js +1 -1
  125. package/dist/esm/Render.js.map +1 -1
  126. package/dist/esm/RenderContext.js +38 -17
  127. package/dist/esm/RenderContext.js.map +1 -1
  128. package/dist/esm/RenderTemplate.js +2 -12
  129. package/dist/esm/RenderTemplate.js.map +1 -1
  130. package/dist/esm/Template.js +24 -0
  131. package/dist/esm/Template.js.map +1 -1
  132. package/dist/esm/TemplateInstance.js +2 -2
  133. package/dist/esm/TemplateInstance.js.map +1 -1
  134. package/dist/esm/Test.js +20 -7
  135. package/dist/esm/Test.js.map +1 -1
  136. package/dist/esm/index.js +0 -4
  137. package/dist/esm/index.js.map +1 -1
  138. package/dist/esm/internal/EventSource.js +91 -0
  139. package/dist/esm/internal/EventSource.js.map +1 -0
  140. package/dist/esm/internal/browser.js +12 -12
  141. package/dist/esm/internal/browser.js.map +1 -1
  142. package/dist/esm/internal/hydrate.js +45 -46
  143. package/dist/esm/internal/hydrate.js.map +1 -1
  144. package/dist/esm/internal/indexRefCounter.js +50 -2
  145. package/dist/esm/internal/indexRefCounter.js.map +1 -1
  146. package/dist/esm/internal/parser.js +84 -17
  147. package/dist/esm/internal/parser.js.map +1 -1
  148. package/dist/esm/internal/parts.js +110 -27
  149. package/dist/esm/internal/parts.js.map +1 -1
  150. package/dist/esm/internal/render.js +476 -58
  151. package/dist/esm/internal/render.js.map +1 -1
  152. package/dist/esm/internal/server.js +5 -4
  153. package/dist/esm/internal/server.js.map +1 -1
  154. package/package.json +10 -26
  155. package/src/Directive.ts +1 -1
  156. package/src/ElementRef.ts +18 -14
  157. package/src/ElementSource.ts +62 -47
  158. package/src/EventHandler.ts +1 -1
  159. package/src/Html.ts +58 -57
  160. package/src/HtmlChunk.ts +15 -1
  161. package/src/Hydrate.ts +1 -1
  162. package/src/Many.ts +53 -43
  163. package/src/Parser.ts +10 -453
  164. package/src/Part.ts +15 -3
  165. package/src/Placeholder.ts +4 -4
  166. package/src/Platform.ts +2 -2
  167. package/src/Render.ts +7 -2
  168. package/src/RenderContext.ts +47 -19
  169. package/src/RenderTemplate.ts +9 -54
  170. package/src/Renderable.ts +2 -1
  171. package/src/Template.ts +26 -0
  172. package/src/TemplateInstance.ts +9 -9
  173. package/src/Test.ts +40 -21
  174. package/src/index.ts +0 -4
  175. package/src/internal/EventSource.ts +153 -0
  176. package/src/internal/browser.ts +26 -25
  177. package/src/internal/hydrate.ts +68 -61
  178. package/src/internal/indexRefCounter.ts +63 -2
  179. package/src/internal/module-augmentation.ts +0 -4
  180. package/src/internal/parser.ts +92 -19
  181. package/src/internal/parts.ts +158 -73
  182. package/src/internal/render.ts +701 -89
  183. package/src/internal/server.ts +5 -3
  184. package/Token/package.json +0 -6
  185. package/Tokenizer/package.json +0 -6
  186. package/dist/cjs/Token.js +0 -270
  187. package/dist/cjs/Token.js.map +0 -1
  188. package/dist/cjs/Tokenizer.js +0 -18
  189. package/dist/cjs/Tokenizer.js.map +0 -1
  190. package/dist/cjs/internal/readAttribute.js +0 -34
  191. package/dist/cjs/internal/readAttribute.js.map +0 -1
  192. package/dist/cjs/internal/tokenizer.js +0 -264
  193. package/dist/cjs/internal/tokenizer.js.map +0 -1
  194. package/dist/dts/Token.d.ts +0 -202
  195. package/dist/dts/Token.d.ts.map +0 -1
  196. package/dist/dts/Tokenizer.d.ts +0 -6
  197. package/dist/dts/Tokenizer.d.ts.map +0 -1
  198. package/dist/dts/internal/readAttribute.d.ts +0 -9
  199. package/dist/dts/internal/readAttribute.d.ts.map +0 -1
  200. package/dist/dts/internal/tokenizer.d.ts +0 -3
  201. package/dist/dts/internal/tokenizer.d.ts.map +0 -1
  202. package/dist/esm/Token.js +0 -264
  203. package/dist/esm/Token.js.map +0 -1
  204. package/dist/esm/Tokenizer.js +0 -9
  205. package/dist/esm/Tokenizer.js.map +0 -1
  206. package/dist/esm/internal/readAttribute.js +0 -24
  207. package/dist/esm/internal/readAttribute.js.map +0 -1
  208. package/dist/esm/internal/tokenizer.js +0 -296
  209. package/dist/esm/internal/tokenizer.js.map +0 -1
  210. package/src/Token.ts +0 -269
  211. package/src/Tokenizer.ts +0 -10
  212. package/src/internal/readAttribute.ts +0 -28
  213. package/src/internal/tokenizer.ts +0 -338
@@ -1,338 +0,0 @@
1
- import * as Token from "../Token.js"
2
- import {
3
- getAllTextUntilElementClose,
4
- getAttributeWithoutQuotes,
5
- getAttributeWithQuotes,
6
- getBooleanAttribute,
7
- getClosingTag,
8
- getComment,
9
- getOpeningTag,
10
- getOpeningTagEnd,
11
- getPart,
12
- getSelfClosingTagEnd,
13
- getTextUntilCloseBrace,
14
- getTextUntilPart,
15
- getWhitespace,
16
- PART_REGEX,
17
- PART_STRING
18
- } from "./chunks.js"
19
- import type { TextChunk } from "./chunks.js"
20
-
21
- export function tokenize(template: ReadonlyArray<string>): Iterable<Token.Token> {
22
- return new Tokenizer(template)
23
- }
24
-
25
- function templateWithParts(template: ReadonlyArray<string>): string {
26
- const length = template.length
27
- const lastIndex = length - 1
28
-
29
- let output = ""
30
-
31
- for (let i = 0; i < length; i++) {
32
- const str = template[i]
33
-
34
- if (i === lastIndex) {
35
- output += str
36
- } else {
37
- output += str + PART_STRING(i)
38
- }
39
- }
40
-
41
- return output
42
- }
43
-
44
- class Tokenizer implements Iterable<Token.Token> {
45
- protected input: string = ""
46
- protected pos: number = 0
47
- protected context: "text" | "element" | "self-closing" | "text-only" = "text"
48
- protected currentTag: Stack<string> | null = null
49
-
50
- constructor(private readonly template: ReadonlyArray<string>) {}
51
-
52
- *[Symbol.iterator](): Generator<Token.Token> {
53
- this.init()
54
-
55
- // eslint-disable-next-line no-constant-condition
56
- while (this.pos < this.input.length) {
57
- switch (this.context) {
58
- case "element":
59
- yield* this.nextElementToken()
60
- break
61
- case "self-closing":
62
- yield* this.nextSelfClosingToken()
63
- break
64
- case "text-only":
65
- yield* this.nextTextOnlyToken()
66
- break
67
- default:
68
- yield* this.nextTextToken()
69
- }
70
- }
71
- }
72
-
73
- private init(): void {
74
- // Convert our template into a string for easier tokenization
75
- // Remove any whitespace at the beginning or end of the template since we don't care about it.
76
- this.input = this.template.length === 1 ? this.template[0] : templateWithParts(this.template)
77
- }
78
-
79
- private *nextTextToken(): Generator<Token.Token> {
80
- const char = this.nextChar()
81
- const isOpenBracket = char === "<"
82
-
83
- let next: TextChunk | undefined
84
-
85
- if (isOpenBracket && (next = this.chunk(getOpeningTag))) {
86
- const name = next.match[2]
87
-
88
- this.pushTag(name)
89
- this.context = Token.SELF_CLOSING_TAGS.has(name)
90
- ? "self-closing"
91
- : Token.TEXT_ONLY_NODES_REGEX.has(name)
92
- ? "text-only"
93
- : "element"
94
-
95
- yield new Token.OpeningTagToken(name)
96
- } else if (isOpenBracket && (next = this.chunk(getClosingTag))) {
97
- yield new Token.ClosingTagToken(next.match[3])
98
- this.popTag()
99
- } else if (isOpenBracket && (next = this.chunk(getComment))) {
100
- yield* this.parseComment(next.match[2])
101
- } else if ((next = this.chunk(getPart))) {
102
- yield new Token.PartToken(parseInt(next.match[2], 10))
103
- } else if ((next = this.chunk(getWhitespace))) {
104
- yield new Token.TextToken(next.match[1])
105
- } else if ((next = this.chunk(getTextUntilCloseBrace))) {
106
- yield* parseTextAndParts(next.match[1])
107
- } else {
108
- yield new Token.TextToken(this.takeNextChar())
109
- }
110
- }
111
-
112
- private *nextElementToken(): Generator<Token.Token> {
113
- let next: TextChunk | undefined
114
-
115
- if ((next = this.chunk(getAttributeWithQuotes))) {
116
- yield* this.parseAttribute(next.match[2], next.match[4])
117
- } else if ((next = this.chunk(getAttributeWithoutQuotes))) {
118
- yield* this.parseAttribute(next.match[2], next.match[4])
119
- } else if ((next = this.chunk(getOpeningTagEnd))) {
120
- this.context = "text"
121
-
122
- yield new Token.OpeningTagEndToken(this.currentTag!.value)
123
- } else if ((next = this.chunk(getSelfClosingTagEnd))) {
124
- yield new Token.OpeningTagEndToken(this.currentTag!.value, false)
125
- yield new Token.ClosingTagToken(this.currentTag!.value)
126
- this.popTag()
127
- this.context = "text"
128
- } else if ((next = this.chunk(getBooleanAttribute))) {
129
- yield new Token.BooleanAttributeToken(next.match[2])
130
- } else if ((next = this.chunk(getWhitespace))) {
131
- // Continue
132
- } else {
133
- this.invalidTemplate()
134
- }
135
- }
136
-
137
- private *nextSelfClosingToken(): Generator<Token.Token> {
138
- let next: TextChunk | undefined
139
-
140
- if ((next = this.chunk(getAttributeWithQuotes))) {
141
- yield* this.parseAttribute(next.match[2], next.match[4])
142
- } else if ((next = this.chunk(getAttributeWithoutQuotes))) {
143
- yield* this.parseAttribute(next.match[2], next.match[4])
144
- } else if ((next = this.chunk(getSelfClosingTagEnd))) {
145
- yield new Token.OpeningTagEndToken(this.currentTag!.value, true)
146
- this.popTag()
147
- this.context = "text"
148
- } else if ((next = this.chunk(getBooleanAttribute))) {
149
- yield new Token.BooleanAttributeToken(next.match[2])
150
- } else {
151
- this.invalidTemplate()
152
- }
153
- }
154
-
155
- private *nextTextOnlyToken(): Generator<Token.Token> {
156
- let next: TextChunk | undefined
157
-
158
- if ((next = this.chunk(getAttributeWithQuotes))) {
159
- yield* this.parseAttribute(next.match[2], next.match[4])
160
- } else if ((next = this.chunk(getAttributeWithoutQuotes))) {
161
- yield* this.parseAttribute(next.match[2], next.match[4])
162
- } else if ((next = this.chunk(getOpeningTagEnd))) {
163
- yield new Token.OpeningTagEndToken(this.currentTag!.value)
164
- } else if ((next = this.chunk(getClosingTag))) {
165
- yield new Token.ClosingTagToken(next.match[3])
166
- this.context = "text"
167
- } else if ((next = this.chunk(getAllTextUntilElementClose(this.currentTag!.value)))) {
168
- const text = next.match[1]
169
-
170
- if (PART_REGEX.test(text)) {
171
- yield* parseTextAndParts(text)
172
- } else {
173
- yield new Token.TextToken(text)
174
- }
175
- this.context = "text"
176
- } else {
177
- this.invalidTemplate()
178
- }
179
- }
180
-
181
- private *parseComment(comment: string): Generator<Token.Token> {
182
- const parts = Array.from(parseTextAndParts(comment))
183
-
184
- if (parts.length === 1 && parts[0]._tag === "text") {
185
- yield new Token.CommentToken(parts[0].value)
186
- return
187
- }
188
-
189
- yield new Token.CommentStartToken("<!--")
190
-
191
- for (const part of parts) {
192
- yield part
193
- }
194
-
195
- yield new Token.CommentEndToken("-->")
196
- }
197
-
198
- private *parseAttribute(name: string, value: string) {
199
- const parts = Array.from(parseTextAndParts(value))
200
-
201
- if (value === "") {
202
- yield new Token.BooleanAttributeToken(name)
203
- return
204
- }
205
-
206
- if (parts.length === 1 && parts[0]._tag === "text") {
207
- yield getAttributeToken(name, value)
208
- return
209
- }
210
-
211
- yield getAttributeTokenPartial(name, "start")
212
-
213
- for (const part of parts) {
214
- yield part
215
- }
216
-
217
- yield getAttributeTokenPartial(name, "end")
218
- }
219
-
220
- private nextChar(): string {
221
- return this.input.charAt(this.pos)
222
- }
223
-
224
- private takeNextChar(): string {
225
- const text = this.input.substring(this.pos, this.pos + 1)
226
- this.pos += 1
227
-
228
- return text
229
- }
230
-
231
- private chunk(f: (str: string, pos: number) => TextChunk | undefined): TextChunk | undefined {
232
- const chunk = f(this.input, this.pos)
233
-
234
- if (chunk) {
235
- this.pos += chunk.length
236
- }
237
-
238
- return chunk
239
- }
240
-
241
- private pushTag(name: string): void {
242
- this.currentTag = new Stack(name, this.currentTag)
243
- }
244
-
245
- private popTag(): void {
246
- if (this.currentTag) {
247
- this.currentTag = this.currentTag.previous
248
- }
249
- }
250
-
251
- protected invalidTemplate() {
252
- let message = `Invalid template ${this.input}`
253
- message += "\n\nFrom:\n\n"
254
- message += this.input.substring(this.pos)
255
-
256
- throw new SyntaxError(message)
257
- }
258
- }
259
-
260
- class Stack<A> {
261
- constructor(
262
- readonly value: A,
263
- readonly previous: Stack<A> | null
264
- ) {}
265
- }
266
-
267
- function* parseTextAndParts(s: string): Generator<Token.TextToken | Token.PartToken> {
268
- let next: TextChunk | undefined
269
- let pos: number = 0
270
-
271
- while (pos < s.length) {
272
- if ((next = getPart(s, pos))) {
273
- yield new Token.PartToken(parseInt(next.match[2], 10))
274
- pos += next.length
275
- } else if ((next = getTextUntilPart(s, pos))) {
276
- yield new Token.TextToken(next.match[1])
277
-
278
- pos += next.length
279
- } else {
280
- yield new Token.TextToken(s.substring(pos))
281
-
282
- break
283
- }
284
- }
285
- }
286
-
287
- function getAttributeTokenPartial(name: string, ctx: "start" | "end") {
288
- switch (name[0]) {
289
- case "?":
290
- return ctx === "start"
291
- ? new Token.BooleanAttributeStartToken(name.substring(1))
292
- : new Token.BooleanAttributeEndToken(name.substring(1))
293
- case ".": {
294
- const propertyName = name.substring(1)
295
-
296
- switch (propertyName) {
297
- case "data":
298
- return ctx === "start"
299
- ? new Token.DataAttributeStartToken()
300
- : new Token.DataAttributeEndToken()
301
- default:
302
- return ctx === "start"
303
- ? new Token.PropertyAttributeStartToken(propertyName)
304
- : new Token.PropertyAttributeEndToken(propertyName)
305
- }
306
- }
307
- case "@":
308
- return ctx === "start"
309
- ? new Token.EventAttributeStartToken(name.substring(1))
310
- : new Token.EventAttributeEndToken(name.substring(1))
311
- case "o":
312
- if (name[1] === "n") {
313
- return ctx === "start"
314
- ? new Token.EventAttributeStartToken(name.substring(2))
315
- : new Token.EventAttributeEndToken(name.substring(2))
316
- }
317
- }
318
-
319
- switch (name.toLowerCase()) {
320
- case "class":
321
- case "classname":
322
- return ctx === "start"
323
- ? new Token.ClassNameAttributeStartToken()
324
- : new Token.ClassNameAttributeEndToken()
325
- case "ref":
326
- return ctx === "start" ? new Token.RefAttributeStartToken() : new Token.RefAttributeEndToken()
327
- }
328
-
329
- return ctx === "start" ? new Token.AttributeStartToken(name) : new Token.AttributeEndToken(name)
330
- }
331
-
332
- function getAttributeToken(name: string, value: string) {
333
- if (name[0] === "?") {
334
- return new Token.BooleanAttributeToken(name.substring(1))
335
- }
336
-
337
- return new Token.AttributeToken(name, value)
338
- }