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.
- package/CHANGELOG.md +144 -1
- package/README.md +113 -15
- package/dist/index.d.ts +19 -2
- package/dist/index.js +1490 -1003
- package/dist/model/types.d.ts +38 -1
- package/dist/template/expand.d.ts +26 -0
- package/package.json +5 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,149 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 0.
|
|
3
|
+
## 0.5.0 — 2026-08-26
|
|
4
|
+
|
|
5
|
+
### Known limitations
|
|
6
|
+
|
|
7
|
+
- Slots are deliberately unsupported this release. **Slots — measured alive in
|
|
8
|
+
6000.0.40f1. Out of this release scope and reported with
|
|
9
|
+
`template-slot-unsupported`.** Slot children are not placed in an arbitrary
|
|
10
|
+
location.
|
|
11
|
+
- A `style` AttributeOverride is reported as `override-style-ignored` and is not
|
|
12
|
+
applied, matching Unity's import behavior.
|
|
13
|
+
- Runtime `binding-path`, C# `makeItem`-selected `ListView`/`TreeView` item
|
|
14
|
+
templates, per-instance pseudo-state control, cyclic-graph truncation,
|
|
15
|
+
template editing, automatic extraction, and UI Builder reproduction remain
|
|
16
|
+
outside the viewer-core scope.
|
|
17
|
+
- The external 14-document sample is not broad template validation: only **1
|
|
18
|
+
document uses `<ui:Template>`**. Its former **31 → 0** figure counted
|
|
19
|
+
diagnostic lines — 1 Template declaration + 15 Instances + 15
|
|
20
|
+
AttributeOverrides — not 31 opened subtrees.
|
|
21
|
+
- An embedded package UXML physically present at
|
|
22
|
+
`<projectRoot>/Packages/<name>/` resolves through
|
|
23
|
+
`project://database/Packages/...`, as measured in Unity 6000.0.40f1. The core
|
|
24
|
+
and host still do not search `Library/PackageCache`; a registry-package
|
|
25
|
+
template available only there reports `package-path-not-searched`.
|
|
26
|
+
|
|
27
|
+
### Added
|
|
28
|
+
|
|
29
|
+
- **Template / Instance expansion.** `<ui:Template>` declarations are resolved
|
|
30
|
+
through the existing `resolveImport(url, from)` host hook, and
|
|
31
|
+
`<ui:Instance>` expands to an opaque `TemplateContainer`. Instance `name`,
|
|
32
|
+
`class`, and inline `style` attach to that container; nested expansion is
|
|
33
|
+
capped at 32 levels.
|
|
34
|
+
- `collectDependencies(source)` returns template `src` URLs in source order so a
|
|
35
|
+
synchronous host can prefetch the transitive input before rendering.
|
|
36
|
+
- `WarningKindMap<T>` is exported so consumers can make their diagnostic
|
|
37
|
+
classifier exhaustive.
|
|
38
|
+
- `AttributeOverrides` reaches every duplicate `element-name` target and reports
|
|
39
|
+
`override-target-missing` with the requested and available names when it finds
|
|
40
|
+
none. A `style` override reports `override-style-ignored` with the target name
|
|
41
|
+
and value; Unity ignores it during import, so it is not applied. Template source
|
|
42
|
+
provenance is kept separate from the derived render tree.
|
|
43
|
+
- The public `WarningKind` union grows from **8 to 17**. Consumers must update
|
|
44
|
+
their warning classifiers. The nine new template diagnostics are:
|
|
45
|
+
`template-src-unresolved`, `template-not-declared`, `template-cycle`,
|
|
46
|
+
`template-depth-exceeded`, `override-target-missing`,
|
|
47
|
+
`duplicate-name-in-tree`, `package-path-not-searched`,
|
|
48
|
+
`template-slot-unsupported`, and `override-style-ignored`.
|
|
49
|
+
|
|
50
|
+
### Changed
|
|
51
|
+
|
|
52
|
+
- Template stylesheet attachments remain scoped to the generated
|
|
53
|
+
`TemplateContainer` subtree. `Packages/...` is declaring-document-relative;
|
|
54
|
+
an embedded package UXML physically present at
|
|
55
|
+
`<projectRoot>/Packages/<name>/` resolves through the project-root-fixed
|
|
56
|
+
`project://database/Packages/...` form, as measured in Unity 6000.0.40f1.
|
|
57
|
+
`Library/PackageCache` is not searched, so a registry-package template
|
|
58
|
+
available only there reports `package-path-not-searched`.
|
|
59
|
+
- Cyclic templates fail closed with the complete cycle path. The source AST is
|
|
60
|
+
still round-tripped unchanged; expansion exists only in the render tree.
|
|
61
|
+
|
|
62
|
+
### Verified
|
|
63
|
+
|
|
64
|
+
- Unity 6000.0.40f1 template cohort: **200 / 220 coordinate values**, 55
|
|
65
|
+
elements, and 11 rendered cases with 11/11 rendered baselines. The 20
|
|
66
|
+
mismatches classify as (a) known font/text metrics 20, (b) 1px 0, and (c) new
|
|
67
|
+
cause 0; axes are height 14, width 4, x 1, y 1.
|
|
68
|
+
- G3-11 has no layout baseline because Unity `CloneTree` overflows the stack on
|
|
69
|
+
the cyclic input; the preview reports `template-cycle` and fails closed.
|
|
70
|
+
- This cohort is separate from the v0.4.0 base-control figure of **660 / 676**
|
|
71
|
+
for 169 elements. The figures are not combined.
|
|
72
|
+
|
|
73
|
+
## 0.4.0 — 2026-08-12
|
|
74
|
+
|
|
75
|
+
### Added
|
|
76
|
+
|
|
77
|
+
- The Unity golden dumper can run from the command line, records the Unity
|
|
78
|
+
revision, editor scale, accessible font settings, and timestamp beside each
|
|
79
|
+
measurement, rejects `-nographics` and `-quit` up front, and exits non-zero
|
|
80
|
+
unless it writes exactly one JSON file per discovered case.
|
|
81
|
+
|
|
82
|
+
### Changed
|
|
83
|
+
|
|
84
|
+
- Relative `@import` requests are deduplicated by `(url, from)`, matching Unity's
|
|
85
|
+
parent-relative loading. Root-fixed imports (`project://…` or a path beginning
|
|
86
|
+
with `/`) are globally deduplicated, and nested `<Style>` attachments now keep
|
|
87
|
+
their Unity subtree scope. The rule comes from five Unity measurement cases,
|
|
88
|
+
including the otherwise surprising split between `Packages/...` (relative)
|
|
89
|
+
and `/Packages/...` (root-fixed).
|
|
90
|
+
|
|
91
|
+
- **Issue #1: `resolveImport` now receives a second argument,
|
|
92
|
+
`from: string | null`** —
|
|
93
|
+
the URL of the stylesheet containing the import being resolved, `null` for
|
|
94
|
+
a `<Style src="…">` reference. Without it, a relative `@import` inside an
|
|
95
|
+
imported sheet was unresolvable in principle: `a.uss` importing `"b.uss"`
|
|
96
|
+
means a path relative to `a.uss`, and the host had no way to learn `a.uss`'s
|
|
97
|
+
own URL at the point it resolved `b.uss`. `from` is always the exact string
|
|
98
|
+
this hook received as `url` for the containing sheet, never reconstructed —
|
|
99
|
+
matters most for nested imports, where it is the immediate parent, not the
|
|
100
|
+
original sheet. **Non-breaking**: existing one-argument callbacks keep
|
|
101
|
+
working unchanged, same as `resolveAsset`'s `form` argument in 0.3.0.
|
|
102
|
+
- With this, `resolveImport` joins `resolveAsset` at two positional arguments.
|
|
103
|
+
Per the "코어에 무언가를 더하기 전에" rule in CLAUDE.md, the next argument
|
|
104
|
+
either hook would need is the point to switch to an options object instead
|
|
105
|
+
of adding a third positional one.
|
|
106
|
+
|
|
107
|
+
### Fixed
|
|
108
|
+
|
|
109
|
+
- **Issue #2: inline `style="…"` asset URLs reach `resolveAsset`
|
|
110
|
+
XML-entity-decoded**,
|
|
111
|
+
matching what a `<Style src>`-loaded `.uss` file's URLs already got (that
|
|
112
|
+
file was never XML, so it never had entities to decode; an inline attribute
|
|
113
|
+
is XML text and did). `background-image: url('…&guid=…')` written inline
|
|
114
|
+
used to reach the hook as `'…&guid=…'` — wrapper quotes and
|
|
115
|
+
ampersands both literal — because `inlineDeclarations` (style/resolve.ts)
|
|
116
|
+
parses straight from the raw XML source. Fixed at `assetPath()`
|
|
117
|
+
(render/css-map.ts), immediately before the `url()`/`resource()` wrapper is
|
|
118
|
+
parsed and right before the value leaves the model for the hook — the same
|
|
119
|
+
point `<Style src>` and painted text already decode at, not at parse time
|
|
120
|
+
(decoding then would corrupt the byte-exact round-trip source slices).
|
|
121
|
+
Confirmed against two real URLs from the external corpus in
|
|
122
|
+
`ReuHomi/vscode-uxml-preview` (`examples/external`, commit `dbda387`) where
|
|
123
|
+
this caused `asset-unresolved` for 7 URLs across 2 files. Scope: only the
|
|
124
|
+
asset-URL value reaching `resolveAsset`; other inline-style property values
|
|
125
|
+
still carry undecoded entities in the model (unaffected here, since no
|
|
126
|
+
other current consumer inspects their text — `-unity-font-definition`'s
|
|
127
|
+
`resource(...)` value is only checked for presence, never read).
|
|
128
|
+
|
|
129
|
+
### Docs
|
|
130
|
+
|
|
131
|
+
- **`docs/accuracy.md`'s "which controls this covers" table now has a stated,
|
|
132
|
+
computed rule** instead of being left unverified. It never added up on its
|
|
133
|
+
own terms (17+1+6+5+1 = 30, not the stated 31) and the original counting
|
|
134
|
+
rule was never written down, so it is now defined explicitly — classify
|
|
135
|
+
`inventory` as the representative screen, then each other case by the first
|
|
136
|
+
of `<ui:ScrollView`, `<ui:Button`, `<ui:Label` its UXML contains, else
|
|
137
|
+
`VisualElement` only — and computed from `tests/golden/cases.ts` rather than
|
|
138
|
+
hand-counted. Updated numbers: `Button` 6→10, `ScrollView` 5→4 (`VisualElement`
|
|
139
|
+
only, `Label`, and the representative screen are unchanged). Mirrored into
|
|
140
|
+
`docs/accuracy.en.md`, which is not machine-checked.
|
|
141
|
+
- **The drift guard now covers this table's five numbers too**, in
|
|
142
|
+
`docs/accuracy.md` only. Same shape as the three headline figures: recomputed
|
|
143
|
+
live and failing (not skipping) if it can't find a row to check. Confirmed by
|
|
144
|
+
breaking a count and by removing a row's label, both on purpose.
|
|
145
|
+
|
|
146
|
+
## 0.3.0 — 2026-08-09
|
|
4
147
|
|
|
5
148
|
Four fixes the VSCode extension (`vscode-uxml-preview`) hit while consuming
|
|
6
149
|
this package as a dependency — not speculative additions.
|
package/README.md
CHANGED
|
@@ -25,12 +25,12 @@ stylesheet comes out wrong.</sub>
|
|
|
25
25
|
npm install uxml-preview
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
-
> **v0.
|
|
28
|
+
> **v0.5.0.** Five controls (`VisualElement`, `Label`, `Button`,
|
|
29
29
|
> `Image`, `ScrollView`), everything else drawn as a plain box with a warning,
|
|
30
30
|
> and a support matrix that says plainly what has not been measured.
|
|
31
31
|
> Read [what is not verified yet](#what-is-not-verified-yet) before relying on it.
|
|
32
32
|
>
|
|
33
|
-
> **v0.
|
|
33
|
+
> **v0.5.0.** 컨트롤 5종(`VisualElement`, `Label`, `Button`,
|
|
34
34
|
> `Image`, `ScrollView`)이고, 나머지는 경고와 함께 일반 박스로 그립니다.
|
|
35
35
|
> 검증되지 않은 부분은 지원 범위표에 그대로 적어뒀습니다. 쓰시기 전에
|
|
36
36
|
> [아직 검증되지 않은 것](#아직-검증되지-않은-것)을 먼저 봐주세요.
|
|
@@ -47,12 +47,26 @@ directly in a web browser. It uses **Yoga** — the same layout engine Unity UI
|
|
|
47
47
|
itself uses — compiled to WebAssembly, so results match the Unity Editor rather than
|
|
48
48
|
approximating it.
|
|
49
49
|
|
|
50
|
-
Measured against Unity 6000.0.40f1: **
|
|
51
|
-
across
|
|
50
|
+
Measured against Unity 6000.0.40f1: **660 of 676 element coordinates identical**
|
|
51
|
+
across 40 layout cases, including a full working screen. Ten of the sixteen
|
|
52
52
|
differences are font metrics rather than layout — a browser cannot measure
|
|
53
53
|
Unity's font asset. All sixteen are named in
|
|
54
54
|
[`docs/accuracy.en.md`](docs/accuracy.en.md).
|
|
55
55
|
|
|
56
|
+
This changes what you can open: **you can now open real screens made by someone
|
|
57
|
+
else**, including screens assembled from reusable UXML parts rather than one
|
|
58
|
+
self-contained file. `<ui:Template>` declarations and `<ui:Instance>` elements
|
|
59
|
+
are expanded for rendering. The template cohort is measured separately:
|
|
60
|
+
**200 / 220 coordinate values across 55 elements and 11 rendered cases**; it is
|
|
61
|
+
not added to the base 660/676 figure. Cycles fail closed with a diagnostic, and
|
|
62
|
+
slots are measured as alive in Unity 6000.0.40f1 but remain out of scope and
|
|
63
|
+
report `template-slot-unsupported`.
|
|
64
|
+
|
|
65
|
+
This is not a claim that every external sample exercises templates: only **1 of
|
|
66
|
+
14** external documents uses `<ui:Template>`. The reported 31 → 0 improvement
|
|
67
|
+
there counts diagnostic lines (1 declaration + 15 instances + 15 overrides),
|
|
68
|
+
not 31 opened subtrees.
|
|
69
|
+
|
|
56
70
|
```
|
|
57
71
|
.uxml + .uss → parse → style resolve → Yoga layout → DOM paint
|
|
58
72
|
↓
|
|
@@ -99,7 +113,9 @@ That broken feedback loop is what this library fixes.
|
|
|
99
113
|
| 5 | Golden tests against Unity | ✅ |
|
|
100
114
|
| 6 | **v0.1 release** | ✅ |
|
|
101
115
|
| 7 | **v0.2 — ScrollView, Image, states, a measured screen** | ✅ |
|
|
102
|
-
| 8
|
|
116
|
+
| 8 | **v0.3–0.4 — asset/import resolution semantics, Unity CLI measurement** | ✅ |
|
|
117
|
+
| 9 | **v0.5 — Template / Instance expansion and diagnostics** | ✅ |
|
|
118
|
+
| 10+ | Editing layer, tool integration | ⬜ |
|
|
103
119
|
|
|
104
120
|
Full plan: [`docs/ROADMAP.md`](docs/ROADMAP.md)
|
|
105
121
|
|
|
@@ -108,6 +124,18 @@ Full plan: [`docs/ROADMAP.md`](docs/ROADMAP.md)
|
|
|
108
124
|
The support matrix is deliberately conservative — see
|
|
109
125
|
[`docs/supported.en.md`](docs/supported.en.md) for the full table.
|
|
110
126
|
|
|
127
|
+
- **Slots are not supported in v0.5.0.** They were measured alive in Unity
|
|
128
|
+
6000.0.40f1; slot children are not placed and `template-slot-unsupported` is
|
|
129
|
+
reported.
|
|
130
|
+
- **A `style` AttributeOverride is not applied.** Unity ignores it during import,
|
|
131
|
+
and the preview reports `override-style-ignored` instead of drawing a plausible
|
|
132
|
+
but wrong result.
|
|
133
|
+
- **`Library/PackageCache` is not searched.** Embedded package UXML physically
|
|
134
|
+
present under `<projectRoot>/Packages/<name>/` resolves through
|
|
135
|
+
`project://database/Packages/...`; a registry-package template available only
|
|
136
|
+
in the cache reports `package-path-not-searched`.
|
|
137
|
+
- **The external 14-document sample contains only 1 template document.** Its
|
|
138
|
+
31 → 0 result counts diagnostic lines, not rendered template subtrees.
|
|
111
139
|
- **Only geometry is compared automatically, and only as far as Yoga.** The
|
|
112
140
|
figure above is measured at the coordinates the layout engine produces.
|
|
113
141
|
Whether the painted DOM reproduces them is checked by an invariant of our own
|
|
@@ -143,7 +171,8 @@ const doc = parse(uxmlText, ussText);
|
|
|
143
171
|
|
|
144
172
|
// model → screen
|
|
145
173
|
const view = render(doc, document.getElementById('preview'), {
|
|
146
|
-
resolveAsset: (path) =>
|
|
174
|
+
resolveAsset: (path, form) =>
|
|
175
|
+
form === 'url' ? myAssetUrlFor(path) : myResourcesAssetUrlFor(path),
|
|
147
176
|
|
|
148
177
|
// Pseudo-class states are explicit input, keyed by USS selector, so the same
|
|
149
178
|
// call always draws the same picture. Per element, because real screens mix.
|
|
@@ -158,6 +187,20 @@ view.dispose();
|
|
|
158
187
|
const { uxml, uss } = serialize(doc);
|
|
159
188
|
```
|
|
160
189
|
|
|
190
|
+
`form` keeps `url()` and `resource()` distinct. `url()` is a host-defined asset
|
|
191
|
+
path; `resource()` is Unity's Resources lookup, where the extension is optional
|
|
192
|
+
and the folder may occur anywhere under `Assets`. Unity can also resolve editor
|
|
193
|
+
built-ins that a disk-only host cannot, so return `null` rather than treating a
|
|
194
|
+
resource name as an ordinary project path.
|
|
195
|
+
|
|
196
|
+
For external stylesheets and template `src` files,
|
|
197
|
+
`parse(uxml, uss, { resolveImport: (url, from) => ... })` passes the immediate
|
|
198
|
+
containing URL as `from`. Entry-UXML references receive `null`; nested stylesheet
|
|
199
|
+
imports receive the containing stylesheet URL, and nested template dependencies
|
|
200
|
+
receive the containing UXML URL. Existing one-argument callbacks remain valid; a future third hook
|
|
201
|
+
argument will use an options object instead. `collectDependencies(source)` lists
|
|
202
|
+
template dependency URLs in source order for host prefetching.
|
|
203
|
+
|
|
161
204
|
### Playground
|
|
162
205
|
|
|
163
206
|
**[reuhomi.github.io/uxml-preview](https://reuhomi.github.io/uxml-preview/)** —
|
|
@@ -210,12 +253,14 @@ Checked by comparing element geometry against the Unity Editor, case by case.
|
|
|
210
253
|
Geometry rather than pixels: Unity draws text with its own font asset and a
|
|
211
254
|
browser does not, so a pixel diff would measure the font more than the layout.
|
|
212
255
|
|
|
213
|
-
|
|
256
|
+
Coordinates measured against Unity on 2026-08-12, over 40 layout cases and 169
|
|
257
|
+
elements:
|
|
214
258
|
|
|
215
259
|
| | |
|
|
216
260
|
|---|---|
|
|
217
|
-
| Cases matching exactly | **
|
|
218
|
-
| Values within 0.5px | **
|
|
261
|
+
| Cases matching exactly | **38 / 40** |
|
|
262
|
+
| Values within 0.5px | **660 / 676 (97.6%)** |
|
|
263
|
+
| Unity baselines recorded | **41 / 41** (40 coordinate cases + 1 resource observation) |
|
|
219
264
|
|
|
220
265
|
The sixteen divergences are four different things, and the distinction matters
|
|
221
266
|
more than the ratio: **ten are text metrics**, three are 1px, two are a
|
|
@@ -246,7 +291,7 @@ as nested flex, and computed values have to be resolved to fixed numbers or
|
|
|
246
291
|
calculated in C#.
|
|
247
292
|
|
|
248
293
|
**How close is the output to Unity?**
|
|
249
|
-
|
|
294
|
+
660 of 676 element coordinates identical against Unity 6000.0.40f1, across 40
|
|
250
295
|
layout cases including a complete inventory screen. Geometry is compared rather
|
|
251
296
|
than screenshots, because Unity draws text with its own font asset — which is
|
|
252
297
|
also why ten of the sixteen differences are font metrics rather than layout.
|
|
@@ -264,6 +309,14 @@ back out unchanged. Their own styles and their children come out normally; only
|
|
|
264
309
|
what makes that control look like itself is missing. One unfamiliar tag never
|
|
265
310
|
takes down the rest of the screen, and nothing is silently dropped.
|
|
266
311
|
|
|
312
|
+
**Are templates and instances rendered?**
|
|
313
|
+
Yes. Template declarations resolve through the host import hook, instances become
|
|
314
|
+
opaque `TemplateContainer` elements, and `AttributeOverrides` reach every
|
|
315
|
+
duplicate target for ordinary attributes. A `style` AttributeOverride is reported
|
|
316
|
+
as `override-style-ignored` because Unity ignores it during import. Slot children
|
|
317
|
+
are intentionally not placed; the measured Unity slot behavior is reported as
|
|
318
|
+
`template-slot-unsupported` in this release.
|
|
319
|
+
|
|
267
320
|
### License
|
|
268
321
|
|
|
269
322
|
Apache-2.0
|
|
@@ -280,11 +333,23 @@ Apache-2.0
|
|
|
280
333
|
**Yoga**를 WebAssembly로 그대로 사용하기 때문에, 결과를 "비슷하게 흉내내는" 것이 아니라
|
|
281
334
|
유니티 에디터와 일치시킵니다.
|
|
282
335
|
|
|
283
|
-
Unity 6000.0.40f1과 대조한 결과, 실무형 화면을 포함한 레이아웃 케이스
|
|
284
|
-
**요소 좌표
|
|
336
|
+
Unity 6000.0.40f1과 대조한 결과, 실무형 화면을 포함한 레이아웃 케이스 40개에서
|
|
337
|
+
**요소 좌표 676개 중 660개가 일치**합니다. 어긋난 16개 중 **10개는 레이아웃이 아니라
|
|
285
338
|
폰트 메트릭** 차이입니다 — 브라우저는 유니티 폰트 에셋을 잴 수 없습니다.
|
|
286
339
|
16개 전부 [`docs/accuracy.md`](docs/accuracy.md)에 이름과 사유를 적어뒀습니다.
|
|
287
340
|
|
|
341
|
+
이제 **남이 만든 실제 화면을 열 수 있게 됩니다.** 한 파일에 모든 내용을 넣은
|
|
342
|
+
화면뿐 아니라 재사용 가능한 UXML 조각을 조립한 화면도 `<ui:Template>`과
|
|
343
|
+
`<ui:Instance>`를 전개해 렌더링합니다. 템플릿 코호트는 기본 수치와 분리해
|
|
344
|
+
**55 elements, 11개 렌더 케이스의 좌표 220개 중 200개**로 측정했으며
|
|
345
|
+
660/676에 합산하지 않습니다. 순환은 진단과 함께 fail-closed로 막고, 슬롯은
|
|
346
|
+
Unity 6000.0.40f1에서 살아 있음을 실측했지만 이번 범위 밖이라
|
|
347
|
+
`template-slot-unsupported`로 보고합니다.
|
|
348
|
+
|
|
349
|
+
외부 14개 표본 전체가 템플릿을 검증한 것은 아닙니다. 그중 `<ui:Template>`을
|
|
350
|
+
쓰는 문서는 **1개**뿐이고, 보고된 31 → 0은 열린 서브트리 수가 아니라 진단
|
|
351
|
+
줄 수(선언 1 + Instance 15 + override 15)입니다.
|
|
352
|
+
|
|
288
353
|
```
|
|
289
354
|
.uxml + .uss → 파싱 → 스타일 계산 → Yoga 레이아웃 → DOM 페인팅
|
|
290
355
|
↓
|
|
@@ -330,7 +395,9 @@ Unity 6000.0.40f1과 대조한 결과, 실무형 화면을 포함한 레이아
|
|
|
330
395
|
| 5 | 유니티 대조 골든 테스트 | ✅ |
|
|
331
396
|
| 6 | **v0.1 공개** | ✅ |
|
|
332
397
|
| 7 | **v0.2 — ScrollView·Image·상태, 대표 화면 대조** | ✅ |
|
|
333
|
-
| 8
|
|
398
|
+
| 8 | **v0.3–0.4 — 에셋·import 해석 의미론, Unity CLI 계측** | ✅ |
|
|
399
|
+
| 9 | **v0.5 — Template / Instance 전개와 진단** | ✅ |
|
|
400
|
+
| 10+ | 편집 레이어, 도구 통합 | ⬜ |
|
|
334
401
|
|
|
335
402
|
전체 계획: [`docs/ROADMAP.md`](docs/ROADMAP.md)
|
|
336
403
|
|
|
@@ -339,6 +406,17 @@ Unity 6000.0.40f1과 대조한 결과, 실무형 화면을 포함한 레이아
|
|
|
339
406
|
지원 범위는 일부러 보수적으로 적었습니다. 전체 표는
|
|
340
407
|
[`docs/supported.md`](docs/supported.md)에 있습니다.
|
|
341
408
|
|
|
409
|
+
- **v0.5.0은 슬롯을 지원하지 않습니다.** Unity 6000.0.40f1에서 살아 있음을
|
|
410
|
+
실측했지만 슬롯 자식은 배치하지 않고 `template-slot-unsupported`로 보고합니다
|
|
411
|
+
- **`style` AttributeOverride는 적용하지 않습니다.** Unity가 import 과정에서
|
|
412
|
+
무시하는 동작을 따르며, 그럴듯하지만 틀린 결과 대신
|
|
413
|
+
`override-style-ignored`를 보고합니다
|
|
414
|
+
- **`Library/PackageCache`는 탐색하지 않습니다.**
|
|
415
|
+
`<projectRoot>/Packages/<name>/`에 실물이 있는 embedded package UXML은
|
|
416
|
+
`project://database/Packages/...`로 해석하지만, 캐시에만 있는 레지스트리 패키지
|
|
417
|
+
템플릿은 `package-path-not-searched`로 보고합니다
|
|
418
|
+
- **외부 14개 표본 중 템플릿 문서는 1개뿐입니다.** 31 → 0은 렌더된 템플릿
|
|
419
|
+
서브트리가 아니라 진단 줄 수입니다
|
|
342
420
|
- **자동 대조는 좌표만, 그것도 Yoga 층까지입니다.** 위 수치는 레이아웃 엔진이 낸
|
|
343
421
|
좌표를 잰 것입니다. 그려진 DOM이 그 좌표를 재현하는지는 유니티가 아니라 자체
|
|
344
422
|
불변식 검사로 봅니다
|
|
@@ -396,6 +474,19 @@ pnpm build
|
|
|
396
474
|
정확도 수치를 재현하려면 유니티가 필요합니다. 절차는
|
|
397
475
|
[`docs/accuracy.md`](docs/accuracy.md)에 있습니다.
|
|
398
476
|
|
|
477
|
+
### API
|
|
478
|
+
|
|
479
|
+
`render` 옵션의 `resolveAsset(path, form)`에서 `form`은 `'url' | 'resource'`입니다.
|
|
480
|
+
`url()`은 호스트의 에셋 경로이고 `resource()`는 Unity Resources 검색입니다. 후자는
|
|
481
|
+
확장자 없이 쓸 수 있고 Resources 폴더가 `Assets` 아래 어디에나 있을 수 있으며, 에디터
|
|
482
|
+
내장 리소스처럼 프로젝트 디스크만 보는 호스트가 풀 수 없는 값도 있으므로 그때는 `null`을
|
|
483
|
+
반환해야 합니다. 외부 스타일시트와 템플릿 `src`는
|
|
484
|
+
`parse(uxml, uss, { resolveImport: (url, from) => ... })`로 읽습니다. 엔트리 UXML의
|
|
485
|
+
참조는 `from: null`, 중첩 stylesheet import는 부모 stylesheet URL, 중첩 템플릿
|
|
486
|
+
의존성은 부모 UXML URL을 받습니다. 기존 한 인자 콜백은 계속 동작합니다.
|
|
487
|
+
`collectDependencies(source)`는 호스트가
|
|
488
|
+
미리 가져올 템플릿 의존 URL을 소스 순서대로 돌려줍니다.
|
|
489
|
+
|
|
399
490
|
### 이런 질문에 답합니다
|
|
400
491
|
|
|
401
492
|
**유니티를 켜지 않고 UXML을 미리 볼 수 있나요?**
|
|
@@ -414,8 +505,8 @@ pnpm build
|
|
|
414
505
|
계산이 필요한 값은 고정값으로 풀거나 C#에서 계산해야 합니다.
|
|
415
506
|
|
|
416
507
|
**유니티와 얼마나 같나요?**
|
|
417
|
-
Unity 6000.0.40f1 기준, 인벤토리 화면 전체를 포함한 레이아웃 케이스
|
|
418
|
-
**요소 좌표
|
|
508
|
+
Unity 6000.0.40f1 기준, 인벤토리 화면 전체를 포함한 레이아웃 케이스 40개에서
|
|
509
|
+
**요소 좌표 676개 중 660개 일치**입니다. 스크린샷이 아니라 좌표를 비교하는데,
|
|
419
510
|
유니티가 자기 폰트 에셋으로 글자를 그리기 때문입니다 — 그리고 그 사실 때문에
|
|
420
511
|
불일치 16개 중 **10개가 레이아웃이 아니라 폰트 메트릭**입니다. 전부
|
|
421
512
|
[`docs/accuracy.md`](docs/accuracy.md)에 이름이 적혀 있습니다.
|
|
@@ -430,6 +521,13 @@ Unity 6000.0.40f1 기준, 인벤토리 화면 전체를 포함한 레이아웃
|
|
|
430
521
|
자기 스타일과 자식은 정상적으로 나오며 그 컨트롤 고유의 모양만 빠집니다. 모르는 태그
|
|
431
522
|
하나 때문에 화면 전체가 죽지 않고, 조용히 사라지는 것도 없습니다.
|
|
432
523
|
|
|
524
|
+
**템플릿과 인스턴스도 렌더링하나요?**
|
|
525
|
+
네. 템플릿 선언은 호스트 import 훅으로 해석하고, 인스턴스는 불투명한
|
|
526
|
+
`TemplateContainer`로 전개하며, `AttributeOverrides`는 같은 이름의 모든 대상에
|
|
527
|
+
일반 속성을 적용합니다. `style` AttributeOverride는 Unity가 import에서 무시하므로
|
|
528
|
+
`override-style-ignored`로 보고하고 적용하지 않습니다. 슬롯 자식은 이번 릴리스에서
|
|
529
|
+
배치하지 않고 `template-slot-unsupported` 진단으로 보고합니다.
|
|
530
|
+
|
|
433
531
|
### 라이선스
|
|
434
532
|
|
|
435
533
|
Apache-2.0
|
package/dist/index.d.ts
CHANGED
|
@@ -7,7 +7,9 @@ import { LayoutBox, MeasureText } from './layout/yoga';
|
|
|
7
7
|
* below are still signatures only; implementations land in Phases 2–4.
|
|
8
8
|
* See docs/ROADMAP.md.
|
|
9
9
|
*/
|
|
10
|
-
export type { Span, SourceRef, NodeId, ElementName, Attribute, ElementSpans, ElementNode, Combinator, SimpleSelector, SelectorPart, Selector, Declaration, Rule, SheetItem, StyleSheet, WarningKind, Warning, UxmlDocument, StyleOrigin, } from './model/types';
|
|
10
|
+
export type { Span, SourceRef, NodeId, ElementName, Attribute, ElementSpans, ElementNode, Combinator, SimpleSelector, SelectorPart, Selector, Declaration, Rule, SheetItem, StyleSheet, WarningKind, WarningKindMap, Warning, UxmlDocument, StyleOrigin, } from './model/types';
|
|
11
|
+
export { collectDependencies, expandTemplates } from './template/expand';
|
|
12
|
+
export type { TemplateExpansion, TemplateResolver } from './template/expand';
|
|
11
13
|
export { loadLayoutEngine, isLayoutEngineReady, liveNodeCount } from './layout/yoga';
|
|
12
14
|
export type { LayoutBox, MeasureText, TextContext, TextMetrics } from './layout/yoga';
|
|
13
15
|
export { createDefaultMeasureText } from './render/measure';
|
|
@@ -37,8 +39,23 @@ export interface ParseOptions {
|
|
|
37
39
|
* `project://database/Assets/UI/base.uss`, which only the host application
|
|
38
40
|
* knows how to turn into file contents, and there is no reason for a host to
|
|
39
41
|
* implement that lookup twice.
|
|
42
|
+
*
|
|
43
|
+
* `from` is the URL of the stylesheet containing this import — exactly the
|
|
44
|
+
* string this hook received as `url` when that containing sheet was itself
|
|
45
|
+
* resolved, unmodified. `null` for a `<Style src="…">` reference, which is
|
|
46
|
+
* not contained in any stylesheet. A relative `@import` cannot be resolved
|
|
47
|
+
* without this: `a.uss` importing `"b.uss"` means a path relative to `a.uss`,
|
|
48
|
+
* not to the UXML document, and there is no other way for the host to learn
|
|
49
|
+
* `a.uss`'s own URL at the point it resolves `b.uss`.
|
|
50
|
+
*
|
|
51
|
+
* Non-breaking: this is an added argument, not a replacement one, so an
|
|
52
|
+
* existing one-argument callback keeps working unchanged.
|
|
53
|
+
*
|
|
54
|
+
* Relative imports are deduplicated by `(url, from)`, so two parent sheets
|
|
55
|
+
* may resolve the same spelling to different files. Root-fixed URLs —
|
|
56
|
+
* `project://…` or a path beginning with `/` — are deduplicated by URL alone.
|
|
40
57
|
*/
|
|
41
|
-
resolveImport?: (url: string) => string | null;
|
|
58
|
+
resolveImport?: (url: string, from: string | null) => string | null;
|
|
42
59
|
}
|
|
43
60
|
export declare function parse(uxml: string, uss?: string, options?: ParseOptions): UxmlDocument;
|
|
44
61
|
/**
|