domflax 0.1.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/LICENSE +214 -0
- package/dist/chunk-4HHISSMR.js +2227 -0
- package/dist/chunk-4HHISSMR.js.map +1 -0
- package/dist/chunk-6WVVF6AD.js +55 -0
- package/dist/chunk-6WVVF6AD.js.map +1 -0
- package/dist/chunk-77SLHRN6.js +2047 -0
- package/dist/chunk-77SLHRN6.js.map +1 -0
- package/dist/chunk-ZJ2S36GY.js +175 -0
- package/dist/chunk-ZJ2S36GY.js.map +1 -0
- package/dist/cli.cjs +5207 -0
- package/dist/cli.cjs.map +1 -0
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +1310 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.cjs +4383 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +539 -0
- package/dist/index.d.ts +539 -0
- package/dist/index.js +110 -0
- package/dist/index.js.map +1 -0
- package/dist/pattern-CX6iBzTD.d.ts +237 -0
- package/dist/pattern-P4FIKAUB.d.cts +237 -0
- package/dist/pattern-kit.cjs +630 -0
- package/dist/pattern-kit.cjs.map +1 -0
- package/dist/pattern-kit.d.cts +80 -0
- package/dist/pattern-kit.d.ts +80 -0
- package/dist/pattern-kit.js +55 -0
- package/dist/pattern-kit.js.map +1 -0
- package/dist/types-BQ7l6dVe.d.cts +749 -0
- package/dist/types-BQ7l6dVe.d.ts +749 -0
- package/dist/verify.cjs +2747 -0
- package/dist/verify.cjs.map +1 -0
- package/dist/verify.d.cts +245 -0
- package/dist/verify.d.ts +245 -0
- package/dist/verify.js +2700 -0
- package/dist/verify.js.map +1 -0
- package/dist/webpack-loader.cjs +4149 -0
- package/dist/webpack-loader.cjs.map +1 -0
- package/dist/webpack-loader.d.cts +21 -0
- package/dist/webpack-loader.d.ts +21 -0
- package/dist/webpack-loader.js +30 -0
- package/dist/webpack-loader.js.map +1 -0
- package/package.json +99 -0
|
@@ -0,0 +1,2047 @@
|
|
|
1
|
+
import {
|
|
2
|
+
init_esm_shims
|
|
3
|
+
} from "./chunk-6WVVF6AD.js";
|
|
4
|
+
|
|
5
|
+
// ../core/src/builders.ts
|
|
6
|
+
init_esm_shims();
|
|
7
|
+
function createIdAllocator(start = 1) {
|
|
8
|
+
let n = start;
|
|
9
|
+
return {
|
|
10
|
+
next() {
|
|
11
|
+
const id = n;
|
|
12
|
+
n += 1;
|
|
13
|
+
return id;
|
|
14
|
+
},
|
|
15
|
+
get peek() {
|
|
16
|
+
return n;
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
function createExprRegistry(start = 1) {
|
|
21
|
+
const map = /* @__PURE__ */ new Map();
|
|
22
|
+
let n = start;
|
|
23
|
+
return {
|
|
24
|
+
get(r) {
|
|
25
|
+
return map.get(r);
|
|
26
|
+
},
|
|
27
|
+
intern(rec) {
|
|
28
|
+
const ref = n;
|
|
29
|
+
n += 1;
|
|
30
|
+
map.set(ref, { ...rec, ref });
|
|
31
|
+
return ref;
|
|
32
|
+
},
|
|
33
|
+
releasePayloads() {
|
|
34
|
+
for (const [k, v] of map) map.set(k, { ...v, payload: void 0 });
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
function createBackrefTable() {
|
|
39
|
+
const map = /* @__PURE__ */ new Map();
|
|
40
|
+
return {
|
|
41
|
+
get(id) {
|
|
42
|
+
return map.get(id);
|
|
43
|
+
},
|
|
44
|
+
span(id) {
|
|
45
|
+
return map.get(id)?.span ?? null;
|
|
46
|
+
},
|
|
47
|
+
childrenSpan(id) {
|
|
48
|
+
return map.get(id)?.innerSpan ?? null;
|
|
49
|
+
},
|
|
50
|
+
set(id, backref) {
|
|
51
|
+
map.set(id, backref);
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function defaultMeta(safetyFloor = 0) {
|
|
56
|
+
return {
|
|
57
|
+
hasRef: false,
|
|
58
|
+
hasEventHandlers: false,
|
|
59
|
+
hasKey: false,
|
|
60
|
+
hasSpreadAttrs: false,
|
|
61
|
+
hasDynamicChildren: false,
|
|
62
|
+
isComponent: false,
|
|
63
|
+
hasDangerousHtml: false,
|
|
64
|
+
targetedByCombinator: false,
|
|
65
|
+
targetedByStructuralPseudo: false,
|
|
66
|
+
selectorDependents: 0,
|
|
67
|
+
hasOwnVisualStyle: false,
|
|
68
|
+
establishesBox: false,
|
|
69
|
+
establishesStackingContext: false,
|
|
70
|
+
isContainingBlock: false,
|
|
71
|
+
establishesFormattingContext: false,
|
|
72
|
+
declaresCustomProperties: false,
|
|
73
|
+
whitespaceSensitive: false,
|
|
74
|
+
touched: false,
|
|
75
|
+
synthetic: false,
|
|
76
|
+
safetyFloor
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
var BASE_CONDITION = { media: "", states: [], pseudoElement: "" };
|
|
80
|
+
function conditionKey(c) {
|
|
81
|
+
const states = [...c.states].sort().join(",");
|
|
82
|
+
return `${c.media}|${states}|${c.pseudoElement}`;
|
|
83
|
+
}
|
|
84
|
+
var BASE_CONDITION_KEY = conditionKey(BASE_CONDITION);
|
|
85
|
+
function emptyStyleMap() {
|
|
86
|
+
return { blocks: /* @__PURE__ */ new Map() };
|
|
87
|
+
}
|
|
88
|
+
function emptyClassList() {
|
|
89
|
+
return {
|
|
90
|
+
form: "absent",
|
|
91
|
+
segments: [],
|
|
92
|
+
valueSpan: null,
|
|
93
|
+
hasDynamic: false,
|
|
94
|
+
opaque: false,
|
|
95
|
+
rewritable: false
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
function emptyAttrMap() {
|
|
99
|
+
return { entries: /* @__PURE__ */ new Map(), spreads: [], order: [] };
|
|
100
|
+
}
|
|
101
|
+
function emptyInlineStyle() {
|
|
102
|
+
return { decls: /* @__PURE__ */ new Map(), dynamic: null };
|
|
103
|
+
}
|
|
104
|
+
function createElement(id, init) {
|
|
105
|
+
return {
|
|
106
|
+
id,
|
|
107
|
+
kind: "element",
|
|
108
|
+
parent: init.parent ?? null,
|
|
109
|
+
span: init.span ?? null,
|
|
110
|
+
meta: init.meta ?? defaultMeta(),
|
|
111
|
+
tag: init.tag,
|
|
112
|
+
namespace: init.namespace ?? "html",
|
|
113
|
+
isComponent: init.isComponent ?? false,
|
|
114
|
+
selfClosing: init.selfClosing ?? false,
|
|
115
|
+
classes: init.classes ?? emptyClassList(),
|
|
116
|
+
inlineStyle: init.inlineStyle ?? emptyInlineStyle(),
|
|
117
|
+
computed: init.computed ?? emptyStyleMap(),
|
|
118
|
+
attrs: init.attrs ?? emptyAttrMap(),
|
|
119
|
+
children: init.children ?? []
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
function createText(id, value, opts) {
|
|
123
|
+
return {
|
|
124
|
+
id,
|
|
125
|
+
kind: "text",
|
|
126
|
+
parent: opts?.parent ?? null,
|
|
127
|
+
span: opts?.span ?? null,
|
|
128
|
+
meta: defaultMeta(),
|
|
129
|
+
value,
|
|
130
|
+
collapsible: opts?.collapsible ?? true
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
function createExpr(id, expr, opts) {
|
|
134
|
+
return {
|
|
135
|
+
id,
|
|
136
|
+
kind: "expr",
|
|
137
|
+
parent: opts?.parent ?? null,
|
|
138
|
+
span: opts?.span ?? null,
|
|
139
|
+
meta: defaultMeta(),
|
|
140
|
+
expr
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
function createFragment(id, opts) {
|
|
144
|
+
return {
|
|
145
|
+
id,
|
|
146
|
+
kind: "fragment",
|
|
147
|
+
parent: opts?.parent ?? null,
|
|
148
|
+
span: opts?.span ?? null,
|
|
149
|
+
meta: defaultMeta(),
|
|
150
|
+
children: opts?.children ?? []
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
function createComment(id, value, opts) {
|
|
154
|
+
return {
|
|
155
|
+
id,
|
|
156
|
+
kind: "comment",
|
|
157
|
+
parent: opts?.parent ?? null,
|
|
158
|
+
span: opts?.span ?? null,
|
|
159
|
+
meta: defaultMeta(),
|
|
160
|
+
value
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
function createDocument(frontend) {
|
|
164
|
+
const alloc = createIdAllocator();
|
|
165
|
+
const rootId = alloc.next();
|
|
166
|
+
const root = createFragment(rootId);
|
|
167
|
+
const nodes = /* @__PURE__ */ new Map([[rootId, root]]);
|
|
168
|
+
return {
|
|
169
|
+
root: rootId,
|
|
170
|
+
nodes,
|
|
171
|
+
exprs: createExprRegistry(),
|
|
172
|
+
sources: /* @__PURE__ */ new Map(),
|
|
173
|
+
backref: createBackrefTable(),
|
|
174
|
+
frontend,
|
|
175
|
+
alloc
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
function childIds(node) {
|
|
179
|
+
return node.kind === "element" || node.kind === "fragment" ? node.children : [];
|
|
180
|
+
}
|
|
181
|
+
function getNode(doc, id) {
|
|
182
|
+
return doc.nodes.get(id);
|
|
183
|
+
}
|
|
184
|
+
function getElement(doc, id) {
|
|
185
|
+
const n = doc.nodes.get(id);
|
|
186
|
+
return n && n.kind === "element" ? n : void 0;
|
|
187
|
+
}
|
|
188
|
+
function elementIds(doc) {
|
|
189
|
+
const out = [];
|
|
190
|
+
const visit = (id) => {
|
|
191
|
+
const n = doc.nodes.get(id);
|
|
192
|
+
if (!n) return;
|
|
193
|
+
if (n.kind === "element") out.push(id);
|
|
194
|
+
for (const c of childIds(n)) visit(c);
|
|
195
|
+
};
|
|
196
|
+
visit(doc.root);
|
|
197
|
+
return out;
|
|
198
|
+
}
|
|
199
|
+
function walk(doc, visitor) {
|
|
200
|
+
const roDoc = doc;
|
|
201
|
+
let stopped = false;
|
|
202
|
+
const visit = (id, depth) => {
|
|
203
|
+
if (stopped) return;
|
|
204
|
+
const node = doc.nodes.get(id);
|
|
205
|
+
if (!node) return;
|
|
206
|
+
const ctx = {
|
|
207
|
+
doc: roDoc,
|
|
208
|
+
depth,
|
|
209
|
+
parent() {
|
|
210
|
+
return node.parent == null ? null : doc.nodes.get(node.parent) ?? null;
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
const entered = visitor.enter ? visitor.enter(node, ctx) : void 0;
|
|
214
|
+
if (entered === "stop") {
|
|
215
|
+
stopped = true;
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
if (entered !== "skip") {
|
|
219
|
+
for (const child of childIds(node)) {
|
|
220
|
+
visit(child, depth + 1);
|
|
221
|
+
if (stopped) return;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
const exited = visitor.exit ? visitor.exit(node, ctx) : void 0;
|
|
225
|
+
if (exited === "stop") stopped = true;
|
|
226
|
+
};
|
|
227
|
+
visit(doc.root, 0);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// ../core/src/ops.ts
|
|
231
|
+
init_esm_shims();
|
|
232
|
+
function cloneStyleMap(sm) {
|
|
233
|
+
const blocks = /* @__PURE__ */ new Map();
|
|
234
|
+
for (const [key, block] of sm.blocks) {
|
|
235
|
+
blocks.set(key, {
|
|
236
|
+
condition: block.condition,
|
|
237
|
+
decls: new Map(block.decls)
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
return { blocks };
|
|
241
|
+
}
|
|
242
|
+
function cloneNode(node) {
|
|
243
|
+
const meta = { ...node.meta };
|
|
244
|
+
switch (node.kind) {
|
|
245
|
+
case "element":
|
|
246
|
+
return {
|
|
247
|
+
...node,
|
|
248
|
+
meta,
|
|
249
|
+
children: [...node.children],
|
|
250
|
+
computed: cloneStyleMap(node.computed)
|
|
251
|
+
};
|
|
252
|
+
case "fragment":
|
|
253
|
+
return { ...node, meta, children: [...node.children] };
|
|
254
|
+
default:
|
|
255
|
+
return { ...node, meta };
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
function cloneDocument(doc) {
|
|
259
|
+
const nodes = /* @__PURE__ */ new Map();
|
|
260
|
+
for (const [id, n] of doc.nodes) nodes.set(id, cloneNode(n));
|
|
261
|
+
return {
|
|
262
|
+
root: doc.root,
|
|
263
|
+
nodes,
|
|
264
|
+
exprs: doc.exprs,
|
|
265
|
+
sources: doc.sources,
|
|
266
|
+
backref: doc.backref,
|
|
267
|
+
frontend: doc.frontend,
|
|
268
|
+
alloc: doc.alloc
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
function diag(code, message, extra) {
|
|
272
|
+
return { code, severity: "warn", message, ...extra };
|
|
273
|
+
}
|
|
274
|
+
function getParentChildren(doc, id) {
|
|
275
|
+
const node = doc.nodes.get(id);
|
|
276
|
+
if (!node || node.parent == null) return null;
|
|
277
|
+
const parent = doc.nodes.get(node.parent);
|
|
278
|
+
if (!parent) return null;
|
|
279
|
+
if (parent.kind === "element" || parent.kind === "fragment") return parent.children;
|
|
280
|
+
return null;
|
|
281
|
+
}
|
|
282
|
+
function markTouched(state, id) {
|
|
283
|
+
const n = state.doc.nodes.get(id);
|
|
284
|
+
if (n) {
|
|
285
|
+
n.meta.touched = true;
|
|
286
|
+
state.touched.add(id);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
function removeSubtree(state, id) {
|
|
290
|
+
const node = state.doc.nodes.get(id);
|
|
291
|
+
if (!node) return;
|
|
292
|
+
if (node.kind === "element" || node.kind === "fragment") {
|
|
293
|
+
for (const child of [...node.children]) removeSubtree(state, child);
|
|
294
|
+
}
|
|
295
|
+
state.doc.nodes.delete(id);
|
|
296
|
+
state.removed.add(id);
|
|
297
|
+
}
|
|
298
|
+
function specToAttrs(map) {
|
|
299
|
+
if (!map || map.size === 0) return { entries: /* @__PURE__ */ new Map(), spreads: [], order: [] };
|
|
300
|
+
const entries = /* @__PURE__ */ new Map();
|
|
301
|
+
const order = [];
|
|
302
|
+
for (const [k, v] of map) {
|
|
303
|
+
entries.set(k, { kind: "static", value: v });
|
|
304
|
+
order.push(k);
|
|
305
|
+
}
|
|
306
|
+
return { entries, spreads: [], order };
|
|
307
|
+
}
|
|
308
|
+
function materialize(state, spec, parent) {
|
|
309
|
+
const { doc } = state;
|
|
310
|
+
if (spec.kind === "ref") {
|
|
311
|
+
const existing = doc.nodes.get(spec.ref);
|
|
312
|
+
if (existing) existing.parent = parent;
|
|
313
|
+
return spec.ref;
|
|
314
|
+
}
|
|
315
|
+
const id = doc.alloc.next();
|
|
316
|
+
state.created.add(id);
|
|
317
|
+
switch (spec.kind) {
|
|
318
|
+
case "element": {
|
|
319
|
+
const childIds2 = [];
|
|
320
|
+
const el = createElement(id, {
|
|
321
|
+
tag: spec.tag,
|
|
322
|
+
namespace: spec.namespace,
|
|
323
|
+
selfClosing: spec.selfClosing,
|
|
324
|
+
attrs: specToAttrs(spec.attrs),
|
|
325
|
+
parent,
|
|
326
|
+
meta: { ...defaultMeta(), synthetic: true }
|
|
327
|
+
});
|
|
328
|
+
if (spec.classes) el.computed = cloneStyleMap(spec.classes);
|
|
329
|
+
doc.nodes.set(id, el);
|
|
330
|
+
for (const child of spec.children ?? []) {
|
|
331
|
+
childIds2.push(materialize(state, child, id));
|
|
332
|
+
}
|
|
333
|
+
el.children = childIds2;
|
|
334
|
+
return id;
|
|
335
|
+
}
|
|
336
|
+
case "text": {
|
|
337
|
+
const t = createText(id, spec.value, { parent });
|
|
338
|
+
t.meta.synthetic = true;
|
|
339
|
+
doc.nodes.set(id, t);
|
|
340
|
+
return id;
|
|
341
|
+
}
|
|
342
|
+
case "expr": {
|
|
343
|
+
const e = createExpr(id, spec.expr, { parent });
|
|
344
|
+
e.meta.synthetic = true;
|
|
345
|
+
doc.nodes.set(id, e);
|
|
346
|
+
return id;
|
|
347
|
+
}
|
|
348
|
+
case "comment": {
|
|
349
|
+
const c = createComment(id, spec.value, { parent });
|
|
350
|
+
c.meta.synthetic = true;
|
|
351
|
+
doc.nodes.set(id, c);
|
|
352
|
+
return id;
|
|
353
|
+
}
|
|
354
|
+
case "fragment": {
|
|
355
|
+
const frag = createFragment(id, { parent });
|
|
356
|
+
frag.meta.synthetic = true;
|
|
357
|
+
doc.nodes.set(id, frag);
|
|
358
|
+
const childIds2 = [];
|
|
359
|
+
for (const child of spec.children) childIds2.push(materialize(state, child, id));
|
|
360
|
+
frag.children = childIds2;
|
|
361
|
+
return id;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
function elementSpecToNode(state, spec, parent) {
|
|
366
|
+
return materialize(state, spec, parent);
|
|
367
|
+
}
|
|
368
|
+
function isInherited(state, decl) {
|
|
369
|
+
if (decl.inherited) return true;
|
|
370
|
+
const table = state.ctx.normalizer?.inherited;
|
|
371
|
+
if (table) {
|
|
372
|
+
try {
|
|
373
|
+
return table.isInherited(decl.property);
|
|
374
|
+
} catch {
|
|
375
|
+
return decl.inherited;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
return decl.inherited;
|
|
379
|
+
}
|
|
380
|
+
function mergeStyleMaps(target, source, policy) {
|
|
381
|
+
const blocks = new Map(cloneStyleMap(target).blocks);
|
|
382
|
+
let conflict = false;
|
|
383
|
+
for (const [key, srcBlock] of source.blocks) {
|
|
384
|
+
const existing = blocks.get(key);
|
|
385
|
+
if (!existing) {
|
|
386
|
+
blocks.set(key, {
|
|
387
|
+
condition: srcBlock.condition,
|
|
388
|
+
decls: new Map(srcBlock.decls)
|
|
389
|
+
});
|
|
390
|
+
continue;
|
|
391
|
+
}
|
|
392
|
+
const decls = new Map(existing.decls);
|
|
393
|
+
for (const [prop, srcDecl] of srcBlock.decls) {
|
|
394
|
+
const had = decls.get(prop);
|
|
395
|
+
if (had && had.value !== srcDecl.value) {
|
|
396
|
+
conflict = true;
|
|
397
|
+
if (policy === "target-wins") continue;
|
|
398
|
+
}
|
|
399
|
+
if (policy === "target-wins" && had) continue;
|
|
400
|
+
decls.set(prop, srcDecl);
|
|
401
|
+
}
|
|
402
|
+
blocks.set(key, { condition: existing.condition, decls });
|
|
403
|
+
}
|
|
404
|
+
return { map: { blocks }, conflict };
|
|
405
|
+
}
|
|
406
|
+
function safetyOk(state, op, targetId) {
|
|
407
|
+
const opSafety = op.origin.safety;
|
|
408
|
+
if (opSafety > state.ceiling) {
|
|
409
|
+
return diag(
|
|
410
|
+
"DF_SAFETY_CEILING_EXCEEDED",
|
|
411
|
+
`op '${op.op}' safety ${opSafety} exceeds ceiling ${state.ceiling}`,
|
|
412
|
+
{ nodeId: targetId, pattern: op.origin.pattern, severity: "error" }
|
|
413
|
+
);
|
|
414
|
+
}
|
|
415
|
+
const node = state.doc.nodes.get(targetId);
|
|
416
|
+
if (node && opSafety > node.meta.safetyFloor) {
|
|
417
|
+
return diag(
|
|
418
|
+
"DF_SAFETY_CEILING_EXCEEDED",
|
|
419
|
+
`op '${op.op}' safety ${opSafety} exceeds node ${targetId} floor ${node.meta.safetyFloor}`,
|
|
420
|
+
{ nodeId: targetId, pattern: op.origin.pattern, severity: "error" }
|
|
421
|
+
);
|
|
422
|
+
}
|
|
423
|
+
return null;
|
|
424
|
+
}
|
|
425
|
+
function applyOne(state, op) {
|
|
426
|
+
const { doc } = state;
|
|
427
|
+
const primary = primaryTarget(op);
|
|
428
|
+
if (primary != null) {
|
|
429
|
+
if (!doc.nodes.get(primary)) {
|
|
430
|
+
return [
|
|
431
|
+
diag("DF_OP_PRECONDITION_FAILED", `target node ${primary} not found`, {
|
|
432
|
+
nodeId: primary,
|
|
433
|
+
pattern: op.origin.pattern,
|
|
434
|
+
severity: "error"
|
|
435
|
+
})
|
|
436
|
+
];
|
|
437
|
+
}
|
|
438
|
+
const safety = safetyOk(state, op, primary);
|
|
439
|
+
if (safety) return [safety];
|
|
440
|
+
}
|
|
441
|
+
switch (op.op) {
|
|
442
|
+
case "removeNode": {
|
|
443
|
+
const siblings = getParentChildren(doc, op.target);
|
|
444
|
+
if (siblings) {
|
|
445
|
+
const i = siblings.indexOf(op.target);
|
|
446
|
+
if (i >= 0) siblings.splice(i, 1);
|
|
447
|
+
}
|
|
448
|
+
removeSubtree(state, op.target);
|
|
449
|
+
return [];
|
|
450
|
+
}
|
|
451
|
+
case "unwrap": {
|
|
452
|
+
const node = doc.nodes.get(op.target);
|
|
453
|
+
if (!node || node.kind !== "element" && node.kind !== "fragment") {
|
|
454
|
+
return [precond(op, op.target, "unwrap target is not a container")];
|
|
455
|
+
}
|
|
456
|
+
const siblings = getParentChildren(doc, op.target);
|
|
457
|
+
if (!siblings) return [precond(op, op.target, "unwrap target has no parent")];
|
|
458
|
+
const at = siblings.indexOf(op.target);
|
|
459
|
+
const kids = node.children;
|
|
460
|
+
for (const k of kids) {
|
|
461
|
+
const kn = doc.nodes.get(k);
|
|
462
|
+
if (kn) kn.parent = node.parent;
|
|
463
|
+
}
|
|
464
|
+
siblings.splice(at, 1, ...kids);
|
|
465
|
+
doc.nodes.delete(op.target);
|
|
466
|
+
state.removed.add(op.target);
|
|
467
|
+
if (node.parent != null) markTouched(state, node.parent);
|
|
468
|
+
return [];
|
|
469
|
+
}
|
|
470
|
+
case "replaceWith": {
|
|
471
|
+
const siblings = getParentChildren(doc, op.target);
|
|
472
|
+
if (!siblings) return [precond(op, op.target, "replaceWith target has no parent")];
|
|
473
|
+
const at = siblings.indexOf(op.target);
|
|
474
|
+
const parentId = doc.nodes.get(op.target)?.parent ?? null;
|
|
475
|
+
const newId = materialize(state, op.replacement, parentId);
|
|
476
|
+
siblings.splice(at, 1, newId);
|
|
477
|
+
removeSubtree(state, op.target);
|
|
478
|
+
if (parentId != null) markTouched(state, parentId);
|
|
479
|
+
return [];
|
|
480
|
+
}
|
|
481
|
+
case "wrap": {
|
|
482
|
+
const siblings = getParentChildren(doc, op.target);
|
|
483
|
+
if (!siblings) return [precond(op, op.target, "wrap target has no parent")];
|
|
484
|
+
const at = siblings.indexOf(op.target);
|
|
485
|
+
const parentId = doc.nodes.get(op.target)?.parent ?? null;
|
|
486
|
+
const wrapperId = elementSpecToNode(state, op.wrapper, parentId);
|
|
487
|
+
const wrapper = doc.nodes.get(wrapperId);
|
|
488
|
+
const targetNode = doc.nodes.get(op.target);
|
|
489
|
+
if (wrapper && (wrapper.kind === "element" || wrapper.kind === "fragment")) {
|
|
490
|
+
wrapper.children.push(op.target);
|
|
491
|
+
}
|
|
492
|
+
if (targetNode) targetNode.parent = wrapperId;
|
|
493
|
+
siblings.splice(at, 1, wrapperId);
|
|
494
|
+
return [];
|
|
495
|
+
}
|
|
496
|
+
case "insertBefore":
|
|
497
|
+
case "insertAfter": {
|
|
498
|
+
const siblings = getParentChildren(doc, op.anchor);
|
|
499
|
+
if (!siblings) return [precond(op, op.anchor, "insert anchor has no parent")];
|
|
500
|
+
const at = siblings.indexOf(op.anchor);
|
|
501
|
+
const parentId = doc.nodes.get(op.anchor)?.parent ?? null;
|
|
502
|
+
const newId = materialize(state, op.node, parentId);
|
|
503
|
+
siblings.splice(op.op === "insertBefore" ? at : at + 1, 0, newId);
|
|
504
|
+
if (parentId != null) markTouched(state, parentId);
|
|
505
|
+
return [];
|
|
506
|
+
}
|
|
507
|
+
case "moveNode": {
|
|
508
|
+
const newParent = doc.nodes.get(op.newParent);
|
|
509
|
+
if (!newParent || newParent.kind !== "element" && newParent.kind !== "fragment") {
|
|
510
|
+
return [precond(op, op.newParent, "moveNode newParent is not a container")];
|
|
511
|
+
}
|
|
512
|
+
const siblings = getParentChildren(doc, op.target);
|
|
513
|
+
if (siblings) {
|
|
514
|
+
const i = siblings.indexOf(op.target);
|
|
515
|
+
if (i >= 0) siblings.splice(i, 1);
|
|
516
|
+
}
|
|
517
|
+
const target = doc.nodes.get(op.target);
|
|
518
|
+
if (target) target.parent = op.newParent;
|
|
519
|
+
const idx = Math.max(0, Math.min(op.index, newParent.children.length));
|
|
520
|
+
newParent.children.splice(idx, 0, op.target);
|
|
521
|
+
markTouched(state, op.newParent);
|
|
522
|
+
return [];
|
|
523
|
+
}
|
|
524
|
+
case "mergeSiblings": {
|
|
525
|
+
const first = doc.nodes.get(op.first);
|
|
526
|
+
const second = doc.nodes.get(op.second);
|
|
527
|
+
if (!first || !second) return [precond(op, op.first, "mergeSiblings node missing")];
|
|
528
|
+
if ((first.kind === "element" || first.kind === "fragment") && (second.kind === "element" || second.kind === "fragment")) {
|
|
529
|
+
for (const c of second.children) {
|
|
530
|
+
const cn = doc.nodes.get(c);
|
|
531
|
+
if (cn) cn.parent = op.first;
|
|
532
|
+
first.children.push(c);
|
|
533
|
+
}
|
|
534
|
+
second.children = [];
|
|
535
|
+
}
|
|
536
|
+
const siblings = getParentChildren(doc, op.second);
|
|
537
|
+
if (siblings) {
|
|
538
|
+
const i = siblings.indexOf(op.second);
|
|
539
|
+
if (i >= 0) siblings.splice(i, 1);
|
|
540
|
+
}
|
|
541
|
+
doc.nodes.delete(op.second);
|
|
542
|
+
state.removed.add(op.second);
|
|
543
|
+
markTouched(state, op.first);
|
|
544
|
+
return [];
|
|
545
|
+
}
|
|
546
|
+
case "setClassList": {
|
|
547
|
+
const el = doc.nodes.get(op.target);
|
|
548
|
+
if (!el || el.kind !== "element") {
|
|
549
|
+
return [precond(op, op.target, "setClassList target is not an element")];
|
|
550
|
+
}
|
|
551
|
+
el.computed = cloneStyleMap(op.style);
|
|
552
|
+
markTouched(state, op.target);
|
|
553
|
+
return [];
|
|
554
|
+
}
|
|
555
|
+
case "mergeStyle": {
|
|
556
|
+
const el = doc.nodes.get(op.target);
|
|
557
|
+
if (!el || el.kind !== "element") {
|
|
558
|
+
return [precond(op, op.target, "mergeStyle target is not an element")];
|
|
559
|
+
}
|
|
560
|
+
const report = mergeStyleMaps(el.computed, op.style, op.onConflict);
|
|
561
|
+
if (report.conflict && op.onConflict === "abort") {
|
|
562
|
+
return [
|
|
563
|
+
diag("DF_STYLE_CONFLICT_UNRESOLVED", `mergeStyle aborted on conflict at ${op.target}`, {
|
|
564
|
+
nodeId: op.target,
|
|
565
|
+
pattern: op.origin.pattern,
|
|
566
|
+
severity: "error"
|
|
567
|
+
})
|
|
568
|
+
];
|
|
569
|
+
}
|
|
570
|
+
el.computed = report.map;
|
|
571
|
+
if (op.source != null) {
|
|
572
|
+
const src = doc.nodes.get(op.source);
|
|
573
|
+
if (src) markTouched(state, op.source);
|
|
574
|
+
}
|
|
575
|
+
markTouched(state, op.target);
|
|
576
|
+
return [];
|
|
577
|
+
}
|
|
578
|
+
case "foldInheritedStyles":
|
|
579
|
+
return applyFold(state, op);
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
function applyFold(state, op) {
|
|
583
|
+
const { doc } = state;
|
|
584
|
+
const from = doc.nodes.get(op.from);
|
|
585
|
+
if (!from || from.kind !== "element") {
|
|
586
|
+
return [precond(op, op.from, "fold source is not an element")];
|
|
587
|
+
}
|
|
588
|
+
const issues = [];
|
|
589
|
+
const onlyProps = op.properties === "all-inherited" ? null : new Set(op.properties);
|
|
590
|
+
const conditionKeys = op.conditions === "all" ? [...from.computed.blocks.keys()] : [BASE_CONDITION_KEY];
|
|
591
|
+
for (const intoId of op.into) {
|
|
592
|
+
const into = doc.nodes.get(intoId);
|
|
593
|
+
if (!into || into.kind !== "element") {
|
|
594
|
+
issues.push(precond(op, intoId, "fold target is not an element"));
|
|
595
|
+
continue;
|
|
596
|
+
}
|
|
597
|
+
const nextBlocks = new Map(cloneStyleMap(into.computed).blocks);
|
|
598
|
+
let folded = false;
|
|
599
|
+
for (const key of conditionKeys) {
|
|
600
|
+
const srcBlock = from.computed.blocks.get(key);
|
|
601
|
+
if (!srcBlock) continue;
|
|
602
|
+
const dstBlock = nextBlocks.get(key);
|
|
603
|
+
const decls = dstBlock ? new Map(dstBlock.decls) : /* @__PURE__ */ new Map();
|
|
604
|
+
for (const [prop, decl] of srcBlock.decls) {
|
|
605
|
+
if (onlyProps && !onlyProps.has(prop)) continue;
|
|
606
|
+
if (!isInherited(state, decl)) continue;
|
|
607
|
+
if (decl.relativeToParent) {
|
|
608
|
+
issues.push(
|
|
609
|
+
diag(
|
|
610
|
+
"DF_RELATIVE_UNIT_FOLD",
|
|
611
|
+
`refused to fold relative-unit declaration '${decl.property}' onto ${intoId}`,
|
|
612
|
+
{ nodeId: intoId, pattern: op.origin.pattern, severity: "warn" }
|
|
613
|
+
)
|
|
614
|
+
);
|
|
615
|
+
continue;
|
|
616
|
+
}
|
|
617
|
+
if (!decls.has(prop)) {
|
|
618
|
+
decls.set(prop, decl);
|
|
619
|
+
folded = true;
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
nextBlocks.set(key, { condition: srcBlock.condition, decls });
|
|
623
|
+
}
|
|
624
|
+
if (folded) {
|
|
625
|
+
into.computed = { blocks: nextBlocks };
|
|
626
|
+
markTouched(state, intoId);
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
for (const d of issues) state.diagnostics.push(d);
|
|
630
|
+
return [];
|
|
631
|
+
}
|
|
632
|
+
function precond(op, nodeId, message) {
|
|
633
|
+
return diag("DF_OP_PRECONDITION_FAILED", message, {
|
|
634
|
+
nodeId,
|
|
635
|
+
pattern: op.origin.pattern,
|
|
636
|
+
severity: "error"
|
|
637
|
+
});
|
|
638
|
+
}
|
|
639
|
+
function primaryTarget(op) {
|
|
640
|
+
switch (op.op) {
|
|
641
|
+
case "removeNode":
|
|
642
|
+
case "unwrap":
|
|
643
|
+
case "replaceWith":
|
|
644
|
+
case "wrap":
|
|
645
|
+
case "moveNode":
|
|
646
|
+
case "setClassList":
|
|
647
|
+
case "mergeStyle":
|
|
648
|
+
return op.target;
|
|
649
|
+
case "insertBefore":
|
|
650
|
+
case "insertAfter":
|
|
651
|
+
return op.anchor;
|
|
652
|
+
case "mergeSiblings":
|
|
653
|
+
return op.first;
|
|
654
|
+
case "foldInheritedStyles":
|
|
655
|
+
return op.from;
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
function applyOps(doc, ops, ctx) {
|
|
659
|
+
const cloned = cloneDocument(doc);
|
|
660
|
+
const state = {
|
|
661
|
+
doc: cloned,
|
|
662
|
+
touched: /* @__PURE__ */ new Set(),
|
|
663
|
+
removed: /* @__PURE__ */ new Set(),
|
|
664
|
+
created: /* @__PURE__ */ new Set(),
|
|
665
|
+
diagnostics: [],
|
|
666
|
+
skipped: [],
|
|
667
|
+
appliedGroups: 0,
|
|
668
|
+
ceiling: ctx?.safetyCeiling ?? 3,
|
|
669
|
+
ctx: { doc: cloned, safetyCeiling: ctx?.safetyCeiling ?? 3, ...ctx }
|
|
670
|
+
};
|
|
671
|
+
for (const op of ops) {
|
|
672
|
+
const issues = applyOne(state, op);
|
|
673
|
+
if (issues.length > 0) {
|
|
674
|
+
state.skipped.push({
|
|
675
|
+
group: { pattern: op.origin.pattern, anchor: primaryTarget(op) ?? doc.root, ops: [op] },
|
|
676
|
+
issues: issues.map((d) => ({ op, code: d.code, message: d.message }))
|
|
677
|
+
});
|
|
678
|
+
for (const d of issues) state.diagnostics.push(d);
|
|
679
|
+
} else {
|
|
680
|
+
state.appliedGroups += 1;
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
return { doc: cloned, result: finalize(state) };
|
|
684
|
+
}
|
|
685
|
+
function applyGroups(doc, groups, ctx) {
|
|
686
|
+
let current = cloneDocument(doc);
|
|
687
|
+
const touched = /* @__PURE__ */ new Set();
|
|
688
|
+
const removed = /* @__PURE__ */ new Set();
|
|
689
|
+
const created = /* @__PURE__ */ new Set();
|
|
690
|
+
const diagnostics = [];
|
|
691
|
+
const skipped = [];
|
|
692
|
+
let appliedGroups = 0;
|
|
693
|
+
for (const group of groups) {
|
|
694
|
+
const attempt = applyOps(current, group.ops, ctx);
|
|
695
|
+
if (attempt.result.skipped.length > 0) {
|
|
696
|
+
skipped.push({
|
|
697
|
+
group,
|
|
698
|
+
issues: attempt.result.skipped.flatMap((s) => s.issues)
|
|
699
|
+
});
|
|
700
|
+
for (const s of attempt.result.skipped) for (const i of s.issues) {
|
|
701
|
+
diagnostics.push(diag(i.code, i.message, { pattern: group.pattern }));
|
|
702
|
+
}
|
|
703
|
+
continue;
|
|
704
|
+
}
|
|
705
|
+
current = attempt.doc;
|
|
706
|
+
appliedGroups += 1;
|
|
707
|
+
for (const id of attempt.result.touched) touched.add(id);
|
|
708
|
+
for (const id of attempt.result.removed) removed.add(id);
|
|
709
|
+
for (const id of attempt.result.created) created.add(id);
|
|
710
|
+
for (const d of attempt.result.diagnostics) diagnostics.push(d);
|
|
711
|
+
}
|
|
712
|
+
const result = {
|
|
713
|
+
touched,
|
|
714
|
+
removed,
|
|
715
|
+
created,
|
|
716
|
+
appliedGroups,
|
|
717
|
+
skipped,
|
|
718
|
+
journal: [],
|
|
719
|
+
diagnostics
|
|
720
|
+
};
|
|
721
|
+
return { doc: current, result };
|
|
722
|
+
}
|
|
723
|
+
function finalize(state) {
|
|
724
|
+
return {
|
|
725
|
+
touched: state.touched,
|
|
726
|
+
removed: state.removed,
|
|
727
|
+
created: state.created,
|
|
728
|
+
appliedGroups: state.appliedGroups,
|
|
729
|
+
skipped: state.skipped,
|
|
730
|
+
journal: [],
|
|
731
|
+
diagnostics: state.diagnostics
|
|
732
|
+
};
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
// ../core/src/pass-manager.ts
|
|
736
|
+
init_esm_shims();
|
|
737
|
+
var DEFAULT_FIXPOINT = {
|
|
738
|
+
maxIterations: 16,
|
|
739
|
+
phases: { flatten: 16, compress: 8, extract: 4 },
|
|
740
|
+
onBudgetExhausted: "warn",
|
|
741
|
+
detectOscillation: true
|
|
742
|
+
};
|
|
743
|
+
var PHASE_ORDER = ["flatten", "compress", "extract"];
|
|
744
|
+
function createNullResolver() {
|
|
745
|
+
const empty = {
|
|
746
|
+
styles: emptyStyleMap(),
|
|
747
|
+
resolved: [],
|
|
748
|
+
unknown: [],
|
|
749
|
+
opaque: [],
|
|
750
|
+
warnings: []
|
|
751
|
+
};
|
|
752
|
+
const usage = {
|
|
753
|
+
asSubject: false,
|
|
754
|
+
asAncestor: false,
|
|
755
|
+
asCompound: false,
|
|
756
|
+
asSibling: false,
|
|
757
|
+
asHasArgument: false,
|
|
758
|
+
asStructural: false,
|
|
759
|
+
droppable: true
|
|
760
|
+
};
|
|
761
|
+
return {
|
|
762
|
+
id: "null",
|
|
763
|
+
provider: "null@0.0.0",
|
|
764
|
+
fingerprint: "null",
|
|
765
|
+
owns() {
|
|
766
|
+
return false;
|
|
767
|
+
},
|
|
768
|
+
resolve(_input) {
|
|
769
|
+
return empty;
|
|
770
|
+
},
|
|
771
|
+
emit(_styles, _ctx) {
|
|
772
|
+
return { classes: [], exact: true, warnings: [] };
|
|
773
|
+
},
|
|
774
|
+
selectorUsage() {
|
|
775
|
+
return usage;
|
|
776
|
+
}
|
|
777
|
+
};
|
|
778
|
+
}
|
|
779
|
+
function createNullSelectorIndex() {
|
|
780
|
+
const none = /* @__PURE__ */ new Set();
|
|
781
|
+
return {
|
|
782
|
+
targetedByCombinator() {
|
|
783
|
+
return false;
|
|
784
|
+
},
|
|
785
|
+
targetedByStructuralPseudo() {
|
|
786
|
+
return false;
|
|
787
|
+
},
|
|
788
|
+
reparentImpact() {
|
|
789
|
+
return none;
|
|
790
|
+
}
|
|
791
|
+
};
|
|
792
|
+
}
|
|
793
|
+
function hasComplexSelectors(r) {
|
|
794
|
+
return typeof r.complexSelectors === "function";
|
|
795
|
+
}
|
|
796
|
+
function buildSelectorIndex(doc, resolver) {
|
|
797
|
+
if (!hasComplexSelectors(resolver) || resolver.complexSelectors().length === 0) {
|
|
798
|
+
return createNullSelectorIndex();
|
|
799
|
+
}
|
|
800
|
+
const combinator = /* @__PURE__ */ new Set();
|
|
801
|
+
const structural = /* @__PURE__ */ new Set();
|
|
802
|
+
for (const id of elementIds(doc)) {
|
|
803
|
+
const el = getElement(doc, id);
|
|
804
|
+
if (!el) continue;
|
|
805
|
+
for (const seg of el.classes.segments) {
|
|
806
|
+
if (seg.kind !== "static") continue;
|
|
807
|
+
for (const t of seg.tokens) {
|
|
808
|
+
const u = resolver.selectorUsage(t.value);
|
|
809
|
+
if (u.asAncestor || u.asSibling || u.asHasArgument) combinator.add(id);
|
|
810
|
+
if (u.asStructural) structural.add(id);
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
const impact = /* @__PURE__ */ new Map();
|
|
815
|
+
for (const id of elementIds(doc)) {
|
|
816
|
+
const el = getElement(doc, id);
|
|
817
|
+
if (!el) continue;
|
|
818
|
+
if (!combinator.has(id) && !structural.has(id)) continue;
|
|
819
|
+
const set = /* @__PURE__ */ new Set([id]);
|
|
820
|
+
for (const c of el.children) {
|
|
821
|
+
const cn = doc.nodes.get(c);
|
|
822
|
+
if (cn && cn.kind === "element") set.add(c);
|
|
823
|
+
}
|
|
824
|
+
impact.set(id, set);
|
|
825
|
+
}
|
|
826
|
+
const empty = /* @__PURE__ */ new Set();
|
|
827
|
+
return {
|
|
828
|
+
targetedByCombinator: (id) => combinator.has(id),
|
|
829
|
+
targetedByStructuralPseudo: (id) => structural.has(id),
|
|
830
|
+
reparentImpact: (id) => impact.get(id) ?? empty
|
|
831
|
+
};
|
|
832
|
+
}
|
|
833
|
+
function idOf(n) {
|
|
834
|
+
return n.id;
|
|
835
|
+
}
|
|
836
|
+
function createRewriteFactory() {
|
|
837
|
+
return {
|
|
838
|
+
unwrap(target) {
|
|
839
|
+
return { op: "unwrap", target: idOf(target) };
|
|
840
|
+
},
|
|
841
|
+
removeNode(target) {
|
|
842
|
+
return { op: "removeNode", target: idOf(target) };
|
|
843
|
+
},
|
|
844
|
+
replaceWith(target, replacement) {
|
|
845
|
+
return { op: "replaceWith", target: idOf(target), replacement };
|
|
846
|
+
},
|
|
847
|
+
wrap(target, wrapper) {
|
|
848
|
+
return { op: "wrap", target: idOf(target), wrapper };
|
|
849
|
+
},
|
|
850
|
+
insertBefore(anchor, node) {
|
|
851
|
+
return { op: "insertBefore", anchor: idOf(anchor), node };
|
|
852
|
+
},
|
|
853
|
+
insertAfter(anchor, node) {
|
|
854
|
+
return { op: "insertAfter", anchor: idOf(anchor), node };
|
|
855
|
+
},
|
|
856
|
+
moveNode(target, newParent, index) {
|
|
857
|
+
return { op: "moveNode", target: idOf(target), newParent: idOf(newParent), index };
|
|
858
|
+
},
|
|
859
|
+
mergeSiblings(first, second) {
|
|
860
|
+
return { op: "mergeSiblings", first: idOf(first), second: idOf(second) };
|
|
861
|
+
},
|
|
862
|
+
setClassList(target, style, preserveOpaque = true) {
|
|
863
|
+
return { op: "setClassList", target: idOf(target), style, preserveOpaque };
|
|
864
|
+
},
|
|
865
|
+
mergeStyle(target, source, style, onConflict = "abort") {
|
|
866
|
+
return {
|
|
867
|
+
op: "mergeStyle",
|
|
868
|
+
target: idOf(target),
|
|
869
|
+
source: source ? idOf(source) : null,
|
|
870
|
+
style,
|
|
871
|
+
onConflict
|
|
872
|
+
};
|
|
873
|
+
},
|
|
874
|
+
foldInheritedStyles(from, into, opts) {
|
|
875
|
+
const list = Array.isArray(into) ? into : [into];
|
|
876
|
+
return {
|
|
877
|
+
op: "foldInheritedStyles",
|
|
878
|
+
from: idOf(from),
|
|
879
|
+
into: list.map((t) => idOf(t)),
|
|
880
|
+
properties: opts?.only ?? "all-inherited",
|
|
881
|
+
conditions: opts?.conditions ?? "base"
|
|
882
|
+
};
|
|
883
|
+
},
|
|
884
|
+
element(spec) {
|
|
885
|
+
return spec;
|
|
886
|
+
},
|
|
887
|
+
text(value) {
|
|
888
|
+
return { kind: "text", value };
|
|
889
|
+
},
|
|
890
|
+
keep(node) {
|
|
891
|
+
return { kind: "ref", ref: idOf(node) };
|
|
892
|
+
}
|
|
893
|
+
};
|
|
894
|
+
}
|
|
895
|
+
function ro(v) {
|
|
896
|
+
return v;
|
|
897
|
+
}
|
|
898
|
+
function buildMatchContext(doc, elementId, resolver, selectors, safety, phase, iteration) {
|
|
899
|
+
const self = getElement(doc, elementId);
|
|
900
|
+
const parentEl = () => {
|
|
901
|
+
if (self.parent == null) return null;
|
|
902
|
+
const p = doc.nodes.get(self.parent);
|
|
903
|
+
return p && p.kind === "element" ? ro(p) : null;
|
|
904
|
+
};
|
|
905
|
+
const elementChildren = () => {
|
|
906
|
+
const out = [];
|
|
907
|
+
for (const c of self.children) {
|
|
908
|
+
const cn = doc.nodes.get(c);
|
|
909
|
+
if (cn && cn.kind === "element") out.push(ro(cn));
|
|
910
|
+
}
|
|
911
|
+
return out;
|
|
912
|
+
};
|
|
913
|
+
const ancestors = () => {
|
|
914
|
+
const out = [];
|
|
915
|
+
let cur = self.parent;
|
|
916
|
+
while (cur != null) {
|
|
917
|
+
const n = doc.nodes.get(cur);
|
|
918
|
+
if (!n) break;
|
|
919
|
+
if (n.kind === "element") out.push(ro(n));
|
|
920
|
+
cur = n.parent;
|
|
921
|
+
}
|
|
922
|
+
return out;
|
|
923
|
+
};
|
|
924
|
+
const siblingAt = (delta) => {
|
|
925
|
+
if (self.parent == null) return null;
|
|
926
|
+
const p = doc.nodes.get(self.parent);
|
|
927
|
+
if (!p || p.kind !== "element" && p.kind !== "fragment") return null;
|
|
928
|
+
const i = p.children.indexOf(elementId);
|
|
929
|
+
const sib = p.children[i + delta];
|
|
930
|
+
if (sib == null) return null;
|
|
931
|
+
const sn = doc.nodes.get(sib);
|
|
932
|
+
return sn ? ro(sn) : null;
|
|
933
|
+
};
|
|
934
|
+
const computedOf = (n) => {
|
|
935
|
+
const node = doc.nodes.get(n.id);
|
|
936
|
+
return node && node.kind === "element" ? node.computed : emptyStyleMap();
|
|
937
|
+
};
|
|
938
|
+
return {
|
|
939
|
+
node: ro(self),
|
|
940
|
+
doc: ro(doc),
|
|
941
|
+
resolver,
|
|
942
|
+
selectors,
|
|
943
|
+
safety,
|
|
944
|
+
phase,
|
|
945
|
+
iteration,
|
|
946
|
+
parent: parentEl,
|
|
947
|
+
elementChildren,
|
|
948
|
+
onlyElementChild() {
|
|
949
|
+
const els = elementChildren();
|
|
950
|
+
return els.length === 1 ? els[0] : null;
|
|
951
|
+
},
|
|
952
|
+
computed() {
|
|
953
|
+
return self.computed;
|
|
954
|
+
},
|
|
955
|
+
computedOf,
|
|
956
|
+
isOpaque(n) {
|
|
957
|
+
const target = n ? doc.nodes.get(n.id) : self;
|
|
958
|
+
if (!target || target.kind !== "element") return true;
|
|
959
|
+
return target.classes.opaque || target.meta.hasSpreadAttrs;
|
|
960
|
+
},
|
|
961
|
+
ancestors,
|
|
962
|
+
closest(pred) {
|
|
963
|
+
for (const a of ancestors()) if (pred(a)) return a;
|
|
964
|
+
return null;
|
|
965
|
+
},
|
|
966
|
+
prevSibling() {
|
|
967
|
+
return siblingAt(-1);
|
|
968
|
+
},
|
|
969
|
+
nextSibling() {
|
|
970
|
+
return siblingAt(1);
|
|
971
|
+
},
|
|
972
|
+
nthChildIndex() {
|
|
973
|
+
if (self.parent == null) return 1;
|
|
974
|
+
const p = doc.nodes.get(self.parent);
|
|
975
|
+
if (!p || p.kind !== "element" && p.kind !== "fragment") return 1;
|
|
976
|
+
let idx = 0;
|
|
977
|
+
for (const c of p.children) {
|
|
978
|
+
const cn = doc.nodes.get(c);
|
|
979
|
+
if (cn && cn.kind === "element") {
|
|
980
|
+
idx += 1;
|
|
981
|
+
if (c === elementId) return idx;
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
return idx;
|
|
985
|
+
}
|
|
986
|
+
};
|
|
987
|
+
}
|
|
988
|
+
function stampOrigin(draft, pattern2) {
|
|
989
|
+
return {
|
|
990
|
+
...draft,
|
|
991
|
+
origin: { pattern: pattern2.name, category: pattern2.category, safety: pattern2.safety }
|
|
992
|
+
};
|
|
993
|
+
}
|
|
994
|
+
function patternsForPhase(passes, phase) {
|
|
995
|
+
const out = [];
|
|
996
|
+
for (const pass of passes) {
|
|
997
|
+
if (pass.phase !== phase) continue;
|
|
998
|
+
for (const p of pass.patterns) out.push(p);
|
|
999
|
+
}
|
|
1000
|
+
out.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
|
|
1001
|
+
return out;
|
|
1002
|
+
}
|
|
1003
|
+
function probeSink() {
|
|
1004
|
+
return {
|
|
1005
|
+
register(s) {
|
|
1006
|
+
return s.className;
|
|
1007
|
+
},
|
|
1008
|
+
drain() {
|
|
1009
|
+
return [];
|
|
1010
|
+
}
|
|
1011
|
+
};
|
|
1012
|
+
}
|
|
1013
|
+
function styleWriteTargets(ops) {
|
|
1014
|
+
const ids = [];
|
|
1015
|
+
for (const op of ops) {
|
|
1016
|
+
if (op.op === "mergeStyle" || op.op === "setClassList") ids.push(op.target);
|
|
1017
|
+
else if (op.op === "foldInheritedStyles") ids.push(...op.into);
|
|
1018
|
+
}
|
|
1019
|
+
return ids;
|
|
1020
|
+
}
|
|
1021
|
+
function emitIsExact(resolver, normalizer2, sm) {
|
|
1022
|
+
if (sm.blocks.size === 0) return true;
|
|
1023
|
+
try {
|
|
1024
|
+
const ctx = { normalizer: normalizer2, sink: probeSink() };
|
|
1025
|
+
const r = resolver.emit(sm, ctx);
|
|
1026
|
+
return r.exact && r.residual == null;
|
|
1027
|
+
} catch {
|
|
1028
|
+
return true;
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
function flattenWouldDropStyle(before, after, ops, resolver, normalizer2) {
|
|
1032
|
+
for (const id of styleWriteTargets(ops)) {
|
|
1033
|
+
const newEl = getElement(after, id);
|
|
1034
|
+
if (!newEl) continue;
|
|
1035
|
+
if (newEl.classes.opaque || newEl.classes.hasDynamic) continue;
|
|
1036
|
+
if (emitIsExact(resolver, normalizer2, newEl.computed)) continue;
|
|
1037
|
+
const oldEl = getElement(before, id);
|
|
1038
|
+
const wasExact = !oldEl || emitIsExact(resolver, normalizer2, oldEl.computed);
|
|
1039
|
+
if (wasExact) return true;
|
|
1040
|
+
}
|
|
1041
|
+
return false;
|
|
1042
|
+
}
|
|
1043
|
+
function runSweep(state, patterns, ctx, factory, phase, iteration, touched, diagnostics, flattenBarred) {
|
|
1044
|
+
let appliedOps = 0;
|
|
1045
|
+
const resolver = ctx.resolver;
|
|
1046
|
+
const selectors = ctx.selectors;
|
|
1047
|
+
for (const elId of elementIds(state.doc)) {
|
|
1048
|
+
const el = getElement(state.doc, elId);
|
|
1049
|
+
if (!el) continue;
|
|
1050
|
+
if (phase === "flatten" && flattenBarred.has(elId)) continue;
|
|
1051
|
+
for (const pattern2 of patterns) {
|
|
1052
|
+
if (pattern2.safety > ctx.safetyCeiling) continue;
|
|
1053
|
+
let drafts = [];
|
|
1054
|
+
try {
|
|
1055
|
+
const mctx = buildMatchContext(
|
|
1056
|
+
state.doc,
|
|
1057
|
+
elId,
|
|
1058
|
+
resolver,
|
|
1059
|
+
selectors,
|
|
1060
|
+
ctx.safetyCeiling,
|
|
1061
|
+
phase,
|
|
1062
|
+
iteration
|
|
1063
|
+
);
|
|
1064
|
+
const result = pattern2.evaluate(mctx, factory);
|
|
1065
|
+
if (!result) continue;
|
|
1066
|
+
drafts = result.ops;
|
|
1067
|
+
if (result.diagnostics) for (const d of result.diagnostics) diagnostics.push(d);
|
|
1068
|
+
} catch (err) {
|
|
1069
|
+
diagnostics.push({
|
|
1070
|
+
code: "DF_PATTERN_THREW",
|
|
1071
|
+
severity: "error",
|
|
1072
|
+
message: `pattern '${pattern2.name}' threw: ${String(err?.message ?? err)}`,
|
|
1073
|
+
nodeId: elId,
|
|
1074
|
+
pattern: pattern2.name,
|
|
1075
|
+
phase,
|
|
1076
|
+
iteration,
|
|
1077
|
+
cause: err
|
|
1078
|
+
});
|
|
1079
|
+
continue;
|
|
1080
|
+
}
|
|
1081
|
+
if (drafts.length === 0) continue;
|
|
1082
|
+
const ops = drafts.map((d) => stampOrigin(d, pattern2));
|
|
1083
|
+
const outcome = applyOps(state.doc, ops, ctx);
|
|
1084
|
+
for (const d of outcome.result.diagnostics) diagnostics.push(d);
|
|
1085
|
+
if (outcome.result.appliedGroups > 0) {
|
|
1086
|
+
if (phase === "flatten" && flattenWouldDropStyle(state.doc, outcome.doc, ops, resolver, ctx.normalizer)) {
|
|
1087
|
+
diagnostics.push({
|
|
1088
|
+
code: "DF_VERIFY_REVERTED",
|
|
1089
|
+
severity: "warn",
|
|
1090
|
+
message: `flatten '${pattern2.name}' reverted on node ${elId}: residual style is not reproducible by resolver '${resolver.id}', so flattening would drop it`,
|
|
1091
|
+
nodeId: elId,
|
|
1092
|
+
pattern: pattern2.name,
|
|
1093
|
+
phase,
|
|
1094
|
+
iteration
|
|
1095
|
+
});
|
|
1096
|
+
flattenBarred.add(elId);
|
|
1097
|
+
break;
|
|
1098
|
+
}
|
|
1099
|
+
state.doc = outcome.doc;
|
|
1100
|
+
appliedOps += outcome.result.appliedGroups;
|
|
1101
|
+
for (const id of outcome.result.touched) touched.add(id);
|
|
1102
|
+
for (const id of outcome.result.created) touched.add(id);
|
|
1103
|
+
break;
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
1107
|
+
return appliedOps;
|
|
1108
|
+
}
|
|
1109
|
+
function docFingerprint(doc) {
|
|
1110
|
+
const parts = [];
|
|
1111
|
+
const visit = (id) => {
|
|
1112
|
+
const n = doc.nodes.get(id);
|
|
1113
|
+
if (!n) return;
|
|
1114
|
+
parts.push(`${id}:${n.kind}`);
|
|
1115
|
+
for (const c of childIds(n)) visit(c);
|
|
1116
|
+
};
|
|
1117
|
+
visit(doc.root);
|
|
1118
|
+
return parts.join("|");
|
|
1119
|
+
}
|
|
1120
|
+
function runPasses(doc, passes, ctx, config) {
|
|
1121
|
+
const cfg = { ...DEFAULT_FIXPOINT, ...config };
|
|
1122
|
+
const factory = createRewriteFactory();
|
|
1123
|
+
const state = { doc };
|
|
1124
|
+
const results = [];
|
|
1125
|
+
const flattenBarred = /* @__PURE__ */ new Set();
|
|
1126
|
+
for (const phase of PHASE_ORDER) {
|
|
1127
|
+
const patterns = patternsForPhase(passes, phase);
|
|
1128
|
+
const phaseTouched = /* @__PURE__ */ new Set();
|
|
1129
|
+
const diagnostics = [];
|
|
1130
|
+
const budget = cfg.phases[phase] ?? cfg.maxIterations;
|
|
1131
|
+
let iterations = 0;
|
|
1132
|
+
let converged = false;
|
|
1133
|
+
let haltReason = "converged";
|
|
1134
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1135
|
+
if (patterns.length === 0) {
|
|
1136
|
+
results.push({
|
|
1137
|
+
phase,
|
|
1138
|
+
iterations: 0,
|
|
1139
|
+
converged: true,
|
|
1140
|
+
haltReason: "converged",
|
|
1141
|
+
touched: phaseTouched,
|
|
1142
|
+
diagnostics
|
|
1143
|
+
});
|
|
1144
|
+
continue;
|
|
1145
|
+
}
|
|
1146
|
+
while (iterations < budget) {
|
|
1147
|
+
iterations += 1;
|
|
1148
|
+
const applied = runSweep(
|
|
1149
|
+
state,
|
|
1150
|
+
patterns,
|
|
1151
|
+
ctx,
|
|
1152
|
+
factory,
|
|
1153
|
+
phase,
|
|
1154
|
+
iterations,
|
|
1155
|
+
phaseTouched,
|
|
1156
|
+
diagnostics,
|
|
1157
|
+
flattenBarred
|
|
1158
|
+
);
|
|
1159
|
+
if (applied === 0) {
|
|
1160
|
+
converged = true;
|
|
1161
|
+
haltReason = "converged";
|
|
1162
|
+
break;
|
|
1163
|
+
}
|
|
1164
|
+
if (cfg.detectOscillation) {
|
|
1165
|
+
const fp = docFingerprint(state.doc);
|
|
1166
|
+
if (seen.has(fp)) {
|
|
1167
|
+
haltReason = "oscillation";
|
|
1168
|
+
diagnostics.push({
|
|
1169
|
+
code: "DF_FIXPOINT_OSCILLATION",
|
|
1170
|
+
severity: "warn",
|
|
1171
|
+
message: `phase '${phase}' oscillated; halting`,
|
|
1172
|
+
phase,
|
|
1173
|
+
iteration: iterations
|
|
1174
|
+
});
|
|
1175
|
+
break;
|
|
1176
|
+
}
|
|
1177
|
+
seen.add(fp);
|
|
1178
|
+
}
|
|
1179
|
+
}
|
|
1180
|
+
if (!converged && haltReason !== "oscillation") {
|
|
1181
|
+
haltReason = "budget";
|
|
1182
|
+
diagnostics.push({
|
|
1183
|
+
code: "DF_FIXPOINT_BUDGET",
|
|
1184
|
+
severity: cfg.onBudgetExhausted === "error" ? "error" : "warn",
|
|
1185
|
+
message: `phase '${phase}' exhausted ${budget}-iteration budget`,
|
|
1186
|
+
phase,
|
|
1187
|
+
iteration: iterations
|
|
1188
|
+
});
|
|
1189
|
+
}
|
|
1190
|
+
results.push({
|
|
1191
|
+
phase,
|
|
1192
|
+
iterations,
|
|
1193
|
+
converged,
|
|
1194
|
+
haltReason,
|
|
1195
|
+
touched: phaseTouched,
|
|
1196
|
+
diagnostics
|
|
1197
|
+
});
|
|
1198
|
+
}
|
|
1199
|
+
return { doc: state.doc, results };
|
|
1200
|
+
}
|
|
1201
|
+
function createPassManager(passes) {
|
|
1202
|
+
return {
|
|
1203
|
+
run(doc, ctx, config) {
|
|
1204
|
+
return runPasses(doc, passes, ctx, config).results;
|
|
1205
|
+
}
|
|
1206
|
+
};
|
|
1207
|
+
}
|
|
1208
|
+
|
|
1209
|
+
// ../core/src/pipeline.ts
|
|
1210
|
+
init_esm_shims();
|
|
1211
|
+
function createSyntheticSink() {
|
|
1212
|
+
const map = /* @__PURE__ */ new Map();
|
|
1213
|
+
return {
|
|
1214
|
+
register(s) {
|
|
1215
|
+
if (!map.has(s.className)) map.set(s.className, s);
|
|
1216
|
+
return s.className;
|
|
1217
|
+
},
|
|
1218
|
+
drain() {
|
|
1219
|
+
return [...map.values()];
|
|
1220
|
+
}
|
|
1221
|
+
};
|
|
1222
|
+
}
|
|
1223
|
+
function staticClassTokens(el) {
|
|
1224
|
+
const out = [];
|
|
1225
|
+
for (const seg of el.classes.segments) {
|
|
1226
|
+
if (seg.kind === "static") for (const t of seg.tokens) out.push(t.value);
|
|
1227
|
+
}
|
|
1228
|
+
return out;
|
|
1229
|
+
}
|
|
1230
|
+
function resolveStyles(doc, input, diagnostics) {
|
|
1231
|
+
const { resolver, normalizer: normalizer2 } = input;
|
|
1232
|
+
for (const id of elementIds(doc)) {
|
|
1233
|
+
const el = getElement(doc, id);
|
|
1234
|
+
if (!el || el.classes.opaque) continue;
|
|
1235
|
+
const tokens = staticClassTokens(el);
|
|
1236
|
+
if (tokens.length === 0) continue;
|
|
1237
|
+
try {
|
|
1238
|
+
const result = resolver.resolve({
|
|
1239
|
+
classes: tokens,
|
|
1240
|
+
element: {
|
|
1241
|
+
tagName: el.tag,
|
|
1242
|
+
namespace: el.namespace === "svg" ? "svg" : "html"
|
|
1243
|
+
}
|
|
1244
|
+
});
|
|
1245
|
+
let styles = result.styles;
|
|
1246
|
+
try {
|
|
1247
|
+
styles = normalizer2.normalizeStyleMap(styles);
|
|
1248
|
+
} catch {
|
|
1249
|
+
}
|
|
1250
|
+
el.computed = styles;
|
|
1251
|
+
for (const w of result.warnings) {
|
|
1252
|
+
diagnostics.push({
|
|
1253
|
+
code: "DF_STYLE_CONFLICT_UNRESOLVED",
|
|
1254
|
+
severity: w.severity,
|
|
1255
|
+
message: w.message,
|
|
1256
|
+
nodeId: id
|
|
1257
|
+
});
|
|
1258
|
+
}
|
|
1259
|
+
} catch (err) {
|
|
1260
|
+
diagnostics.push({
|
|
1261
|
+
code: "DF_OP_PRECONDITION_FAILED",
|
|
1262
|
+
severity: "debug",
|
|
1263
|
+
message: `resolve skipped for <${el.tag}>: ${String(err?.message ?? err)}`,
|
|
1264
|
+
nodeId: id,
|
|
1265
|
+
cause: err
|
|
1266
|
+
});
|
|
1267
|
+
}
|
|
1268
|
+
}
|
|
1269
|
+
}
|
|
1270
|
+
var ZERO_ITERATIONS = {
|
|
1271
|
+
flatten: 0,
|
|
1272
|
+
compress: 0,
|
|
1273
|
+
extract: 0
|
|
1274
|
+
};
|
|
1275
|
+
var DefaultPipeline = class {
|
|
1276
|
+
run(input) {
|
|
1277
|
+
const startedAt = now();
|
|
1278
|
+
const diagnostics = [];
|
|
1279
|
+
const report = (d) => {
|
|
1280
|
+
diagnostics.push(d);
|
|
1281
|
+
input.reporter?.report(d);
|
|
1282
|
+
};
|
|
1283
|
+
const parseCtx = {
|
|
1284
|
+
id: input.id,
|
|
1285
|
+
kind: input.kind,
|
|
1286
|
+
resolver: input.resolver,
|
|
1287
|
+
normalizer: input.normalizer,
|
|
1288
|
+
config: { preserveComments: input.config?.preserveComments ?? true },
|
|
1289
|
+
onDiagnostic: report
|
|
1290
|
+
};
|
|
1291
|
+
if (input.babelAst !== void 0) parseCtx.babelAst = input.babelAst;
|
|
1292
|
+
const parsed = input.frontend.parse(input.code, parseCtx);
|
|
1293
|
+
for (const d of parsed.diagnostics) report(d);
|
|
1294
|
+
const doc = parsed.doc;
|
|
1295
|
+
const nodesIn = doc.nodes.size;
|
|
1296
|
+
resolveStyles(doc, input, diagnostics);
|
|
1297
|
+
const ctx = {
|
|
1298
|
+
doc,
|
|
1299
|
+
safetyCeiling: input.config?.safety ?? 2,
|
|
1300
|
+
normalizer: input.normalizer,
|
|
1301
|
+
selectors: createNullSelectorIndex(),
|
|
1302
|
+
resolver: input.resolver
|
|
1303
|
+
};
|
|
1304
|
+
const { doc: optimized, results } = runPasses(doc, input.passes, ctx, fixpointFrom(input));
|
|
1305
|
+
let opsApplied = 0;
|
|
1306
|
+
const iterations = { ...ZERO_ITERATIONS };
|
|
1307
|
+
for (const r of results) {
|
|
1308
|
+
iterations[r.phase] = r.iterations;
|
|
1309
|
+
for (const d of r.diagnostics) {
|
|
1310
|
+
diagnostics.push(d);
|
|
1311
|
+
input.reporter?.report(d);
|
|
1312
|
+
}
|
|
1313
|
+
opsApplied += r.touched.size;
|
|
1314
|
+
}
|
|
1315
|
+
const editPlan = {
|
|
1316
|
+
moduleId: input.id,
|
|
1317
|
+
ops: [],
|
|
1318
|
+
provenance: /* @__PURE__ */ new Map()
|
|
1319
|
+
};
|
|
1320
|
+
const backendCtx = {
|
|
1321
|
+
normalizer: input.normalizer,
|
|
1322
|
+
resolver: input.resolver,
|
|
1323
|
+
sink: createSyntheticSink(),
|
|
1324
|
+
eol: eolOf(optimized),
|
|
1325
|
+
onDiagnostic: report
|
|
1326
|
+
};
|
|
1327
|
+
const printed = input.backend.print(optimized, editPlan, backendCtx);
|
|
1328
|
+
for (const d of printed.diagnostics) {
|
|
1329
|
+
diagnostics.push(d);
|
|
1330
|
+
input.reporter?.report(d);
|
|
1331
|
+
}
|
|
1332
|
+
const stats = {
|
|
1333
|
+
nodesIn,
|
|
1334
|
+
nodesOut: optimized.nodes.size,
|
|
1335
|
+
opsApplied,
|
|
1336
|
+
iterations,
|
|
1337
|
+
durationMs: now() - startedAt
|
|
1338
|
+
};
|
|
1339
|
+
const touched = printed.edits.map((e) => e.span);
|
|
1340
|
+
return {
|
|
1341
|
+
code: printed.code,
|
|
1342
|
+
map: printed.map,
|
|
1343
|
+
changed: printed.code !== input.code,
|
|
1344
|
+
touched,
|
|
1345
|
+
diagnostics,
|
|
1346
|
+
stats,
|
|
1347
|
+
doc: optimized,
|
|
1348
|
+
editPlan
|
|
1349
|
+
};
|
|
1350
|
+
}
|
|
1351
|
+
};
|
|
1352
|
+
function fixpointFrom(input) {
|
|
1353
|
+
const fp = input.config?.fixpoint;
|
|
1354
|
+
if (!fp) return void 0;
|
|
1355
|
+
return {
|
|
1356
|
+
maxIterations: fp.maxIterations ?? 16,
|
|
1357
|
+
phases: fp.phases ?? {},
|
|
1358
|
+
onBudgetExhausted: fp.onBudgetExhausted ?? "warn",
|
|
1359
|
+
detectOscillation: fp.detectOscillation ?? true
|
|
1360
|
+
};
|
|
1361
|
+
}
|
|
1362
|
+
function eolOf(doc) {
|
|
1363
|
+
for (const src of doc.sources.values()) return src.eol;
|
|
1364
|
+
return "\n";
|
|
1365
|
+
}
|
|
1366
|
+
function now() {
|
|
1367
|
+
return typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
|
|
1368
|
+
}
|
|
1369
|
+
function createPipeline() {
|
|
1370
|
+
return new DefaultPipeline();
|
|
1371
|
+
}
|
|
1372
|
+
|
|
1373
|
+
// ../core/src/reverse-emit.ts
|
|
1374
|
+
init_esm_shims();
|
|
1375
|
+
function staticTokensOf(cl) {
|
|
1376
|
+
const out = [];
|
|
1377
|
+
for (const seg of cl.segments) {
|
|
1378
|
+
if (seg.kind === "static") for (const t of seg.tokens) out.push(t.value);
|
|
1379
|
+
}
|
|
1380
|
+
return out;
|
|
1381
|
+
}
|
|
1382
|
+
function staticClassList(prev, tokens) {
|
|
1383
|
+
const classTokens = tokens.map((value) => ({ value }));
|
|
1384
|
+
const seg = { kind: "static", tokens: classTokens };
|
|
1385
|
+
return {
|
|
1386
|
+
form: "string-literal",
|
|
1387
|
+
segments: [seg],
|
|
1388
|
+
valueSpan: prev.valueSpan,
|
|
1389
|
+
attrSpan: prev.attrSpan,
|
|
1390
|
+
hasDynamic: false,
|
|
1391
|
+
opaque: false,
|
|
1392
|
+
rewritable: true
|
|
1393
|
+
};
|
|
1394
|
+
}
|
|
1395
|
+
function sameTokens(a, b) {
|
|
1396
|
+
if (a.length !== b.length) return false;
|
|
1397
|
+
for (let i = 0; i < a.length; i += 1) if (a[i] !== b[i]) return false;
|
|
1398
|
+
return true;
|
|
1399
|
+
}
|
|
1400
|
+
function syncClassesFromComputed(doc, resolver, norm) {
|
|
1401
|
+
const sink = createSyntheticSink();
|
|
1402
|
+
for (const id of elementIds(doc)) {
|
|
1403
|
+
const el = getElement(doc, id);
|
|
1404
|
+
if (!el || !el.meta.touched) continue;
|
|
1405
|
+
if (el.classes.opaque || el.classes.hasDynamic) continue;
|
|
1406
|
+
const tokens = staticTokensOf(el.classes);
|
|
1407
|
+
const ctx = { normalizer: norm, sink };
|
|
1408
|
+
const emitted = resolver.emit(el.computed, ctx).classes;
|
|
1409
|
+
if (emitted.length === 0) continue;
|
|
1410
|
+
const emittedSet = new Set(emitted);
|
|
1411
|
+
const next = [];
|
|
1412
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1413
|
+
for (const t of tokens) {
|
|
1414
|
+
if (seen.has(t)) continue;
|
|
1415
|
+
const keep = emittedSet.has(t) || !resolver.selectorUsage(t).droppable;
|
|
1416
|
+
if (keep) {
|
|
1417
|
+
next.push(t);
|
|
1418
|
+
seen.add(t);
|
|
1419
|
+
}
|
|
1420
|
+
}
|
|
1421
|
+
for (const c of emitted) {
|
|
1422
|
+
if (seen.has(c)) continue;
|
|
1423
|
+
next.push(c);
|
|
1424
|
+
seen.add(c);
|
|
1425
|
+
}
|
|
1426
|
+
if (sameTokens(next, tokens)) continue;
|
|
1427
|
+
el.classes = staticClassList(el.classes, next);
|
|
1428
|
+
}
|
|
1429
|
+
}
|
|
1430
|
+
|
|
1431
|
+
// ../core/src/index.ts
|
|
1432
|
+
init_esm_shims();
|
|
1433
|
+
|
|
1434
|
+
// ../pattern-kit/src/define.ts
|
|
1435
|
+
init_esm_shims();
|
|
1436
|
+
var PHASES = /* @__PURE__ */ new Set(["flatten", "compress", "extract"]);
|
|
1437
|
+
var SAFETY_LEVELS = /* @__PURE__ */ new Set([0, 1, 2, 3]);
|
|
1438
|
+
function fail(name, why) {
|
|
1439
|
+
throw new Error(`definePattern(${name || "<anonymous>"}): ${why}`);
|
|
1440
|
+
}
|
|
1441
|
+
function definePattern(spec) {
|
|
1442
|
+
if (spec == null || typeof spec !== "object") {
|
|
1443
|
+
throw new Error("definePattern: spec must be an object");
|
|
1444
|
+
}
|
|
1445
|
+
const name = spec.name;
|
|
1446
|
+
if (typeof name !== "string" || name.length === 0) {
|
|
1447
|
+
fail(String(name), "name must be a non-empty string");
|
|
1448
|
+
}
|
|
1449
|
+
if (typeof spec.category !== "string" || !spec.category.includes("/")) {
|
|
1450
|
+
fail(name, `category must be a "<phase>/<slug>" string (got ${JSON.stringify(spec.category)})`);
|
|
1451
|
+
}
|
|
1452
|
+
const phase = spec.category.split("/", 1)[0];
|
|
1453
|
+
if (!PHASES.has(phase)) {
|
|
1454
|
+
fail(name, `category phase must be one of flatten|compress|extract (got "${phase}")`);
|
|
1455
|
+
}
|
|
1456
|
+
if (!SAFETY_LEVELS.has(spec.safety)) {
|
|
1457
|
+
fail(name, `safety must be 0|1|2|3 (got ${JSON.stringify(spec.safety)})`);
|
|
1458
|
+
}
|
|
1459
|
+
if (typeof spec.evaluate !== "function") {
|
|
1460
|
+
fail(name, "evaluate must be a function");
|
|
1461
|
+
}
|
|
1462
|
+
if (spec.priority !== void 0 && !Number.isFinite(spec.priority)) {
|
|
1463
|
+
fail(name, "priority must be a finite number when provided");
|
|
1464
|
+
}
|
|
1465
|
+
return Object.freeze({ ...spec });
|
|
1466
|
+
}
|
|
1467
|
+
|
|
1468
|
+
// ../pattern-kit/src/normalize.ts
|
|
1469
|
+
init_esm_shims();
|
|
1470
|
+
var INHERITED_PROPERTIES = [
|
|
1471
|
+
"azimuth",
|
|
1472
|
+
"border-collapse",
|
|
1473
|
+
"border-spacing",
|
|
1474
|
+
"caption-side",
|
|
1475
|
+
"color",
|
|
1476
|
+
"cursor",
|
|
1477
|
+
"direction",
|
|
1478
|
+
"empty-cells",
|
|
1479
|
+
"font-family",
|
|
1480
|
+
"font-feature-settings",
|
|
1481
|
+
"font-kerning",
|
|
1482
|
+
"font-size",
|
|
1483
|
+
"font-size-adjust",
|
|
1484
|
+
"font-stretch",
|
|
1485
|
+
"font-style",
|
|
1486
|
+
"font-variant",
|
|
1487
|
+
"font-variant-caps",
|
|
1488
|
+
"font-variant-numeric",
|
|
1489
|
+
"font-weight",
|
|
1490
|
+
"hyphens",
|
|
1491
|
+
"letter-spacing",
|
|
1492
|
+
"line-height",
|
|
1493
|
+
"list-style-image",
|
|
1494
|
+
"list-style-position",
|
|
1495
|
+
"list-style-type",
|
|
1496
|
+
"orphans",
|
|
1497
|
+
"overflow-wrap",
|
|
1498
|
+
"quotes",
|
|
1499
|
+
"tab-size",
|
|
1500
|
+
"text-align",
|
|
1501
|
+
"text-align-last",
|
|
1502
|
+
"text-decoration-color",
|
|
1503
|
+
"text-indent",
|
|
1504
|
+
"text-justify",
|
|
1505
|
+
"text-rendering",
|
|
1506
|
+
"text-shadow",
|
|
1507
|
+
"text-transform",
|
|
1508
|
+
"text-underline-position",
|
|
1509
|
+
"visibility",
|
|
1510
|
+
"white-space",
|
|
1511
|
+
"widows",
|
|
1512
|
+
"word-break",
|
|
1513
|
+
"word-spacing",
|
|
1514
|
+
"writing-mode",
|
|
1515
|
+
"-webkit-font-smoothing"
|
|
1516
|
+
];
|
|
1517
|
+
function createInheritedTable() {
|
|
1518
|
+
const properties = new Set(INHERITED_PROPERTIES);
|
|
1519
|
+
return {
|
|
1520
|
+
version: "domflax-inherited@1",
|
|
1521
|
+
properties,
|
|
1522
|
+
isInherited(property) {
|
|
1523
|
+
return String(property).startsWith("--") || properties.has(property);
|
|
1524
|
+
}
|
|
1525
|
+
};
|
|
1526
|
+
}
|
|
1527
|
+
var ZERO_LENGTH_RE = /\b0(?:px|em|rem|ex|ch|vh|vw|vmin|vmax|vi|vb|pt|pc|cm|mm|in|q|lh|rlh|fr|deg|rad|turn|s|ms|%)\b/g;
|
|
1528
|
+
var FUNC_ARGS_RE = /\b(rgba?|hsla?|hwb|lab|lch|oklab|oklch)\(([^()]*)\)/gi;
|
|
1529
|
+
var RELATIVE_UNIT_RE = /(?:\d*\.?\d+)(?:em|ex|ch|lh)\b|%/i;
|
|
1530
|
+
function canonValue(raw) {
|
|
1531
|
+
let v = raw.trim().replace(/\s+/g, " ");
|
|
1532
|
+
v = v.replace(/#([0-9a-fA-F]{3,8})\b/g, (_m, hex) => "#" + hex.toLowerCase());
|
|
1533
|
+
v = v.replace(
|
|
1534
|
+
/#([0-9a-f])([0-9a-f])([0-9a-f])(?![0-9a-f])/g,
|
|
1535
|
+
(_m, r, g, b) => `#${r}${r}${g}${g}${b}${b}`
|
|
1536
|
+
);
|
|
1537
|
+
v = v.replace(/\btransparent\b/gi, "rgba(0, 0, 0, 0)");
|
|
1538
|
+
v = v.replace(/#00000000\b/g, "rgba(0, 0, 0, 0)");
|
|
1539
|
+
v = v.replace(ZERO_LENGTH_RE, "0");
|
|
1540
|
+
v = v.replace(FUNC_ARGS_RE, (_m, fn, args) => {
|
|
1541
|
+
const parts = args.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
|
|
1542
|
+
return `${fn.toLowerCase()}(${parts.join(", ")})`;
|
|
1543
|
+
});
|
|
1544
|
+
return v;
|
|
1545
|
+
}
|
|
1546
|
+
function isRelativeValue(value) {
|
|
1547
|
+
return RELATIVE_UNIT_RE.test(value);
|
|
1548
|
+
}
|
|
1549
|
+
var BOX_SIDES = {
|
|
1550
|
+
padding: ["padding-top", "padding-right", "padding-bottom", "padding-left"],
|
|
1551
|
+
margin: ["margin-top", "margin-right", "margin-bottom", "margin-left"],
|
|
1552
|
+
inset: ["top", "right", "bottom", "left"],
|
|
1553
|
+
"border-width": [
|
|
1554
|
+
"border-top-width",
|
|
1555
|
+
"border-right-width",
|
|
1556
|
+
"border-bottom-width",
|
|
1557
|
+
"border-left-width"
|
|
1558
|
+
],
|
|
1559
|
+
"border-style": [
|
|
1560
|
+
"border-top-style",
|
|
1561
|
+
"border-right-style",
|
|
1562
|
+
"border-bottom-style",
|
|
1563
|
+
"border-left-style"
|
|
1564
|
+
],
|
|
1565
|
+
"border-color": [
|
|
1566
|
+
"border-top-color",
|
|
1567
|
+
"border-right-color",
|
|
1568
|
+
"border-bottom-color",
|
|
1569
|
+
"border-left-color"
|
|
1570
|
+
]
|
|
1571
|
+
};
|
|
1572
|
+
function splitTopLevel(value) {
|
|
1573
|
+
const out = [];
|
|
1574
|
+
let depth = 0;
|
|
1575
|
+
let cur = "";
|
|
1576
|
+
for (const ch of value) {
|
|
1577
|
+
if (ch === "(") depth += 1;
|
|
1578
|
+
else if (ch === ")") depth = Math.max(0, depth - 1);
|
|
1579
|
+
if (depth === 0 && /\s/.test(ch)) {
|
|
1580
|
+
if (cur.length > 0) {
|
|
1581
|
+
out.push(cur);
|
|
1582
|
+
cur = "";
|
|
1583
|
+
}
|
|
1584
|
+
continue;
|
|
1585
|
+
}
|
|
1586
|
+
cur += ch;
|
|
1587
|
+
}
|
|
1588
|
+
if (cur.length > 0) out.push(cur);
|
|
1589
|
+
return out;
|
|
1590
|
+
}
|
|
1591
|
+
function boxFourSides(values) {
|
|
1592
|
+
const [a, b, c, d] = values;
|
|
1593
|
+
switch (values.length) {
|
|
1594
|
+
case 1:
|
|
1595
|
+
return [a, a, a, a];
|
|
1596
|
+
case 2:
|
|
1597
|
+
return [a, b, a, b];
|
|
1598
|
+
case 3:
|
|
1599
|
+
return [a, b, c, b];
|
|
1600
|
+
default:
|
|
1601
|
+
return [a, b, c, d];
|
|
1602
|
+
}
|
|
1603
|
+
}
|
|
1604
|
+
function expandShorthand(prop, value) {
|
|
1605
|
+
const box = BOX_SIDES[prop];
|
|
1606
|
+
if (box) {
|
|
1607
|
+
const parts = splitTopLevel(value);
|
|
1608
|
+
if (parts.length >= 1 && parts.length <= 4) {
|
|
1609
|
+
const sides = boxFourSides(parts);
|
|
1610
|
+
return box.map((p, i) => [p, sides[i]]);
|
|
1611
|
+
}
|
|
1612
|
+
return [[prop, value]];
|
|
1613
|
+
}
|
|
1614
|
+
if (prop === "gap" || prop === "grid-gap") {
|
|
1615
|
+
const parts = splitTopLevel(value);
|
|
1616
|
+
if (parts.length === 1) {
|
|
1617
|
+
return [
|
|
1618
|
+
["row-gap", parts[0]],
|
|
1619
|
+
["column-gap", parts[0]]
|
|
1620
|
+
];
|
|
1621
|
+
}
|
|
1622
|
+
if (parts.length === 2) {
|
|
1623
|
+
return [
|
|
1624
|
+
["row-gap", parts[0]],
|
|
1625
|
+
["column-gap", parts[1]]
|
|
1626
|
+
];
|
|
1627
|
+
}
|
|
1628
|
+
return [[prop, value]];
|
|
1629
|
+
}
|
|
1630
|
+
return [[prop, value]];
|
|
1631
|
+
}
|
|
1632
|
+
function makeDecl(table, prop, rawValue, important) {
|
|
1633
|
+
const property = prop.trim().toLowerCase();
|
|
1634
|
+
const value = canonValue(rawValue);
|
|
1635
|
+
return {
|
|
1636
|
+
property,
|
|
1637
|
+
value,
|
|
1638
|
+
important,
|
|
1639
|
+
relativeToParent: isRelativeValue(value),
|
|
1640
|
+
inherited: table.isInherited(property)
|
|
1641
|
+
};
|
|
1642
|
+
}
|
|
1643
|
+
function createNormalizer() {
|
|
1644
|
+
const inherited = createInheritedTable();
|
|
1645
|
+
const normalizeDeclaration = (prop, value, important) => {
|
|
1646
|
+
const p = prop.trim().toLowerCase();
|
|
1647
|
+
const expanded = expandShorthand(p, value.trim());
|
|
1648
|
+
return expanded.map(([lp, lv]) => makeDecl(inherited, lp, lv, important));
|
|
1649
|
+
};
|
|
1650
|
+
const normalizeValue = (prop, raw) => {
|
|
1651
|
+
void prop;
|
|
1652
|
+
return canonValue(raw);
|
|
1653
|
+
};
|
|
1654
|
+
const normalizeStyleMap = (sm) => {
|
|
1655
|
+
const blocks = /* @__PURE__ */ new Map();
|
|
1656
|
+
for (const block of sm.blocks.values()) {
|
|
1657
|
+
const decls = /* @__PURE__ */ new Map();
|
|
1658
|
+
for (const decl of block.decls.values()) {
|
|
1659
|
+
const next = {
|
|
1660
|
+
...decl,
|
|
1661
|
+
value: canonValue(String(decl.value)),
|
|
1662
|
+
relativeToParent: isRelativeValue(String(decl.value)),
|
|
1663
|
+
inherited: inherited.isInherited(decl.property)
|
|
1664
|
+
};
|
|
1665
|
+
decls.set(next.property, next);
|
|
1666
|
+
}
|
|
1667
|
+
const sorted = new Map(
|
|
1668
|
+
[...decls.entries()].sort((a, b) => a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0)
|
|
1669
|
+
);
|
|
1670
|
+
const key = conditionKey(block.condition);
|
|
1671
|
+
blocks.set(key, { condition: block.condition, decls: sorted });
|
|
1672
|
+
}
|
|
1673
|
+
return { blocks };
|
|
1674
|
+
};
|
|
1675
|
+
const equals = (a, b) => {
|
|
1676
|
+
const na = normalizeStyleMap(a);
|
|
1677
|
+
const nb = normalizeStyleMap(b);
|
|
1678
|
+
if (na.blocks.size !== nb.blocks.size) return false;
|
|
1679
|
+
for (const [key, blockA] of na.blocks) {
|
|
1680
|
+
const blockB = nb.blocks.get(key);
|
|
1681
|
+
if (!blockB) return false;
|
|
1682
|
+
if (blockA.decls.size !== blockB.decls.size) return false;
|
|
1683
|
+
for (const [prop, declA] of blockA.decls) {
|
|
1684
|
+
const declB = blockB.decls.get(prop);
|
|
1685
|
+
if (!declB) return false;
|
|
1686
|
+
if (declA.value !== declB.value || declA.important !== declB.important) return false;
|
|
1687
|
+
}
|
|
1688
|
+
}
|
|
1689
|
+
return true;
|
|
1690
|
+
};
|
|
1691
|
+
return {
|
|
1692
|
+
version: "domflax-normalizer@1",
|
|
1693
|
+
normalizeDeclaration,
|
|
1694
|
+
normalizeValue,
|
|
1695
|
+
normalizeStyleMap,
|
|
1696
|
+
equals,
|
|
1697
|
+
inherited
|
|
1698
|
+
};
|
|
1699
|
+
}
|
|
1700
|
+
var normalizer = createNormalizer();
|
|
1701
|
+
function isStyleSuperset(full, partial, norm = normalizer) {
|
|
1702
|
+
const nf = norm.normalizeStyleMap(full);
|
|
1703
|
+
const np = norm.normalizeStyleMap(partial);
|
|
1704
|
+
for (const [key, want] of np.blocks) {
|
|
1705
|
+
const have = nf.blocks.get(key) ?? nf.blocks.get(conditionKey(want.condition));
|
|
1706
|
+
if (!have) return false;
|
|
1707
|
+
for (const [prop, decl] of want.decls) {
|
|
1708
|
+
const got = have.decls.get(prop);
|
|
1709
|
+
if (!got || got.value !== decl.value) return false;
|
|
1710
|
+
}
|
|
1711
|
+
}
|
|
1712
|
+
return true;
|
|
1713
|
+
}
|
|
1714
|
+
|
|
1715
|
+
// ../pattern-kit/src/combinators.ts
|
|
1716
|
+
init_esm_shims();
|
|
1717
|
+
function asElement(node) {
|
|
1718
|
+
const n = node;
|
|
1719
|
+
return n.kind === "element" ? n : null;
|
|
1720
|
+
}
|
|
1721
|
+
function elementChildrenOf(el, ctx) {
|
|
1722
|
+
const out = [];
|
|
1723
|
+
for (const childId of el.children) {
|
|
1724
|
+
const child = ctx.doc.nodes.get(childId);
|
|
1725
|
+
if (child && child.kind === "element") out.push(child);
|
|
1726
|
+
}
|
|
1727
|
+
return out;
|
|
1728
|
+
}
|
|
1729
|
+
function and(...matchers) {
|
|
1730
|
+
return (node, ctx) => matchers.every((m) => m(node, ctx));
|
|
1731
|
+
}
|
|
1732
|
+
function or(...matchers) {
|
|
1733
|
+
return (node, ctx) => matchers.some((m) => m(node, ctx));
|
|
1734
|
+
}
|
|
1735
|
+
function not(matcher) {
|
|
1736
|
+
return (node, ctx) => !matcher(node, ctx);
|
|
1737
|
+
}
|
|
1738
|
+
function isElement(tag) {
|
|
1739
|
+
const want = tag?.toLowerCase();
|
|
1740
|
+
return (node) => {
|
|
1741
|
+
const el = asElement(node);
|
|
1742
|
+
if (!el) return false;
|
|
1743
|
+
return want === void 0 || el.tag.toLowerCase() === want;
|
|
1744
|
+
};
|
|
1745
|
+
}
|
|
1746
|
+
var hasSingleElementChild = (node, ctx) => {
|
|
1747
|
+
const el = asElement(node);
|
|
1748
|
+
if (!el) return false;
|
|
1749
|
+
return elementChildrenOf(el, ctx).length === 1;
|
|
1750
|
+
};
|
|
1751
|
+
function computed(partial) {
|
|
1752
|
+
return (node, ctx) => {
|
|
1753
|
+
const el = asElement(node);
|
|
1754
|
+
if (!el) return false;
|
|
1755
|
+
const full = ctx.computedOf(el) ?? el.computed;
|
|
1756
|
+
return isStyleSuperset(full, partial, normalizer);
|
|
1757
|
+
};
|
|
1758
|
+
}
|
|
1759
|
+
var VISUAL_PROPERTIES = /* @__PURE__ */ new Set([
|
|
1760
|
+
"background",
|
|
1761
|
+
"background-color",
|
|
1762
|
+
"background-image",
|
|
1763
|
+
"border-top-width",
|
|
1764
|
+
"border-right-width",
|
|
1765
|
+
"border-bottom-width",
|
|
1766
|
+
"border-left-width",
|
|
1767
|
+
"border-top-style",
|
|
1768
|
+
"border-right-style",
|
|
1769
|
+
"border-bottom-style",
|
|
1770
|
+
"border-left-style",
|
|
1771
|
+
"border-top-color",
|
|
1772
|
+
"border-right-color",
|
|
1773
|
+
"border-bottom-color",
|
|
1774
|
+
"border-left-color",
|
|
1775
|
+
"border-radius",
|
|
1776
|
+
"box-shadow",
|
|
1777
|
+
"outline",
|
|
1778
|
+
"outline-width",
|
|
1779
|
+
"outline-style",
|
|
1780
|
+
"outline-color",
|
|
1781
|
+
"text-shadow",
|
|
1782
|
+
"filter",
|
|
1783
|
+
"backdrop-filter",
|
|
1784
|
+
"mix-blend-mode",
|
|
1785
|
+
"opacity"
|
|
1786
|
+
]);
|
|
1787
|
+
var EMPTY_VISUAL_VALUES = /* @__PURE__ */ new Set([
|
|
1788
|
+
"none",
|
|
1789
|
+
"0",
|
|
1790
|
+
"normal",
|
|
1791
|
+
"transparent",
|
|
1792
|
+
"rgba(0, 0, 0, 0)",
|
|
1793
|
+
"initial",
|
|
1794
|
+
"unset",
|
|
1795
|
+
"auto"
|
|
1796
|
+
]);
|
|
1797
|
+
var hasOwnVisualStyle = (node, ctx) => {
|
|
1798
|
+
const el = asElement(node);
|
|
1799
|
+
if (!el) return false;
|
|
1800
|
+
if (el.meta.hasOwnVisualStyle) return true;
|
|
1801
|
+
const computedMap = ctx.computedOf(el) ?? el.computed;
|
|
1802
|
+
const norm = normalizer.normalizeStyleMap(computedMap);
|
|
1803
|
+
for (const block of norm.blocks.values()) {
|
|
1804
|
+
for (const decl of block.decls.values()) {
|
|
1805
|
+
if (!VISUAL_PROPERTIES.has(String(decl.property))) continue;
|
|
1806
|
+
if (!EMPTY_VISUAL_VALUES.has(String(decl.value))) return true;
|
|
1807
|
+
}
|
|
1808
|
+
}
|
|
1809
|
+
return false;
|
|
1810
|
+
};
|
|
1811
|
+
var hasRef = (node) => asElement(node)?.meta.hasRef ?? false;
|
|
1812
|
+
var hasEventHandlers = (node) => asElement(node)?.meta.hasEventHandlers ?? false;
|
|
1813
|
+
var hasDynamicChildren = (node) => asElement(node)?.meta.hasDynamicChildren ?? false;
|
|
1814
|
+
var hasDynamicClasses = (node) => asElement(node)?.classes.hasDynamic ?? false;
|
|
1815
|
+
var targetedByCombinator = (node, ctx) => {
|
|
1816
|
+
const el = asElement(node);
|
|
1817
|
+
if (!el) return false;
|
|
1818
|
+
if (el.meta.targetedByCombinator) return true;
|
|
1819
|
+
return ctx.selectors.targetedByCombinator(el.id);
|
|
1820
|
+
};
|
|
1821
|
+
|
|
1822
|
+
// ../pattern-kit/src/ops.ts
|
|
1823
|
+
init_esm_shims();
|
|
1824
|
+
function idOf2(ref) {
|
|
1825
|
+
return typeof ref === "number" ? ref : ref.id;
|
|
1826
|
+
}
|
|
1827
|
+
function mergeStyle(target, source, style, onConflict = "abort") {
|
|
1828
|
+
return {
|
|
1829
|
+
op: "mergeStyle",
|
|
1830
|
+
target: idOf2(target),
|
|
1831
|
+
source: source == null ? null : idOf2(source),
|
|
1832
|
+
style,
|
|
1833
|
+
onConflict
|
|
1834
|
+
};
|
|
1835
|
+
}
|
|
1836
|
+
function foldInheritedStyles(from, into, opts) {
|
|
1837
|
+
const list = Array.isArray(into) ? into : [into];
|
|
1838
|
+
return {
|
|
1839
|
+
op: "foldInheritedStyles",
|
|
1840
|
+
from: idOf2(from),
|
|
1841
|
+
into: list.map(idOf2),
|
|
1842
|
+
properties: opts?.only ?? "all-inherited",
|
|
1843
|
+
conditions: opts?.conditions ?? "base"
|
|
1844
|
+
};
|
|
1845
|
+
}
|
|
1846
|
+
function replaceWith(target, replacement) {
|
|
1847
|
+
return { op: "replaceWith", target: idOf2(target), replacement };
|
|
1848
|
+
}
|
|
1849
|
+
function removeNode(target) {
|
|
1850
|
+
return { op: "removeNode", target: idOf2(target) };
|
|
1851
|
+
}
|
|
1852
|
+
|
|
1853
|
+
// ../pattern-kit/src/pattern.ts
|
|
1854
|
+
init_esm_shims();
|
|
1855
|
+
function camelToKebab(key) {
|
|
1856
|
+
if (key.startsWith("--")) return key;
|
|
1857
|
+
return key.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
|
|
1858
|
+
}
|
|
1859
|
+
function plainToStyleMap(style) {
|
|
1860
|
+
const decls = /* @__PURE__ */ new Map();
|
|
1861
|
+
for (const [rawKey, rawValue] of Object.entries(style)) {
|
|
1862
|
+
const prop = camelToKebab(rawKey);
|
|
1863
|
+
for (const decl of normalizer.normalizeDeclaration(prop, String(rawValue), false)) {
|
|
1864
|
+
decls.set(decl.property, decl);
|
|
1865
|
+
}
|
|
1866
|
+
}
|
|
1867
|
+
const block = { condition: BASE_CONDITION, decls };
|
|
1868
|
+
return { blocks: /* @__PURE__ */ new Map([[conditionKey(BASE_CONDITION), block]]) };
|
|
1869
|
+
}
|
|
1870
|
+
function asElement2(node) {
|
|
1871
|
+
const n = node;
|
|
1872
|
+
return n.kind === "element" ? n : null;
|
|
1873
|
+
}
|
|
1874
|
+
function metaFlag(flag) {
|
|
1875
|
+
return (node) => Boolean(asElement2(node)?.meta[flag]);
|
|
1876
|
+
}
|
|
1877
|
+
var hasRawHtml = metaFlag("hasDangerousHtml");
|
|
1878
|
+
var affectsSelectorMatching = (node, ctx) => {
|
|
1879
|
+
const el = asElement2(node);
|
|
1880
|
+
if (!el) return false;
|
|
1881
|
+
return ctx.selectors.reparentImpact(el.id).size > 0;
|
|
1882
|
+
};
|
|
1883
|
+
var FLATTEN_GUARDS = and(
|
|
1884
|
+
not(hasRef),
|
|
1885
|
+
not(hasEventHandlers),
|
|
1886
|
+
not(hasDynamicChildren),
|
|
1887
|
+
not(hasRawHtml),
|
|
1888
|
+
not(targetedByCombinator),
|
|
1889
|
+
not(affectsSelectorMatching)
|
|
1890
|
+
);
|
|
1891
|
+
function isFlattenCategory(category) {
|
|
1892
|
+
return category.split("/", 1)[0] === "flatten";
|
|
1893
|
+
}
|
|
1894
|
+
function compileDeclarativeMatch(m) {
|
|
1895
|
+
const parts = [isElement(m.tag)];
|
|
1896
|
+
if (m.style) parts.push(computed(plainToStyleMap(m.style)));
|
|
1897
|
+
if (m.onlyChild === "element") parts.push(hasSingleElementChild);
|
|
1898
|
+
if (m.paintsNothing) parts.push(not(hasOwnVisualStyle));
|
|
1899
|
+
if (m.where) {
|
|
1900
|
+
const extra = Array.isArray(m.where) ? m.where : [m.where];
|
|
1901
|
+
for (const w of extra) parts.push(w);
|
|
1902
|
+
}
|
|
1903
|
+
return and(...parts);
|
|
1904
|
+
}
|
|
1905
|
+
function compileMatch(match, category) {
|
|
1906
|
+
if (typeof match === "function") return match;
|
|
1907
|
+
const declarative = compileDeclarativeMatch(match ?? {});
|
|
1908
|
+
const guarded = isFlattenCategory(category) ? and(declarative, FLATTEN_GUARDS) : declarative;
|
|
1909
|
+
return (node, ctx) => guarded(node, ctx);
|
|
1910
|
+
}
|
|
1911
|
+
function pruneShadowed(sm, drop) {
|
|
1912
|
+
const blocks = /* @__PURE__ */ new Map();
|
|
1913
|
+
for (const [key, block] of sm.blocks) {
|
|
1914
|
+
const decls = /* @__PURE__ */ new Map();
|
|
1915
|
+
for (const [prop, decl] of block.decls) {
|
|
1916
|
+
const filtered = (decl.shadowed ?? []).filter(
|
|
1917
|
+
(o) => !(o.kind === "class" && drop.has(o.className))
|
|
1918
|
+
);
|
|
1919
|
+
const rest = { ...decl };
|
|
1920
|
+
delete rest.shadowed;
|
|
1921
|
+
const next = filtered.length > 0 ? { ...rest, shadowed: filtered } : rest;
|
|
1922
|
+
decls.set(prop, next);
|
|
1923
|
+
}
|
|
1924
|
+
blocks.set(key, { condition: block.condition, decls });
|
|
1925
|
+
}
|
|
1926
|
+
return { blocks };
|
|
1927
|
+
}
|
|
1928
|
+
function compileFlattenInto(recipe) {
|
|
1929
|
+
const childGains = recipe.childGains ? plainToStyleMap(recipe.childGains) : null;
|
|
1930
|
+
const fold = recipe.foldInherited !== false;
|
|
1931
|
+
return (ctx, rw) => {
|
|
1932
|
+
const wrapper = ctx.node;
|
|
1933
|
+
const child = ctx.onlyElementChild();
|
|
1934
|
+
if (!child) return null;
|
|
1935
|
+
const ops = [];
|
|
1936
|
+
if (fold) ops.push(rw.foldInheritedStyles(wrapper, child, { conditions: "all" }));
|
|
1937
|
+
if (childGains) ops.push(rw.mergeStyle(child, null, childGains, "source-wins"));
|
|
1938
|
+
ops.push(rw.unwrap(wrapper));
|
|
1939
|
+
return ops;
|
|
1940
|
+
};
|
|
1941
|
+
}
|
|
1942
|
+
function compileRewrite(rewrite) {
|
|
1943
|
+
if (typeof rewrite === "function") return rewrite;
|
|
1944
|
+
if ("flattenInto" in rewrite) return compileFlattenInto(rewrite);
|
|
1945
|
+
if ("rewriteClasses" in rewrite) {
|
|
1946
|
+
const preserveOpaque = rewrite.preserveOpaque ?? true;
|
|
1947
|
+
return (ctx, rw) => {
|
|
1948
|
+
const next = rewrite.rewriteClasses(ctx.computed(), ctx);
|
|
1949
|
+
if (!next) return null;
|
|
1950
|
+
return [rw.setClassList(ctx.node, next, preserveOpaque)];
|
|
1951
|
+
};
|
|
1952
|
+
}
|
|
1953
|
+
if ("dropClasses" in rewrite) {
|
|
1954
|
+
const preserveOpaque = rewrite.preserveOpaque ?? true;
|
|
1955
|
+
return (ctx, rw) => {
|
|
1956
|
+
const drop = new Set(rewrite.dropClasses(ctx.computed(), ctx));
|
|
1957
|
+
if (drop.size === 0) return null;
|
|
1958
|
+
return [rw.setClassList(ctx.node, pruneShadowed(ctx.computed(), drop), preserveOpaque)];
|
|
1959
|
+
};
|
|
1960
|
+
}
|
|
1961
|
+
const style = plainToStyleMap(rewrite.mergeStyle);
|
|
1962
|
+
const onConflict = rewrite.onConflict ?? "abort";
|
|
1963
|
+
return (ctx, rw) => [rw.mergeStyle(ctx.node, null, style, onConflict)];
|
|
1964
|
+
}
|
|
1965
|
+
function pattern(config) {
|
|
1966
|
+
const matchFn = compileMatch(config.match, config.category);
|
|
1967
|
+
const rewriteFn = compileRewrite(config.rewrite);
|
|
1968
|
+
const spec = {
|
|
1969
|
+
name: config.name,
|
|
1970
|
+
category: config.category,
|
|
1971
|
+
safety: config.safety,
|
|
1972
|
+
priority: config.priority,
|
|
1973
|
+
precondition: config.precondition,
|
|
1974
|
+
doc: config.doc,
|
|
1975
|
+
examples: config.examples,
|
|
1976
|
+
evaluate(ctx, rw) {
|
|
1977
|
+
if (!matchFn(ctx.node, ctx)) return null;
|
|
1978
|
+
const ops = rewriteFn(ctx, rw);
|
|
1979
|
+
if (!ops || ops.length === 0) return null;
|
|
1980
|
+
return { ops };
|
|
1981
|
+
}
|
|
1982
|
+
};
|
|
1983
|
+
return definePattern(spec);
|
|
1984
|
+
}
|
|
1985
|
+
|
|
1986
|
+
// ../pattern-kit/src/index.ts
|
|
1987
|
+
init_esm_shims();
|
|
1988
|
+
|
|
1989
|
+
export {
|
|
1990
|
+
createIdAllocator,
|
|
1991
|
+
createExprRegistry,
|
|
1992
|
+
createBackrefTable,
|
|
1993
|
+
defaultMeta,
|
|
1994
|
+
BASE_CONDITION,
|
|
1995
|
+
conditionKey,
|
|
1996
|
+
BASE_CONDITION_KEY,
|
|
1997
|
+
emptyStyleMap,
|
|
1998
|
+
emptyClassList,
|
|
1999
|
+
emptyAttrMap,
|
|
2000
|
+
emptyInlineStyle,
|
|
2001
|
+
createElement,
|
|
2002
|
+
createText,
|
|
2003
|
+
createExpr,
|
|
2004
|
+
createFragment,
|
|
2005
|
+
createComment,
|
|
2006
|
+
createDocument,
|
|
2007
|
+
childIds,
|
|
2008
|
+
getNode,
|
|
2009
|
+
getElement,
|
|
2010
|
+
elementIds,
|
|
2011
|
+
walk,
|
|
2012
|
+
cloneDocument,
|
|
2013
|
+
applyOps,
|
|
2014
|
+
applyGroups,
|
|
2015
|
+
DEFAULT_FIXPOINT,
|
|
2016
|
+
createNullResolver,
|
|
2017
|
+
createNullSelectorIndex,
|
|
2018
|
+
buildSelectorIndex,
|
|
2019
|
+
createRewriteFactory,
|
|
2020
|
+
runPasses,
|
|
2021
|
+
createPassManager,
|
|
2022
|
+
createSyntheticSink,
|
|
2023
|
+
createPipeline,
|
|
2024
|
+
syncClassesFromComputed,
|
|
2025
|
+
definePattern,
|
|
2026
|
+
createNormalizer,
|
|
2027
|
+
normalizer,
|
|
2028
|
+
isStyleSuperset,
|
|
2029
|
+
and,
|
|
2030
|
+
or,
|
|
2031
|
+
not,
|
|
2032
|
+
isElement,
|
|
2033
|
+
hasSingleElementChild,
|
|
2034
|
+
computed,
|
|
2035
|
+
hasOwnVisualStyle,
|
|
2036
|
+
hasRef,
|
|
2037
|
+
hasEventHandlers,
|
|
2038
|
+
hasDynamicChildren,
|
|
2039
|
+
hasDynamicClasses,
|
|
2040
|
+
targetedByCombinator,
|
|
2041
|
+
mergeStyle,
|
|
2042
|
+
foldInheritedStyles,
|
|
2043
|
+
replaceWith,
|
|
2044
|
+
removeNode,
|
|
2045
|
+
pattern
|
|
2046
|
+
};
|
|
2047
|
+
//# sourceMappingURL=chunk-77SLHRN6.js.map
|