@pygmalionjs/pygmalion 0.8.1 → 0.9.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/binding-source.d.ts +25 -0
- package/dist-lib/{CameraLayer-B2D29VXQ.js → CameraLayer-BdOko8XE.js} +17 -17
- package/dist-lib/pygmalion.js +24599 -12746
- package/dist-lib/{runtime-BAy8W1mJ.js → runtime-Dxb-IaLN.js} +12414 -11114
- package/dist-lib/style.css +1 -1
- package/dist-lib/testing.js +10 -10
- package/dist-lib/types/binding/catalog.d.ts +10 -0
- package/dist-lib/types/binding/contracts.d.ts +202 -0
- package/dist-lib/types/binding/documentCommands.d.ts +38 -0
- package/dist-lib/types/binding/index.d.ts +6 -0
- package/dist-lib/types/binding/preview.d.ts +37 -0
- package/dist-lib/types/binding/source.d.ts +109 -0
- package/dist-lib/types/binding/useDataProjection.d.ts +9 -0
- package/dist-lib/types/binding/validate.d.ts +8 -0
- package/dist-lib/types/core/runtime.d.ts +6 -0
- package/dist-lib/types/document/appearance.d.ts +112 -0
- package/dist-lib/types/document/assets.d.ts +204 -0
- package/dist-lib/types/document/components.d.ts +169 -0
- package/dist-lib/types/document/contracts.d.ts +171 -0
- package/dist-lib/types/document/engine.d.ts +20 -0
- package/dist-lib/types/document/exportSettings.d.ts +45 -0
- package/dist-lib/types/document/geometry.d.ts +11 -0
- package/dist-lib/types/document/layout.d.ts +53 -0
- package/dist-lib/types/document/prototype.d.ts +424 -0
- package/dist-lib/types/document/prototypeReferences.d.ts +3 -0
- package/dist-lib/types/document/richText.d.ts +185 -0
- package/dist-lib/types/document/styles.d.ts +216 -0
- package/dist-lib/types/document/svgImport.d.ts +17 -0
- package/dist-lib/types/document/vector.d.ts +222 -0
- package/dist-lib/types/editor/designCompiler.d.ts +7 -0
- package/dist-lib/types/editor/designImport.d.ts +7 -0
- package/dist-lib/types/editor/inspect.d.ts +8 -0
- package/dist-lib/types/editor/revisionCatalogInstall.d.ts +1 -1
- package/dist-lib/types/editor/screenInteractions.d.ts +3 -3
- package/dist-lib/types/editor/store.d.ts +1 -1
- package/dist-lib/types/host/project.d.ts +44 -0
- package/dist-lib/types/host/registryConnections.d.ts +11 -0
- package/dist-lib/types/host/sourceFilePlan.d.ts +15 -0
- package/dist-lib/types/host/sourceWriteback.d.ts +50 -0
- package/dist-lib/types/lib.d.ts +101 -3
- package/dist-lib/types/token-library/bindings.d.ts +62 -0
- package/dist-lib/types/token-library/contracts.d.ts +117 -0
- package/dist-lib/types/token-library/engine.d.ts +13 -0
- package/dist-lib/types/workspace/WorkspaceShell.d.ts +9 -0
- package/dist-lib/types/workspace/application/ApplicationWorkspace.d.ts +3 -0
- package/dist-lib/types/workspace/configuration.d.ts +39 -0
- package/dist-lib/types/workspace/contracts.d.ts +64 -0
- package/dist-lib/types/workspace/controller.d.ts +35 -0
- package/dist-lib/types/workspace/documentSessions.d.ts +42 -0
- package/dist-lib/types/workspace/edit/AppearancePanel.d.ts +23 -0
- package/dist-lib/types/workspace/edit/ArrangeLayers.d.ts +10 -0
- package/dist-lib/types/workspace/edit/AssetsPanel.d.ts +16 -0
- package/dist-lib/types/workspace/edit/CanvasGuides.d.ts +19 -0
- package/dist-lib/types/workspace/edit/ComponentPanel.d.ts +11 -0
- package/dist-lib/types/workspace/edit/DataPanel.d.ts +16 -0
- package/dist-lib/types/workspace/edit/DesignWorkspace.d.ts +10 -0
- package/dist-lib/types/workspace/edit/LayerTree.d.ts +14 -0
- package/dist-lib/types/workspace/edit/LayoutPanel.d.ts +13 -0
- package/dist-lib/types/workspace/edit/PrototypePanel.d.ts +12 -0
- package/dist-lib/types/workspace/edit/ScopeTransferDialog.d.ts +40 -0
- package/dist-lib/types/workspace/edit/SelectionHandles.d.ts +52 -0
- package/dist-lib/types/workspace/edit/StylesPanel.d.ts +8 -0
- package/dist-lib/types/workspace/edit/TextEditor.d.ts +50 -0
- package/dist-lib/types/workspace/edit/VectorEditor.d.ts +89 -0
- package/dist-lib/types/workspace/edit/VectorToolbar.d.ts +5 -0
- package/dist-lib/types/workspace/edit/canvasGuideModel.d.ts +102 -0
- package/dist-lib/types/workspace/edit/clipboard.d.ts +35 -0
- package/dist-lib/types/workspace/edit/duplicateMetadata.d.ts +2 -0
- package/dist-lib/types/workspace/edit/geometryHandles.d.ts +224 -0
- package/dist-lib/types/workspace/edit/layerArrangement.d.ts +39 -0
- package/dist-lib/types/workspace/edit/layerMoves.d.ts +44 -0
- package/dist-lib/types/workspace/edit/projection.d.ts +12 -0
- package/dist-lib/types/workspace/edit/scopeTransfer.d.ts +96 -0
- package/dist-lib/types/workspace/edit/textStyles.d.ts +75 -0
- package/dist-lib/types/workspace/edit/vectorTools.d.ts +136 -0
- package/dist-lib/types/workspace/legacyModeAdapter.d.ts +13 -0
- package/dist-lib/types/workspace/source/ResponsiveLayoutPanel.d.ts +20 -0
- package/dist-lib/types/workspace/source/SourceReview.d.ts +11 -0
- package/dist-lib/types/workspace/source/appearanceSource.d.ts +19 -0
- package/dist-lib/types/workspace/source/compiler.d.ts +5 -0
- package/dist-lib/types/workspace/source/contracts.d.ts +156 -0
- package/dist-lib/types/workspace/source/controller.d.ts +50 -0
- package/dist-lib/types/workspace/source/documentRevision.d.ts +2 -0
- package/dist-lib/types/workspace/source/draftPreviewClient.d.ts +13 -0
- package/dist-lib/types/workspace/source/draftRecipe.d.ts +30 -0
- package/dist-lib/types/workspace/source/flowContracts.d.ts +72 -0
- package/dist-lib/types/workspace/source/prototypeSource.d.ts +4 -0
- package/dist-lib/types/workspace/source/responsive.d.ts +13 -0
- package/dist-lib/types/workspace/source/responsiveContracts.d.ts +78 -0
- package/dist-lib/types/workspace/source/structure.d.ts +21 -0
- package/dist-lib/types/workspace/source/textSource.d.ts +28 -0
- package/dist-lib/types/workspace/tokens/TokenLibraryContext.d.ts +11 -0
- package/dist-lib/types/workspace/tokens/TokenLibraryWorkspace.d.ts +14 -0
- package/dist-lib/types/workspace/tokens/contracts.d.ts +74 -0
- package/dist-lib/types/workspace/tokens/controller.d.ts +44 -0
- package/dist-lib/types/workspace/view/PrototypePlayer.d.ts +17 -0
- package/dist-lib/types/workspace/view/StoryboardWorkspace.d.ts +3 -0
- package/dist-lib/types/workspace/view/prototypePlayback.d.ts +46 -0
- package/draft-preview.d.ts +54 -0
- package/inspect.d.ts +2 -0
- package/node/design-session.mjs +3 -0
- package/node/inspect-plugin.mjs +3 -1
- package/node/inspect-writeback.mjs +18 -2
- package/node/preview-artifact-store.mjs +10 -7
- package/node/source-archive.mjs +88 -0
- package/node/source-bindings.mjs +65 -0
- package/node/source-file-lock.mjs +15 -0
- package/node/source-file-plan.mjs +162 -0
- package/node/source-file-proofs.mjs +44 -0
- package/node/source-responsive-codec.d.mts +17 -0
- package/node/source-responsive-codec.mjs +133 -0
- package/node/source-responsive.mjs +189 -0
- package/node/source-structure-reconcile.mjs +186 -0
- package/node/source-structure-wrapper-codec.d.mts +20 -0
- package/node/source-structure-wrapper-codec.mjs +205 -0
- package/node/source-structure.mjs +404 -0
- package/node/token-source-references.mjs +136 -0
- package/node/workspace-draft-preview-plugin.mjs +70 -0
- package/node/workspace-draft-preview.mjs +231 -0
- package/node/workspace-source-identity.d.mts +1 -0
- package/node/workspace-source-identity.mjs +21 -0
- package/node/workspace-source-plan.mjs +195 -0
- package/package.json +52 -6
- package/source-files.d.ts +35 -0
- package/source-responsive.d.ts +10 -0
- package/source-structure.d.ts +155 -0
- package/workspace-source-plan.d.ts +44 -0
- package/docs/coverage-contracts.md +0 -444
- package/docs/screen-state-contract.md +0 -252
|
@@ -1,252 +0,0 @@
|
|
|
1
|
-
# Screen state contract
|
|
2
|
-
|
|
3
|
-
Pygmalion uses six review placements. A host must choose the placement from
|
|
4
|
-
how the variation is reproduced, not from how different its pixels look.
|
|
5
|
-
|
|
6
|
-
| Placement | Use when | Pygmalion declaration |
|
|
7
|
-
| --- | --- | --- |
|
|
8
|
-
| Frame | The variation is an independent task, journey checkpoint, structural composition, overlay context, or supported viewport that reviewers must navigate to directly. | `DesignScreenCase` |
|
|
9
|
-
| Interaction state | The same booted screen has a deterministic, reversible visual endpoint, reached either directly or through a local gesture. | `ScreenStateAxisDef` with `kind: 'interaction'` and `desiredState` or `steps` |
|
|
10
|
-
| Condition state | The same screen needs external data, network, storage, permission, media, or timing conditions before it boots. | `ScreenStateAxisDef` with `kind: 'condition'` |
|
|
11
|
-
| Editable parameter | The variation only samples text length, row count, content, or another freely editable value and has no distinct product endpoint. | Edit mode, component props, list controls, viewport controls, or QA data |
|
|
12
|
-
| Motion preview | The same screen continuously changes through CSS or Web Animations without becoming a new product state. | Nothing to declare: a live frame animates on its own; a capture holds the settled baseline |
|
|
13
|
-
| Behavior | The action has no stable visual endpoint to preserve. | `DesignBehaviorScenario` or an automated interaction test |
|
|
14
|
-
|
|
15
|
-
The practical test is: after reproducing the variation, is there a stable state
|
|
16
|
-
that another reviewer should be able to select again? If yes, use a frame or a
|
|
17
|
-
screen-state axis. If the answer is only “this value is longer” or “the request
|
|
18
|
-
was sent,” keep it in editing or QA instead.
|
|
19
|
-
|
|
20
|
-
## Frame versus same-frame state
|
|
21
|
-
|
|
22
|
-
Preserve a separate frame when at least one of these is true:
|
|
23
|
-
|
|
24
|
-
- it is a named step in a user journey;
|
|
25
|
-
- it changes the screen's primary task or structural composition;
|
|
26
|
-
- it provides an independent review anchor that must remain visible beside
|
|
27
|
-
another screen;
|
|
28
|
-
- it is a supported viewport whose responsive composition must be compared.
|
|
29
|
-
|
|
30
|
-
Use a same-frame axis when all of these are true:
|
|
31
|
-
|
|
32
|
-
- the route, task, and main structure stay the same;
|
|
33
|
-
- the variation is deterministic and can be recreated from the captured base;
|
|
34
|
-
- choosing it does not depend on an undocumented sequence;
|
|
35
|
-
- the final visual state remains visible long enough to capture.
|
|
36
|
-
|
|
37
|
-
Pseudo states such as hover, keyboard focus, and pointer active are always
|
|
38
|
-
interaction states. They must not become duplicate frames.
|
|
39
|
-
|
|
40
|
-
## Frame size
|
|
41
|
-
|
|
42
|
-
The W and H controls in the frame inspector change the frame viewport, not the
|
|
43
|
-
canvas camera. A committed size is part of the frame fingerprint and its exact
|
|
44
|
-
capture recipe. The request carries the route, width, height, conditions,
|
|
45
|
-
desired state, and interactions that produced that fingerprint. A returned
|
|
46
|
-
artifact is seeded under that requested recipe instead of the authored catalog
|
|
47
|
-
key.
|
|
48
|
-
|
|
49
|
-
This distinction is observable: resizing a frame may change responsive layout,
|
|
50
|
-
while changing canvas zoom only changes how large the same frame appears in the
|
|
51
|
-
editor. Hosts that implement an on-demand capture adapter must apply the
|
|
52
|
-
requested `route`, `width`, and `height` overrides before launching the capture.
|
|
53
|
-
|
|
54
|
-
## Automatic pseudo-state coverage
|
|
55
|
-
|
|
56
|
-
Pygmalion discovers pseudo-state surfaces while it serializes a screen. Every
|
|
57
|
-
rendered target matched by `:hover`, `:focus`, `:focus-visible`,
|
|
58
|
-
`:focus-within`, or `:active` is stamped into the inert DOM preview. React
|
|
59
|
-
hover and focus handlers are discovered from the rendered element props; the
|
|
60
|
-
inspect transform also marks native JSX event surfaces. The right panel's
|
|
61
|
-
variant matrix shows the chosen target as an **Elements** row with Default,
|
|
62
|
-
Hover, Focus, and Pressed options as applicable; a filterable picker chooses
|
|
63
|
-
the target, and picking an element with Inspect on chooses it from the canvas.
|
|
64
|
-
|
|
65
|
-
Discovery does not apply a semantic or size threshold. A plain button whose
|
|
66
|
-
only hover effect is a color, border, shadow, or opacity change belongs in the
|
|
67
|
-
panel just as much as a title that reveals an edit affordance. Transparent hit
|
|
68
|
-
areas are included when they occupy layout space. This makes pseudo-state
|
|
69
|
-
coverage a property of the captured UI instead of a list each host must keep
|
|
70
|
-
in sync by hand.
|
|
71
|
-
|
|
72
|
-
Hosts still declare an interaction axis when the endpoint needs several steps,
|
|
73
|
-
a product-specific label, or behavior beyond a pseudo gesture. If a declared
|
|
74
|
-
axis targets the same element and pseudo action, Pygmalion suppresses that
|
|
75
|
-
automatic duplicate. Click-driven toggles and other application states remain
|
|
76
|
-
declared axes unless they already have their own review frame.
|
|
77
|
-
|
|
78
|
-
In view-only mode, `requires.testId` is matched against the frozen preview's
|
|
79
|
-
lightweight **reachable** test-id index as well as an imported layer tree. A
|
|
80
|
-
test id under `display: none`, hidden visibility, zero opacity, or an inert
|
|
81
|
-
ancestor does not qualify merely because React kept that branch mounted. This
|
|
82
|
-
keeps right-panel state controls available without turning selection into a
|
|
83
|
-
layer import or live boot, while hiding axes that the captured frame cannot
|
|
84
|
-
actually reach. Legacy snapshots without a capture-time index are measured
|
|
85
|
-
after their inert DOM mounts.
|
|
86
|
-
|
|
87
|
-
## Automatic motion coverage
|
|
88
|
-
|
|
89
|
-
Pygmalion discovers visible CSS animation owners, animated pseudo elements,
|
|
90
|
-
matching animation rules, and Web Animations API targets while it serializes a
|
|
91
|
-
screen, and stamps every target into the inert preview. The stamps are what
|
|
92
|
-
the capture runtime settles: finite animations at their terminal state,
|
|
93
|
-
repeating animations at the start of their cycle. This keeps entrance motion
|
|
94
|
-
from hiding the base UI while screenshots and visual comparisons remain
|
|
95
|
-
repeatable, and a mounted frozen preview holds the same baseline.
|
|
96
|
-
|
|
97
|
-
Motion discovery has no semantic or size threshold. Small progress dots,
|
|
98
|
-
ordinary status indicators, shimmer bars, and full-surface animation are
|
|
99
|
-
settled the same way. There are no playback controls in the editor: a live
|
|
100
|
-
frame runs the real application, so its motion plays as it does in the
|
|
101
|
-
product, and a capture is by definition still.
|
|
102
|
-
|
|
103
|
-
An animation does not need duplicate frames merely to show several points in
|
|
104
|
-
its cycle. Preserve a separate frame only when the motion ends in an independent
|
|
105
|
-
task, journey checkpoint, structural composition, or other state that already
|
|
106
|
-
meets the frame criteria above.
|
|
107
|
-
|
|
108
|
-
## Required axis classification
|
|
109
|
-
|
|
110
|
-
`kind` is mandatory and is enforced when the editor installs the axes.
|
|
111
|
-
`validateScreenStateAxes` is also exported for host validation gates.
|
|
112
|
-
|
|
113
|
-
```ts
|
|
114
|
-
import type { ScreenStateAxisDef } from '@pygmalionjs/pygmalion';
|
|
115
|
-
|
|
116
|
-
export const screenStateAxes: readonly ScreenStateAxisDef[] = [
|
|
117
|
-
{
|
|
118
|
-
id: 'editable-heading',
|
|
119
|
-
label: 'Heading',
|
|
120
|
-
kind: 'interaction',
|
|
121
|
-
requires: { testId: 'editable-heading' },
|
|
122
|
-
options: [
|
|
123
|
-
{ id: 'rest', label: 'Rest' },
|
|
124
|
-
{
|
|
125
|
-
id: 'hover',
|
|
126
|
-
label: 'Hover',
|
|
127
|
-
steps: [
|
|
128
|
-
{
|
|
129
|
-
action: 'hover',
|
|
130
|
-
label: 'Hover heading',
|
|
131
|
-
selector: '[data-testid="editable-heading"]',
|
|
132
|
-
},
|
|
133
|
-
],
|
|
134
|
-
},
|
|
135
|
-
{
|
|
136
|
-
id: 'editing',
|
|
137
|
-
label: 'Editing',
|
|
138
|
-
steps: [
|
|
139
|
-
{
|
|
140
|
-
action: 'click',
|
|
141
|
-
label: 'Open heading editor',
|
|
142
|
-
selector: '[data-testid="editable-heading"]',
|
|
143
|
-
},
|
|
144
|
-
{
|
|
145
|
-
action: 'wait',
|
|
146
|
-
label: 'Heading input is visible',
|
|
147
|
-
selector: '[data-testid="heading-input"]',
|
|
148
|
-
},
|
|
149
|
-
],
|
|
150
|
-
},
|
|
151
|
-
{
|
|
152
|
-
id: 'collapsed',
|
|
153
|
-
label: 'Collapsed',
|
|
154
|
-
desiredState: 'collapsed',
|
|
155
|
-
},
|
|
156
|
-
],
|
|
157
|
-
},
|
|
158
|
-
{
|
|
159
|
-
id: 'results',
|
|
160
|
-
label: 'Results',
|
|
161
|
-
kind: 'condition',
|
|
162
|
-
options: [
|
|
163
|
-
{ id: 'loaded', label: 'Loaded' },
|
|
164
|
-
{
|
|
165
|
-
id: 'failed',
|
|
166
|
-
label: 'Failed',
|
|
167
|
-
environment: {
|
|
168
|
-
network: {
|
|
169
|
-
conditions: [
|
|
170
|
-
{ match: '/api/results', outcome: { kind: 'fail', status: 500 } },
|
|
171
|
-
],
|
|
172
|
-
},
|
|
173
|
-
},
|
|
174
|
-
},
|
|
175
|
-
],
|
|
176
|
-
},
|
|
177
|
-
];
|
|
178
|
-
|
|
179
|
-
<PygmalionEditor screenStateAxes={screenStateAxes} />;
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
An interaction option cannot declare `environment`. Every non-base condition
|
|
183
|
-
option must declare one. A direct `desiredState` value cannot be combined with
|
|
184
|
-
steps or an environment on the same option. An interaction option ending in
|
|
185
|
-
`fill` is rejected unless a later targeted `wait` proves that the input reached
|
|
186
|
-
a distinct visual result. This keeps empty strings and maximum-length samples
|
|
187
|
-
out of the state panel while still allowing a search input to reproduce a real
|
|
188
|
-
empty-result state.
|
|
189
|
-
|
|
190
|
-
## Direct desired state
|
|
191
|
-
|
|
192
|
-
Use direct desired state for a locally controlled endpoint whose final visual
|
|
193
|
-
state matters more than the gestures used to reach it. Pygmalion builds a
|
|
194
|
-
complete map from selected axes, such as `{ sidebar: 'collapsed' }`, and calls
|
|
195
|
-
the host's `executeDesiredState` adapter after mount and before any remaining
|
|
196
|
-
interaction steps. The map participates in capture and preview identity.
|
|
197
|
-
|
|
198
|
-
The adapter must replace its whole preview state, not merge it. Pygmalion calls
|
|
199
|
-
it with `{}` as well, so a warm iframe reused for another frame cannot retain a
|
|
200
|
-
previous override. A typical React host exposes the map through an external
|
|
201
|
-
store and lets each component read only its own axis. The adapter is preview
|
|
202
|
-
infrastructure: it must not dispatch the application's production store or
|
|
203
|
-
write persistent product state. When a reviewer uses the real control, the
|
|
204
|
-
component should release its preview override and continue from the currently
|
|
205
|
-
displayed value.
|
|
206
|
-
|
|
207
|
-
The right-panel selection starts delivery in the same input task. Once one
|
|
208
|
-
option has a live document, sibling direct-state options share that document:
|
|
209
|
-
Pygmalion skips boot, route entry, gesture replay, assertions, and geometry
|
|
210
|
-
settling, then sends the replacement map to the host adapter. The React commit
|
|
211
|
-
is the presentation boundary; snapshot serialization may continue afterward
|
|
212
|
-
without blocking the visible state. A live direct-state document is pinned
|
|
213
|
-
against normal warm-pool eviction and cannot be claimed through gesture-prefix
|
|
214
|
-
matching, because those signatures do not describe host-owned state.
|
|
215
|
-
Sibling delivery calls the live adapter directly rather than joining the replay
|
|
216
|
-
runner's FIFO. Frames that expose a direct-state axis also reserve their
|
|
217
|
-
activation-warmed document from unrelated gesture prefetch and align it
|
|
218
|
-
invisibly behind the frozen frame. The first selection can therefore reveal the
|
|
219
|
-
already-positioned React document after its adapter commit; speculative work
|
|
220
|
-
cannot reintroduce a queue between the panel click and that commit.
|
|
221
|
-
|
|
222
|
-
Keep gesture steps when the transition itself is under review, when effects
|
|
223
|
-
outside local render state establish the endpoint, or when the host has no safe
|
|
224
|
-
preview-only adapter for that state.
|
|
225
|
-
|
|
226
|
-
## Scroll positions
|
|
227
|
-
|
|
228
|
-
A stable scroll endpoint is an interaction state. Use a `scroll` recipe step
|
|
229
|
-
with absolute `scrollX` and/or `scrollY` coordinates. With no selector the step
|
|
230
|
-
restores the document viewport; a selector targets a specific overflow
|
|
231
|
-
container. An omitted axis keeps its current position.
|
|
232
|
-
|
|
233
|
-
Absolute coordinates make the endpoint repeatable in both the in-editor replay
|
|
234
|
-
and the capture worker. A free wheel gesture remains transient until the host
|
|
235
|
-
preserves its endpoint as a recipe. The frame inspector enumerates the document
|
|
236
|
-
viewport and independently scrollable nested surfaces. Preserving one records
|
|
237
|
-
both its stable selector and coordinates; the target picker keeps nested list
|
|
238
|
-
or panel scroll distinct from the document viewport.
|
|
239
|
-
|
|
240
|
-
## Held pseudo states
|
|
241
|
-
|
|
242
|
-
Recipes support `hover`, `focus-visible`, and `active` in addition to `focus`.
|
|
243
|
-
These actions remain held through capture. The browser runner dispatches the
|
|
244
|
-
corresponding events, the Playwright worker performs the real pointer or focus
|
|
245
|
-
gesture, and frozen DOM previews materialize `:hover`, `:focus`,
|
|
246
|
-
`:focus-visible`, `:focus-within`, and `:active` selectors as scoped data
|
|
247
|
-
attributes. A DOM preview therefore preserves the same pseudo-state styling as
|
|
248
|
-
the captured application rather than relying on the editor's current pointer.
|
|
249
|
-
|
|
250
|
-
A held pseudo action must be terminal; only `wait` steps may follow it. This
|
|
251
|
-
prevents a declaration from claiming a transient hover that a later click has
|
|
252
|
-
already replaced.
|