@agent-native/core 0.114.2 → 0.114.4
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/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +30 -0
- package/corpus/core/package.json +2 -1
- package/corpus/core/src/a2a/artifact-response.ts +42 -16
- package/corpus/core/src/a2a/client.ts +4 -0
- package/corpus/core/src/a2a/handlers.ts +133 -2
- package/corpus/core/src/a2a/index.ts +1 -0
- package/corpus/core/src/a2a/types.ts +14 -0
- package/corpus/core/src/db/request-telemetry.ts +32 -8
- package/corpus/core/src/integrations/index.ts +6 -0
- package/corpus/core/src/integrations/pending-tasks-store.ts +89 -0
- package/corpus/core/src/integrations/webhook-handler.ts +17 -7
- package/corpus/core/src/scripts/call-agent.ts +54 -10
- package/corpus/core/src/server/agent-discovery.ts +22 -0
- package/corpus/core/src/settings/store.ts +15 -6
- package/corpus/core/src/shared/optional-node-builtins.ts +66 -0
- package/corpus/core/src/templates/default/.agents/skills/feature-flags/SKILL.md +1 -1
- package/corpus/core/src/templates/headless/.agents/skills/feature-flags/SKILL.md +1 -1
- package/corpus/core/src/templates/workspace-core/.agents/skills/feature-flags/SKILL.md +1 -1
- package/corpus/core/src/vite/client.ts +5 -0
- package/corpus/templates/analytics/.agents/skills/feature-flags/SKILL.md +1 -1
- package/corpus/templates/assets/.agents/skills/feature-flags/SKILL.md +1 -1
- package/corpus/templates/assets/app/routes/brand-kits.$id.tsx +2 -2
- package/corpus/templates/brain/.agents/skills/feature-flags/SKILL.md +1 -1
- package/corpus/templates/calendar/.agents/skills/feature-flags/SKILL.md +1 -1
- package/corpus/templates/chat/.agents/skills/feature-flags/SKILL.md +1 -1
- package/corpus/templates/clips/.agents/skills/feature-flags/SKILL.md +1 -1
- package/corpus/templates/clips/shared/feature-flags.ts +1 -1
- package/corpus/templates/content/.agents/skills/content/SKILL.md +19 -5
- package/corpus/templates/content/.agents/skills/feature-flags/SKILL.md +1 -1
- package/corpus/templates/content/changelog/2026-07-17-slack-created-database-entries-now-record-slack-as-their-sub.md +6 -0
- package/corpus/templates/design/.agents/skills/feature-flags/SKILL.md +1 -1
- package/corpus/templates/design/actions/update-file.ts +10 -1
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +30 -1
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +14 -1
- package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +547 -50
- package/corpus/templates/design/app/components/design/dnd-debug.ts +27 -0
- package/corpus/templates/design/app/components/design/multi-screen/draft-primitives.ts +19 -2
- package/corpus/templates/design/app/i18n-data.ts +19 -0
- package/corpus/templates/design/app/lib/design-save-outbox.ts +46 -2
- package/corpus/templates/design/app/pages/design-editor/canvas-primitive-insert.ts +4 -9
- package/corpus/templates/design/app/pages/design-editor/history.ts +14 -1
- package/corpus/templates/design/changelog/2026-07-17-drawn-shapes-stay-free-positioned-when-dragged.md +6 -0
- package/corpus/templates/design/changelog/2026-07-17-shapes-show-a-live-outline-while-you-draw.md +6 -0
- package/corpus/templates/design/shared/drag-reflow.ts +375 -0
- package/corpus/templates/design/shared/full-app.ts +1 -1
- package/corpus/templates/dispatch/.agents/skills/feature-flags/SKILL.md +1 -1
- package/corpus/templates/forms/.agents/skills/feature-flags/SKILL.md +1 -1
- package/corpus/templates/macros/.agents/skills/feature-flags/SKILL.md +1 -1
- package/corpus/templates/mail/.agents/skills/feature-flags/SKILL.md +1 -1
- package/corpus/templates/plan/.agents/skills/feature-flags/SKILL.md +1 -1
- package/corpus/templates/slides/.agents/skills/feature-flags/SKILL.md +1 -1
- package/corpus/templates/tasks/.agents/skills/feature-flags/SKILL.md +1 -1
- package/dist/a2a/artifact-response.d.ts +5 -0
- package/dist/a2a/artifact-response.d.ts.map +1 -1
- package/dist/a2a/artifact-response.js +20 -5
- package/dist/a2a/artifact-response.js.map +1 -1
- package/dist/a2a/client.d.ts +3 -1
- package/dist/a2a/client.d.ts.map +1 -1
- package/dist/a2a/client.js +2 -0
- package/dist/a2a/client.js.map +1 -1
- package/dist/a2a/handlers.d.ts.map +1 -1
- package/dist/a2a/handlers.js +100 -8
- package/dist/a2a/handlers.js.map +1 -1
- package/dist/a2a/index.d.ts +1 -1
- package/dist/a2a/index.d.ts.map +1 -1
- package/dist/a2a/index.js.map +1 -1
- package/dist/a2a/types.d.ts +12 -0
- package/dist/a2a/types.d.ts.map +1 -1
- package/dist/a2a/types.js.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/db/request-telemetry.d.ts.map +1 -1
- package/dist/db/request-telemetry.js +24 -6
- package/dist/db/request-telemetry.js.map +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +1 -1
- package/dist/integrations/index.d.ts +1 -0
- package/dist/integrations/index.d.ts.map +1 -1
- package/dist/integrations/index.js +1 -0
- package/dist/integrations/index.js.map +1 -1
- package/dist/integrations/pending-tasks-store.d.ts +9 -0
- package/dist/integrations/pending-tasks-store.d.ts.map +1 -1
- package/dist/integrations/pending-tasks-store.js +60 -0
- package/dist/integrations/pending-tasks-store.js.map +1 -1
- package/dist/integrations/webhook-handler.d.ts.map +1 -1
- package/dist/integrations/webhook-handler.js +13 -7
- package/dist/integrations/webhook-handler.js.map +1 -1
- package/dist/notifications/routes.d.ts +2 -2
- package/dist/observability/routes.d.ts +3 -3
- package/dist/scripts/call-agent.d.ts.map +1 -1
- package/dist/scripts/call-agent.js +39 -10
- package/dist/scripts/call-agent.js.map +1 -1
- package/dist/secrets/routes.d.ts +9 -9
- package/dist/server/agent-discovery.d.ts +2 -0
- package/dist/server/agent-discovery.d.ts.map +1 -1
- package/dist/server/agent-discovery.js +19 -0
- package/dist/server/agent-discovery.js.map +1 -1
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/settings/store.d.ts +1 -1
- package/dist/settings/store.d.ts.map +1 -1
- package/dist/settings/store.js +14 -6
- package/dist/settings/store.js.map +1 -1
- package/dist/shared/optional-node-builtins.d.ts +23 -0
- package/dist/shared/optional-node-builtins.d.ts.map +1 -0
- package/dist/shared/optional-node-builtins.js +35 -0
- package/dist/shared/optional-node-builtins.js.map +1 -0
- package/dist/templates/chat/.agents/skills/feature-flags/SKILL.md +1 -1
- package/dist/templates/default/.agents/skills/feature-flags/SKILL.md +1 -1
- package/dist/templates/headless/.agents/skills/feature-flags/SKILL.md +1 -1
- package/dist/templates/workspace-core/.agents/skills/feature-flags/SKILL.md +1 -1
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +2 -0
- package/dist/vite/client.js.map +1 -1
- package/package.json +2 -1
- package/src/a2a/artifact-response.ts +42 -16
- package/src/a2a/client.ts +4 -0
- package/src/a2a/handlers.ts +133 -2
- package/src/a2a/index.ts +1 -0
- package/src/a2a/types.ts +14 -0
- package/src/db/request-telemetry.ts +32 -8
- package/src/integrations/index.ts +6 -0
- package/src/integrations/pending-tasks-store.ts +89 -0
- package/src/integrations/webhook-handler.ts +17 -7
- package/src/scripts/call-agent.ts +54 -10
- package/src/server/agent-discovery.ts +22 -0
- package/src/settings/store.ts +15 -6
- package/src/shared/optional-node-builtins.ts +66 -0
- package/src/templates/chat/.agents/skills/feature-flags/SKILL.md +1 -1
- package/src/templates/default/.agents/skills/feature-flags/SKILL.md +1 -1
- package/src/templates/headless/.agents/skills/feature-flags/SKILL.md +1 -1
- package/src/templates/workspace-core/.agents/skills/feature-flags/SKILL.md +1 -1
- package/src/vite/client.ts +5 -0
|
@@ -34,6 +34,7 @@ declare var __DESIGN_CANVAS_BOARD_SURFACE__: boolean;
|
|
|
34
34
|
declare var __DESIGN_CANVAS_CONTENT_OFFSET_X__: number;
|
|
35
35
|
declare var __DESIGN_CANVAS_CONTENT_OFFSET_Y__: number;
|
|
36
36
|
declare var __RUNTIME_LAYER_SNAPSHOT_ENABLED__: boolean;
|
|
37
|
+
declare var __LIVE_REFLOW_ENABLED__: boolean;
|
|
37
38
|
|
|
38
39
|
(function () {
|
|
39
40
|
// Idempotency guard: replace-document-content / srcdoc rebuilds can end up
|
|
@@ -62,8 +63,58 @@ declare var __RUNTIME_LAYER_SNAPSHOT_ENABLED__: boolean;
|
|
|
62
63
|
var designCanvasContentOffsetY =
|
|
63
64
|
Number(__DESIGN_CANVAS_CONTENT_OFFSET_Y__) || 0;
|
|
64
65
|
var runtimeLayerSnapshotEnabled = !!__RUNTIME_LAYER_SNAPSHOT_ENABLED__;
|
|
66
|
+
// Figma-parity live-reflow drag (Phase 0 + 1: hysteresis-stabilized target
|
|
67
|
+
// resolution, size guard, transform lift/follow, live sibling reflow,
|
|
68
|
+
// exact absolute commit). Gated so it can be flipped off without a revert.
|
|
69
|
+
// The placeholder is referenced EXACTLY ONCE so the host's single
|
|
70
|
+
// String.replace fully substitutes it; the try/catch keeps it crash-safe if
|
|
71
|
+
// an injection site forgets to replace it (an un-replaced identifier read
|
|
72
|
+
// throws ReferenceError, which we treat as "off") — the behavior is additive
|
|
73
|
+
// and rolling out incrementally.
|
|
74
|
+
var liveReflowEnabled = (function () {
|
|
75
|
+
try {
|
|
76
|
+
return !!__LIVE_REFLOW_ENABLED__;
|
|
77
|
+
} catch (_e) {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
})();
|
|
65
81
|
var scaleToolEnabled = false;
|
|
66
82
|
|
|
83
|
+
// ── Drag-and-drop debug logging ────────────────────────────────────
|
|
84
|
+
// Every DnD seam logs under the "[dnd]" prefix with a phase tag, so the
|
|
85
|
+
// console reads as a narrated timeline of ONE gesture:
|
|
86
|
+
// start:* → target → lift/reflow → commit:* → post:* → ack:*
|
|
87
|
+
// The iframe posts these to its own console; the host mirrors its side
|
|
88
|
+
// under the same prefix. Defaults OFF; opt in at runtime from the iframe
|
|
89
|
+
// console with `window.__DND_DEBUG = true` — no rebuild needed.
|
|
90
|
+
function dndLog(phase: string, data?: unknown): void {
|
|
91
|
+
if (!(window as any).__DND_DEBUG) return;
|
|
92
|
+
try {
|
|
93
|
+
var tag = "%c[dnd:" + phase + "]";
|
|
94
|
+
var style = "color:#8b5cf6;font-weight:bold";
|
|
95
|
+
if (data === undefined) console.log(tag, style);
|
|
96
|
+
else console.log(tag, style, data);
|
|
97
|
+
} catch (_e) {}
|
|
98
|
+
}
|
|
99
|
+
// Describe a resolved drop target compactly for the log timeline. Reads
|
|
100
|
+
// getSelector/dropContainerForTarget (declared later, hoisted) at call time.
|
|
101
|
+
function dndTarget(t): unknown {
|
|
102
|
+
if (!t) return null;
|
|
103
|
+
try {
|
|
104
|
+
var container = dropContainerForTarget(t);
|
|
105
|
+
return {
|
|
106
|
+
anchor: t.anchor ? getSelector(t.anchor) : null,
|
|
107
|
+
placement: t.placement,
|
|
108
|
+
dropMode: t.dropMode,
|
|
109
|
+
axis: t.axis,
|
|
110
|
+
container: container ? getSelector(container) : null,
|
|
111
|
+
needsConversion: !!t.needsAutoLayoutConversion,
|
|
112
|
+
};
|
|
113
|
+
} catch (_e) {
|
|
114
|
+
return { placement: t.placement, dropMode: t.dropMode };
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
67
118
|
// Interaction-state forced preview (phase 2 — see shared/interaction-states.ts's
|
|
68
119
|
// "Forced-preview mechanism" doc comment). Keep the actual element rather
|
|
69
120
|
// than only its node id: localhost React layers can resolve through runtime
|
|
@@ -1961,18 +2012,30 @@ declare var __RUNTIME_LAYER_SNAPSHOT_ENABLED__: boolean;
|
|
|
1961
2012
|
|
|
1962
2013
|
var transformBadge = document.createElement("div");
|
|
1963
2014
|
transformBadge.setAttribute("data-agent-native-transform-badge", "");
|
|
2015
|
+
// Classify as edit-overlay so the content-stamp pass (isEditorChrome) does
|
|
2016
|
+
// not strip it and replaceRuntimeDocument preserves it — otherwise the badge
|
|
2017
|
+
// is detached from the DOM and its styling targets a dead node (invisible).
|
|
2018
|
+
transformBadge.setAttribute(
|
|
2019
|
+
"data-agent-native-edit-overlay",
|
|
2020
|
+
"transform-badge",
|
|
2021
|
+
);
|
|
1964
2022
|
transformBadge.style.cssText =
|
|
1965
2023
|
"position:fixed;z-index:100000;display:none;pointer-events:none;border:1px solid rgba(255,255,255,0.16);border-radius:4px;background:rgba(24,24,27,0.96);color:rgba(255,255,255,0.96);font:11px/1.4 ui-monospace,SFMono-Regular,Menlo,monospace;padding:3px 5px;box-shadow:0 8px 20px rgba(0,0,0,0.28);";
|
|
1966
2024
|
document.body.appendChild(transformBadge);
|
|
1967
2025
|
|
|
1968
2026
|
var spacingBadge = document.createElement("div");
|
|
1969
2027
|
spacingBadge.setAttribute("data-agent-native-spacing-badge", "");
|
|
2028
|
+
spacingBadge.setAttribute("data-agent-native-edit-overlay", "spacing-badge");
|
|
1970
2029
|
spacingBadge.style.cssText =
|
|
1971
2030
|
"position:fixed;z-index:100000;display:none;pointer-events:none;border-radius:3px;color:white;font:10px/1.2 ui-monospace,SFMono-Regular,Menlo,monospace;font-weight:700;padding:2px 4px;box-shadow:0 4px 14px rgba(0,0,0,0.18);";
|
|
1972
2031
|
document.body.appendChild(spacingBadge);
|
|
1973
2032
|
|
|
1974
2033
|
var insertionGuide = document.createElement("div");
|
|
1975
2034
|
insertionGuide.setAttribute("data-agent-native-insertion-guide", "");
|
|
2035
|
+
insertionGuide.setAttribute(
|
|
2036
|
+
"data-agent-native-edit-overlay",
|
|
2037
|
+
"insertion-guide",
|
|
2038
|
+
);
|
|
1976
2039
|
insertionGuide.style.cssText =
|
|
1977
2040
|
"position:fixed;z-index:100000;display:none;pointer-events:none;background:var(--design-editor-accent-color);border-radius:999px;box-shadow:0 0 0 1px var(--design-editor-accent-color);";
|
|
1978
2041
|
document.body.appendChild(insertionGuide);
|
|
@@ -6786,6 +6849,7 @@ declare var __RUNTIME_LAYER_SNAPSHOT_ENABLED__: boolean;
|
|
|
6786
6849
|
el?: Element | null,
|
|
6787
6850
|
ev?: { clientX?: number; clientY?: number } | null,
|
|
6788
6851
|
): void {
|
|
6852
|
+
dndLog("post:cross-screen", { phase: phase, el: getSelector(el ?? null) });
|
|
6789
6853
|
if (phase === "cancel") {
|
|
6790
6854
|
activeCrossScreenStyleSnapshot = undefined;
|
|
6791
6855
|
(window.parent as Window).postMessage(
|
|
@@ -6921,6 +6985,17 @@ declare var __RUNTIME_LAYER_SNAPSHOT_ENABLED__: boolean;
|
|
|
6921
6985
|
return true;
|
|
6922
6986
|
}
|
|
6923
6987
|
|
|
6988
|
+
// Figma R11: an element whose entire content is text / inline leaves is a
|
|
6989
|
+
// text node, not a frame — it must never swallow a flow-reordered sibling as
|
|
6990
|
+
// a child. Used to keep the flow-reorder resolver on before/after for text
|
|
6991
|
+
// cards (§1.1/§1.2 nest-into-text + silent flex-conversion bug). A truly
|
|
6992
|
+
// empty element (no text, no children) is NOT a text leaf — it stays a valid
|
|
6993
|
+
// empty frame you can drop into, and the absolute-drag nest path is
|
|
6994
|
+
// unaffected (it targets frames, not reordered flow siblings).
|
|
6995
|
+
function isTextBearingLeaf(el: Element): boolean {
|
|
6996
|
+
return hasOnlyLeafContent(el) && (el.textContent || "").trim().length > 0;
|
|
6997
|
+
}
|
|
6998
|
+
|
|
6924
6999
|
function isContainerDropTarget(el: Element | null): boolean {
|
|
6925
7000
|
if (!el || el === document.documentElement) return false;
|
|
6926
7001
|
if (isOverlayElement(el) || isLayerInteractionBlocked(el)) return false;
|
|
@@ -7113,7 +7188,7 @@ declare var __RUNTIME_LAYER_SNAPSHOT_ENABLED__: boolean;
|
|
|
7113
7188
|
!isOverlayElement(hit) &&
|
|
7114
7189
|
!isTemplateCloneElement(hit)
|
|
7115
7190
|
) {
|
|
7116
|
-
if (isContainerDropTarget(hit)) {
|
|
7191
|
+
if (isContainerDropTarget(hit) && !isTextBearingLeaf(hit)) {
|
|
7117
7192
|
var containerRect = hit.getBoundingClientRect();
|
|
7118
7193
|
var edgeAxis = hit.parentElement
|
|
7119
7194
|
? parentFlowAxis(hit.parentElement)
|
|
@@ -7294,8 +7369,9 @@ declare var __RUNTIME_LAYER_SNAPSHOT_ENABLED__: boolean;
|
|
|
7294
7369
|
};
|
|
7295
7370
|
}
|
|
7296
7371
|
|
|
7297
|
-
// Flow child dropped into a plain container:
|
|
7298
|
-
//
|
|
7372
|
+
// Flow child (a real flow-reorder gesture) dropped into a plain container:
|
|
7373
|
+
// convert it to auto layout before the structural move. This is the flow
|
|
7374
|
+
// path only; the absolute/free drag keeps shapes free (no conversion).
|
|
7299
7375
|
if (
|
|
7300
7376
|
target &&
|
|
7301
7377
|
target.dropMode === "flow-insert" &&
|
|
@@ -7471,11 +7547,21 @@ declare var __RUNTIME_LAYER_SNAPSHOT_ENABLED__: boolean;
|
|
|
7471
7547
|
isContainerDropTarget(cursor) &&
|
|
7472
7548
|
!(parent && parent !== document.body && isAutoLayoutElement(parent))
|
|
7473
7549
|
) {
|
|
7474
|
-
//
|
|
7475
|
-
//
|
|
7476
|
-
//
|
|
7477
|
-
|
|
7478
|
-
|
|
7550
|
+
// Free (absolute) element into a non-auto-layout container stays free:
|
|
7551
|
+
// nest as an absolute child at the drop point, never convert to flex.
|
|
7552
|
+
// Same-parent drop is a pure reposition (null → onUp writes left/top).
|
|
7553
|
+
if (!isAutoLayoutElement(cursor)) {
|
|
7554
|
+
if (cursor === el.parentElement) return null;
|
|
7555
|
+
return {
|
|
7556
|
+
anchor: cursor,
|
|
7557
|
+
placement: "inside",
|
|
7558
|
+
axis: "y",
|
|
7559
|
+
dropMode: "absolute-container",
|
|
7560
|
+
};
|
|
7561
|
+
}
|
|
7562
|
+
// B5-4: pointer over an auto-layout container's background (padding or a
|
|
7563
|
+
// gap). Prefer the nearest child slot over plain "inside" (append last);
|
|
7564
|
+
// fall back to "inside" for an empty container.
|
|
7479
7565
|
var betweenContainerChildren = nearestChildInsertionTarget(
|
|
7480
7566
|
cursor,
|
|
7481
7567
|
clientX,
|
|
@@ -7488,8 +7574,6 @@ declare var __RUNTIME_LAYER_SNAPSHOT_ENABLED__: boolean;
|
|
|
7488
7574
|
placement: betweenContainerChildren.placement,
|
|
7489
7575
|
axis: betweenContainerChildren.axis,
|
|
7490
7576
|
dropMode: "flow-insert",
|
|
7491
|
-
needsAutoLayoutConversion: !isAutoLayoutElement(cursor),
|
|
7492
|
-
conversionTarget: cursor,
|
|
7493
7577
|
};
|
|
7494
7578
|
}
|
|
7495
7579
|
return {
|
|
@@ -7497,11 +7581,21 @@ declare var __RUNTIME_LAYER_SNAPSHOT_ENABLED__: boolean;
|
|
|
7497
7581
|
placement: "inside",
|
|
7498
7582
|
axis: parentFlowAxis(cursor),
|
|
7499
7583
|
dropMode: "flow-insert",
|
|
7500
|
-
needsAutoLayoutConversion: !isAutoLayoutElement(cursor),
|
|
7501
|
-
conversionTarget: cursor,
|
|
7502
7584
|
};
|
|
7503
7585
|
}
|
|
7504
7586
|
if (parent && parent !== document.body && isContainerDropTarget(parent)) {
|
|
7587
|
+
// Free element over a sibling in a non-auto-layout parent stays free:
|
|
7588
|
+
// absolute child at the drop point (same-parent → null reposition).
|
|
7589
|
+
if (!isAutoLayoutElement(parent)) {
|
|
7590
|
+
if (parent === el.parentElement) return null;
|
|
7591
|
+
return {
|
|
7592
|
+
anchor: parent,
|
|
7593
|
+
placement: "inside",
|
|
7594
|
+
axis: "y",
|
|
7595
|
+
dropMode: "absolute-container",
|
|
7596
|
+
};
|
|
7597
|
+
}
|
|
7598
|
+
// parent is an established auto-layout list: reorder within its flow.
|
|
7505
7599
|
// Anchor-candidate gate: cursor is a plain sibling under `parent`
|
|
7506
7600
|
// being used as a before/after anchor — but if it's a template
|
|
7507
7601
|
// clone (no counterpart in source HTML), fall back to the nearest
|
|
@@ -7521,8 +7615,6 @@ declare var __RUNTIME_LAYER_SNAPSHOT_ENABLED__: boolean;
|
|
|
7521
7615
|
placement: cloneFallback.placement,
|
|
7522
7616
|
axis: cloneFallback.axis,
|
|
7523
7617
|
dropMode: "flow-insert",
|
|
7524
|
-
needsAutoLayoutConversion: !isAutoLayoutElement(parent),
|
|
7525
|
-
conversionTarget: parent,
|
|
7526
7618
|
};
|
|
7527
7619
|
}
|
|
7528
7620
|
return {
|
|
@@ -7530,8 +7622,6 @@ declare var __RUNTIME_LAYER_SNAPSHOT_ENABLED__: boolean;
|
|
|
7530
7622
|
placement: "inside",
|
|
7531
7623
|
axis: parentFlowAxis(parent),
|
|
7532
7624
|
dropMode: "flow-insert",
|
|
7533
|
-
needsAutoLayoutConversion: !isAutoLayoutElement(parent),
|
|
7534
|
-
conversionTarget: parent,
|
|
7535
7625
|
};
|
|
7536
7626
|
}
|
|
7537
7627
|
var parentAxis = parentFlowAxis(parent);
|
|
@@ -7546,8 +7636,6 @@ declare var __RUNTIME_LAYER_SNAPSHOT_ENABLED__: boolean;
|
|
|
7546
7636
|
placement: childPointer < childCenter ? "before" : "after",
|
|
7547
7637
|
axis: parentAxis,
|
|
7548
7638
|
dropMode: "flow-insert",
|
|
7549
|
-
needsAutoLayoutConversion: !isAutoLayoutElement(parent),
|
|
7550
|
-
conversionTarget: parent,
|
|
7551
7639
|
};
|
|
7552
7640
|
}
|
|
7553
7641
|
cursor = parent;
|
|
@@ -7986,6 +8074,12 @@ declare var __RUNTIME_LAYER_SNAPSHOT_ENABLED__: boolean;
|
|
|
7986
8074
|
|
|
7987
8075
|
function postVisualStructureChange(el, target, origin) {
|
|
7988
8076
|
if (!el || !target || !target.anchor) return;
|
|
8077
|
+
dndLog("post:structure-change", {
|
|
8078
|
+
el: getSelector(el),
|
|
8079
|
+
anchor: getSelector(target.anchor),
|
|
8080
|
+
placement: target.placement,
|
|
8081
|
+
dropMode: target.dropMode || "flow-insert",
|
|
8082
|
+
});
|
|
7989
8083
|
var requestId =
|
|
7990
8084
|
"move-" + Date.now() + "-" + Math.random().toString(16).slice(2);
|
|
7991
8085
|
pendingStructureMoves[requestId] = {
|
|
@@ -8411,6 +8505,7 @@ declare var __RUNTIME_LAYER_SNAPSHOT_ENABLED__: boolean;
|
|
|
8411
8505
|
};
|
|
8412
8506
|
});
|
|
8413
8507
|
var reorderGestureStartRect = reorderEl.getBoundingClientRect();
|
|
8508
|
+
var reorderLastTargetKey = null;
|
|
8414
8509
|
var keepCurrentFlowParent = bridgeSpaceKeyPressed;
|
|
8415
8510
|
var currentTarget = flowMoveTargetForPoint(
|
|
8416
8511
|
reorderEl,
|
|
@@ -8421,6 +8516,12 @@ declare var __RUNTIME_LAYER_SNAPSHOT_ENABLED__: boolean;
|
|
|
8421
8516
|
Boolean(e.ctrlKey),
|
|
8422
8517
|
);
|
|
8423
8518
|
showInsertionGuideFor(currentTarget);
|
|
8519
|
+
dndLog("start:reorder", {
|
|
8520
|
+
el: getSelector(reorderEl),
|
|
8521
|
+
isGroup: isGroupDrag,
|
|
8522
|
+
ctrl: Boolean(e.ctrlKey),
|
|
8523
|
+
target: dndTarget(currentTarget),
|
|
8524
|
+
});
|
|
8424
8525
|
// Cross-screen drag state: true when the pointer is outside this iframe's
|
|
8425
8526
|
// viewport bounds. The host frame renders the ghost + highlight and owns
|
|
8426
8527
|
// the drop when this is true; the bridge suppresses its in-iframe reorder.
|
|
@@ -8434,11 +8535,355 @@ declare var __RUNTIME_LAYER_SNAPSHOT_ENABLED__: boolean;
|
|
|
8434
8535
|
x: reorderPointerStart.clientX - reorderRect.left,
|
|
8435
8536
|
y: reorderPointerStart.clientY - reorderRect.top,
|
|
8436
8537
|
};
|
|
8538
|
+
// Transform-only follow: must be cleared before any pointer-up commit
|
|
8539
|
+
// reads getBoundingClientRect, or the drag delta corrupts the result.
|
|
8540
|
+
function authoredTransformOf(el: HTMLElement): string {
|
|
8541
|
+
// The element's own transform to compose the drag translate WITH: inline
|
|
8542
|
+
// if set, else the class/stylesheet value so a drag never wipes an
|
|
8543
|
+
// authored rotate/scale. "none" → "" so we don't emit an identity.
|
|
8544
|
+
if (el.style.transform) return el.style.transform;
|
|
8545
|
+
var computed = window.getComputedStyle(el).transform;
|
|
8546
|
+
return computed && computed !== "none" ? computed : "";
|
|
8547
|
+
}
|
|
8548
|
+
var reorderLiftedMembers: {
|
|
8549
|
+
el: HTMLElement;
|
|
8550
|
+
prevTransform: string;
|
|
8551
|
+
authoredTransform: string;
|
|
8552
|
+
prevTransition: string;
|
|
8553
|
+
prevZIndex: string;
|
|
8554
|
+
prevBoxShadow: string;
|
|
8555
|
+
prevWillChange: string;
|
|
8556
|
+
prevPointerEvents: string;
|
|
8557
|
+
}[] = [];
|
|
8558
|
+
function applyReorderLift(dx: number, dy: number): void {
|
|
8559
|
+
if (!liveReflowEnabled) return;
|
|
8560
|
+
groupEls.forEach(function (member) {
|
|
8561
|
+
var el = member as HTMLElement;
|
|
8562
|
+
var snap = reorderLiftedMembers.filter(function (s) {
|
|
8563
|
+
return s.el === el;
|
|
8564
|
+
})[0];
|
|
8565
|
+
if (!snap) {
|
|
8566
|
+
snap = {
|
|
8567
|
+
el: el,
|
|
8568
|
+
prevTransform: el.style.transform,
|
|
8569
|
+
authoredTransform: authoredTransformOf(el),
|
|
8570
|
+
prevTransition: el.style.transition,
|
|
8571
|
+
prevZIndex: el.style.zIndex,
|
|
8572
|
+
prevBoxShadow: el.style.boxShadow,
|
|
8573
|
+
prevWillChange: el.style.willChange,
|
|
8574
|
+
prevPointerEvents: el.style.pointerEvents,
|
|
8575
|
+
};
|
|
8576
|
+
reorderLiftedMembers.push(snap);
|
|
8577
|
+
el.style.transition = "none";
|
|
8578
|
+
el.style.willChange = "transform";
|
|
8579
|
+
el.style.zIndex = "2147483646";
|
|
8580
|
+
el.style.boxShadow = "0 8px 24px rgba(0, 0, 0, 0.18)";
|
|
8581
|
+
// Hit-test through the lifted element so it never resolves as its
|
|
8582
|
+
// own drop target while following the cursor.
|
|
8583
|
+
el.style.pointerEvents = "none";
|
|
8584
|
+
}
|
|
8585
|
+
// Translate FIRST so movement is in screen space (an authored rotate
|
|
8586
|
+
// would otherwise send the drag off-axis), composed with the element's
|
|
8587
|
+
// own transform (inline OR class/stylesheet) so the drag never wipes
|
|
8588
|
+
// it.
|
|
8589
|
+
el.style.transform =
|
|
8590
|
+
"translate(" +
|
|
8591
|
+
dx +
|
|
8592
|
+
"px, " +
|
|
8593
|
+
dy +
|
|
8594
|
+
"px)" +
|
|
8595
|
+
(snap.authoredTransform ? " " + snap.authoredTransform : "");
|
|
8596
|
+
});
|
|
8597
|
+
}
|
|
8598
|
+
function clearReorderLift(): void {
|
|
8599
|
+
reorderLiftedMembers.forEach(function (snap) {
|
|
8600
|
+
var el = snap.el;
|
|
8601
|
+
el.style.transform = snap.prevTransform;
|
|
8602
|
+
el.style.transition = snap.prevTransition;
|
|
8603
|
+
el.style.zIndex = snap.prevZIndex;
|
|
8604
|
+
el.style.boxShadow = snap.prevBoxShadow;
|
|
8605
|
+
el.style.willChange = snap.prevWillChange;
|
|
8606
|
+
el.style.pointerEvents = snap.prevPointerEvents;
|
|
8607
|
+
});
|
|
8608
|
+
reorderLiftedMembers = [];
|
|
8609
|
+
}
|
|
8610
|
+
// Live sibling reflow, restricted to same-container simple-packed flex so
|
|
8611
|
+
// a constant per-sibling shift always matches the real drop; ported from
|
|
8612
|
+
// shared/drag-reflow.ts.
|
|
8613
|
+
var reorderCommittedTarget: any = null;
|
|
8614
|
+
var reorderCommittedSlot: number | null = null;
|
|
8615
|
+
var reorderCommittedAt = 0;
|
|
8616
|
+
var reorderCommittedPointer = { x: 0, y: 0 };
|
|
8617
|
+
var reorderPendingSlot: number | null = null;
|
|
8618
|
+
var reorderPendingAt = 0;
|
|
8619
|
+
var reflowSiblings: {
|
|
8620
|
+
el: HTMLElement;
|
|
8621
|
+
prevTransform: string;
|
|
8622
|
+
authoredTransform: string;
|
|
8623
|
+
prevTransition: string;
|
|
8624
|
+
}[] = [];
|
|
8625
|
+
var reflowKey: string | null = null;
|
|
8626
|
+
var packedCacheContainer: Element | null = null;
|
|
8627
|
+
var packedCacheResult = false;
|
|
8628
|
+
function reorderMainAxis(target): "x" | "y" {
|
|
8629
|
+
return target && target.axis === "y" ? "y" : "x";
|
|
8630
|
+
}
|
|
8631
|
+
function reorderRealChildren(container: Element): Element[] {
|
|
8632
|
+
var out: Element[] = [];
|
|
8633
|
+
var kids = container.children;
|
|
8634
|
+
for (var i = 0; i < kids.length; i += 1) {
|
|
8635
|
+
var k = kids[i];
|
|
8636
|
+
if (k.nodeType === 1 && !isOverlayElement(k)) out.push(k);
|
|
8637
|
+
}
|
|
8638
|
+
return out;
|
|
8639
|
+
}
|
|
8640
|
+
function reorderSlotForTarget(target, real: Element[]) {
|
|
8641
|
+
if (target.placement === "inside") return { slot: real.length };
|
|
8642
|
+
var ai = real.indexOf(target.anchor);
|
|
8643
|
+
if (ai < 0) return null;
|
|
8644
|
+
return { slot: target.placement === "before" ? ai : ai + 1 };
|
|
8645
|
+
}
|
|
8646
|
+
function containerIsSimplePacked(container: Element): boolean {
|
|
8647
|
+
if (packedCacheContainer === container) return packedCacheResult;
|
|
8648
|
+
packedCacheContainer = container;
|
|
8649
|
+
packedCacheResult = false;
|
|
8650
|
+
var cs = window.getComputedStyle(container);
|
|
8651
|
+
if (cs.display !== "flex" && cs.display !== "inline-flex") return false;
|
|
8652
|
+
if (cs.flexDirection !== "row" && cs.flexDirection !== "column") {
|
|
8653
|
+
return false;
|
|
8654
|
+
}
|
|
8655
|
+
if (cs.flexWrap !== "nowrap") return false;
|
|
8656
|
+
var jc = cs.justifyContent;
|
|
8657
|
+
if (
|
|
8658
|
+
jc !== "flex-start" &&
|
|
8659
|
+
jc !== "start" &&
|
|
8660
|
+
jc !== "normal" &&
|
|
8661
|
+
jc !== "left" &&
|
|
8662
|
+
jc !== ""
|
|
8663
|
+
) {
|
|
8664
|
+
return false;
|
|
8665
|
+
}
|
|
8666
|
+
var kids = container.children;
|
|
8667
|
+
for (var i = 0; i < kids.length; i += 1) {
|
|
8668
|
+
if (kids[i].nodeType !== 1) continue;
|
|
8669
|
+
if (parseFloat(window.getComputedStyle(kids[i]).flexGrow) > 0) {
|
|
8670
|
+
return false;
|
|
8671
|
+
}
|
|
8672
|
+
}
|
|
8673
|
+
packedCacheResult = true;
|
|
8674
|
+
return true;
|
|
8675
|
+
}
|
|
8676
|
+
function reorderMainGap(container: Element, axis: "x" | "y"): number {
|
|
8677
|
+
var cs = window.getComputedStyle(container);
|
|
8678
|
+
var raw = axis === "x" ? cs.columnGap || cs.gap : cs.rowGap || cs.gap;
|
|
8679
|
+
var n = readPx(raw);
|
|
8680
|
+
return Number.isFinite(n) && n > 0 ? n : 0;
|
|
8681
|
+
}
|
|
8682
|
+
function clearReorderReflow(): void {
|
|
8683
|
+
reflowSiblings.forEach(function (s) {
|
|
8684
|
+
s.el.style.transform = s.prevTransform;
|
|
8685
|
+
s.el.style.transition = s.prevTransition;
|
|
8686
|
+
});
|
|
8687
|
+
reflowSiblings = [];
|
|
8688
|
+
reflowKey = null;
|
|
8689
|
+
}
|
|
8690
|
+
// Auto-layout children reorder into a slot on plain drag — they have no
|
|
8691
|
+
// free x/y without leaving the layout, which would collapse it. Ctrl
|
|
8692
|
+
// "ignore auto layout" is the explicit free-place escape.
|
|
8693
|
+
function resolveReorderOrFreeTarget(cx, cy, ctrlKey) {
|
|
8694
|
+
return flowMoveTargetForPoint(
|
|
8695
|
+
reorderEl,
|
|
8696
|
+
cx,
|
|
8697
|
+
cy,
|
|
8698
|
+
groupOthers,
|
|
8699
|
+
keepCurrentFlowParent,
|
|
8700
|
+
ctrlKey,
|
|
8701
|
+
);
|
|
8702
|
+
}
|
|
8703
|
+
// Figma's "don't nest into a smaller container" guard (⌘/Ctrl overrides).
|
|
8704
|
+
// Instead of nesting into a too-small container, fall back to placing
|
|
8705
|
+
// beside it in its parent so the drop is never silently discarded.
|
|
8706
|
+
function applyReorderSizeGuard(target, ev) {
|
|
8707
|
+
if (!liveReflowEnabled || !target || target.placement !== "inside") {
|
|
8708
|
+
return target;
|
|
8709
|
+
}
|
|
8710
|
+
if (ev && (ev.metaKey || ev.ctrlKey)) return target;
|
|
8711
|
+
var container = dropContainerForTarget(target);
|
|
8712
|
+
// Never treat the screen root (body/html) as a too-small container: the
|
|
8713
|
+
// before/after fallback would reparent to documentElement and insert a
|
|
8714
|
+
// full-size layer as a sibling of <body>. Guard nested frames only.
|
|
8715
|
+
if (
|
|
8716
|
+
!container ||
|
|
8717
|
+
container === reorderEl ||
|
|
8718
|
+
container === document.body ||
|
|
8719
|
+
container === document.documentElement
|
|
8720
|
+
) {
|
|
8721
|
+
return target;
|
|
8722
|
+
}
|
|
8723
|
+
var crect = container.getBoundingClientRect();
|
|
8724
|
+
var drect = (reorderEl as HTMLElement).getBoundingClientRect();
|
|
8725
|
+
if (crect.width >= drect.width && crect.height >= drect.height) {
|
|
8726
|
+
return target;
|
|
8727
|
+
}
|
|
8728
|
+
var parent = container.parentElement;
|
|
8729
|
+
if (!parent) return null;
|
|
8730
|
+
var pcs = window.getComputedStyle(parent);
|
|
8731
|
+
var pAxis =
|
|
8732
|
+
pcs.flexDirection === "column" ||
|
|
8733
|
+
pcs.flexDirection === "column-reverse"
|
|
8734
|
+
? "y"
|
|
8735
|
+
: "x";
|
|
8736
|
+
var center =
|
|
8737
|
+
pAxis === "x"
|
|
8738
|
+
? crect.left + crect.width / 2
|
|
8739
|
+
: crect.top + crect.height / 2;
|
|
8740
|
+
var ptr =
|
|
8741
|
+
pAxis === "x" ? (ev ? ev.clientX : center) : ev ? ev.clientY : center;
|
|
8742
|
+
return {
|
|
8743
|
+
anchor: container,
|
|
8744
|
+
placement: ptr < center ? "before" : "after",
|
|
8745
|
+
axis: pAxis,
|
|
8746
|
+
dropMode: "flow-insert",
|
|
8747
|
+
};
|
|
8748
|
+
}
|
|
8749
|
+
// Stabilize a freshly-resolved target against the committed one so the
|
|
8750
|
+
// preview only moves on a deliberate ≥8px pointer move from the last
|
|
8751
|
+
// commit or after the NEW candidate persists ≥60ms. Mirrors
|
|
8752
|
+
// shared/drag-reflow.ts resolveTargetHysteresis; same-container only.
|
|
8753
|
+
function stabilizeReorderTarget(rawTarget, cx, cy, now) {
|
|
8754
|
+
var reset = function () {
|
|
8755
|
+
reorderCommittedTarget = null;
|
|
8756
|
+
reorderCommittedSlot = null;
|
|
8757
|
+
reorderPendingSlot = null;
|
|
8758
|
+
};
|
|
8759
|
+
if (
|
|
8760
|
+
!liveReflowEnabled ||
|
|
8761
|
+
!rawTarget ||
|
|
8762
|
+
rawTarget.dropMode !== "flow-insert"
|
|
8763
|
+
) {
|
|
8764
|
+
reset();
|
|
8765
|
+
return rawTarget;
|
|
8766
|
+
}
|
|
8767
|
+
var container = dropContainerForTarget(rawTarget);
|
|
8768
|
+
if (
|
|
8769
|
+
!container ||
|
|
8770
|
+
(reorderEl as HTMLElement).parentElement !== container
|
|
8771
|
+
) {
|
|
8772
|
+
reset();
|
|
8773
|
+
return rawTarget;
|
|
8774
|
+
}
|
|
8775
|
+
var slotInfo = reorderSlotForTarget(
|
|
8776
|
+
rawTarget,
|
|
8777
|
+
reorderRealChildren(container),
|
|
8778
|
+
);
|
|
8779
|
+
if (!slotInfo) {
|
|
8780
|
+
reset();
|
|
8781
|
+
return rawTarget;
|
|
8782
|
+
}
|
|
8783
|
+
var slot = slotInfo.slot;
|
|
8784
|
+
var commit = function () {
|
|
8785
|
+
reorderCommittedSlot = slot;
|
|
8786
|
+
reorderCommittedTarget = rawTarget;
|
|
8787
|
+
reorderCommittedPointer = { x: cx, y: cy };
|
|
8788
|
+
reorderCommittedAt = now;
|
|
8789
|
+
reorderPendingSlot = null;
|
|
8790
|
+
return rawTarget;
|
|
8791
|
+
};
|
|
8792
|
+
if (reorderCommittedSlot === null) return commit();
|
|
8793
|
+
if (slot === reorderCommittedSlot) {
|
|
8794
|
+
reorderCommittedTarget = rawTarget;
|
|
8795
|
+
reorderPendingSlot = null;
|
|
8796
|
+
return rawTarget;
|
|
8797
|
+
}
|
|
8798
|
+
if (reorderPendingSlot !== slot) {
|
|
8799
|
+
reorderPendingSlot = slot;
|
|
8800
|
+
reorderPendingAt = now;
|
|
8801
|
+
}
|
|
8802
|
+
var movedPx = Math.hypot(
|
|
8803
|
+
cx - reorderCommittedPointer.x,
|
|
8804
|
+
cy - reorderCommittedPointer.y,
|
|
8805
|
+
);
|
|
8806
|
+
if (movedPx >= 8 || now - reorderPendingAt >= 60) return commit();
|
|
8807
|
+
return reorderCommittedTarget || rawTarget;
|
|
8808
|
+
}
|
|
8809
|
+
function applyReorderReflow(target, cx, cy): void {
|
|
8810
|
+
if (!liveReflowEnabled) return;
|
|
8811
|
+
// Group members are each lifted and follow the cursor; also reflowing
|
|
8812
|
+
// them would double-transform and strand a residual on teardown, so
|
|
8813
|
+
// group drags stay indicator-only.
|
|
8814
|
+
if (isGroupDrag || !target || target.dropMode !== "flow-insert") {
|
|
8815
|
+
clearReorderReflow();
|
|
8816
|
+
return;
|
|
8817
|
+
}
|
|
8818
|
+
var container = dropContainerForTarget(target);
|
|
8819
|
+
if (
|
|
8820
|
+
!container ||
|
|
8821
|
+
(reorderEl as HTMLElement).parentElement !== container ||
|
|
8822
|
+
!containerIsSimplePacked(container)
|
|
8823
|
+
) {
|
|
8824
|
+
clearReorderReflow();
|
|
8825
|
+
return;
|
|
8826
|
+
}
|
|
8827
|
+
var real = reorderRealChildren(container);
|
|
8828
|
+
var originIndex = real.indexOf(reorderEl);
|
|
8829
|
+
var slotInfo = reorderSlotForTarget(target, real);
|
|
8830
|
+
if (originIndex < 0 || !slotInfo) {
|
|
8831
|
+
clearReorderReflow();
|
|
8832
|
+
return;
|
|
8833
|
+
}
|
|
8834
|
+
var axis = reorderMainAxis(target);
|
|
8835
|
+
var key = axis + ":" + slotInfo.slot;
|
|
8836
|
+
if (key === reflowKey) return;
|
|
8837
|
+
clearReorderReflow();
|
|
8838
|
+
reflowKey = key;
|
|
8839
|
+
var drect = (reorderEl as HTMLElement).getBoundingClientRect();
|
|
8840
|
+
var slotMain =
|
|
8841
|
+
(axis === "x" ? drect.width : drect.height) +
|
|
8842
|
+
reorderMainGap(container, axis);
|
|
8843
|
+
// Only siblings between origin and target shift, by ±slotMain — exact
|
|
8844
|
+
// for a packed container regardless of each sibling's own size.
|
|
8845
|
+
var offsets: number[] = new Array(real.length).fill(0);
|
|
8846
|
+
if (slotInfo.slot > originIndex + 1) {
|
|
8847
|
+
for (var a = originIndex + 1; a <= slotInfo.slot - 1; a += 1) {
|
|
8848
|
+
offsets[a] = -slotMain;
|
|
8849
|
+
}
|
|
8850
|
+
} else if (slotInfo.slot < originIndex) {
|
|
8851
|
+
for (var b = slotInfo.slot; b <= originIndex - 1; b += 1) {
|
|
8852
|
+
offsets[b] = slotMain;
|
|
8853
|
+
}
|
|
8854
|
+
}
|
|
8855
|
+
for (var i = 0; i < real.length; i += 1) {
|
|
8856
|
+
if (i === originIndex) continue;
|
|
8857
|
+
var el = real[i] as HTMLElement;
|
|
8858
|
+
var prevTransform = el.style.transform;
|
|
8859
|
+
var authoredTransform = authoredTransformOf(el);
|
|
8860
|
+
reflowSiblings.push({
|
|
8861
|
+
el: el,
|
|
8862
|
+
prevTransform: prevTransform,
|
|
8863
|
+
authoredTransform: authoredTransform,
|
|
8864
|
+
prevTransition: el.style.transition,
|
|
8865
|
+
});
|
|
8866
|
+
el.style.transition = "transform 140ms cubic-bezier(0.2, 0, 0, 1)";
|
|
8867
|
+
var tx = axis === "x" ? offsets[i] : 0;
|
|
8868
|
+
var ty = axis === "y" ? offsets[i] : 0;
|
|
8869
|
+
// Translate FIRST (screen space) composed with the sibling's own
|
|
8870
|
+
// transform so an authored rotate/scale survives the reflow shift.
|
|
8871
|
+
el.style.transform =
|
|
8872
|
+
"translate(" +
|
|
8873
|
+
tx +
|
|
8874
|
+
"px, " +
|
|
8875
|
+
ty +
|
|
8876
|
+
"px)" +
|
|
8877
|
+
(authoredTransform ? " " + authoredTransform : "");
|
|
8878
|
+
}
|
|
8879
|
+
}
|
|
8437
8880
|
function onReorderMove(ev) {
|
|
8438
8881
|
var vw = window.innerWidth;
|
|
8439
8882
|
var vh = window.innerHeight;
|
|
8440
8883
|
var cx = ev.clientX;
|
|
8441
8884
|
var cy = ev.clientY;
|
|
8885
|
+
var dx = cx - reorderPointerStart.clientX;
|
|
8886
|
+
var dy = cy - reorderPointerStart.clientY;
|
|
8442
8887
|
var outside = cx < 0 || cy < 0 || cx > vw || cy > vh;
|
|
8443
8888
|
pointerOutsideIframe = outside;
|
|
8444
8889
|
// Always notify the host frame so it can track the cursor position,
|
|
@@ -8465,28 +8910,58 @@ declare var __RUNTIME_LAYER_SNAPSHOT_ENABLED__: boolean;
|
|
|
8465
8910
|
if (outside && !isGroupDrag) {
|
|
8466
8911
|
// Cursor left this iframe — hide the in-iframe insertion guide so
|
|
8467
8912
|
// it does not render while the host shows a cross-screen drop target.
|
|
8913
|
+
// Drop the lift so the host-rendered ghost is the only moving visual
|
|
8914
|
+
// (re-applied automatically if the cursor comes back inside).
|
|
8468
8915
|
hideInsertionGuide();
|
|
8916
|
+
clearReorderLift();
|
|
8917
|
+
clearReorderReflow();
|
|
8469
8918
|
showTransformBadge("Move layer", cx, cy);
|
|
8470
8919
|
} else {
|
|
8471
|
-
// Cursor is inside this iframe — use existing in-iframe behavior
|
|
8472
|
-
|
|
8473
|
-
|
|
8920
|
+
// Cursor is inside this iframe — use existing in-iframe behavior,
|
|
8921
|
+
// stabilized (hysteresis) and previewed with live sibling reflow when
|
|
8922
|
+
// liveReflowEnabled. stabilizeReorderTarget / applyReorderReflow are
|
|
8923
|
+
// no-ops (pass-through) when the flag is off.
|
|
8924
|
+
var rawTarget = resolveReorderOrFreeTarget(
|
|
8474
8925
|
cx,
|
|
8475
8926
|
cy,
|
|
8476
|
-
groupOthers,
|
|
8477
|
-
keepCurrentFlowParent,
|
|
8478
8927
|
Boolean(ev.ctrlKey),
|
|
8479
8928
|
);
|
|
8929
|
+
rawTarget = applyReorderSizeGuard(rawTarget, ev);
|
|
8930
|
+
currentTarget = stabilizeReorderTarget(
|
|
8931
|
+
rawTarget,
|
|
8932
|
+
cx,
|
|
8933
|
+
cy,
|
|
8934
|
+
ev.timeStamp,
|
|
8935
|
+
);
|
|
8480
8936
|
showInsertionGuideFor(currentTarget);
|
|
8937
|
+
var _dndKey = currentTarget
|
|
8938
|
+
? getSelector(currentTarget.anchor) +
|
|
8939
|
+
"|" +
|
|
8940
|
+
currentTarget.placement +
|
|
8941
|
+
"|" +
|
|
8942
|
+
currentTarget.dropMode
|
|
8943
|
+
: "none";
|
|
8944
|
+
if (_dndKey !== reorderLastTargetKey) {
|
|
8945
|
+
reorderLastTargetKey = _dndKey;
|
|
8946
|
+
dndLog("target", dndTarget(currentTarget));
|
|
8947
|
+
}
|
|
8948
|
+
applyReorderLift(dx, dy);
|
|
8949
|
+
applyReorderReflow(currentTarget, cx, cy);
|
|
8481
8950
|
showTransformBadge(currentTarget ? "Move layer" : "Move", cx, cy);
|
|
8482
8951
|
}
|
|
8483
8952
|
}
|
|
8484
8953
|
function cleanupReorderDrag() {
|
|
8485
8954
|
document.removeEventListener(events.move, onReorderMove, true);
|
|
8486
8955
|
document.removeEventListener(events.up, onReorderUp, true);
|
|
8956
|
+
document.removeEventListener("pointercancel", onReorderEscape, true);
|
|
8487
8957
|
document.removeEventListener("keydown", onReorderKeyDown, true);
|
|
8488
8958
|
document.removeEventListener("keyup", onReorderKeyUp, true);
|
|
8489
8959
|
clearActiveDragCancel(onReorderEscape);
|
|
8960
|
+
// onReorderUp calls this before resolving/reordering, so the commit
|
|
8961
|
+
// reads un-transformed rects and — one synchronous task — paints once
|
|
8962
|
+
// in the final slot with no back-to-origin flicker.
|
|
8963
|
+
clearReorderLift();
|
|
8964
|
+
clearReorderReflow();
|
|
8490
8965
|
}
|
|
8491
8966
|
function onReorderEscape() {
|
|
8492
8967
|
cleanupReorderDrag();
|
|
@@ -8566,14 +9041,26 @@ declare var __RUNTIME_LAYER_SNAPSHOT_ENABLED__: boolean;
|
|
|
8566
9041
|
// already clears cross-screen state on re-entry so checking the
|
|
8567
9042
|
// momentary excursion flag here would wrongly drop the element nowhere.
|
|
8568
9043
|
if (outsideOnDrop) return;
|
|
8569
|
-
|
|
8570
|
-
|
|
8571
|
-
|
|
8572
|
-
|
|
8573
|
-
|
|
8574
|
-
|
|
8575
|
-
|
|
8576
|
-
|
|
9044
|
+
// Resolve from the RELEASE point + release-time modifiers so a Ctrl or
|
|
9045
|
+
// Space held only at release still takes effect; live reflow then runs
|
|
9046
|
+
// one final stabilize tick so the drop still lands on the previewed
|
|
9047
|
+
// slot rather than jumping.
|
|
9048
|
+
var finalRaw = resolveReorderOrFreeTarget(cx, cy, Boolean(ev?.ctrlKey));
|
|
9049
|
+
currentTarget = liveReflowEnabled
|
|
9050
|
+
? stabilizeReorderTarget(
|
|
9051
|
+
applyReorderSizeGuard(finalRaw, ev),
|
|
9052
|
+
cx,
|
|
9053
|
+
cy,
|
|
9054
|
+
ev && typeof ev.timeStamp === "number"
|
|
9055
|
+
? ev.timeStamp
|
|
9056
|
+
: reorderCommittedAt,
|
|
9057
|
+
)
|
|
9058
|
+
: finalRaw;
|
|
9059
|
+
dndLog("commit:resolve", {
|
|
9060
|
+
raw: dndTarget(finalRaw),
|
|
9061
|
+
final: dndTarget(currentTarget),
|
|
9062
|
+
ctrl: Boolean(ev && ev.ctrlKey),
|
|
9063
|
+
});
|
|
8577
9064
|
if (!currentTarget) {
|
|
8578
9065
|
// No valid drop target — clean up the clone if one was inserted so
|
|
8579
9066
|
// no ghost element is left in the DOM.
|
|
@@ -8657,6 +9144,12 @@ declare var __RUNTIME_LAYER_SNAPSHOT_ENABLED__: boolean;
|
|
|
8657
9144
|
// visual feedback; the visual-structure-ack handler will confirm
|
|
8658
9145
|
// or revert once the parent processes the change.
|
|
8659
9146
|
applyRuntimeReorder(reorderEl, currentTarget);
|
|
9147
|
+
dndLog("commit:done", {
|
|
9148
|
+
el: getSelector(reorderEl),
|
|
9149
|
+
parent: reorderEl.parentElement
|
|
9150
|
+
? getSelector(reorderEl.parentElement)
|
|
9151
|
+
: null,
|
|
9152
|
+
});
|
|
8660
9153
|
postVisualStructureChange(reorderEl, currentTarget, {
|
|
8661
9154
|
prevParent: prevParent,
|
|
8662
9155
|
prevNextSibling: prevNextSibling,
|
|
@@ -8666,6 +9159,7 @@ declare var __RUNTIME_LAYER_SNAPSHOT_ENABLED__: boolean;
|
|
|
8666
9159
|
}
|
|
8667
9160
|
document.addEventListener(events.move, onReorderMove, true);
|
|
8668
9161
|
document.addEventListener(events.up, onReorderUp, true);
|
|
9162
|
+
document.addEventListener("pointercancel", onReorderEscape, true);
|
|
8669
9163
|
document.addEventListener("keydown", onReorderKeyDown, true);
|
|
8670
9164
|
document.addEventListener("keyup", onReorderKeyUp, true);
|
|
8671
9165
|
setActiveDragCancel(onReorderEscape);
|
|
@@ -8711,6 +9205,7 @@ declare var __RUNTIME_LAYER_SNAPSHOT_ENABLED__: boolean;
|
|
|
8711
9205
|
var dragEl = gestureEl;
|
|
8712
9206
|
var moved = false;
|
|
8713
9207
|
var DRAG_THRESHOLD = 3;
|
|
9208
|
+
dndLog("start:free", { el: getSelector(gestureEl), isGroup: isGroupDrag });
|
|
8714
9209
|
var currentAutoLayoutTarget: {
|
|
8715
9210
|
anchor: Element;
|
|
8716
9211
|
placement: string;
|
|
@@ -8973,25 +9468,10 @@ declare var __RUNTIME_LAYER_SNAPSHOT_ENABLED__: boolean;
|
|
|
8973
9468
|
postVisualDuplicateChange(originalSelectedEl, dragEl);
|
|
8974
9469
|
} else if (currentAutoLayoutTarget) {
|
|
8975
9470
|
setMembersOpacity(null);
|
|
8976
|
-
//
|
|
8977
|
-
//
|
|
8978
|
-
//
|
|
8979
|
-
//
|
|
8980
|
-
// host applies the two edits in the right order against its
|
|
8981
|
-
// synchronous same-tick content refs (container becomes flex, then
|
|
8982
|
-
// the child moves into it and loses absolute positioning via the
|
|
8983
|
-
// existing "flow-insert" dropMode handling). For group drags the
|
|
8984
|
-
// conversion fires ONCE for the container; every member then nests
|
|
8985
|
-
// consecutively via applyGroupStructureDrop.
|
|
8986
|
-
if (
|
|
8987
|
-
currentAutoLayoutTarget.needsAutoLayoutConversion &&
|
|
8988
|
-
currentAutoLayoutTarget.conversionTarget
|
|
8989
|
-
) {
|
|
8990
|
-
applyAutoLayoutConversionForDrop(
|
|
8991
|
-
currentAutoLayoutTarget.conversionTarget,
|
|
8992
|
-
groupEls,
|
|
8993
|
-
);
|
|
8994
|
-
}
|
|
9471
|
+
// Nest-on-drop: a free element nests as an absolute child of a plain
|
|
9472
|
+
// container ("absolute-container", keeps left/top) or flow-inserts into
|
|
9473
|
+
// an existing auto-layout frame. The resolver never requests an implicit
|
|
9474
|
+
// flex conversion, so there is none to apply here.
|
|
8995
9475
|
if (isGroupDrag) {
|
|
8996
9476
|
applyGroupStructureDrop(
|
|
8997
9477
|
groupEls,
|
|
@@ -9023,6 +9503,10 @@ declare var __RUNTIME_LAYER_SNAPSHOT_ENABLED__: boolean;
|
|
|
9023
9503
|
dropContainerForTarget(currentAutoLayoutTarget),
|
|
9024
9504
|
);
|
|
9025
9505
|
applyRuntimeReorder(dragEl, currentAutoLayoutTarget);
|
|
9506
|
+
dndLog("commit:free-nest", {
|
|
9507
|
+
el: getSelector(dragEl),
|
|
9508
|
+
target: dndTarget(currentAutoLayoutTarget),
|
|
9509
|
+
});
|
|
9026
9510
|
postVisualStructureChange(dragEl, currentAutoLayoutTarget, {
|
|
9027
9511
|
prevParent: prevParent,
|
|
9028
9512
|
prevNextSibling: prevNextSibling,
|
|
@@ -9031,6 +9515,7 @@ declare var __RUNTIME_LAYER_SNAPSHOT_ENABLED__: boolean;
|
|
|
9031
9515
|
}
|
|
9032
9516
|
} else {
|
|
9033
9517
|
setMembersOpacity(null);
|
|
9518
|
+
dndLog("commit:free-absolute", { count: memberStates.length });
|
|
9034
9519
|
// Free absolute placement: one style-change message per member, in
|
|
9035
9520
|
// order — the host composes them against its synchronous same-tick
|
|
9036
9521
|
// content refs exactly like multi-property style commits.
|
|
@@ -9505,6 +9990,14 @@ declare var __RUNTIME_LAYER_SNAPSHOT_ENABLED__: boolean;
|
|
|
9505
9990
|
var previousSelectedEl = selectedEl;
|
|
9506
9991
|
selectedEl = target;
|
|
9507
9992
|
positionOverlay(selectionOverlay, selectedEl);
|
|
9993
|
+
// A plain (non-shift) select on a fresh target collapses any prior
|
|
9994
|
+
// multi-selection, so a following drag can never inherit stale passive
|
|
9995
|
+
// members from an earlier gesture (phantom-passenger fix, §3.5). Shift
|
|
9996
|
+
// keeps + extends the set via the helper below. Only reached for
|
|
9997
|
+
// single-element drags — an intentional group drag returns earlier.
|
|
9998
|
+
if (!ev?.shiftKey && passiveSelectionEls.length) {
|
|
9999
|
+
setPassiveSelectionElements([]);
|
|
10000
|
+
}
|
|
9508
10001
|
preservePreviousSelectedElementForShiftClick(
|
|
9509
10002
|
previousSelectedEl,
|
|
9510
10003
|
selectedEl,
|
|
@@ -11210,6 +11703,10 @@ declare var __RUNTIME_LAYER_SNAPSHOT_ENABLED__: boolean;
|
|
|
11210
11703
|
return;
|
|
11211
11704
|
}
|
|
11212
11705
|
if (e.data.type === "visual-structure-ack") {
|
|
11706
|
+
dndLog("ack", {
|
|
11707
|
+
requestId: e.data.requestId,
|
|
11708
|
+
applied: Boolean(e.data.applied),
|
|
11709
|
+
});
|
|
11213
11710
|
var move = pendingStructureMoves[e.data.requestId];
|
|
11214
11711
|
if (!move) return;
|
|
11215
11712
|
delete pendingStructureMoves[e.data.requestId];
|