iobroker.mywebui 1.37.21 → 1.37.22
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/io-package.json +1 -1
- package/package.json +1 -1
- package/www/node_modules/@node-projects/css-parser/LICENSE +11 -0
- package/www/node_modules/@node-projects/css-parser/README.md +161 -0
- package/www/node_modules/@node-projects/css-parser/dist/CssParseError.d.ts +8 -0
- package/www/node_modules/@node-projects/css-parser/dist/CssParseError.js +15 -0
- package/www/node_modules/@node-projects/css-parser/dist/CssPosition.d.ts +25 -0
- package/www/node_modules/@node-projects/css-parser/dist/CssPosition.js +13 -0
- package/www/node_modules/@node-projects/css-parser/dist/index-min.js +56 -0
- package/www/node_modules/@node-projects/css-parser/dist/index-min.js.map +7 -0
- package/www/node_modules/@node-projects/css-parser/dist/index.d.ts +12 -0
- package/www/node_modules/@node-projects/css-parser/dist/index.js +8 -0
- package/www/node_modules/@node-projects/css-parser/dist/parse/index.d.ts +8 -0
- package/www/node_modules/@node-projects/css-parser/dist/parse/index.js +1293 -0
- package/www/node_modules/@node-projects/css-parser/dist/parse/lexer.d.ts +118 -0
- package/www/node_modules/@node-projects/css-parser/dist/parse/lexer.js +248 -0
- package/www/node_modules/@node-projects/css-parser/dist/stringify/compiler.d.ts +172 -0
- package/www/node_modules/@node-projects/css-parser/dist/stringify/compiler.js +732 -0
- package/www/node_modules/@node-projects/css-parser/dist/stringify/index.d.ts +5 -0
- package/www/node_modules/@node-projects/css-parser/dist/stringify/index.js +5 -0
- package/www/node_modules/@node-projects/css-parser/dist/type.d.ts +205 -0
- package/www/node_modules/@node-projects/css-parser/dist/type.js +31 -0
- package/www/node_modules/@node-projects/css-parser/dist/utils/stringSearch.d.ts +53 -0
- package/www/node_modules/@node-projects/css-parser/dist/utils/stringSearch.js +166 -0
- package/www/node_modules/@node-projects/css-parser/docs/API.md +362 -0
- package/www/node_modules/@node-projects/css-parser/docs/AST.md +417 -0
- package/www/node_modules/@node-projects/css-parser/docs/CHANGELOG.md +205 -0
- package/www/node_modules/@node-projects/css-parser/docs/EXAMPLES.md +497 -0
- package/www/node_modules/@node-projects/css-parser/package.json +66 -0
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import type CssParseError from './CssParseError.js';
|
|
2
|
+
import type Position from './CssPosition.js';
|
|
3
|
+
export declare enum CssTypes {
|
|
4
|
+
stylesheet = "stylesheet",
|
|
5
|
+
rule = "rule",
|
|
6
|
+
declaration = "declaration",
|
|
7
|
+
comment = "comment",
|
|
8
|
+
whitespace = "whitespace",
|
|
9
|
+
atRule = "at-rule",
|
|
10
|
+
container = "container",
|
|
11
|
+
charset = "charset",
|
|
12
|
+
counterStyle = "counter-style",
|
|
13
|
+
document = "document",
|
|
14
|
+
customMedia = "custom-media",
|
|
15
|
+
fontFace = "font-face",
|
|
16
|
+
fontFeatureValues = "font-feature-values",
|
|
17
|
+
host = "host",
|
|
18
|
+
import = "import",
|
|
19
|
+
keyframes = "keyframes",
|
|
20
|
+
keyframe = "keyframe",
|
|
21
|
+
layer = "layer",
|
|
22
|
+
media = "media",
|
|
23
|
+
namespace = "namespace",
|
|
24
|
+
page = "page",
|
|
25
|
+
pageMarginBox = "page-margin-box",
|
|
26
|
+
positionTry = "position-try",
|
|
27
|
+
property = "property",
|
|
28
|
+
scope = "scope",
|
|
29
|
+
startingStyle = "starting-style",
|
|
30
|
+
supports = "supports",
|
|
31
|
+
viewTransition = "view-transition"
|
|
32
|
+
}
|
|
33
|
+
export type CssCommonAST = {
|
|
34
|
+
type: CssTypes;
|
|
35
|
+
};
|
|
36
|
+
export type CssCommonPositionAST = CssCommonAST & {
|
|
37
|
+
position?: Position;
|
|
38
|
+
parent?: unknown;
|
|
39
|
+
};
|
|
40
|
+
export type CssWhitespaceAST = CssCommonPositionAST & {
|
|
41
|
+
type: CssTypes.whitespace;
|
|
42
|
+
value: string;
|
|
43
|
+
};
|
|
44
|
+
export type CssStylesheetAST = CssCommonAST & {
|
|
45
|
+
type: CssTypes.stylesheet;
|
|
46
|
+
stylesheet: {
|
|
47
|
+
source?: string;
|
|
48
|
+
rules: Array<CssAtRuleAST | CssWhitespaceAST>;
|
|
49
|
+
parsingErrors?: Array<CssParseError>;
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
export type CssRuleAST = CssCommonPositionAST & {
|
|
53
|
+
type: CssTypes.rule;
|
|
54
|
+
selectors: Array<string>;
|
|
55
|
+
declarations: Array<CssDeclarationAST | CssCommentAST | CssAtRuleAST | CssWhitespaceAST>;
|
|
56
|
+
rawPrelude?: string;
|
|
57
|
+
};
|
|
58
|
+
export type CssDeclarationAST = CssCommonPositionAST & {
|
|
59
|
+
type: CssTypes.declaration;
|
|
60
|
+
property: string;
|
|
61
|
+
value: string;
|
|
62
|
+
rawBetween?: string;
|
|
63
|
+
rawValue?: string;
|
|
64
|
+
};
|
|
65
|
+
export type CssCommentAST = CssCommonPositionAST & {
|
|
66
|
+
type: CssTypes.comment;
|
|
67
|
+
comment: string;
|
|
68
|
+
};
|
|
69
|
+
export type CssContainerAST = CssCommonPositionAST & {
|
|
70
|
+
type: CssTypes.container;
|
|
71
|
+
container: string;
|
|
72
|
+
rules: Array<CssAtRuleAST | CssDeclarationAST | CssWhitespaceAST>;
|
|
73
|
+
rawPrelude?: string;
|
|
74
|
+
};
|
|
75
|
+
export type CssCharsetAST = CssCommonPositionAST & {
|
|
76
|
+
type: CssTypes.charset;
|
|
77
|
+
charset: string;
|
|
78
|
+
rawSource?: string;
|
|
79
|
+
};
|
|
80
|
+
export type CssCustomMediaAST = CssCommonPositionAST & {
|
|
81
|
+
type: CssTypes.customMedia;
|
|
82
|
+
name: string;
|
|
83
|
+
media: string;
|
|
84
|
+
rawSource?: string;
|
|
85
|
+
};
|
|
86
|
+
export type CssDocumentAST = CssCommonPositionAST & {
|
|
87
|
+
type: CssTypes.document;
|
|
88
|
+
document: string;
|
|
89
|
+
vendor?: string;
|
|
90
|
+
rules: Array<CssAtRuleAST | CssDeclarationAST | CssWhitespaceAST>;
|
|
91
|
+
rawPrelude?: string;
|
|
92
|
+
};
|
|
93
|
+
export type CssFontFaceAST = CssCommonPositionAST & {
|
|
94
|
+
type: CssTypes.fontFace;
|
|
95
|
+
declarations: Array<CssDeclarationAST | CssCommentAST | CssWhitespaceAST>;
|
|
96
|
+
rawPrelude?: string;
|
|
97
|
+
};
|
|
98
|
+
export type CssHostAST = CssCommonPositionAST & {
|
|
99
|
+
type: CssTypes.host;
|
|
100
|
+
rules: Array<CssAtRuleAST | CssDeclarationAST | CssWhitespaceAST>;
|
|
101
|
+
rawPrelude?: string;
|
|
102
|
+
};
|
|
103
|
+
export type CssImportAST = CssCommonPositionAST & {
|
|
104
|
+
type: CssTypes.import;
|
|
105
|
+
import: string;
|
|
106
|
+
rawSource?: string;
|
|
107
|
+
};
|
|
108
|
+
export type CssKeyframesAST = CssCommonPositionAST & {
|
|
109
|
+
type: CssTypes.keyframes;
|
|
110
|
+
name: string;
|
|
111
|
+
vendor?: string;
|
|
112
|
+
keyframes: Array<CssKeyframeAST | CssCommentAST | CssWhitespaceAST>;
|
|
113
|
+
rawPrelude?: string;
|
|
114
|
+
};
|
|
115
|
+
export type CssKeyframeAST = CssCommonPositionAST & {
|
|
116
|
+
type: CssTypes.keyframe;
|
|
117
|
+
values: Array<string>;
|
|
118
|
+
declarations: Array<CssDeclarationAST | CssCommentAST | CssWhitespaceAST>;
|
|
119
|
+
rawPrelude?: string;
|
|
120
|
+
};
|
|
121
|
+
export type CssLayerAST = CssCommonPositionAST & {
|
|
122
|
+
type: CssTypes.layer;
|
|
123
|
+
layer: string;
|
|
124
|
+
rules?: Array<CssAtRuleAST | CssDeclarationAST | CssWhitespaceAST>;
|
|
125
|
+
rawPrelude?: string;
|
|
126
|
+
rawSource?: string;
|
|
127
|
+
};
|
|
128
|
+
export type CssMediaAST = CssCommonPositionAST & {
|
|
129
|
+
type: CssTypes.media;
|
|
130
|
+
media: string;
|
|
131
|
+
rules: Array<CssAtRuleAST | CssDeclarationAST | CssWhitespaceAST>;
|
|
132
|
+
rawPrelude?: string;
|
|
133
|
+
};
|
|
134
|
+
export type CssNamespaceAST = CssCommonPositionAST & {
|
|
135
|
+
type: CssTypes.namespace;
|
|
136
|
+
namespace: string;
|
|
137
|
+
rawSource?: string;
|
|
138
|
+
};
|
|
139
|
+
export type CssPageAST = CssCommonPositionAST & {
|
|
140
|
+
type: CssTypes.page;
|
|
141
|
+
selectors: Array<string>;
|
|
142
|
+
declarations: Array<CssDeclarationAST | CssCommentAST | CssAtRuleAST | CssWhitespaceAST>;
|
|
143
|
+
rawPrelude?: string;
|
|
144
|
+
};
|
|
145
|
+
export type CssSupportsAST = CssCommonPositionAST & {
|
|
146
|
+
type: CssTypes.supports;
|
|
147
|
+
supports: string;
|
|
148
|
+
rules: Array<CssAtRuleAST | CssDeclarationAST | CssWhitespaceAST>;
|
|
149
|
+
rawPrelude?: string;
|
|
150
|
+
};
|
|
151
|
+
export type CssStartingStyleAST = CssCommonPositionAST & {
|
|
152
|
+
type: CssTypes.startingStyle;
|
|
153
|
+
rules: Array<CssAtRuleAST | CssDeclarationAST | CssWhitespaceAST>;
|
|
154
|
+
rawPrelude?: string;
|
|
155
|
+
};
|
|
156
|
+
export type CssCounterStyleAST = CssCommonPositionAST & {
|
|
157
|
+
type: CssTypes.counterStyle;
|
|
158
|
+
name: string;
|
|
159
|
+
declarations: Array<CssDeclarationAST | CssCommentAST | CssWhitespaceAST>;
|
|
160
|
+
rawPrelude?: string;
|
|
161
|
+
};
|
|
162
|
+
export type CssFontFeatureValuesAST = CssCommonPositionAST & {
|
|
163
|
+
type: CssTypes.fontFeatureValues;
|
|
164
|
+
fontFamily: string;
|
|
165
|
+
rules: Array<CssAtRuleAST | CssDeclarationAST | CssWhitespaceAST>;
|
|
166
|
+
rawPrelude?: string;
|
|
167
|
+
};
|
|
168
|
+
export type CssPositionTryAST = CssCommonPositionAST & {
|
|
169
|
+
type: CssTypes.positionTry;
|
|
170
|
+
name: string;
|
|
171
|
+
declarations: Array<CssDeclarationAST | CssCommentAST | CssWhitespaceAST>;
|
|
172
|
+
rawPrelude?: string;
|
|
173
|
+
};
|
|
174
|
+
export type CssPropertyAST = CssCommonPositionAST & {
|
|
175
|
+
type: CssTypes.property;
|
|
176
|
+
name: string;
|
|
177
|
+
declarations: Array<CssDeclarationAST | CssCommentAST | CssWhitespaceAST>;
|
|
178
|
+
rawPrelude?: string;
|
|
179
|
+
};
|
|
180
|
+
export type CssScopeAST = CssCommonPositionAST & {
|
|
181
|
+
type: CssTypes.scope;
|
|
182
|
+
scope: string;
|
|
183
|
+
rules: Array<CssAtRuleAST | CssDeclarationAST | CssWhitespaceAST>;
|
|
184
|
+
rawPrelude?: string;
|
|
185
|
+
};
|
|
186
|
+
export type CssViewTransitionAST = CssCommonPositionAST & {
|
|
187
|
+
type: CssTypes.viewTransition;
|
|
188
|
+
declarations: Array<CssDeclarationAST | CssCommentAST | CssWhitespaceAST>;
|
|
189
|
+
rawPrelude?: string;
|
|
190
|
+
};
|
|
191
|
+
export type CssPageMarginBoxAST = CssCommonPositionAST & {
|
|
192
|
+
type: CssTypes.pageMarginBox;
|
|
193
|
+
name: string;
|
|
194
|
+
declarations: Array<CssDeclarationAST | CssCommentAST | CssWhitespaceAST>;
|
|
195
|
+
rawPrelude?: string;
|
|
196
|
+
};
|
|
197
|
+
export type CssGenericAtRuleAST = CssCommonPositionAST & {
|
|
198
|
+
type: CssTypes.atRule;
|
|
199
|
+
name: string;
|
|
200
|
+
prelude: string;
|
|
201
|
+
rules?: Array<CssAtRuleAST | CssDeclarationAST | CssWhitespaceAST>;
|
|
202
|
+
rawPrelude?: string;
|
|
203
|
+
};
|
|
204
|
+
export type CssAtRuleAST = CssRuleAST | CssCommentAST | CssContainerAST | CssCharsetAST | CssCounterStyleAST | CssCustomMediaAST | CssDocumentAST | CssFontFaceAST | CssFontFeatureValuesAST | CssHostAST | CssImportAST | CssKeyframesAST | CssLayerAST | CssMediaAST | CssNamespaceAST | CssPageAST | CssPageMarginBoxAST | CssPositionTryAST | CssPropertyAST | CssScopeAST | CssSupportsAST | CssStartingStyleAST | CssViewTransitionAST | CssGenericAtRuleAST;
|
|
205
|
+
export type CssAllNodesAST = CssAtRuleAST | CssStylesheetAST | CssDeclarationAST | CssKeyframeAST | CssWhitespaceAST;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export var CssTypes;
|
|
2
|
+
(function (CssTypes) {
|
|
3
|
+
CssTypes["stylesheet"] = "stylesheet";
|
|
4
|
+
CssTypes["rule"] = "rule";
|
|
5
|
+
CssTypes["declaration"] = "declaration";
|
|
6
|
+
CssTypes["comment"] = "comment";
|
|
7
|
+
CssTypes["whitespace"] = "whitespace";
|
|
8
|
+
CssTypes["atRule"] = "at-rule";
|
|
9
|
+
CssTypes["container"] = "container";
|
|
10
|
+
CssTypes["charset"] = "charset";
|
|
11
|
+
CssTypes["counterStyle"] = "counter-style";
|
|
12
|
+
CssTypes["document"] = "document";
|
|
13
|
+
CssTypes["customMedia"] = "custom-media";
|
|
14
|
+
CssTypes["fontFace"] = "font-face";
|
|
15
|
+
CssTypes["fontFeatureValues"] = "font-feature-values";
|
|
16
|
+
CssTypes["host"] = "host";
|
|
17
|
+
CssTypes["import"] = "import";
|
|
18
|
+
CssTypes["keyframes"] = "keyframes";
|
|
19
|
+
CssTypes["keyframe"] = "keyframe";
|
|
20
|
+
CssTypes["layer"] = "layer";
|
|
21
|
+
CssTypes["media"] = "media";
|
|
22
|
+
CssTypes["namespace"] = "namespace";
|
|
23
|
+
CssTypes["page"] = "page";
|
|
24
|
+
CssTypes["pageMarginBox"] = "page-margin-box";
|
|
25
|
+
CssTypes["positionTry"] = "position-try";
|
|
26
|
+
CssTypes["property"] = "property";
|
|
27
|
+
CssTypes["scope"] = "scope";
|
|
28
|
+
CssTypes["startingStyle"] = "starting-style";
|
|
29
|
+
CssTypes["supports"] = "supports";
|
|
30
|
+
CssTypes["viewTransition"] = "view-transition";
|
|
31
|
+
})(CssTypes || (CssTypes = {}));
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export declare const MAX_LOOP = 10000;
|
|
2
|
+
/**
|
|
3
|
+
* Find the first occurrence of any search string in the input string, ignoring escaped characters
|
|
4
|
+
* @param string - The input string to search in
|
|
5
|
+
* @param search - Array of strings to search for
|
|
6
|
+
* @param position - Optional starting position for the search
|
|
7
|
+
* @returns The index of the first match, or -1 if not found
|
|
8
|
+
* @throws {Error} If too many escape sequences are encountered (> MAX_LOOP)
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* // Basic search
|
|
12
|
+
* indexOfArrayNonEscaped('a,b,c', [',']) // 1
|
|
13
|
+
*
|
|
14
|
+
* // Handles escaped characters
|
|
15
|
+
* indexOfArrayNonEscaped('a\\,b,c', [',']) // 4, the first comma is escaped
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export declare const indexOfArrayNonEscaped: (string: string, search: Array<string>, position?: number) => number;
|
|
19
|
+
/**
|
|
20
|
+
* Find the first occurrence of any search string in the input string, respecting brackets and quotes
|
|
21
|
+
* @param string - The input string to search in
|
|
22
|
+
* @param search - Array of strings to search for
|
|
23
|
+
* @param position - Optional starting position for the search
|
|
24
|
+
* @returns The index of the first match, or -1 if not found
|
|
25
|
+
* @throws {Error} If too many escape sequences are encountered (> MAX_LOOP)
|
|
26
|
+
* @example
|
|
27
|
+
* ```ts
|
|
28
|
+
* // Basic search
|
|
29
|
+
* indexOfArrayWithBracketAndQuoteSupport('a,b,c', [',']) // 1
|
|
30
|
+
*
|
|
31
|
+
* // Respects brackets - won't match inside ()
|
|
32
|
+
* indexOfArrayWithBracketAndQuoteSupport('(a,b),c', [',']) // 4, ignores the comma inside ()
|
|
33
|
+
*
|
|
34
|
+
* // Respects quotes - won't match inside quotes
|
|
35
|
+
* indexOfArrayWithBracketAndQuoteSupport('"a,b",c', [',']) // 4, ignores the comma inside quotes
|
|
36
|
+
* indexOfArrayWithBracketAndQuoteSupport("'a,b',c", [',']) // 4, ignores the comma inside quotes
|
|
37
|
+
*
|
|
38
|
+
* // Handles escaped characters
|
|
39
|
+
* indexOfArrayWithBracketAndQuoteSupport('a\\,b,c', [',']) // 4, the first comma is escaped
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export declare const indexOfArrayWithBracketAndQuoteSupport: (string: string, search: Array<string>, position?: number) => number;
|
|
43
|
+
/**
|
|
44
|
+
* Split a string by search tokens, respecting brackets and quotes
|
|
45
|
+
* @example
|
|
46
|
+
* ```ts
|
|
47
|
+
* splitWithBracketAndQuoteSupport('a,b', [',']) // ['a', 'b']
|
|
48
|
+
* splitWithBracketAndQuoteSupport('a,(b,c)', [',']) // ['a', '(b,c)']
|
|
49
|
+
* splitWithBracketAndQuoteSupport('a,"b,c"', [',']) // ['a', '"b,c"']
|
|
50
|
+
* splitWithBracketAndQuoteSupport("a,'b,c'", [',']) // ['a', "'b,c'"]
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export declare const splitWithBracketAndQuoteSupport: (string: string, search: Array<string>) => Array<string>;
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
export const MAX_LOOP = 10000;
|
|
2
|
+
// ─── Character-code constants for fast comparisons ───────────────────────────
|
|
3
|
+
const Ch_BACKSLASH = 92; // \
|
|
4
|
+
const Ch_OPEN_PAREN = 40; // (
|
|
5
|
+
const Ch_DOUBLE_QUOTE = 34; // "
|
|
6
|
+
const Ch_SINGLE_QUOTE = 39; // '
|
|
7
|
+
/**
|
|
8
|
+
* Find the first occurrence of any search string in the input string, ignoring escaped characters
|
|
9
|
+
* @param string - The input string to search in
|
|
10
|
+
* @param search - Array of strings to search for
|
|
11
|
+
* @param position - Optional starting position for the search
|
|
12
|
+
* @returns The index of the first match, or -1 if not found
|
|
13
|
+
* @throws {Error} If too many escape sequences are encountered (> MAX_LOOP)
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* // Basic search
|
|
17
|
+
* indexOfArrayNonEscaped('a,b,c', [',']) // 1
|
|
18
|
+
*
|
|
19
|
+
* // Handles escaped characters
|
|
20
|
+
* indexOfArrayNonEscaped('a\\,b,c', [',']) // 4, the first comma is escaped
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export const indexOfArrayNonEscaped = (string, search, position) => {
|
|
24
|
+
let currentPosition = position ?? 0;
|
|
25
|
+
let maxLoop = MAX_LOOP;
|
|
26
|
+
do {
|
|
27
|
+
// Find the minimum index across all search terms and backslash
|
|
28
|
+
// without allocating temporary arrays.
|
|
29
|
+
let found = string.indexOf('\\', currentPosition);
|
|
30
|
+
for (let i = 0; i < search.length; i++) {
|
|
31
|
+
const idx = string.indexOf(search[i], currentPosition);
|
|
32
|
+
if (idx !== -1 && (found === -1 || idx < found)) {
|
|
33
|
+
found = idx;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (found === -1) {
|
|
37
|
+
return -1;
|
|
38
|
+
}
|
|
39
|
+
if (string.charCodeAt(found) === Ch_BACKSLASH) {
|
|
40
|
+
currentPosition = found + 2;
|
|
41
|
+
maxLoop--;
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
return found;
|
|
45
|
+
}
|
|
46
|
+
} while (maxLoop > 0);
|
|
47
|
+
throw new Error('Too many escaping');
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Find the first occurrence of any search string in the input string, respecting brackets and quotes
|
|
51
|
+
* @param string - The input string to search in
|
|
52
|
+
* @param search - Array of strings to search for
|
|
53
|
+
* @param position - Optional starting position for the search
|
|
54
|
+
* @returns The index of the first match, or -1 if not found
|
|
55
|
+
* @throws {Error} If too many escape sequences are encountered (> MAX_LOOP)
|
|
56
|
+
* @example
|
|
57
|
+
* ```ts
|
|
58
|
+
* // Basic search
|
|
59
|
+
* indexOfArrayWithBracketAndQuoteSupport('a,b,c', [',']) // 1
|
|
60
|
+
*
|
|
61
|
+
* // Respects brackets - won't match inside ()
|
|
62
|
+
* indexOfArrayWithBracketAndQuoteSupport('(a,b),c', [',']) // 4, ignores the comma inside ()
|
|
63
|
+
*
|
|
64
|
+
* // Respects quotes - won't match inside quotes
|
|
65
|
+
* indexOfArrayWithBracketAndQuoteSupport('"a,b",c', [',']) // 4, ignores the comma inside quotes
|
|
66
|
+
* indexOfArrayWithBracketAndQuoteSupport("'a,b',c", [',']) // 4, ignores the comma inside quotes
|
|
67
|
+
*
|
|
68
|
+
* // Handles escaped characters
|
|
69
|
+
* indexOfArrayWithBracketAndQuoteSupport('a\\,b,c', [',']) // 4, the first comma is escaped
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
export const indexOfArrayWithBracketAndQuoteSupport = (string, search, position) => {
|
|
73
|
+
let currentSearchPosition = position ?? 0;
|
|
74
|
+
let maxLoop = MAX_LOOP;
|
|
75
|
+
do {
|
|
76
|
+
// Find the minimum index across all search terms plus special characters,
|
|
77
|
+
// without allocating temporary arrays on each iteration.
|
|
78
|
+
let firstMatchPos = -1;
|
|
79
|
+
for (let i = 0; i < search.length; i++) {
|
|
80
|
+
const idx = string.indexOf(search[i], currentSearchPosition);
|
|
81
|
+
if (idx !== -1 && (firstMatchPos === -1 || idx < firstMatchPos)) {
|
|
82
|
+
firstMatchPos = idx;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
const parenIdx = string.indexOf('(', currentSearchPosition);
|
|
86
|
+
if (parenIdx !== -1 && (firstMatchPos === -1 || parenIdx < firstMatchPos)) {
|
|
87
|
+
firstMatchPos = parenIdx;
|
|
88
|
+
}
|
|
89
|
+
const dqIdx = string.indexOf('"', currentSearchPosition);
|
|
90
|
+
if (dqIdx !== -1 && (firstMatchPos === -1 || dqIdx < firstMatchPos)) {
|
|
91
|
+
firstMatchPos = dqIdx;
|
|
92
|
+
}
|
|
93
|
+
const sqIdx = string.indexOf("'", currentSearchPosition);
|
|
94
|
+
if (sqIdx !== -1 && (firstMatchPos === -1 || sqIdx < firstMatchPos)) {
|
|
95
|
+
firstMatchPos = sqIdx;
|
|
96
|
+
}
|
|
97
|
+
const bsIdx = string.indexOf('\\', currentSearchPosition);
|
|
98
|
+
if (bsIdx !== -1 && (firstMatchPos === -1 || bsIdx < firstMatchPos)) {
|
|
99
|
+
firstMatchPos = bsIdx;
|
|
100
|
+
}
|
|
101
|
+
if (firstMatchPos === -1) {
|
|
102
|
+
return -1;
|
|
103
|
+
}
|
|
104
|
+
const charCode = string.charCodeAt(firstMatchPos);
|
|
105
|
+
switch (charCode) {
|
|
106
|
+
case Ch_BACKSLASH:
|
|
107
|
+
currentSearchPosition = firstMatchPos + 2;
|
|
108
|
+
break;
|
|
109
|
+
case Ch_OPEN_PAREN:
|
|
110
|
+
{
|
|
111
|
+
const endPosition = indexOfArrayWithBracketAndQuoteSupport(string, [')'], firstMatchPos + 1);
|
|
112
|
+
if (endPosition === -1) {
|
|
113
|
+
return -1;
|
|
114
|
+
}
|
|
115
|
+
currentSearchPosition = endPosition + 1;
|
|
116
|
+
}
|
|
117
|
+
break;
|
|
118
|
+
case Ch_DOUBLE_QUOTE:
|
|
119
|
+
{
|
|
120
|
+
const endQuotePosition = indexOfArrayNonEscaped(string, ['"'], firstMatchPos + 1);
|
|
121
|
+
if (endQuotePosition === -1) {
|
|
122
|
+
return -1;
|
|
123
|
+
}
|
|
124
|
+
currentSearchPosition = endQuotePosition + 1;
|
|
125
|
+
}
|
|
126
|
+
break;
|
|
127
|
+
case Ch_SINGLE_QUOTE:
|
|
128
|
+
{
|
|
129
|
+
const endQuotePosition = indexOfArrayNonEscaped(string, ["'"], firstMatchPos + 1);
|
|
130
|
+
if (endQuotePosition === -1) {
|
|
131
|
+
return -1;
|
|
132
|
+
}
|
|
133
|
+
currentSearchPosition = endQuotePosition + 1;
|
|
134
|
+
}
|
|
135
|
+
break;
|
|
136
|
+
default:
|
|
137
|
+
return firstMatchPos;
|
|
138
|
+
}
|
|
139
|
+
maxLoop--;
|
|
140
|
+
} while (maxLoop > 0);
|
|
141
|
+
throw new Error('Too many escaping');
|
|
142
|
+
};
|
|
143
|
+
/**
|
|
144
|
+
* Split a string by search tokens, respecting brackets and quotes
|
|
145
|
+
* @example
|
|
146
|
+
* ```ts
|
|
147
|
+
* splitWithBracketAndQuoteSupport('a,b', [',']) // ['a', 'b']
|
|
148
|
+
* splitWithBracketAndQuoteSupport('a,(b,c)', [',']) // ['a', '(b,c)']
|
|
149
|
+
* splitWithBracketAndQuoteSupport('a,"b,c"', [',']) // ['a', '"b,c"']
|
|
150
|
+
* splitWithBracketAndQuoteSupport("a,'b,c'", [',']) // ['a', "'b,c'"]
|
|
151
|
+
* ```
|
|
152
|
+
*/
|
|
153
|
+
export const splitWithBracketAndQuoteSupport = (string, search) => {
|
|
154
|
+
const result = [];
|
|
155
|
+
let currentPosition = 0;
|
|
156
|
+
while (currentPosition < string.length) {
|
|
157
|
+
const index = indexOfArrayWithBracketAndQuoteSupport(string, search, currentPosition);
|
|
158
|
+
if (index === -1) {
|
|
159
|
+
result.push(string.substring(currentPosition));
|
|
160
|
+
return result;
|
|
161
|
+
}
|
|
162
|
+
result.push(string.substring(currentPosition, index));
|
|
163
|
+
currentPosition = index + 1;
|
|
164
|
+
}
|
|
165
|
+
return result;
|
|
166
|
+
};
|