playwright-ui5 1.5.0 → 1.6.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/README.md +100 -5
- package/dist/browser/css.js +1166 -0
- package/dist/browser/xpath.js +29155 -0
- package/dist/node/main.d.ts +14 -2
- package/dist/node/main.d.ts.map +1 -1
- package/dist/node/main.js +10 -4
- package/dist/node/main.js.map +1 -1
- package/package.json +19 -12
- package/src/node/main.ts +10 -4
- package/dist/browser/main.js +0 -1474
|
@@ -0,0 +1,1166 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __commonJS = (cb, mod) => function __require() {
|
|
9
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
10
|
+
};
|
|
11
|
+
var __export = (target, all) => {
|
|
12
|
+
for (var name in all)
|
|
13
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
14
|
+
};
|
|
15
|
+
var __copyProps = (to, from, except, desc) => {
|
|
16
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
17
|
+
for (let key of __getOwnPropNames(from))
|
|
18
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
19
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
20
|
+
}
|
|
21
|
+
return to;
|
|
22
|
+
};
|
|
23
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
24
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
25
|
+
mod
|
|
26
|
+
));
|
|
27
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
+
|
|
29
|
+
// node_modules/throw-expression/index.js
|
|
30
|
+
var require_throw_expression = __commonJS({
|
|
31
|
+
"node_modules/throw-expression/index.js"(exports) {
|
|
32
|
+
"use strict";
|
|
33
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
34
|
+
exports.throwIfFalsy = exports.throwIfUndefined = exports.throwIfNull = exports.Throw = void 0;
|
|
35
|
+
exports.Throw = function(error) {
|
|
36
|
+
if (typeof error === "string") {
|
|
37
|
+
throw new Error(error);
|
|
38
|
+
}
|
|
39
|
+
throw error;
|
|
40
|
+
};
|
|
41
|
+
exports.throwIfNull = function(value, error) {
|
|
42
|
+
if (error === void 0) {
|
|
43
|
+
error = "value is null";
|
|
44
|
+
}
|
|
45
|
+
return value === null ? exports.Throw(error) : value;
|
|
46
|
+
};
|
|
47
|
+
exports.throwIfUndefined = function(value, error) {
|
|
48
|
+
if (error === void 0) {
|
|
49
|
+
error = "value is undefined";
|
|
50
|
+
}
|
|
51
|
+
return value === void 0 ? exports.Throw(error) : value;
|
|
52
|
+
};
|
|
53
|
+
exports.throwIfFalsy = function(value, error) {
|
|
54
|
+
if (error === void 0) {
|
|
55
|
+
error = "value is undefined";
|
|
56
|
+
}
|
|
57
|
+
return value === void 0 || value === null ? exports.Throw(error) : value;
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
// src/browser/css.ts
|
|
63
|
+
var css_exports = {};
|
|
64
|
+
__export(css_exports, {
|
|
65
|
+
default: () => css_default
|
|
66
|
+
});
|
|
67
|
+
module.exports = __toCommonJS(css_exports);
|
|
68
|
+
|
|
69
|
+
// src/browser/common.ts
|
|
70
|
+
var isUi5 = () => typeof sap !== "undefined" && typeof sap.ui !== "undefined";
|
|
71
|
+
var Ui5SelectorEngineError = class extends Error {
|
|
72
|
+
constructor(selector, error) {
|
|
73
|
+
super(`ui5 selector engine failed on selector: "${selector}"
|
|
74
|
+
|
|
75
|
+
${String(error)}`);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
// node_modules/css-selector-parser/dist/mjs/indexes.js
|
|
80
|
+
var emptyMulticharIndex = {};
|
|
81
|
+
var emptyRegularIndex = {};
|
|
82
|
+
function extendIndex(item, index) {
|
|
83
|
+
let currentIndex = index;
|
|
84
|
+
for (let pos = 0; pos < item.length; pos++) {
|
|
85
|
+
const isLast = pos === item.length - 1;
|
|
86
|
+
const char = item.charAt(pos);
|
|
87
|
+
const charIndex = currentIndex[char] || (currentIndex[char] = { chars: {} });
|
|
88
|
+
if (isLast) {
|
|
89
|
+
charIndex.self = item;
|
|
90
|
+
}
|
|
91
|
+
currentIndex = charIndex.chars;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
function createMulticharIndex(items) {
|
|
95
|
+
if (items.length === 0) {
|
|
96
|
+
return emptyMulticharIndex;
|
|
97
|
+
}
|
|
98
|
+
const index = {};
|
|
99
|
+
for (const item of items) {
|
|
100
|
+
extendIndex(item, index);
|
|
101
|
+
}
|
|
102
|
+
return index;
|
|
103
|
+
}
|
|
104
|
+
function createRegularIndex(items) {
|
|
105
|
+
if (items.length === 0) {
|
|
106
|
+
return emptyRegularIndex;
|
|
107
|
+
}
|
|
108
|
+
const result = {};
|
|
109
|
+
for (const item of items) {
|
|
110
|
+
result[item] = true;
|
|
111
|
+
}
|
|
112
|
+
return result;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// node_modules/css-selector-parser/dist/mjs/pseudo-class-signatures.js
|
|
116
|
+
var emptyPseudoClassSignatures = {};
|
|
117
|
+
var defaultPseudoClassSignature = {
|
|
118
|
+
type: "String",
|
|
119
|
+
optional: true
|
|
120
|
+
};
|
|
121
|
+
function calculatePseudoClassSignature(types) {
|
|
122
|
+
const result = {
|
|
123
|
+
optional: false
|
|
124
|
+
};
|
|
125
|
+
function setResultType(type) {
|
|
126
|
+
if (result.type && result.type !== type) {
|
|
127
|
+
throw new Error(`Conflicting pseudo-class argument type: "${result.type}" vs "${type}".`);
|
|
128
|
+
}
|
|
129
|
+
result.type = type;
|
|
130
|
+
}
|
|
131
|
+
for (const type of types) {
|
|
132
|
+
if (type === "NoArgument") {
|
|
133
|
+
result.optional = true;
|
|
134
|
+
}
|
|
135
|
+
if (type === "Formula") {
|
|
136
|
+
setResultType("Formula");
|
|
137
|
+
}
|
|
138
|
+
if (type === "FormulaOfSelector") {
|
|
139
|
+
setResultType("Formula");
|
|
140
|
+
result.ofSelector = true;
|
|
141
|
+
}
|
|
142
|
+
if (type === "String") {
|
|
143
|
+
setResultType("String");
|
|
144
|
+
}
|
|
145
|
+
if (type === "Selector") {
|
|
146
|
+
setResultType("Selector");
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return result;
|
|
150
|
+
}
|
|
151
|
+
function inverseCategories(obj) {
|
|
152
|
+
const result = {};
|
|
153
|
+
for (const category of Object.keys(obj)) {
|
|
154
|
+
const items = obj[category];
|
|
155
|
+
if (items) {
|
|
156
|
+
for (const item of items) {
|
|
157
|
+
(result[item] || (result[item] = [])).push(category);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return result;
|
|
162
|
+
}
|
|
163
|
+
function calculatePseudoClassSignatures(definitions) {
|
|
164
|
+
const pseudoClassesToArgumentTypes = inverseCategories(definitions);
|
|
165
|
+
const result = {};
|
|
166
|
+
for (const pseudoClass of Object.keys(pseudoClassesToArgumentTypes)) {
|
|
167
|
+
const argumentTypes = pseudoClassesToArgumentTypes[pseudoClass];
|
|
168
|
+
if (argumentTypes) {
|
|
169
|
+
result[pseudoClass] = calculatePseudoClassSignature(argumentTypes);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return result;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// node_modules/css-selector-parser/dist/mjs/syntax-definitions.js
|
|
176
|
+
var emptyXmlOptions = {};
|
|
177
|
+
var defaultXmlOptions = { wildcard: true };
|
|
178
|
+
function getXmlOptions(param) {
|
|
179
|
+
if (param) {
|
|
180
|
+
if (typeof param === "boolean") {
|
|
181
|
+
return defaultXmlOptions;
|
|
182
|
+
} else {
|
|
183
|
+
return param;
|
|
184
|
+
}
|
|
185
|
+
} else {
|
|
186
|
+
return emptyXmlOptions;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
function extendSyntaxDefinition(base, extension) {
|
|
190
|
+
const result = { ...base };
|
|
191
|
+
if ("tag" in extension) {
|
|
192
|
+
if (extension.tag) {
|
|
193
|
+
result.tag = { ...getXmlOptions(base.tag) };
|
|
194
|
+
const extensionOptions = getXmlOptions(extension.tag);
|
|
195
|
+
if ("wildcard" in extensionOptions) {
|
|
196
|
+
result.tag.wildcard = extensionOptions.wildcard;
|
|
197
|
+
}
|
|
198
|
+
} else {
|
|
199
|
+
result.tag = void 0;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
if ("ids" in extension) {
|
|
203
|
+
result.ids = extension.ids;
|
|
204
|
+
}
|
|
205
|
+
if ("classNames" in extension) {
|
|
206
|
+
result.classNames = extension.classNames;
|
|
207
|
+
}
|
|
208
|
+
if ("namespace" in extension) {
|
|
209
|
+
if (extension.namespace) {
|
|
210
|
+
result.namespace = { ...getXmlOptions(base.namespace) };
|
|
211
|
+
const extensionOptions = getXmlOptions(extension.namespace);
|
|
212
|
+
if ("wildcard" in extensionOptions) {
|
|
213
|
+
result.namespace.wildcard = extensionOptions.wildcard;
|
|
214
|
+
}
|
|
215
|
+
} else {
|
|
216
|
+
result.namespace = void 0;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
if ("combinators" in extension) {
|
|
220
|
+
if (extension.combinators) {
|
|
221
|
+
result.combinators = result.combinators ? result.combinators.concat(extension.combinators) : extension.combinators;
|
|
222
|
+
} else {
|
|
223
|
+
result.combinators = void 0;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
if ("attributes" in extension) {
|
|
227
|
+
if (extension.attributes) {
|
|
228
|
+
result.attributes = { ...base.attributes };
|
|
229
|
+
if ("unknownCaseSensitivityModifiers" in extension.attributes) {
|
|
230
|
+
result.attributes.unknownCaseSensitivityModifiers = extension.attributes.unknownCaseSensitivityModifiers;
|
|
231
|
+
}
|
|
232
|
+
if ("operators" in extension.attributes) {
|
|
233
|
+
result.attributes.operators = extension.attributes.operators ? result.attributes.operators ? result.attributes.operators.concat(extension.attributes.operators) : extension.attributes.operators : void 0;
|
|
234
|
+
}
|
|
235
|
+
if ("caseSensitivityModifiers" in extension.attributes) {
|
|
236
|
+
result.attributes.caseSensitivityModifiers = extension.attributes.caseSensitivityModifiers ? result.attributes.caseSensitivityModifiers ? result.attributes.caseSensitivityModifiers.concat(extension.attributes.caseSensitivityModifiers) : extension.attributes.caseSensitivityModifiers : void 0;
|
|
237
|
+
}
|
|
238
|
+
} else {
|
|
239
|
+
result.attributes = void 0;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
if ("pseudoElements" in extension) {
|
|
243
|
+
if (extension.pseudoElements) {
|
|
244
|
+
result.pseudoElements = { ...base.pseudoElements };
|
|
245
|
+
if ("unknown" in extension.pseudoElements) {
|
|
246
|
+
result.pseudoElements.unknown = extension.pseudoElements.unknown;
|
|
247
|
+
}
|
|
248
|
+
if ("notation" in extension.pseudoElements) {
|
|
249
|
+
result.pseudoElements.notation = extension.pseudoElements.notation;
|
|
250
|
+
}
|
|
251
|
+
if ("definitions" in extension.pseudoElements) {
|
|
252
|
+
result.pseudoElements.definitions = extension.pseudoElements.definitions ? result.pseudoElements.definitions ? result.pseudoElements.definitions.concat(extension.pseudoElements.definitions) : extension.pseudoElements.definitions : void 0;
|
|
253
|
+
}
|
|
254
|
+
} else {
|
|
255
|
+
result.pseudoElements = void 0;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
if ("pseudoClasses" in extension) {
|
|
259
|
+
if (extension.pseudoClasses) {
|
|
260
|
+
result.pseudoClasses = { ...base.pseudoClasses };
|
|
261
|
+
if ("unknown" in extension.pseudoClasses) {
|
|
262
|
+
result.pseudoClasses.unknown = extension.pseudoClasses.unknown;
|
|
263
|
+
}
|
|
264
|
+
if ("definitions" in extension.pseudoClasses) {
|
|
265
|
+
const newDefinitions = extension.pseudoClasses.definitions;
|
|
266
|
+
if (newDefinitions) {
|
|
267
|
+
result.pseudoClasses.definitions = {
|
|
268
|
+
...result.pseudoClasses.definitions
|
|
269
|
+
};
|
|
270
|
+
const existingDefinitions = result.pseudoClasses.definitions;
|
|
271
|
+
for (const key of Object.keys(newDefinitions)) {
|
|
272
|
+
const newDefinitionForNotation = newDefinitions[key];
|
|
273
|
+
const existingDefinitionForNotation = existingDefinitions[key];
|
|
274
|
+
if (newDefinitionForNotation) {
|
|
275
|
+
existingDefinitions[key] = existingDefinitionForNotation ? existingDefinitionForNotation.concat(newDefinitionForNotation) : newDefinitionForNotation;
|
|
276
|
+
} else {
|
|
277
|
+
existingDefinitions[key] = void 0;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
} else {
|
|
281
|
+
result.pseudoClasses.definitions = void 0;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
} else {
|
|
285
|
+
result.pseudoClasses = void 0;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
return result;
|
|
289
|
+
}
|
|
290
|
+
var css1SyntaxDefinition = {
|
|
291
|
+
tag: {},
|
|
292
|
+
ids: true,
|
|
293
|
+
classNames: true,
|
|
294
|
+
combinators: [],
|
|
295
|
+
pseudoElements: {
|
|
296
|
+
unknown: "reject",
|
|
297
|
+
notation: "singleColon",
|
|
298
|
+
definitions: ["first-letter", "first-line"]
|
|
299
|
+
},
|
|
300
|
+
pseudoClasses: {
|
|
301
|
+
unknown: "reject",
|
|
302
|
+
definitions: {
|
|
303
|
+
NoArgument: ["link", "visited", "active"]
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
};
|
|
307
|
+
var css2SyntaxDefinition = extendSyntaxDefinition(css1SyntaxDefinition, {
|
|
308
|
+
tag: { wildcard: true },
|
|
309
|
+
combinators: [">", "+"],
|
|
310
|
+
attributes: {
|
|
311
|
+
unknownCaseSensitivityModifiers: "reject",
|
|
312
|
+
operators: ["=", "~=", "|="]
|
|
313
|
+
},
|
|
314
|
+
pseudoElements: {
|
|
315
|
+
definitions: ["before", "after"]
|
|
316
|
+
},
|
|
317
|
+
pseudoClasses: {
|
|
318
|
+
unknown: "reject",
|
|
319
|
+
definitions: {
|
|
320
|
+
NoArgument: ["hover", "focus", "first-child"],
|
|
321
|
+
String: ["lang"]
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
});
|
|
325
|
+
var selectors3SyntaxDefinition = extendSyntaxDefinition(css2SyntaxDefinition, {
|
|
326
|
+
namespace: {
|
|
327
|
+
wildcard: true
|
|
328
|
+
},
|
|
329
|
+
combinators: ["~"],
|
|
330
|
+
attributes: {
|
|
331
|
+
operators: ["^=", "$=", "*="]
|
|
332
|
+
},
|
|
333
|
+
pseudoElements: {
|
|
334
|
+
notation: "both"
|
|
335
|
+
},
|
|
336
|
+
pseudoClasses: {
|
|
337
|
+
definitions: {
|
|
338
|
+
NoArgument: [
|
|
339
|
+
"root",
|
|
340
|
+
"last-child",
|
|
341
|
+
"first-of-type",
|
|
342
|
+
"last-of-type",
|
|
343
|
+
"only-child",
|
|
344
|
+
"only-of-type",
|
|
345
|
+
"empty",
|
|
346
|
+
"target",
|
|
347
|
+
"enabled",
|
|
348
|
+
"disabled",
|
|
349
|
+
"checked",
|
|
350
|
+
"indeterminate"
|
|
351
|
+
],
|
|
352
|
+
Formula: ["nth-child", "nth-last-child", "nth-of-type", "nth-last-of-type"],
|
|
353
|
+
Selector: ["not"]
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
});
|
|
357
|
+
var selectors4SyntaxDefinition = extendSyntaxDefinition(selectors3SyntaxDefinition, {
|
|
358
|
+
combinators: ["||"],
|
|
359
|
+
attributes: {
|
|
360
|
+
caseSensitivityModifiers: ["i", "I", "s", "S"]
|
|
361
|
+
},
|
|
362
|
+
pseudoClasses: {
|
|
363
|
+
definitions: {
|
|
364
|
+
NoArgument: [
|
|
365
|
+
"any-link",
|
|
366
|
+
"local-link",
|
|
367
|
+
"target-within",
|
|
368
|
+
"scope",
|
|
369
|
+
"current",
|
|
370
|
+
"past",
|
|
371
|
+
"future",
|
|
372
|
+
"focus-within",
|
|
373
|
+
"focus-visible",
|
|
374
|
+
"read-write",
|
|
375
|
+
"read-only",
|
|
376
|
+
"placeholder-shown",
|
|
377
|
+
"default",
|
|
378
|
+
"valid",
|
|
379
|
+
"invalid",
|
|
380
|
+
"in-range",
|
|
381
|
+
"out-of-range",
|
|
382
|
+
"required",
|
|
383
|
+
"optional",
|
|
384
|
+
"blank",
|
|
385
|
+
"user-invalid"
|
|
386
|
+
],
|
|
387
|
+
Formula: ["nth-col", "nth-last-col"],
|
|
388
|
+
String: ["dir"],
|
|
389
|
+
FormulaOfSelector: ["nth-child", "nth-last-child"],
|
|
390
|
+
Selector: ["current", "is", "where", "has"]
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
});
|
|
394
|
+
var progressiveSyntaxDefinition = extendSyntaxDefinition(selectors4SyntaxDefinition, {
|
|
395
|
+
pseudoElements: {
|
|
396
|
+
unknown: "accept"
|
|
397
|
+
},
|
|
398
|
+
pseudoClasses: {
|
|
399
|
+
unknown: "accept"
|
|
400
|
+
},
|
|
401
|
+
attributes: {
|
|
402
|
+
unknownCaseSensitivityModifiers: "accept"
|
|
403
|
+
}
|
|
404
|
+
});
|
|
405
|
+
var cssSyntaxDefinitions = {
|
|
406
|
+
css1: css1SyntaxDefinition,
|
|
407
|
+
css2: css2SyntaxDefinition,
|
|
408
|
+
css3: selectors3SyntaxDefinition,
|
|
409
|
+
"selectors-3": selectors3SyntaxDefinition,
|
|
410
|
+
"selectors-4": selectors4SyntaxDefinition,
|
|
411
|
+
latest: selectors4SyntaxDefinition,
|
|
412
|
+
progressive: progressiveSyntaxDefinition
|
|
413
|
+
};
|
|
414
|
+
|
|
415
|
+
// node_modules/css-selector-parser/dist/mjs/utils.js
|
|
416
|
+
function isIdentStart(c) {
|
|
417
|
+
return c >= "a" && c <= "z" || c >= "A" && c <= "Z" || c === "-" || c === "_";
|
|
418
|
+
}
|
|
419
|
+
function isIdent(c) {
|
|
420
|
+
return c >= "a" && c <= "z" || c >= "A" && c <= "Z" || c >= "0" && c <= "9" || c === "-" || c === "_";
|
|
421
|
+
}
|
|
422
|
+
function isHex(c) {
|
|
423
|
+
return c >= "a" && c <= "f" || c >= "A" && c <= "F" || c >= "0" && c <= "9";
|
|
424
|
+
}
|
|
425
|
+
var stringEscapeChars = {
|
|
426
|
+
n: "\n",
|
|
427
|
+
r: "\r",
|
|
428
|
+
t: " ",
|
|
429
|
+
f: "\f",
|
|
430
|
+
"\\": "\\"
|
|
431
|
+
};
|
|
432
|
+
var whitespaceChars = {
|
|
433
|
+
" ": true,
|
|
434
|
+
" ": true,
|
|
435
|
+
"\n": true,
|
|
436
|
+
"\r": true,
|
|
437
|
+
"\f": true
|
|
438
|
+
};
|
|
439
|
+
var quoteChars = {
|
|
440
|
+
'"': true,
|
|
441
|
+
"'": true
|
|
442
|
+
};
|
|
443
|
+
var digitsChars = {
|
|
444
|
+
0: true,
|
|
445
|
+
1: true,
|
|
446
|
+
2: true,
|
|
447
|
+
3: true,
|
|
448
|
+
4: true,
|
|
449
|
+
5: true,
|
|
450
|
+
6: true,
|
|
451
|
+
7: true,
|
|
452
|
+
8: true,
|
|
453
|
+
9: true
|
|
454
|
+
};
|
|
455
|
+
|
|
456
|
+
// node_modules/css-selector-parser/dist/mjs/parser.js
|
|
457
|
+
var errorPrefix = `css-selector-parser parse error: `;
|
|
458
|
+
function createParser(options = {}) {
|
|
459
|
+
const { syntax = "latest", substitutes, strict = true } = options;
|
|
460
|
+
let syntaxDefinition = typeof syntax === "string" ? cssSyntaxDefinitions[syntax] : syntax;
|
|
461
|
+
if (syntaxDefinition.baseSyntax) {
|
|
462
|
+
syntaxDefinition = extendSyntaxDefinition(cssSyntaxDefinitions[syntaxDefinition.baseSyntax], syntaxDefinition);
|
|
463
|
+
}
|
|
464
|
+
const [tagNameEnabled, tagNameWildcardEnabled] = syntaxDefinition.tag ? [true, Boolean(getXmlOptions(syntaxDefinition.tag).wildcard)] : [false, false];
|
|
465
|
+
const idEnabled = Boolean(syntaxDefinition.ids);
|
|
466
|
+
const classNamesEnabled = Boolean(syntaxDefinition.classNames);
|
|
467
|
+
const namespaceEnabled = Boolean(syntaxDefinition.namespace);
|
|
468
|
+
const namespaceWildcardEnabled = syntaxDefinition.namespace && (syntaxDefinition.namespace === true || syntaxDefinition.namespace.wildcard === true);
|
|
469
|
+
if (namespaceEnabled && !tagNameEnabled) {
|
|
470
|
+
throw new Error(`${errorPrefix}Namespaces cannot be enabled while tags are disabled.`);
|
|
471
|
+
}
|
|
472
|
+
const substitutesEnabled = Boolean(substitutes);
|
|
473
|
+
const combinatorsIndex = syntaxDefinition.combinators ? createMulticharIndex(syntaxDefinition.combinators) : emptyMulticharIndex;
|
|
474
|
+
const [attributesEnabled, attributesOperatorsIndex, attributesCaseSensitivityModifiers, attributesAcceptUnknownCaseSensitivityModifiers] = syntaxDefinition.attributes ? [
|
|
475
|
+
true,
|
|
476
|
+
syntaxDefinition.attributes.operators ? createMulticharIndex(syntaxDefinition.attributes.operators) : emptyMulticharIndex,
|
|
477
|
+
syntaxDefinition.attributes.caseSensitivityModifiers ? createRegularIndex(syntaxDefinition.attributes.caseSensitivityModifiers) : emptyRegularIndex,
|
|
478
|
+
syntaxDefinition.attributes.unknownCaseSensitivityModifiers === "accept"
|
|
479
|
+
] : [false, emptyMulticharIndex, emptyRegularIndex, false];
|
|
480
|
+
const attributesCaseSensitivityModifiersEnabled = attributesAcceptUnknownCaseSensitivityModifiers || Object.keys(attributesCaseSensitivityModifiers).length > 0;
|
|
481
|
+
const [pseudoClassesEnabled, paeudoClassesDefinitions, pseudoClassesAcceptUnknown] = syntaxDefinition.pseudoClasses ? [
|
|
482
|
+
true,
|
|
483
|
+
syntaxDefinition.pseudoClasses.definitions ? calculatePseudoClassSignatures(syntaxDefinition.pseudoClasses.definitions) : emptyPseudoClassSignatures,
|
|
484
|
+
syntaxDefinition.pseudoClasses.unknown === "accept"
|
|
485
|
+
] : [false, emptyPseudoClassSignatures, false];
|
|
486
|
+
const [pseudoElementsEnabled, pseudoElementsSingleColonNotationEnabled, pseudoElementsDoubleColonNotationEnabled, pseudoElementsIndex, pseudoElementsAcceptUnknown] = syntaxDefinition.pseudoElements ? [
|
|
487
|
+
true,
|
|
488
|
+
syntaxDefinition.pseudoElements.notation === "singleColon" || syntaxDefinition.pseudoElements.notation === "both",
|
|
489
|
+
!syntaxDefinition.pseudoElements.notation || syntaxDefinition.pseudoElements.notation === "doubleColon" || syntaxDefinition.pseudoElements.notation === "both",
|
|
490
|
+
syntaxDefinition.pseudoElements.definitions ? createRegularIndex(syntaxDefinition.pseudoElements.definitions) : emptyRegularIndex,
|
|
491
|
+
syntaxDefinition.pseudoElements.unknown === "accept"
|
|
492
|
+
] : [false, false, false, emptyRegularIndex, false];
|
|
493
|
+
let str = "";
|
|
494
|
+
let l = str.length;
|
|
495
|
+
let pos = 0;
|
|
496
|
+
let chr = "";
|
|
497
|
+
const is = (comparison) => chr === comparison;
|
|
498
|
+
const isTagStart = () => is("*") || isIdentStart(chr) || is("\\");
|
|
499
|
+
const rewind = (newPos) => {
|
|
500
|
+
pos = newPos;
|
|
501
|
+
chr = str.charAt(pos);
|
|
502
|
+
};
|
|
503
|
+
const next = () => {
|
|
504
|
+
pos++;
|
|
505
|
+
chr = str.charAt(pos);
|
|
506
|
+
};
|
|
507
|
+
const readAndNext = () => {
|
|
508
|
+
const current = chr;
|
|
509
|
+
pos++;
|
|
510
|
+
chr = str.charAt(pos);
|
|
511
|
+
return current;
|
|
512
|
+
};
|
|
513
|
+
function fail(errorMessage) {
|
|
514
|
+
const position = Math.min(l - 1, pos);
|
|
515
|
+
const error = new Error(`${errorPrefix}${errorMessage} Pos: ${position}.`);
|
|
516
|
+
error.position = position;
|
|
517
|
+
error.name = "ParserError";
|
|
518
|
+
throw error;
|
|
519
|
+
}
|
|
520
|
+
function assert(condition, errorMessage) {
|
|
521
|
+
if (!condition) {
|
|
522
|
+
return fail(errorMessage);
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
const assertNonEof = () => {
|
|
526
|
+
assert(pos < l, "Unexpected end of input.");
|
|
527
|
+
};
|
|
528
|
+
const isEof = () => pos >= l;
|
|
529
|
+
const pass = (character) => {
|
|
530
|
+
assert(pos < l, `Expected "${character}" but end of input reached.`);
|
|
531
|
+
assert(chr === character, `Expected "${character}" but "${chr}" found.`);
|
|
532
|
+
pos++;
|
|
533
|
+
chr = str.charAt(pos);
|
|
534
|
+
};
|
|
535
|
+
function matchMulticharIndex(index) {
|
|
536
|
+
const match = matchMulticharIndexPos(index, pos);
|
|
537
|
+
if (match) {
|
|
538
|
+
pos += match.length;
|
|
539
|
+
chr = str.charAt(pos);
|
|
540
|
+
return match;
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
function matchMulticharIndexPos(index, subPos) {
|
|
544
|
+
const char = str.charAt(subPos);
|
|
545
|
+
const charIndex = index[char];
|
|
546
|
+
if (charIndex) {
|
|
547
|
+
const subMatch = matchMulticharIndexPos(charIndex.chars, subPos + 1);
|
|
548
|
+
if (subMatch) {
|
|
549
|
+
return subMatch;
|
|
550
|
+
}
|
|
551
|
+
if (charIndex.self) {
|
|
552
|
+
return charIndex.self;
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
function parseHex() {
|
|
557
|
+
let hex = readAndNext();
|
|
558
|
+
while (isHex(chr)) {
|
|
559
|
+
hex += readAndNext();
|
|
560
|
+
}
|
|
561
|
+
if (is(" ")) {
|
|
562
|
+
next();
|
|
563
|
+
}
|
|
564
|
+
return String.fromCharCode(parseInt(hex, 16));
|
|
565
|
+
}
|
|
566
|
+
function parseString(quote) {
|
|
567
|
+
let result = "";
|
|
568
|
+
pass(quote);
|
|
569
|
+
while (pos < l) {
|
|
570
|
+
if (is(quote)) {
|
|
571
|
+
next();
|
|
572
|
+
return result;
|
|
573
|
+
} else if (is("\\")) {
|
|
574
|
+
next();
|
|
575
|
+
let esc;
|
|
576
|
+
if (is(quote)) {
|
|
577
|
+
result += quote;
|
|
578
|
+
} else if ((esc = stringEscapeChars[chr]) !== void 0) {
|
|
579
|
+
result += esc;
|
|
580
|
+
} else if (isHex(chr)) {
|
|
581
|
+
result += parseHex();
|
|
582
|
+
continue;
|
|
583
|
+
} else {
|
|
584
|
+
result += chr;
|
|
585
|
+
}
|
|
586
|
+
} else {
|
|
587
|
+
result += chr;
|
|
588
|
+
}
|
|
589
|
+
next();
|
|
590
|
+
}
|
|
591
|
+
return result;
|
|
592
|
+
}
|
|
593
|
+
function parseIdentifier() {
|
|
594
|
+
let result = "";
|
|
595
|
+
while (pos < l) {
|
|
596
|
+
if (isIdent(chr)) {
|
|
597
|
+
result += readAndNext();
|
|
598
|
+
} else if (is("\\")) {
|
|
599
|
+
next();
|
|
600
|
+
assertNonEof();
|
|
601
|
+
if (isHex(chr)) {
|
|
602
|
+
result += parseHex();
|
|
603
|
+
} else {
|
|
604
|
+
result += readAndNext();
|
|
605
|
+
}
|
|
606
|
+
} else {
|
|
607
|
+
return result;
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
return result;
|
|
611
|
+
}
|
|
612
|
+
function parsePseudoClassString() {
|
|
613
|
+
let result = "";
|
|
614
|
+
while (pos < l) {
|
|
615
|
+
if (is(")")) {
|
|
616
|
+
break;
|
|
617
|
+
} else if (is("\\")) {
|
|
618
|
+
next();
|
|
619
|
+
if (isEof() && !strict) {
|
|
620
|
+
return (result + "\\").trim();
|
|
621
|
+
}
|
|
622
|
+
assertNonEof();
|
|
623
|
+
if (isHex(chr)) {
|
|
624
|
+
result += parseHex();
|
|
625
|
+
} else {
|
|
626
|
+
result += readAndNext();
|
|
627
|
+
}
|
|
628
|
+
} else {
|
|
629
|
+
result += readAndNext();
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
return result.trim();
|
|
633
|
+
}
|
|
634
|
+
function skipWhitespace() {
|
|
635
|
+
while (whitespaceChars[chr]) {
|
|
636
|
+
next();
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
function parseSelector2(relative = false) {
|
|
640
|
+
skipWhitespace();
|
|
641
|
+
const rules = [parseRule(relative)];
|
|
642
|
+
while (is(",")) {
|
|
643
|
+
next();
|
|
644
|
+
skipWhitespace();
|
|
645
|
+
rules.push(parseRule(relative));
|
|
646
|
+
}
|
|
647
|
+
return {
|
|
648
|
+
type: "Selector",
|
|
649
|
+
rules
|
|
650
|
+
};
|
|
651
|
+
}
|
|
652
|
+
function parseAttribute() {
|
|
653
|
+
pass("[");
|
|
654
|
+
skipWhitespace();
|
|
655
|
+
let attr;
|
|
656
|
+
if (is("|")) {
|
|
657
|
+
assert(namespaceEnabled, "Namespaces are not enabled.");
|
|
658
|
+
next();
|
|
659
|
+
attr = {
|
|
660
|
+
type: "Attribute",
|
|
661
|
+
name: parseIdentifier(),
|
|
662
|
+
namespace: { type: "NoNamespace" }
|
|
663
|
+
};
|
|
664
|
+
} else if (is("*")) {
|
|
665
|
+
assert(namespaceEnabled, "Namespaces are not enabled.");
|
|
666
|
+
assert(namespaceWildcardEnabled, "Wildcard namespace is not enabled.");
|
|
667
|
+
next();
|
|
668
|
+
pass("|");
|
|
669
|
+
attr = {
|
|
670
|
+
type: "Attribute",
|
|
671
|
+
name: parseIdentifier(),
|
|
672
|
+
namespace: { type: "WildcardNamespace" }
|
|
673
|
+
};
|
|
674
|
+
} else {
|
|
675
|
+
const identifier = parseIdentifier();
|
|
676
|
+
attr = {
|
|
677
|
+
type: "Attribute",
|
|
678
|
+
name: identifier
|
|
679
|
+
};
|
|
680
|
+
if (is("|")) {
|
|
681
|
+
const savedPos = pos;
|
|
682
|
+
next();
|
|
683
|
+
if (isIdentStart(chr) || is("\\")) {
|
|
684
|
+
assert(namespaceEnabled, "Namespaces are not enabled.");
|
|
685
|
+
attr = {
|
|
686
|
+
type: "Attribute",
|
|
687
|
+
name: parseIdentifier(),
|
|
688
|
+
namespace: { type: "NamespaceName", name: identifier }
|
|
689
|
+
};
|
|
690
|
+
} else {
|
|
691
|
+
rewind(savedPos);
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
assert(attr.name, "Expected attribute name.");
|
|
696
|
+
skipWhitespace();
|
|
697
|
+
if (isEof() && !strict) {
|
|
698
|
+
return attr;
|
|
699
|
+
}
|
|
700
|
+
if (is("]")) {
|
|
701
|
+
next();
|
|
702
|
+
} else {
|
|
703
|
+
attr.operator = matchMulticharIndex(attributesOperatorsIndex);
|
|
704
|
+
assert(attr.operator, "Expected a valid attribute selector operator.");
|
|
705
|
+
skipWhitespace();
|
|
706
|
+
assertNonEof();
|
|
707
|
+
if (quoteChars[chr]) {
|
|
708
|
+
attr.value = {
|
|
709
|
+
type: "String",
|
|
710
|
+
value: parseString(chr)
|
|
711
|
+
};
|
|
712
|
+
} else if (substitutesEnabled && is("$")) {
|
|
713
|
+
next();
|
|
714
|
+
attr.value = {
|
|
715
|
+
type: "Substitution",
|
|
716
|
+
name: parseIdentifier()
|
|
717
|
+
};
|
|
718
|
+
assert(attr.value.name, "Expected substitute name.");
|
|
719
|
+
} else {
|
|
720
|
+
attr.value = {
|
|
721
|
+
type: "String",
|
|
722
|
+
value: parseIdentifier()
|
|
723
|
+
};
|
|
724
|
+
assert(attr.value.value, "Expected attribute value.");
|
|
725
|
+
}
|
|
726
|
+
skipWhitespace();
|
|
727
|
+
if (isEof() && !strict) {
|
|
728
|
+
return attr;
|
|
729
|
+
}
|
|
730
|
+
if (!is("]")) {
|
|
731
|
+
attr.caseSensitivityModifier = parseIdentifier();
|
|
732
|
+
assert(attr.caseSensitivityModifier, "Expected end of attribute selector.");
|
|
733
|
+
assert(attributesCaseSensitivityModifiersEnabled, "Attribute case sensitivity modifiers are not enabled.");
|
|
734
|
+
assert(attributesAcceptUnknownCaseSensitivityModifiers || attributesCaseSensitivityModifiers[attr.caseSensitivityModifier], "Unknown attribute case sensitivity modifier.");
|
|
735
|
+
skipWhitespace();
|
|
736
|
+
if (isEof() && !strict) {
|
|
737
|
+
return attr;
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
pass("]");
|
|
741
|
+
}
|
|
742
|
+
return attr;
|
|
743
|
+
}
|
|
744
|
+
function parseNumber() {
|
|
745
|
+
let result = "";
|
|
746
|
+
while (digitsChars[chr]) {
|
|
747
|
+
result += readAndNext();
|
|
748
|
+
}
|
|
749
|
+
assert(result !== "", "Formula parse error.");
|
|
750
|
+
return parseInt(result);
|
|
751
|
+
}
|
|
752
|
+
const isNumberStart = () => is("-") || is("+") || digitsChars[chr];
|
|
753
|
+
function parseFormula() {
|
|
754
|
+
if (is("e") || is("o")) {
|
|
755
|
+
const ident = parseIdentifier();
|
|
756
|
+
if (ident === "even") {
|
|
757
|
+
skipWhitespace();
|
|
758
|
+
return [2, 0];
|
|
759
|
+
}
|
|
760
|
+
if (ident === "odd") {
|
|
761
|
+
skipWhitespace();
|
|
762
|
+
return [2, 1];
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
let firstNumber = null;
|
|
766
|
+
let firstNumberMultiplier = 1;
|
|
767
|
+
if (is("-")) {
|
|
768
|
+
next();
|
|
769
|
+
firstNumberMultiplier = -1;
|
|
770
|
+
}
|
|
771
|
+
if (isNumberStart()) {
|
|
772
|
+
if (is("+")) {
|
|
773
|
+
next();
|
|
774
|
+
}
|
|
775
|
+
firstNumber = parseNumber();
|
|
776
|
+
if (!is("\\") && !is("n")) {
|
|
777
|
+
return [0, firstNumber * firstNumberMultiplier];
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
if (firstNumber === null) {
|
|
781
|
+
firstNumber = 1;
|
|
782
|
+
}
|
|
783
|
+
firstNumber *= firstNumberMultiplier;
|
|
784
|
+
let identifier;
|
|
785
|
+
if (is("\\")) {
|
|
786
|
+
next();
|
|
787
|
+
if (isHex(chr)) {
|
|
788
|
+
identifier = parseHex();
|
|
789
|
+
} else {
|
|
790
|
+
identifier = readAndNext();
|
|
791
|
+
}
|
|
792
|
+
} else {
|
|
793
|
+
identifier = readAndNext();
|
|
794
|
+
}
|
|
795
|
+
assert(identifier === "n", 'Formula parse error: expected "n".');
|
|
796
|
+
skipWhitespace();
|
|
797
|
+
if (is("+") || is("-")) {
|
|
798
|
+
const sign = is("+") ? 1 : -1;
|
|
799
|
+
next();
|
|
800
|
+
skipWhitespace();
|
|
801
|
+
return [firstNumber, sign * parseNumber()];
|
|
802
|
+
} else {
|
|
803
|
+
return [firstNumber, 0];
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
function parsePseudoClass(pseudoName) {
|
|
807
|
+
const pseudo = {
|
|
808
|
+
type: "PseudoClass",
|
|
809
|
+
name: pseudoName
|
|
810
|
+
};
|
|
811
|
+
let pseudoDefinition = paeudoClassesDefinitions[pseudoName];
|
|
812
|
+
if (!pseudoDefinition && pseudoClassesAcceptUnknown) {
|
|
813
|
+
pseudoDefinition = defaultPseudoClassSignature;
|
|
814
|
+
}
|
|
815
|
+
assert(pseudoDefinition, `Unknown pseudo-class: "${pseudoName}".`);
|
|
816
|
+
pseudoDefinition = pseudoDefinition;
|
|
817
|
+
if (is("(")) {
|
|
818
|
+
next();
|
|
819
|
+
skipWhitespace();
|
|
820
|
+
if (substitutesEnabled && is("$")) {
|
|
821
|
+
next();
|
|
822
|
+
pseudo.argument = {
|
|
823
|
+
type: "Substitution",
|
|
824
|
+
name: parseIdentifier()
|
|
825
|
+
};
|
|
826
|
+
assert(pseudo.argument.name, "Expected substitute name.");
|
|
827
|
+
} else if (pseudoDefinition.type === "String") {
|
|
828
|
+
pseudo.argument = {
|
|
829
|
+
type: "String",
|
|
830
|
+
value: parsePseudoClassString()
|
|
831
|
+
};
|
|
832
|
+
assert(pseudo.argument.value, "Expected pseudo-class argument value.");
|
|
833
|
+
} else if (pseudoDefinition.type === "Selector") {
|
|
834
|
+
pseudo.argument = parseSelector2(true);
|
|
835
|
+
} else if (pseudoDefinition.type === "Formula") {
|
|
836
|
+
const [a, b] = parseFormula();
|
|
837
|
+
pseudo.argument = {
|
|
838
|
+
type: "Formula",
|
|
839
|
+
a,
|
|
840
|
+
b
|
|
841
|
+
};
|
|
842
|
+
if (pseudoDefinition.ofSelector) {
|
|
843
|
+
skipWhitespace();
|
|
844
|
+
if (is("o") || is("\\")) {
|
|
845
|
+
const ident = parseIdentifier();
|
|
846
|
+
assert(ident === "of", "Formula of selector parse error.");
|
|
847
|
+
skipWhitespace();
|
|
848
|
+
pseudo.argument = {
|
|
849
|
+
type: "FormulaOfSelector",
|
|
850
|
+
a,
|
|
851
|
+
b,
|
|
852
|
+
selector: parseRule()
|
|
853
|
+
};
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
} else {
|
|
857
|
+
return fail("Invalid pseudo-class signature.");
|
|
858
|
+
}
|
|
859
|
+
skipWhitespace();
|
|
860
|
+
if (isEof() && !strict) {
|
|
861
|
+
return pseudo;
|
|
862
|
+
}
|
|
863
|
+
pass(")");
|
|
864
|
+
} else {
|
|
865
|
+
assert(pseudoDefinition.optional, `Argument is required for pseudo-class "${pseudoName}".`);
|
|
866
|
+
}
|
|
867
|
+
return pseudo;
|
|
868
|
+
}
|
|
869
|
+
function parseTagName() {
|
|
870
|
+
if (is("*")) {
|
|
871
|
+
assert(tagNameWildcardEnabled, "Wildcard tag name is not enabled.");
|
|
872
|
+
next();
|
|
873
|
+
return { type: "WildcardTag" };
|
|
874
|
+
} else if (isIdentStart(chr) || is("\\")) {
|
|
875
|
+
assert(tagNameEnabled, "Tag names are not enabled.");
|
|
876
|
+
return {
|
|
877
|
+
type: "TagName",
|
|
878
|
+
name: parseIdentifier()
|
|
879
|
+
};
|
|
880
|
+
} else {
|
|
881
|
+
return fail("Expected tag name.");
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
function parseTagNameWithNamespace() {
|
|
885
|
+
if (is("*")) {
|
|
886
|
+
const savedPos = pos;
|
|
887
|
+
next();
|
|
888
|
+
if (!is("|")) {
|
|
889
|
+
rewind(savedPos);
|
|
890
|
+
return parseTagName();
|
|
891
|
+
}
|
|
892
|
+
next();
|
|
893
|
+
if (!isTagStart()) {
|
|
894
|
+
rewind(savedPos);
|
|
895
|
+
return parseTagName();
|
|
896
|
+
}
|
|
897
|
+
assert(namespaceEnabled, "Namespaces are not enabled.");
|
|
898
|
+
assert(namespaceWildcardEnabled, "Wildcard namespace is not enabled.");
|
|
899
|
+
const tagName = parseTagName();
|
|
900
|
+
tagName.namespace = { type: "WildcardNamespace" };
|
|
901
|
+
return tagName;
|
|
902
|
+
} else if (is("|")) {
|
|
903
|
+
assert(namespaceEnabled, "Namespaces are not enabled.");
|
|
904
|
+
next();
|
|
905
|
+
const tagName = parseTagName();
|
|
906
|
+
tagName.namespace = { type: "NoNamespace" };
|
|
907
|
+
return tagName;
|
|
908
|
+
} else if (isIdentStart(chr) || is("\\")) {
|
|
909
|
+
const identifier = parseIdentifier();
|
|
910
|
+
if (!is("|")) {
|
|
911
|
+
assert(tagNameEnabled, "Tag names are not enabled.");
|
|
912
|
+
return {
|
|
913
|
+
type: "TagName",
|
|
914
|
+
name: identifier
|
|
915
|
+
};
|
|
916
|
+
}
|
|
917
|
+
const savedPos = pos;
|
|
918
|
+
next();
|
|
919
|
+
if (!isTagStart()) {
|
|
920
|
+
rewind(savedPos);
|
|
921
|
+
return {
|
|
922
|
+
type: "TagName",
|
|
923
|
+
name: identifier
|
|
924
|
+
};
|
|
925
|
+
}
|
|
926
|
+
assert(namespaceEnabled, "Namespaces are not enabled.");
|
|
927
|
+
const tagName = parseTagName();
|
|
928
|
+
tagName.namespace = { type: "NamespaceName", name: identifier };
|
|
929
|
+
return tagName;
|
|
930
|
+
} else {
|
|
931
|
+
return fail("Expected tag name.");
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
function parseRule(relative = false) {
|
|
935
|
+
const rule = {};
|
|
936
|
+
let isRuleStart = true;
|
|
937
|
+
if (relative) {
|
|
938
|
+
const combinator = matchMulticharIndex(combinatorsIndex);
|
|
939
|
+
if (combinator) {
|
|
940
|
+
rule.combinator = combinator;
|
|
941
|
+
skipWhitespace();
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
while (pos < l) {
|
|
945
|
+
if (isTagStart()) {
|
|
946
|
+
assert(isRuleStart, "Unexpected tag/namespace start.");
|
|
947
|
+
rule.tag = parseTagNameWithNamespace();
|
|
948
|
+
} else if (is("|")) {
|
|
949
|
+
const savedPos = pos;
|
|
950
|
+
next();
|
|
951
|
+
if (isTagStart()) {
|
|
952
|
+
assert(isRuleStart, "Unexpected tag/namespace start.");
|
|
953
|
+
rewind(savedPos);
|
|
954
|
+
rule.tag = parseTagNameWithNamespace();
|
|
955
|
+
} else {
|
|
956
|
+
rewind(savedPos);
|
|
957
|
+
break;
|
|
958
|
+
}
|
|
959
|
+
} else if (is(".")) {
|
|
960
|
+
assert(classNamesEnabled, "Class names are not enabled.");
|
|
961
|
+
next();
|
|
962
|
+
const className = parseIdentifier();
|
|
963
|
+
assert(className, "Expected class name.");
|
|
964
|
+
(rule.classNames = rule.classNames || []).push(className);
|
|
965
|
+
} else if (is("#")) {
|
|
966
|
+
assert(idEnabled, "IDs are not enabled.");
|
|
967
|
+
next();
|
|
968
|
+
const idName = parseIdentifier();
|
|
969
|
+
assert(idName, "Expected ID name.");
|
|
970
|
+
(rule.ids = rule.ids || []).push(idName);
|
|
971
|
+
} else if (is("[")) {
|
|
972
|
+
assert(attributesEnabled, "Attributes are not enabled.");
|
|
973
|
+
(rule.attributes = rule.attributes || []).push(parseAttribute());
|
|
974
|
+
} else if (is(":")) {
|
|
975
|
+
let isDoubleColon = false;
|
|
976
|
+
let isPseudoElement = false;
|
|
977
|
+
next();
|
|
978
|
+
if (is(":")) {
|
|
979
|
+
assert(pseudoElementsEnabled, "Pseudo elements are not enabled.");
|
|
980
|
+
assert(pseudoElementsDoubleColonNotationEnabled, "Pseudo elements double colon notation is not enabled.");
|
|
981
|
+
isDoubleColon = true;
|
|
982
|
+
next();
|
|
983
|
+
}
|
|
984
|
+
const pseudoName = parseIdentifier();
|
|
985
|
+
assert(isDoubleColon || pseudoName, "Expected pseudo-class name.");
|
|
986
|
+
assert(!isDoubleColon || pseudoName, "Expected pseudo-element name.");
|
|
987
|
+
assert(!isDoubleColon || pseudoElementsAcceptUnknown || pseudoElementsIndex[pseudoName], `Unknown pseudo-element "${pseudoName}".`);
|
|
988
|
+
isPseudoElement = pseudoElementsEnabled && (isDoubleColon || !isDoubleColon && pseudoElementsSingleColonNotationEnabled && pseudoElementsIndex[pseudoName]);
|
|
989
|
+
if (isPseudoElement) {
|
|
990
|
+
rule.pseudoElement = pseudoName;
|
|
991
|
+
if (!whitespaceChars[chr] && !is(",") && !is(")") && !isEof()) {
|
|
992
|
+
return fail("Pseudo-element should be the last component of a CSS selector rule.");
|
|
993
|
+
}
|
|
994
|
+
} else {
|
|
995
|
+
assert(pseudoClassesEnabled, "Pseudo classes are not enabled.");
|
|
996
|
+
(rule.pseudoClasses = rule.pseudoClasses || []).push(parsePseudoClass(pseudoName));
|
|
997
|
+
}
|
|
998
|
+
} else {
|
|
999
|
+
break;
|
|
1000
|
+
}
|
|
1001
|
+
isRuleStart = false;
|
|
1002
|
+
}
|
|
1003
|
+
if (isRuleStart) {
|
|
1004
|
+
if (isEof()) {
|
|
1005
|
+
return fail("Expected rule but end of input reached.");
|
|
1006
|
+
} else {
|
|
1007
|
+
return fail(`Expected rule but "${chr}" found.`);
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
rule.type = "Rule";
|
|
1011
|
+
skipWhitespace();
|
|
1012
|
+
if (!isEof() && !is(",") && !is(")")) {
|
|
1013
|
+
const combinator = matchMulticharIndex(combinatorsIndex);
|
|
1014
|
+
skipWhitespace();
|
|
1015
|
+
rule.nestedRule = parseRule();
|
|
1016
|
+
rule.nestedRule.combinator = combinator;
|
|
1017
|
+
}
|
|
1018
|
+
return rule;
|
|
1019
|
+
}
|
|
1020
|
+
return (input) => {
|
|
1021
|
+
if (typeof input !== "string") {
|
|
1022
|
+
throw new Error(`${errorPrefix}Expected string input.`);
|
|
1023
|
+
}
|
|
1024
|
+
str = input;
|
|
1025
|
+
l = str.length;
|
|
1026
|
+
pos = 0;
|
|
1027
|
+
chr = str.charAt(0);
|
|
1028
|
+
return parseSelector2();
|
|
1029
|
+
};
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
// node_modules/css-selector-parser/dist/mjs/ast.js
|
|
1033
|
+
function astMethods(type) {
|
|
1034
|
+
return (generatorName, checkerName) => ({
|
|
1035
|
+
[generatorName]: (props) => ({
|
|
1036
|
+
type,
|
|
1037
|
+
...props
|
|
1038
|
+
}),
|
|
1039
|
+
[checkerName]: (entity) => typeof entity === "object" && entity !== null && entity.type === type
|
|
1040
|
+
});
|
|
1041
|
+
}
|
|
1042
|
+
var ast = {
|
|
1043
|
+
...astMethods("Selector")("selector", "isSelector"),
|
|
1044
|
+
...astMethods("Rule")("rule", "isRule"),
|
|
1045
|
+
...astMethods("TagName")("tagName", "isTagName"),
|
|
1046
|
+
...astMethods("WildcardTag")("wildcardTag", "isWildcardTag"),
|
|
1047
|
+
...astMethods("NamespaceName")("namespaceName", "isNamespaceName"),
|
|
1048
|
+
...astMethods("WildcardNamespace")("wildcardNamespace", "isWildcardNamespace"),
|
|
1049
|
+
...astMethods("NoNamespace")("noNamespace", "isNoNamespace"),
|
|
1050
|
+
...astMethods("Attribute")("attribute", "isAttribute"),
|
|
1051
|
+
...astMethods("PseudoClass")("pseudoClass", "isPseudoClass"),
|
|
1052
|
+
...astMethods("String")("string", "isString"),
|
|
1053
|
+
...astMethods("Formula")("formula", "isFormula"),
|
|
1054
|
+
...astMethods("FormulaOfSelector")("formulaOfSelector", "isFormulaOfSelector"),
|
|
1055
|
+
...astMethods("Substitution")("substitution", "isSubstitution")
|
|
1056
|
+
};
|
|
1057
|
+
|
|
1058
|
+
// src/browser/css.ts
|
|
1059
|
+
var import_throw_expression = __toESM(require_throw_expression());
|
|
1060
|
+
var getAllParents = (element) => {
|
|
1061
|
+
const getParents = (class_) => {
|
|
1062
|
+
const parent = class_.getParent();
|
|
1063
|
+
if (parent !== void 0) {
|
|
1064
|
+
return [class_, ...getParents(parent)];
|
|
1065
|
+
}
|
|
1066
|
+
return [class_];
|
|
1067
|
+
};
|
|
1068
|
+
return getParents(element.getMetadata()).map((parent) => parent.getName());
|
|
1069
|
+
};
|
|
1070
|
+
var parseSelector = (selector) => {
|
|
1071
|
+
if (selector === "") {
|
|
1072
|
+
throw new Error("ui5 selector is empty");
|
|
1073
|
+
}
|
|
1074
|
+
const parsedSelector = parse(selector);
|
|
1075
|
+
parsedSelector.rules.forEach((rule) => {
|
|
1076
|
+
if (rule.ids && rule.ids.length > 1) {
|
|
1077
|
+
throw new Error("multiple ids are not supported");
|
|
1078
|
+
}
|
|
1079
|
+
if (rule.pseudoElement === "subclass" && rule.tag?.type !== "TagName") {
|
|
1080
|
+
throw new Error(
|
|
1081
|
+
"subclass pseudo-selector cannot be used without specifying a control type"
|
|
1082
|
+
);
|
|
1083
|
+
}
|
|
1084
|
+
});
|
|
1085
|
+
return parsedSelector;
|
|
1086
|
+
};
|
|
1087
|
+
var parse = createParser({
|
|
1088
|
+
syntax: {
|
|
1089
|
+
combinators: [],
|
|
1090
|
+
namespace: false,
|
|
1091
|
+
attributes: { operators: ["=", "^=", "$=", "*=", "~=", "|="] },
|
|
1092
|
+
pseudoElements: { definitions: ["subclass"] },
|
|
1093
|
+
pseudoClasses: { definitions: { Selector: ["has"] } },
|
|
1094
|
+
tag: { wildcard: true },
|
|
1095
|
+
ids: true,
|
|
1096
|
+
classNames: true
|
|
1097
|
+
}
|
|
1098
|
+
});
|
|
1099
|
+
var querySelector = (root, selector) => selector.rules.flatMap((rule) => {
|
|
1100
|
+
if (rule.tag?.type === "TagName" && rule.classNames) {
|
|
1101
|
+
const sapNamespace = "sap";
|
|
1102
|
+
if (rule.tag.name !== sapNamespace) {
|
|
1103
|
+
rule.tag.name = `${sapNamespace}.${rule.tag.name}`;
|
|
1104
|
+
}
|
|
1105
|
+
rule.tag.name = [rule.tag.name, ...rule.classNames].join(".");
|
|
1106
|
+
delete rule.classNames;
|
|
1107
|
+
}
|
|
1108
|
+
const controls = sap.ui.core.Element.registry.filter((element) => {
|
|
1109
|
+
if (rule.tag?.type === "TagName" && rule.tag.name !== element.getMetadata().getName() && (rule.pseudoElement !== "subclass" || !getAllParents(element).includes(rule.tag.name)) || rule.ids && rule.ids[0] !== element.getId()) {
|
|
1110
|
+
return false;
|
|
1111
|
+
}
|
|
1112
|
+
return (rule.attributes ?? []).every((attr) => {
|
|
1113
|
+
let actualValue;
|
|
1114
|
+
try {
|
|
1115
|
+
actualValue = String(element.getProperty(attr.name));
|
|
1116
|
+
} catch {
|
|
1117
|
+
return false;
|
|
1118
|
+
}
|
|
1119
|
+
if (!("value" in attr)) {
|
|
1120
|
+
return true;
|
|
1121
|
+
}
|
|
1122
|
+
const expectedValue = attr.value.value;
|
|
1123
|
+
return {
|
|
1124
|
+
"=": actualValue === expectedValue,
|
|
1125
|
+
"^=": actualValue.startsWith(expectedValue),
|
|
1126
|
+
"$=": actualValue.endsWith(expectedValue),
|
|
1127
|
+
"*=": actualValue.includes(expectedValue),
|
|
1128
|
+
"~=": actualValue.trim() === expectedValue,
|
|
1129
|
+
"|=": actualValue.split("-")[0] === expectedValue
|
|
1130
|
+
}[(0, import_throw_expression.throwIfUndefined)(
|
|
1131
|
+
attr.operator,
|
|
1132
|
+
"attribute operator was undefined when value was set (this should NEVER happen)"
|
|
1133
|
+
)];
|
|
1134
|
+
});
|
|
1135
|
+
});
|
|
1136
|
+
return controls.map((control) => control.getDomRef()).filter((element) => {
|
|
1137
|
+
if (element === null || root.querySelector(`[id='${element.id}']`) === null) {
|
|
1138
|
+
return false;
|
|
1139
|
+
}
|
|
1140
|
+
if (rule.pseudoClasses && querySelector(
|
|
1141
|
+
element,
|
|
1142
|
+
(0, import_throw_expression.throwIfUndefined)(
|
|
1143
|
+
rule.pseudoClasses[0],
|
|
1144
|
+
'":has" pseudo-class was specified without an argument'
|
|
1145
|
+
).argument
|
|
1146
|
+
).length === 0) {
|
|
1147
|
+
return false;
|
|
1148
|
+
}
|
|
1149
|
+
return true;
|
|
1150
|
+
});
|
|
1151
|
+
});
|
|
1152
|
+
var queryAll = (root, selector) => {
|
|
1153
|
+
try {
|
|
1154
|
+
const parsedSelector = parseSelector(selector);
|
|
1155
|
+
if (!isUi5()) {
|
|
1156
|
+
return [];
|
|
1157
|
+
}
|
|
1158
|
+
return querySelector(root, parsedSelector);
|
|
1159
|
+
} catch (e) {
|
|
1160
|
+
throw new Ui5SelectorEngineError(selector, e);
|
|
1161
|
+
}
|
|
1162
|
+
};
|
|
1163
|
+
var css_default = {
|
|
1164
|
+
queryAll,
|
|
1165
|
+
query: (root, selector) => queryAll(root, selector)[0]
|
|
1166
|
+
};
|