uxml-preview 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -66,6 +66,8 @@ export interface Attribute {
66
66
  */
67
67
  value: string;
68
68
  span: Span;
69
+ /** Render-only provenance for a cloned/overridden attribute. */
70
+ sourceDocument?: string | null;
69
71
  }
70
72
  /**
71
73
  * Three spans rather than one, so that an edit stays local.
@@ -111,6 +113,21 @@ export interface ElementNode {
111
113
  * synthesized (copy a sibling's leading whitespace).
112
114
  */
113
115
  childrenDirty: boolean;
116
+ /**
117
+ * A render-only node synthesized while a template instance is expanded.
118
+ * Parsed nodes leave this absent; serialization never sees the derived tree.
119
+ */
120
+ derived?: {
121
+ kind: 'template-container';
122
+ /** The source `<ui:Instance>` that caused this container to exist. */
123
+ instance: NodeId;
124
+ };
125
+ /** URL of the UXML document that supplied a render-only clone. */
126
+ sourceDocument?: string | null;
127
+ /** URL that sourceDocument was resolved from, when it was relative. */
128
+ sourceDocumentFrom?: string | null;
129
+ /** Node id inside sourceDocument for a render-only clone. */
130
+ sourceNode?: NodeId;
114
131
  }
115
132
  export type Combinator = 'descendant' | 'child';
116
133
  /**
@@ -196,6 +213,7 @@ export type SheetItem = {
196
213
  kind: 'import';
197
214
  url: string;
198
215
  span: Span;
216
+ resolvedSheet?: number;
199
217
  } | {
200
218
  kind: 'unknown';
201
219
  span: Span;
@@ -208,9 +226,15 @@ export interface StyleSheet {
208
226
  * passed directly to `parse()`. Used in warning messages only.
209
227
  */
210
228
  origin: string | null;
229
+ /** Containing URL used to resolve origin in a derived template document. */
230
+ sourceDocumentFrom?: string | null;
211
231
  items: SheetItem[];
212
232
  }
213
- export type WarningKind = 'unsupported-control' | 'unsupported-property' | 'unsupported-selector' | 'unsupported-unit' | 'version-dependent' | 'asset-unresolved' | 'import-unresolved' | 'malformed';
233
+ export type WarningKind = 'unsupported-control' | 'unsupported-property' | 'unsupported-selector' | 'unsupported-unit' | 'version-dependent' | 'asset-unresolved' | 'import-unresolved' | 'malformed' | 'template-src-unresolved' | 'template-not-declared' | 'template-cycle' | 'template-depth-exceeded' | 'override-target-missing' | 'duplicate-name-in-tree' | 'package-path-not-searched' | 'template-slot-unsupported' | 'override-style-ignored';
234
+ /** A mapped type consumers can use for exhaustive warning classification. */
235
+ export type WarningKindMap<T> = {
236
+ [K in WarningKind]: T;
237
+ };
214
238
  /**
215
239
  * Never a thrown error. One unsupported property must not take down the render
216
240
  * (see CLAUDE.md rule 6).
@@ -221,6 +245,8 @@ export type WarningKind = 'unsupported-control' | 'unsupported-property' | 'unsu
221
245
  export interface Warning {
222
246
  kind: WarningKind;
223
247
  message: string;
248
+ /** Document URL for a warning originating outside the entry UXML. */
249
+ sourceDocument?: string | null;
224
250
  /** Text location, when the warning has one. */
225
251
  at?: SourceRef;
226
252
  /** Element the warning is about, when it has one. Lets the UI highlight it. */
@@ -244,6 +270,11 @@ export interface UxmlDocument {
244
270
  * own `source`, which is why the source text lives on the sheet.
245
271
  */
246
272
  sheets: StyleSheet[];
273
+ /** Stylesheet entry points and the element subtree each one is attached to. */
274
+ styleRoots?: Array<{
275
+ sheet: number;
276
+ scope: NodeId;
277
+ }>;
247
278
  /**
248
279
  * Parse-time only — `'malformed'` (bad syntax) and `'import-unresolved'`
249
280
  * (a `<Style src="…">` or `@import` that `resolveImport` could not read).
@@ -270,11 +301,17 @@ export type StyleOrigin = {
270
301
  kind: 'inline';
271
302
  node: NodeId;
272
303
  declIndex: number;
304
+ /** URL of the UXML/USS document that supplied this declaration. */
305
+ sourceDocument?: string | null;
306
+ sourceDocumentFrom?: string | null;
273
307
  } | {
274
308
  kind: 'rule';
275
309
  sheet: number;
276
310
  item: number;
277
311
  declIndex: number;
312
+ /** URL of the stylesheet containing the declaration, when external. */
313
+ sourceDocument?: string | null;
314
+ sourceDocumentFrom?: string | null;
278
315
  /**
279
316
  * Pseudo-class states the matched selector required, e.g. `['hover']`.
280
317
  *
@@ -0,0 +1,26 @@
1
+ import { UxmlDocument, Warning } from '../model/types';
2
+ export type TemplateResolver = (url: string, from: string | null) => string | null;
3
+ type TemplateDocumentParser = (source: string, resolver: TemplateResolver | undefined) => UxmlDocument;
4
+ /** Internal registration avoids making the template loader depend on index.ts. */
5
+ export declare function registerTemplateParser(parser: TemplateDocumentParser): void;
6
+ /** Called by parse() so expansion can reuse the exact resolver the host passed. */
7
+ export declare function rememberTemplateResolver(document: UxmlDocument, resolver: TemplateResolver | undefined): void;
8
+ /**
9
+ * Purpose: collect direct template dependencies without a regex pass.
10
+ * Deps/Effects: parses `source`; no I/O and no model mutation.
11
+ * Ensures: returns decoded `<Template src>` values in source order.
12
+ */
13
+ export declare function collectDependencies(source: string): string[];
14
+ export interface TemplateExpansion {
15
+ /** Render-only document. The caller must keep the original for serialization. */
16
+ document: UxmlDocument;
17
+ warnings: readonly Warning[];
18
+ }
19
+ /**
20
+ * Expand all instances in a document into a derived tree.
21
+ *
22
+ * The entry UXML is represented as a tiny loaded record so the same recursive
23
+ * path handles top-level and nested declarations. Its URL is null by contract.
24
+ */
25
+ export declare function expandTemplates(document: UxmlDocument): TemplateExpansion;
26
+ export {};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "uxml-preview",
3
- "version": "0.3.0",
4
- "description": "Preview Unity UI Toolkit UXML/USS in a browser without the Unity Editor. Uses Yoga (WebAssembly), the same layout engine UI Toolkit uses: 548 of 564 element coordinates identical to Unity 6. Parses and writes files back byte-for-byte.",
3
+ "version": "0.5.0",
4
+ "description": "Preview Unity UI Toolkit UXML/USS in a browser without the Unity Editor. Uses Yoga (WebAssembly), the same layout engine UI Toolkit uses: 660 of 676 element coordinates identical to Unity 6. Parses and writes files back byte-for-byte.",
5
5
  "keywords": [
6
6
  "unity",
7
7
  "unity3d",
@@ -69,9 +69,11 @@
69
69
  "test:roundtrip": "vitest run tests/roundtrip",
70
70
  "test:golden": "vitest run tests/golden --passWithNoTests",
71
71
  "golden:emit": "node --experimental-strip-types --no-warnings scripts/emit-golden-cases.mjs",
72
+ "template:emit": "node --experimental-strip-types --no-warnings scripts/emit-template-cases.mjs",
72
73
  "golden:update": "node scripts/update-golden.mjs",
74
+ "check:self-reference": "node scripts/check-self-reference.mjs",
73
75
  "typecheck": "tsc --noEmit",
74
- "prepublishOnly": "npm run typecheck && npm run test && npm run build"
76
+ "prepublishOnly": "npm run check:self-reference && npm run typecheck && npm run test && npm run build"
75
77
  },
76
78
  "dependencies": {
77
79
  "yoga-layout": "^3.2.1"