made-refine 0.2.17 → 0.2.19

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/dist/index.mjs CHANGED
@@ -117,6 +117,255 @@ function getZoomScale() {
117
117
  return snap.active ? snap.zoom : 1;
118
118
  }
119
119
 
120
+ // src/utils/debug-stack.ts
121
+ var STACK_SOURCE_FILE_EXTENSION_REGEX = /\.(jsx|tsx|ts|js)$/;
122
+ var STACK_BUNDLED_FILE_PATTERN_REGEX = /(\.min|bundle|chunk|vendor|vendors|runtime|polyfill|polyfills)\.(js|mjs|cjs)$|(chunk|bundle|vendor|vendors|runtime|polyfill|polyfills|framework|app|main|index)[-_.][A-Za-z0-9_-]{4,}\.(js|mjs|cjs)$|[\da-f]{8,}\.(js|mjs|cjs)$|[-_.][\da-f]{20,}\.(js|mjs|cjs)$|\/dist\/|\/build\/|\/.next\/|\/out\/|\/node_modules\/|\.webpack\.|\.vite\.|\.turbopack\./i;
123
+ var FIREFOX_SAFARI_STACK_REGEXP = /(^|@)\S+:\d+/;
124
+ var SAFARI_NATIVE_CODE_REGEXP = /^(eval@)?(\[native code\])?$/;
125
+ var SERVER_FRAME_MARKER = "(at Server)";
126
+ var STACK_INTERNAL_SCHEME_PREFIXES = [
127
+ "rsc://",
128
+ "about://React/",
129
+ "React/Server/",
130
+ "file:///",
131
+ "webpack://",
132
+ "webpack-internal://",
133
+ "node:",
134
+ "turbopack://",
135
+ "/app-pages-browser/"
136
+ ];
137
+ function formatOwnerDebugStack(stack) {
138
+ if (!stack) return "";
139
+ const lines = stack.split("\n");
140
+ const filtered = [];
141
+ for (const line of lines) {
142
+ const trimmed = line.trim();
143
+ if (!trimmed) continue;
144
+ if (trimmed === "Error: react-stack-top-frame") continue;
145
+ if (trimmed.includes("react_stack_bottom_frame") || trimmed.includes("react-stack-bottom-frame")) {
146
+ continue;
147
+ }
148
+ filtered.push(line);
149
+ }
150
+ if (filtered.length > 0 && filtered[0].includes("fakeJSXCallSite")) {
151
+ filtered.shift();
152
+ }
153
+ return filtered.join("\n");
154
+ }
155
+ function extractStackLocation(urlLike) {
156
+ if (!urlLike.includes(":")) return [urlLike, void 0, void 0];
157
+ const isWrappedLocation = urlLike.startsWith("(") && /:\d+\)$/.test(urlLike);
158
+ const sanitizedResult = isWrappedLocation ? urlLike.slice(1, -1) : urlLike;
159
+ const parts = /(.+?)(?::(\d+))?(?::(\d+))?$/.exec(sanitizedResult);
160
+ if (!parts) return [sanitizedResult, void 0, void 0];
161
+ return [
162
+ parts[1],
163
+ parts[2] !== void 0 ? Number(parts[2]) : void 0,
164
+ parts[3] !== void 0 ? Number(parts[3]) : void 0
165
+ ];
166
+ }
167
+ function parseV8StackLine(line) {
168
+ let currentLine = line;
169
+ if (currentLine.includes("(eval ")) {
170
+ currentLine = currentLine.replace(/eval code/g, "eval").replace(/(\(eval at [^()]*)|(,.*$)/g, "");
171
+ }
172
+ let sanitizedLine = currentLine.replace(/^\s+/, "").replace(/\(eval code/g, "(").replace(/^.*?\s+/, "");
173
+ const locationMatch = sanitizedLine.match(/ (\(.+\)$)/);
174
+ if (locationMatch) {
175
+ sanitizedLine = sanitizedLine.replace(locationMatch[0], "");
176
+ }
177
+ const [fileName, lineNumber, columnNumber] = extractStackLocation(
178
+ locationMatch ? locationMatch[1] : sanitizedLine
179
+ );
180
+ const functionName = locationMatch && sanitizedLine ? sanitizedLine : void 0;
181
+ if (fileName === "eval" || fileName === "<anonymous>") {
182
+ return {
183
+ functionName
184
+ };
185
+ }
186
+ return {
187
+ functionName,
188
+ fileName,
189
+ lineNumber,
190
+ columnNumber,
191
+ source: currentLine,
192
+ isServer: currentLine.includes(SERVER_FRAME_MARKER) || fileName.startsWith("rsc://")
193
+ };
194
+ }
195
+ function parseFFOrSafariStackLine(line) {
196
+ let currentLine = line;
197
+ if (currentLine.includes(" > eval")) {
198
+ currentLine = currentLine.replace(
199
+ / line (\d+)(?: > eval line \d+)* > eval:\d+:\d+/g,
200
+ ":$1"
201
+ );
202
+ }
203
+ const trimmed = currentLine.trim();
204
+ if (!trimmed || SAFARI_NATIVE_CODE_REGEXP.test(trimmed)) {
205
+ return null;
206
+ }
207
+ if (!trimmed.includes("@") && !trimmed.includes(":")) {
208
+ return {
209
+ functionName: trimmed,
210
+ source: currentLine,
211
+ isServer: trimmed.includes(SERVER_FRAME_MARKER)
212
+ };
213
+ }
214
+ const atIndex = trimmed.lastIndexOf("@");
215
+ if (atIndex === -1) {
216
+ return null;
217
+ }
218
+ const maybeFunctionName = trimmed.slice(0, atIndex);
219
+ const location = trimmed.slice(atIndex + 1);
220
+ const [fileName, lineNumber, columnNumber] = extractStackLocation(location);
221
+ return {
222
+ functionName: maybeFunctionName || void 0,
223
+ fileName,
224
+ lineNumber,
225
+ columnNumber,
226
+ source: currentLine,
227
+ isServer: currentLine.includes(SERVER_FRAME_MARKER) || fileName.startsWith("rsc://")
228
+ };
229
+ }
230
+ function parseInStackLine(line) {
231
+ const functionName = line.replace(/^\s*in\s+/, "").replace(/\s*\(at .*\)$/, "").trim();
232
+ if (!functionName) return null;
233
+ return {
234
+ functionName,
235
+ source: line,
236
+ isServer: line.includes(SERVER_FRAME_MARKER)
237
+ };
238
+ }
239
+ function parseDebugStack(stack) {
240
+ const frames = [];
241
+ for (const rawLine of stack.split("\n")) {
242
+ if (FIREFOX_SAFARI_STACK_REGEXP.test(rawLine)) {
243
+ const parsed = parseFFOrSafariStackLine(rawLine);
244
+ if (parsed) frames.push(parsed);
245
+ continue;
246
+ }
247
+ if (/^\s*at\s+/.test(rawLine)) {
248
+ const parsed = parseV8StackLine(rawLine);
249
+ if (parsed) frames.push(parsed);
250
+ continue;
251
+ }
252
+ if (/^\s*in\s+/.test(rawLine)) {
253
+ const parsed = parseInStackLine(rawLine);
254
+ if (parsed) frames.push(parsed);
255
+ }
256
+ }
257
+ return frames;
258
+ }
259
+ function normalizeStackFileName(fileName) {
260
+ if (!fileName) return "";
261
+ let normalized = fileName;
262
+ const isHttpUrl = normalized.startsWith("http://") || normalized.startsWith("https://");
263
+ if (isHttpUrl) {
264
+ try {
265
+ normalized = new URL(normalized).pathname;
266
+ } catch {
267
+ }
268
+ }
269
+ let didStripPrefix = true;
270
+ while (didStripPrefix) {
271
+ didStripPrefix = false;
272
+ for (const prefix of STACK_INTERNAL_SCHEME_PREFIXES) {
273
+ if (normalized.startsWith(prefix)) {
274
+ normalized = normalized.slice(prefix.length);
275
+ if (prefix === "file:///") {
276
+ normalized = `/${normalized.replace(/^\/+/, "")}`;
277
+ }
278
+ didStripPrefix = true;
279
+ break;
280
+ }
281
+ }
282
+ }
283
+ normalized = normalized.replace(/^\/\(app-pages-browser\)\//, "/").replace(/^\/\.\//, "/").replace(/^\.\//, "");
284
+ const queryIndex = normalized.indexOf("?");
285
+ if (queryIndex !== -1) {
286
+ normalized = normalized.slice(0, queryIndex);
287
+ }
288
+ return normalized;
289
+ }
290
+ function isSourceStackFile(fileName) {
291
+ const normalizedFileName = normalizeStackFileName(fileName);
292
+ if (!normalizedFileName) return false;
293
+ if (!STACK_SOURCE_FILE_EXTENSION_REGEX.test(normalizedFileName)) return false;
294
+ return !STACK_BUNDLED_FILE_PATTERN_REGEX.test(normalizedFileName);
295
+ }
296
+ function buildFunctionNameToRscFramesMap(fiber) {
297
+ const functionNameToRscFrames = /* @__PURE__ */ new Map();
298
+ const visited = /* @__PURE__ */ new Set();
299
+ let current = fiber;
300
+ while (current && !visited.has(current)) {
301
+ visited.add(current);
302
+ const rawStack = current?._debugStack?.stack;
303
+ const stack = typeof rawStack === "string" ? formatOwnerDebugStack(rawStack) : "";
304
+ if (stack) {
305
+ const frames = parseDebugStack(stack);
306
+ for (const frame of frames) {
307
+ if (!frame.functionName || !frame.fileName) continue;
308
+ if (!frame.fileName.startsWith("rsc://")) continue;
309
+ const normalized = normalizeStackFileName(frame.fileName);
310
+ if (!normalized) continue;
311
+ const existing = functionNameToRscFrames.get(frame.functionName) ?? [];
312
+ const duplicate = existing.some(
313
+ (candidate) => candidate.fileName === normalized && candidate.lineNumber === frame.lineNumber && candidate.columnNumber === frame.columnNumber
314
+ );
315
+ if (!duplicate) {
316
+ existing.push({
317
+ fileName: normalized,
318
+ lineNumber: frame.lineNumber,
319
+ columnNumber: frame.columnNumber
320
+ });
321
+ functionNameToRscFrames.set(frame.functionName, existing);
322
+ }
323
+ }
324
+ }
325
+ current = current._debugOwner ?? current.return ?? null;
326
+ }
327
+ return functionNameToRscFrames;
328
+ }
329
+ function enrichServerFrame(frame, functionNameToRscFrames, functionNameToUsageIndex) {
330
+ if (!frame.functionName) return frame;
331
+ const available = functionNameToRscFrames.get(frame.functionName);
332
+ if (!available) return frame;
333
+ const usageIndex = functionNameToUsageIndex.get(frame.functionName) ?? 0;
334
+ const resolved = available[usageIndex % available.length];
335
+ functionNameToUsageIndex.set(frame.functionName, usageIndex + 1);
336
+ return {
337
+ ...frame,
338
+ fileName: resolved.fileName,
339
+ lineNumber: resolved.lineNumber,
340
+ columnNumber: resolved.columnNumber
341
+ };
342
+ }
343
+ function getSourceFromDebugStack(fiber) {
344
+ const rawStack = fiber?._debugStack?.stack;
345
+ if (typeof rawStack !== "string" || rawStack.length === 0) {
346
+ return null;
347
+ }
348
+ const formattedStack = formatOwnerDebugStack(rawStack);
349
+ if (!formattedStack) return null;
350
+ const stackFrames = parseDebugStack(formattedStack);
351
+ const functionNameToRscFrames = buildFunctionNameToRscFramesMap(fiber);
352
+ const functionNameToUsageIndex = /* @__PURE__ */ new Map();
353
+ for (const frame of stackFrames) {
354
+ const maybeEnriched = frame.isServer ? enrichServerFrame(frame, functionNameToRscFrames, functionNameToUsageIndex) : frame;
355
+ if (!maybeEnriched.fileName) continue;
356
+ const normalizedFileName = normalizeStackFileName(maybeEnriched.fileName);
357
+ if (!normalizedFileName) continue;
358
+ if (isSourceStackFile(normalizedFileName)) {
359
+ return {
360
+ fileName: normalizedFileName,
361
+ lineNumber: maybeEnriched.lineNumber,
362
+ columnNumber: maybeEnriched.columnNumber
363
+ };
364
+ }
365
+ }
366
+ return null;
367
+ }
368
+
120
369
  // src/utils/react-fiber.ts
121
370
  function getFiberForElement(element) {
122
371
  if (typeof window !== "undefined") {
@@ -144,6 +393,8 @@ function getSourceFromFiber(fiber) {
144
393
  if (pending?.fileName) return pending;
145
394
  const memo = fiber?.memoizedProps?.__source;
146
395
  if (memo?.fileName) return memo;
396
+ const fromDebugStack = getSourceFromDebugStack(fiber);
397
+ if (fromDebugStack?.fileName) return fromDebugStack;
147
398
  return null;
148
399
  }
149
400
  function buildFrame(fiber) {
@@ -1567,516 +1818,164 @@ function htmlChildren(el) {
1567
1818
  function findFlexAncestor(element, boundary) {
1568
1819
  let current = element;
1569
1820
  while (current && current !== document.body) {
1570
- const parent = current.parentElement;
1571
- if (!parent) break;
1572
- const display = getComputedStyle(parent).display;
1573
- if (display === "flex" || display === "inline-flex") {
1574
- return { flexParent: parent, child: current };
1575
- }
1576
- if (boundary && parent === boundary) break;
1577
- current = parent;
1578
- }
1579
- return null;
1580
- }
1581
- function computeHoverHighlight(elementUnder, selectedElement) {
1582
- if (!elementUnder || elementUnder === document.body || elementUnder === document.documentElement || elementUnder.closest("[data-direct-edit]") || elementUnder.closest("[data-direct-edit-host]") || elementUnder === selectedElement) {
1583
- return null;
1584
- }
1585
- const boundary = selectedElement?.contains(elementUnder) ? selectedElement : null;
1586
- const ownDisplay = getComputedStyle(elementUnder).display;
1587
- if (ownDisplay === "flex" || ownDisplay === "inline-flex") {
1588
- return { flexContainer: elementUnder, children: htmlChildren(elementUnder) };
1589
- }
1590
- const found = findFlexAncestor(elementUnder, boundary);
1591
- if (found) {
1592
- return { flexContainer: found.flexParent, children: htmlChildren(found.flexParent) };
1593
- }
1594
- return { flexContainer: elementUnder, children: [] };
1595
- }
1596
- function resolveElementTarget(elementUnder, selectedElement) {
1597
- const boundary = selectedElement?.contains(elementUnder) ? selectedElement : null;
1598
- const found = findFlexAncestor(elementUnder, boundary);
1599
- if (found && found.flexParent === boundary) return elementUnder;
1600
- return found?.child ?? elementUnder;
1601
- }
1602
- function findChildAtPoint(parent, clientX, clientY) {
1603
- const children = htmlChildren(parent);
1604
- if (children.length === 0) return null;
1605
- const hit = children.find((child) => {
1606
- const r = child.getBoundingClientRect();
1607
- return clientX >= r.left && clientX <= r.right && clientY >= r.top && clientY <= r.bottom;
1608
- });
1609
- if (hit) return hit;
1610
- if (children.length === 1 && !hasDirectNonWhitespaceText(parent)) return children[0];
1611
- return null;
1612
- }
1613
- function elementFromPointWithoutOverlays(x, y) {
1614
- const host = document.querySelector("[data-direct-edit-host]");
1615
- if (host) host.style.display = "none";
1616
- const el = document.elementFromPoint(x, y);
1617
- if (host) host.style.display = "";
1618
- return el;
1619
- }
1620
- function isLayoutContainer(element) {
1621
- const display = window.getComputedStyle(element).display;
1622
- return display === "flex" || display === "inline-flex" || display === "grid" || display === "inline-grid";
1623
- }
1624
- function isBlockContainer(element) {
1625
- const display = window.getComputedStyle(element).display;
1626
- return display === "block" || display === "flow-root" || display === "inline-block" || display === "list-item";
1627
- }
1628
- function skipElement(el, exclude) {
1629
- if (exclude && exclude.contains(el)) return true;
1630
- if (el === document.body || el === document.documentElement) return true;
1631
- if (el.closest("[data-direct-edit]") || el.closest("[data-direct-edit-host]")) return true;
1632
- return false;
1633
- }
1634
- function findContainerViaTraversal(x, y, exclude) {
1635
- const el = elementFromPointWithoutOverlays(x, y);
1636
- if (!el) return null;
1637
- let current = el;
1638
- while (current) {
1639
- if (!skipElement(current, exclude)) {
1640
- if (isLayoutContainer(current) || isBlockContainer(current)) return current;
1641
- }
1642
- current = current.parentElement;
1643
- }
1644
- return null;
1645
- }
1646
- function findContainerAtPoint(x, y, exclude, preferredParent) {
1647
- const host = document.querySelector("[data-direct-edit-host]");
1648
- if (host) host.style.display = "none";
1649
- const elements = document.elementsFromPoint(x, y);
1650
- if (host) host.style.display = "";
1651
- for (const el of elements) {
1652
- if (skipElement(el, exclude)) continue;
1653
- if (isLayoutContainer(el) || isBlockContainer(el)) return el;
1654
- }
1655
- if (preferredParent && (isLayoutContainer(preferredParent) || isBlockContainer(preferredParent))) {
1656
- for (const el of elements) {
1657
- if (el === preferredParent) return preferredParent;
1658
- }
1659
- }
1660
- return findContainerViaTraversal(x, y, exclude);
1661
- }
1662
- function findLayoutContainerAtPoint(x, y, exclude, preferredParent) {
1663
- const host = document.querySelector("[data-direct-edit-host]");
1664
- if (host) host.style.display = "none";
1665
- const elements = document.elementsFromPoint(x, y);
1666
- if (host) host.style.display = "";
1667
- for (const el of elements) {
1668
- if (skipElement(el, exclude)) continue;
1669
- if (isLayoutContainer(el)) return el;
1670
- }
1671
- if (preferredParent && isLayoutContainer(preferredParent)) {
1672
- for (const el of elements) {
1673
- if (el === preferredParent) return preferredParent;
1674
- }
1675
- }
1676
- return null;
1677
- }
1678
- function calculateDropPosition(container, pointerX, pointerY, draggedElement) {
1679
- const { axis, reversed: isReversed } = detectChildrenDirection(container, draggedElement);
1680
- const isHorizontal = axis === "horizontal";
1681
- const children = Array.from(container.children).filter(
1682
- (child) => child !== draggedElement && child instanceof HTMLElement
1683
- );
1684
- if (children.length === 0) {
1685
- const containerRect2 = container.getBoundingClientRect();
1686
- return {
1687
- insertBefore: null,
1688
- indicator: {
1689
- x: containerRect2.left + 4,
1690
- y: containerRect2.top + 4,
1691
- width: isHorizontal ? 1 : containerRect2.width - 8,
1692
- height: isHorizontal ? containerRect2.height - 8 : 1
1693
- }
1694
- };
1695
- }
1696
- const containerRect = container.getBoundingClientRect();
1697
- let insertBefore = null;
1698
- let indicatorPosition = 0;
1699
- for (let i = 0; i < children.length; i++) {
1700
- const child = children[i];
1701
- const rect = child.getBoundingClientRect();
1702
- const midpoint = isHorizontal ? rect.left + rect.width / 2 : rect.top + rect.height / 2;
1703
- const pointer = isHorizontal ? pointerX : pointerY;
1704
- const beforeMidpoint = isReversed ? pointer > midpoint : pointer < midpoint;
1705
- if (beforeMidpoint) {
1706
- insertBefore = child;
1707
- indicatorPosition = isHorizontal ? rect.left : rect.top;
1708
- break;
1709
- }
1710
- }
1711
- if (!insertBefore) {
1712
- const lastChild = children[children.length - 1];
1713
- const lastRect = lastChild.getBoundingClientRect();
1714
- indicatorPosition = isHorizontal ? lastRect.right : lastRect.bottom;
1715
- }
1716
- const indicator = isHorizontal ? {
1717
- x: indicatorPosition,
1718
- y: containerRect.top + 4,
1719
- width: 2,
1720
- height: containerRect.height - 8
1721
- } : {
1722
- x: containerRect.left + 4,
1723
- y: indicatorPosition,
1724
- width: containerRect.width - 8,
1725
- height: 2
1726
- };
1727
- return { insertBefore, indicator };
1728
- }
1729
- function getFiberForElement2(element) {
1730
- if (typeof window !== "undefined") {
1731
- const devtools = window.__DIRECT_EDIT_DEVTOOLS__;
1732
- if (devtools?.getFiberForElement) {
1733
- const fiber = devtools.getFiberForElement(element);
1734
- if (fiber) return fiber;
1735
- }
1736
- }
1737
- const fiberKey = Object.keys(element).find(
1738
- (key) => key.startsWith("__reactFiber$") || key.startsWith("__reactInternalInstance$")
1739
- );
1740
- if (!fiberKey) return null;
1741
- return element[fiberKey] || null;
1742
- }
1743
- var STACK_SOURCE_FILE_EXTENSION_REGEX = /\.(jsx|tsx|ts|js)$/;
1744
- var STACK_BUNDLED_FILE_PATTERN_REGEX = /(\.min|bundle|chunk|vendor|vendors|runtime|polyfill|polyfills)\.(js|mjs|cjs)$|(chunk|bundle|vendor|vendors|runtime|polyfill|polyfills|framework|app|main|index)[-_.][A-Za-z0-9_-]{4,}\.(js|mjs|cjs)$|[\da-f]{8,}\.(js|mjs|cjs)$|[-_.][\da-f]{20,}\.(js|mjs|cjs)$|\/dist\/|\/build\/|\/.next\/|\/out\/|\/node_modules\/|\.webpack\.|\.vite\.|\.turbopack\./i;
1745
- var FIREFOX_SAFARI_STACK_REGEXP = /(^|@)\S+:\d+/;
1746
- var SAFARI_NATIVE_CODE_REGEXP = /^(eval@)?(\[native code\])?$/;
1747
- var SERVER_FRAME_MARKER = "(at Server)";
1748
- var STACK_INTERNAL_SCHEME_PREFIXES = [
1749
- "rsc://",
1750
- "about://React/",
1751
- "React/Server/",
1752
- "file:///",
1753
- "webpack://",
1754
- "webpack-internal://",
1755
- "node:",
1756
- "turbopack://",
1757
- "/app-pages-browser/"
1758
- ];
1759
- function formatOwnerDebugStack(stack) {
1760
- if (!stack) return "";
1761
- const lines = stack.split("\n");
1762
- const filtered = [];
1763
- for (const line of lines) {
1764
- const trimmed = line.trim();
1765
- if (!trimmed) continue;
1766
- if (trimmed === "Error: react-stack-top-frame") continue;
1767
- if (trimmed.includes("react_stack_bottom_frame") || trimmed.includes("react-stack-bottom-frame")) {
1768
- continue;
1769
- }
1770
- filtered.push(line);
1771
- }
1772
- if (filtered.length > 0 && filtered[0].includes("fakeJSXCallSite")) {
1773
- filtered.shift();
1774
- }
1775
- return filtered.join("\n");
1776
- }
1777
- function extractStackLocation(urlLike) {
1778
- if (!urlLike.includes(":")) return [urlLike, void 0, void 0];
1779
- const isWrappedLocation = urlLike.startsWith("(") && /:\d+\)$/.test(urlLike);
1780
- const sanitizedResult = isWrappedLocation ? urlLike.slice(1, -1) : urlLike;
1781
- const parts = /(.+?)(?::(\d+))?(?::(\d+))?$/.exec(sanitizedResult);
1782
- if (!parts) return [sanitizedResult, void 0, void 0];
1783
- return [
1784
- parts[1],
1785
- parts[2] !== void 0 ? Number(parts[2]) : void 0,
1786
- parts[3] !== void 0 ? Number(parts[3]) : void 0
1787
- ];
1788
- }
1789
- function parseV8StackLine(line) {
1790
- let currentLine = line;
1791
- if (currentLine.includes("(eval ")) {
1792
- currentLine = currentLine.replace(/eval code/g, "eval").replace(/(\(eval at [^()]*)|(,.*$)/g, "");
1793
- }
1794
- let sanitizedLine = currentLine.replace(/^\s+/, "").replace(/\(eval code/g, "(").replace(/^.*?\s+/, "");
1795
- const locationMatch = sanitizedLine.match(/ (\(.+\)$)/);
1796
- if (locationMatch) {
1797
- sanitizedLine = sanitizedLine.replace(locationMatch[0], "");
1798
- }
1799
- const [fileName, lineNumber, columnNumber] = extractStackLocation(
1800
- locationMatch ? locationMatch[1] : sanitizedLine
1801
- );
1802
- const functionName = locationMatch && sanitizedLine ? sanitizedLine : void 0;
1803
- if (fileName === "eval" || fileName === "<anonymous>") {
1804
- return {
1805
- functionName
1806
- };
1807
- }
1808
- return {
1809
- functionName,
1810
- fileName,
1811
- lineNumber,
1812
- columnNumber,
1813
- source: currentLine,
1814
- isServer: currentLine.includes(SERVER_FRAME_MARKER) || fileName.startsWith("rsc://")
1815
- };
1816
- }
1817
- function parseFFOrSafariStackLine(line) {
1818
- let currentLine = line;
1819
- if (currentLine.includes(" > eval")) {
1820
- currentLine = currentLine.replace(
1821
- / line (\d+)(?: > eval line \d+)* > eval:\d+:\d+/g,
1822
- ":$1"
1823
- );
1824
- }
1825
- const trimmed = currentLine.trim();
1826
- if (!trimmed || SAFARI_NATIVE_CODE_REGEXP.test(trimmed)) {
1827
- return null;
1828
- }
1829
- if (!trimmed.includes("@") && !trimmed.includes(":")) {
1830
- return {
1831
- functionName: trimmed,
1832
- source: currentLine,
1833
- isServer: trimmed.includes(SERVER_FRAME_MARKER)
1834
- };
1835
- }
1836
- const atIndex = trimmed.lastIndexOf("@");
1837
- if (atIndex === -1) {
1838
- return null;
1839
- }
1840
- const maybeFunctionName = trimmed.slice(0, atIndex);
1841
- const location = trimmed.slice(atIndex + 1);
1842
- const [fileName, lineNumber, columnNumber] = extractStackLocation(location);
1843
- return {
1844
- functionName: maybeFunctionName || void 0,
1845
- fileName,
1846
- lineNumber,
1847
- columnNumber,
1848
- source: currentLine,
1849
- isServer: currentLine.includes(SERVER_FRAME_MARKER) || fileName.startsWith("rsc://")
1850
- };
1851
- }
1852
- function parseInStackLine(line) {
1853
- const functionName = line.replace(/^\s*in\s+/, "").replace(/\s*\(at .*\)$/, "").trim();
1854
- if (!functionName) return null;
1855
- return {
1856
- functionName,
1857
- source: line,
1858
- isServer: line.includes(SERVER_FRAME_MARKER)
1859
- };
1860
- }
1861
- function parseDebugStack(stack) {
1862
- const frames = [];
1863
- for (const rawLine of stack.split("\n")) {
1864
- if (FIREFOX_SAFARI_STACK_REGEXP.test(rawLine)) {
1865
- const parsed = parseFFOrSafariStackLine(rawLine);
1866
- if (parsed) frames.push(parsed);
1867
- continue;
1868
- }
1869
- if (/^\s*at\s+/.test(rawLine)) {
1870
- const parsed = parseV8StackLine(rawLine);
1871
- if (parsed) frames.push(parsed);
1872
- continue;
1873
- }
1874
- if (/^\s*in\s+/.test(rawLine)) {
1875
- const parsed = parseInStackLine(rawLine);
1876
- if (parsed) frames.push(parsed);
1877
- }
1878
- }
1879
- return frames;
1880
- }
1881
- function normalizeStackFileName(fileName) {
1882
- if (!fileName) return "";
1883
- let normalized = fileName;
1884
- const isHttpUrl = normalized.startsWith("http://") || normalized.startsWith("https://");
1885
- if (isHttpUrl) {
1886
- try {
1887
- normalized = new URL(normalized).pathname;
1888
- } catch {
1889
- }
1890
- }
1891
- let didStripPrefix = true;
1892
- while (didStripPrefix) {
1893
- didStripPrefix = false;
1894
- for (const prefix of STACK_INTERNAL_SCHEME_PREFIXES) {
1895
- if (normalized.startsWith(prefix)) {
1896
- normalized = normalized.slice(prefix.length);
1897
- if (prefix === "file:///") {
1898
- normalized = `/${normalized.replace(/^\/+/, "")}`;
1899
- }
1900
- didStripPrefix = true;
1901
- break;
1902
- }
1903
- }
1904
- }
1905
- normalized = normalized.replace(/^\/\(app-pages-browser\)\//, "/").replace(/^\/\.\//, "/").replace(/^\.\//, "");
1906
- const queryIndex = normalized.indexOf("?");
1907
- if (queryIndex !== -1) {
1908
- normalized = normalized.slice(0, queryIndex);
1909
- }
1910
- return normalized;
1911
- }
1912
- function isSourceStackFile(fileName) {
1913
- const normalizedFileName = normalizeStackFileName(fileName);
1914
- if (!normalizedFileName) return false;
1915
- if (!STACK_SOURCE_FILE_EXTENSION_REGEX.test(normalizedFileName)) return false;
1916
- return !STACK_BUNDLED_FILE_PATTERN_REGEX.test(normalizedFileName);
1917
- }
1918
- function buildFunctionNameToRscFramesMap(fiber) {
1919
- const functionNameToRscFrames = /* @__PURE__ */ new Map();
1920
- const visited = /* @__PURE__ */ new Set();
1921
- let current = fiber;
1922
- while (current && !visited.has(current)) {
1923
- visited.add(current);
1924
- const rawStack = current?._debugStack?.stack;
1925
- const stack = typeof rawStack === "string" ? formatOwnerDebugStack(rawStack) : "";
1926
- if (stack) {
1927
- const frames = parseDebugStack(stack);
1928
- for (const frame of frames) {
1929
- if (!frame.functionName || !frame.fileName) continue;
1930
- if (!frame.fileName.startsWith("rsc://")) continue;
1931
- const normalized = normalizeStackFileName(frame.fileName);
1932
- if (!normalized) continue;
1933
- const existing = functionNameToRscFrames.get(frame.functionName) ?? [];
1934
- const duplicate = existing.some(
1935
- (candidate) => candidate.fileName === normalized && candidate.lineNumber === frame.lineNumber && candidate.columnNumber === frame.columnNumber
1936
- );
1937
- if (!duplicate) {
1938
- existing.push({
1939
- fileName: normalized,
1940
- lineNumber: frame.lineNumber,
1941
- columnNumber: frame.columnNumber
1942
- });
1943
- functionNameToRscFrames.set(frame.functionName, existing);
1944
- }
1945
- }
1946
- }
1947
- current = current._debugOwner ?? current.return ?? null;
1948
- }
1949
- return functionNameToRscFrames;
1950
- }
1951
- function enrichServerFrame(frame, functionNameToRscFrames, functionNameToUsageIndex) {
1952
- if (!frame.functionName) return frame;
1953
- const available = functionNameToRscFrames.get(frame.functionName);
1954
- if (!available) return frame;
1955
- const usageIndex = functionNameToUsageIndex.get(frame.functionName) ?? 0;
1956
- const resolved = available[usageIndex % available.length];
1957
- functionNameToUsageIndex.set(frame.functionName, usageIndex + 1);
1958
- return {
1959
- ...frame,
1960
- fileName: resolved.fileName,
1961
- lineNumber: resolved.lineNumber,
1962
- columnNumber: resolved.columnNumber
1963
- };
1821
+ const parent = current.parentElement;
1822
+ if (!parent) break;
1823
+ const display = getComputedStyle(parent).display;
1824
+ if (display === "flex" || display === "inline-flex") {
1825
+ return { flexParent: parent, child: current };
1826
+ }
1827
+ if (boundary && parent === boundary) break;
1828
+ current = parent;
1829
+ }
1830
+ return null;
1964
1831
  }
1965
- function getSourceFromDebugStack(fiber) {
1966
- const rawStack = fiber?._debugStack?.stack;
1967
- if (typeof rawStack !== "string" || rawStack.length === 0) {
1832
+ function computeHoverHighlight(elementUnder, selectedElement) {
1833
+ if (!elementUnder || elementUnder === document.body || elementUnder === document.documentElement || elementUnder.closest("[data-direct-edit]") || elementUnder.closest("[data-direct-edit-host]") || elementUnder === selectedElement) {
1968
1834
  return null;
1969
1835
  }
1970
- const formattedStack = formatOwnerDebugStack(rawStack);
1971
- if (!formattedStack) return null;
1972
- const stackFrames = parseDebugStack(formattedStack);
1973
- const functionNameToRscFrames = buildFunctionNameToRscFramesMap(fiber);
1974
- const functionNameToUsageIndex = /* @__PURE__ */ new Map();
1975
- for (const frame of stackFrames) {
1976
- const maybeEnriched = frame.isServer ? enrichServerFrame(frame, functionNameToRscFrames, functionNameToUsageIndex) : frame;
1977
- if (!maybeEnriched.fileName) continue;
1978
- const normalizedFileName = normalizeStackFileName(maybeEnriched.fileName);
1979
- if (!normalizedFileName) continue;
1980
- if (isSourceStackFile(normalizedFileName)) {
1981
- return {
1982
- fileName: normalizedFileName,
1983
- lineNumber: maybeEnriched.lineNumber,
1984
- columnNumber: maybeEnriched.columnNumber
1985
- };
1986
- }
1836
+ const boundary = selectedElement?.contains(elementUnder) ? selectedElement : null;
1837
+ const ownDisplay = getComputedStyle(elementUnder).display;
1838
+ if (ownDisplay === "flex" || ownDisplay === "inline-flex") {
1839
+ return { flexContainer: elementUnder, children: htmlChildren(elementUnder) };
1987
1840
  }
1988
- return null;
1841
+ const found = findFlexAncestor(elementUnder, boundary);
1842
+ if (found) {
1843
+ return { flexContainer: found.flexParent, children: htmlChildren(found.flexParent) };
1844
+ }
1845
+ return { flexContainer: elementUnder, children: [] };
1989
1846
  }
1990
- function getSourceFromFiber2(fiber) {
1991
- const debugSource = fiber?._debugSource;
1992
- if (debugSource?.fileName) return debugSource;
1993
- const owner = fiber?._debugOwner;
1994
- const ownerPending = owner?.pendingProps?.__source;
1995
- if (ownerPending?.fileName) return ownerPending;
1996
- const ownerMemo = owner?.memoizedProps?.__source;
1997
- if (ownerMemo?.fileName) return ownerMemo;
1998
- const pending = fiber?.pendingProps?.__source;
1999
- if (pending?.fileName) return pending;
2000
- const memo = fiber?.memoizedProps?.__source;
2001
- if (memo?.fileName) return memo;
2002
- const fromDebugStack = getSourceFromDebugStack(fiber);
2003
- if (fromDebugStack?.fileName) return fromDebugStack;
1847
+ function resolveElementTarget(elementUnder, selectedElement) {
1848
+ const boundary = selectedElement?.contains(elementUnder) ? selectedElement : null;
1849
+ const found = findFlexAncestor(elementUnder, boundary);
1850
+ if (found && found.flexParent === boundary) return elementUnder;
1851
+ return found?.child ?? elementUnder;
1852
+ }
1853
+ function findChildAtPoint(parent, clientX, clientY) {
1854
+ const children = htmlChildren(parent);
1855
+ if (children.length === 0) return null;
1856
+ const hit = children.find((child) => {
1857
+ const r = child.getBoundingClientRect();
1858
+ return clientX >= r.left && clientX <= r.right && clientY >= r.top && clientY <= r.bottom;
1859
+ });
1860
+ if (hit) return hit;
1861
+ if (children.length === 1 && !hasDirectNonWhitespaceText(parent)) return children[0];
2004
1862
  return null;
2005
1863
  }
2006
- function buildFrame2(fiber) {
2007
- const type = fiber?.type;
2008
- if (typeof type !== "function" && typeof type !== "object") return null;
2009
- const name = type?.displayName || type?.name || null;
2010
- if (!name || name === "Fragment") return null;
2011
- const frame = { name };
2012
- const source = getSourceFromFiber2(fiber);
2013
- if (source?.fileName) {
2014
- frame.file = source.fileName;
2015
- if (typeof source.lineNumber === "number") {
2016
- frame.line = source.lineNumber;
2017
- }
2018
- if (typeof source.columnNumber === "number") {
2019
- frame.column = source.columnNumber;
1864
+ function elementFromPointWithoutOverlays(x, y) {
1865
+ const host = document.querySelector("[data-direct-edit-host]");
1866
+ if (host) host.style.display = "none";
1867
+ const el = document.elementFromPoint(x, y);
1868
+ if (host) host.style.display = "";
1869
+ return el;
1870
+ }
1871
+ function isLayoutContainer(element) {
1872
+ const display = window.getComputedStyle(element).display;
1873
+ return display === "flex" || display === "inline-flex" || display === "grid" || display === "inline-grid";
1874
+ }
1875
+ function isBlockContainer(element) {
1876
+ const display = window.getComputedStyle(element).display;
1877
+ return display === "block" || display === "flow-root" || display === "inline-block" || display === "list-item";
1878
+ }
1879
+ function skipElement(el, exclude) {
1880
+ if (exclude && exclude.contains(el)) return true;
1881
+ if (el === document.body || el === document.documentElement) return true;
1882
+ if (el.closest("[data-direct-edit]") || el.closest("[data-direct-edit-host]")) return true;
1883
+ return false;
1884
+ }
1885
+ function findContainerViaTraversal(x, y, exclude) {
1886
+ const el = elementFromPointWithoutOverlays(x, y);
1887
+ if (!el) return null;
1888
+ let current = el;
1889
+ while (current) {
1890
+ if (!skipElement(current, exclude)) {
1891
+ if (isLayoutContainer(current) || isBlockContainer(current)) return current;
2020
1892
  }
1893
+ current = current.parentElement;
2021
1894
  }
2022
- return frame;
1895
+ return null;
2023
1896
  }
2024
- function shouldIncludeFrame2(frame, lastFrame) {
2025
- if (!lastFrame) return true;
2026
- if (frame.name !== lastFrame.name) return true;
2027
- if (!lastFrame.file && frame.file) return true;
2028
- if (lastFrame.file && frame.file && lastFrame.line == null && frame.line != null) return true;
2029
- if (lastFrame.file && frame.file && lastFrame.line != null && frame.line != null && lastFrame.column == null && frame.column != null) {
2030
- return true;
1897
+ function findContainerAtPoint(x, y, exclude, preferredParent) {
1898
+ const host = document.querySelector("[data-direct-edit-host]");
1899
+ if (host) host.style.display = "none";
1900
+ const elements = document.elementsFromPoint(x, y);
1901
+ if (host) host.style.display = "";
1902
+ for (const el of elements) {
1903
+ if (skipElement(el, exclude)) continue;
1904
+ if (isLayoutContainer(el) || isBlockContainer(el)) return el;
2031
1905
  }
2032
- return false;
1906
+ if (preferredParent && (isLayoutContainer(preferredParent) || isBlockContainer(preferredParent))) {
1907
+ for (const el of elements) {
1908
+ if (el === preferredParent) return preferredParent;
1909
+ }
1910
+ }
1911
+ return findContainerViaTraversal(x, y, exclude);
2033
1912
  }
2034
- function getOwnerStack2(fiber) {
2035
- const frames = [];
2036
- let current = fiber;
2037
- let lastFrame = null;
2038
- let nearestComponentFiber = null;
2039
- while (current) {
2040
- const frame = buildFrame2(current);
2041
- if (frame && shouldIncludeFrame2(frame, lastFrame)) {
2042
- frames.push(frame);
2043
- lastFrame = frame;
2044
- if (!nearestComponentFiber) {
2045
- nearestComponentFiber = current;
2046
- }
1913
+ function findLayoutContainerAtPoint(x, y, exclude, preferredParent) {
1914
+ const host = document.querySelector("[data-direct-edit-host]");
1915
+ if (host) host.style.display = "none";
1916
+ const elements = document.elementsFromPoint(x, y);
1917
+ if (host) host.style.display = "";
1918
+ for (const el of elements) {
1919
+ if (skipElement(el, exclude)) continue;
1920
+ if (isLayoutContainer(el)) return el;
1921
+ }
1922
+ if (preferredParent && isLayoutContainer(preferredParent)) {
1923
+ for (const el of elements) {
1924
+ if (el === preferredParent) return preferredParent;
2047
1925
  }
2048
- current = current._debugOwner;
2049
1926
  }
2050
- return { frames, nearestComponentFiber };
1927
+ return null;
2051
1928
  }
2052
- function getRenderStack2(fiber) {
2053
- const frames = [];
2054
- let current = fiber;
2055
- let lastFrame = null;
2056
- let nearestComponentFiber = null;
2057
- while (current) {
2058
- const frame = buildFrame2(current);
2059
- if (frame && shouldIncludeFrame2(frame, lastFrame)) {
2060
- frames.push(frame);
2061
- lastFrame = frame;
2062
- if (!nearestComponentFiber) {
2063
- nearestComponentFiber = current;
1929
+ function calculateDropPosition(container, pointerX, pointerY, draggedElement) {
1930
+ const { axis, reversed: isReversed } = detectChildrenDirection(container, draggedElement);
1931
+ const isHorizontal = axis === "horizontal";
1932
+ const children = Array.from(container.children).filter(
1933
+ (child) => child !== draggedElement && child instanceof HTMLElement
1934
+ );
1935
+ if (children.length === 0) {
1936
+ const containerRect2 = container.getBoundingClientRect();
1937
+ return {
1938
+ insertBefore: null,
1939
+ indicator: {
1940
+ x: containerRect2.left + 4,
1941
+ y: containerRect2.top + 4,
1942
+ width: isHorizontal ? 1 : containerRect2.width - 8,
1943
+ height: isHorizontal ? containerRect2.height - 8 : 1
2064
1944
  }
1945
+ };
1946
+ }
1947
+ const containerRect = container.getBoundingClientRect();
1948
+ let insertBefore = null;
1949
+ let indicatorPosition = 0;
1950
+ for (let i = 0; i < children.length; i++) {
1951
+ const child = children[i];
1952
+ const rect = child.getBoundingClientRect();
1953
+ const midpoint = isHorizontal ? rect.left + rect.width / 2 : rect.top + rect.height / 2;
1954
+ const pointer = isHorizontal ? pointerX : pointerY;
1955
+ const beforeMidpoint = isReversed ? pointer > midpoint : pointer < midpoint;
1956
+ if (beforeMidpoint) {
1957
+ insertBefore = child;
1958
+ indicatorPosition = isHorizontal ? rect.left : rect.top;
1959
+ break;
2065
1960
  }
2066
- current = current.return;
2067
1961
  }
2068
- return { frames, nearestComponentFiber };
2069
- }
2070
- function getReactComponentInfo2(element) {
2071
- const fiber = getFiberForElement2(element);
2072
- if (!fiber) return { frames: [], nearestComponentFiber: null };
2073
- const elementSource = getSourceFromFiber2(fiber);
2074
- const elementSourceFile = elementSource?.fileName || void 0;
2075
- const ownerResult = getOwnerStack2(fiber);
2076
- if (ownerResult.frames.length > 0) {
2077
- return { ...ownerResult, elementSourceFile };
1962
+ if (!insertBefore) {
1963
+ const lastChild = children[children.length - 1];
1964
+ const lastRect = lastChild.getBoundingClientRect();
1965
+ indicatorPosition = isHorizontal ? lastRect.right : lastRect.bottom;
2078
1966
  }
2079
- return { ...getRenderStack2(fiber), elementSourceFile };
1967
+ const indicator = isHorizontal ? {
1968
+ x: indicatorPosition,
1969
+ y: containerRect.top + 4,
1970
+ width: 2,
1971
+ height: containerRect.height - 8
1972
+ } : {
1973
+ x: containerRect.left + 4,
1974
+ y: indicatorPosition,
1975
+ width: containerRect.width - 8,
1976
+ height: 2
1977
+ };
1978
+ return { insertBefore, indicator };
2080
1979
  }
2081
1980
  function getElementDisplayName(element) {
2082
1981
  const tag = element.tagName.toLowerCase();
@@ -2396,10 +2295,10 @@ function getElementSource(element) {
2396
2295
  const domSource = parseDomSource(element);
2397
2296
  if (domSource) return domSource;
2398
2297
  const seenFibers = /* @__PURE__ */ new Set();
2399
- let fiber = getFiberForElement2(element);
2298
+ let fiber = getFiberForElement(element);
2400
2299
  while (fiber && !seenFibers.has(fiber)) {
2401
2300
  seenFibers.add(fiber);
2402
- const fiberSource = getSourceFromFiber2(fiber);
2301
+ const fiberSource = getSourceFromFiber(fiber);
2403
2302
  if (fiberSource?.fileName) {
2404
2303
  return {
2405
2304
  file: fiberSource.fileName,
@@ -2414,7 +2313,7 @@ function getElementSource(element) {
2414
2313
  function getElementLocator(element) {
2415
2314
  const elementInfo = getElementInfo(element);
2416
2315
  const domSource = getElementSource(element);
2417
- const { frames, nearestComponentFiber, elementSourceFile } = getReactComponentInfo2(element);
2316
+ const { frames, nearestComponentFiber, elementSourceFile } = getReactComponentInfo(element);
2418
2317
  const componentName = nearestComponentFiber?.type?.displayName || nearestComponentFiber?.type?.name || void 0;
2419
2318
  const authoredProps = nearestComponentFiber ? getComponentProps(nearestComponentFiber) : void 0;
2420
2319
  const classification = classifyComponentFiber(nearestComponentFiber, frames, elementSourceFile);
@@ -4475,6 +4374,49 @@ function useSessionManager({
4475
4374
  pushUndo: false
4476
4375
  });
4477
4376
  }, [applySelection, buildSelectionSnapshot, getSanitizedSelection, pushUndo, saveCurrentToSession, stateRef]);
4377
+ const deleteSelection = React3.useCallback(() => {
4378
+ const selected = getSanitizedSelection(stateRef.current.selectedElements);
4379
+ if (selected.length === 0 || !stateRef.current.editModeActive) return;
4380
+ if (selected.some((el) => el === document.body || !el.parentElement)) return;
4381
+ saveCurrentToSession();
4382
+ const restoreSelection = buildSelectionSnapshot();
4383
+ const snapshots = selected.map((el) => ({
4384
+ element: el,
4385
+ parent: el.parentElement,
4386
+ nextSibling: el.nextSibling
4387
+ }));
4388
+ const sessionSnapshots = /* @__PURE__ */ new Map();
4389
+ for (const el of selected) {
4390
+ const edit = sessionEditsRef.current.get(el);
4391
+ if (edit) sessionSnapshots.set(el, edit);
4392
+ sessionEditsRef.current.delete(el);
4393
+ }
4394
+ syncSessionItemCount();
4395
+ for (const { element } of snapshots) {
4396
+ if (element.isConnected) element.remove();
4397
+ }
4398
+ pushUndo({
4399
+ type: "structure",
4400
+ restoreSelection,
4401
+ undo: () => {
4402
+ for (let i = snapshots.length - 1; i >= 0; i--) {
4403
+ const { element, parent, nextSibling } = snapshots[i];
4404
+ if (!element.isConnected && parent.isConnected) {
4405
+ if (nextSibling && nextSibling.parentNode === parent) {
4406
+ parent.insertBefore(element, nextSibling);
4407
+ } else {
4408
+ parent.appendChild(element);
4409
+ }
4410
+ }
4411
+ }
4412
+ for (const [el, edit] of sessionSnapshots) {
4413
+ sessionEditsRef.current.set(el, edit);
4414
+ }
4415
+ syncSessionItemCount();
4416
+ }
4417
+ });
4418
+ applySelection([], { primaryElement: null, pushUndo: false });
4419
+ }, [applySelection, buildSelectionSnapshot, getSanitizedSelection, pushUndo, saveCurrentToSession, stateRef, syncSessionItemCount]);
4478
4420
  const resetToOriginal = React3.useCallback(() => {
4479
4421
  const current = stateRef.current;
4480
4422
  const el = current.selectedElement;
@@ -5011,6 +4953,7 @@ ${exportMarkdown}`);
5011
4953
  selectChild,
5012
4954
  insertElement,
5013
4955
  groupSelection,
4956
+ deleteSelection,
5014
4957
  resetToOriginal,
5015
4958
  undo,
5016
4959
  handleMoveComplete,
@@ -5904,6 +5847,7 @@ function useKeyboardShortcuts({
5904
5847
  closePanel,
5905
5848
  clearSelection,
5906
5849
  groupSelection,
5850
+ deleteSelection,
5907
5851
  insertElement,
5908
5852
  setState,
5909
5853
  toggleCanvas,
@@ -5991,6 +5935,13 @@ function useKeyboardShortcuts({
5991
5935
  return;
5992
5936
  }
5993
5937
  }
5938
+ if ((e.key === "Backspace" || e.key === "Delete") && s.editModeActive && !s.textEditingElement) {
5939
+ if (!isInputFocused() && s.selectedElements.length > 0) {
5940
+ e.preventDefault();
5941
+ deleteSelection();
5942
+ return;
5943
+ }
5944
+ }
5994
5945
  if (e.key === "Enter" && s.editModeActive && !s.textEditingElement && s.selectedElement) {
5995
5946
  if (!isInputFocused() && isTextElement2(s.selectedElement)) {
5996
5947
  e.preventDefault();
@@ -6023,7 +5974,7 @@ function useKeyboardShortcuts({
6023
5974
  }
6024
5975
  window.addEventListener("keydown", handleKeyDown);
6025
5976
  return () => window.removeEventListener("keydown", handleKeyDown);
6026
- }, [clearSelection, closePanel, commitTextEditing, fitCanvasToViewport, groupSelection, insertElement, setCanvasZoom, setState, startTextEditing, toggleCanvas, toggleEditMode, toggleFlexLayout, undo, usesMetaForUndo, zoomCanvasTo100]);
5977
+ }, [clearSelection, closePanel, commitTextEditing, deleteSelection, fitCanvasToViewport, groupSelection, insertElement, setCanvasZoom, setState, startTextEditing, toggleCanvas, toggleEditMode, toggleFlexLayout, undo, usesMetaForUndo, zoomCanvasTo100]);
6027
5978
  }
6028
5979
 
6029
5980
  // src/use-canvas.ts
@@ -6673,6 +6624,7 @@ function DirectEditProvider({ children }) {
6673
6624
  removeSessionEdit,
6674
6625
  clearSessionEdits,
6675
6626
  groupSelection,
6627
+ deleteSelection,
6676
6628
  insertElement
6677
6629
  } = useSessionManager({
6678
6630
  stateRef,
@@ -6901,6 +6853,7 @@ function DirectEditProvider({ children }) {
6901
6853
  setState,
6902
6854
  clearSelection,
6903
6855
  groupSelection,
6856
+ deleteSelection,
6904
6857
  insertElement,
6905
6858
  toggleCanvas: toggleCanvasWithPreference,
6906
6859
  setCanvasZoom,
@@ -6968,6 +6921,7 @@ function DirectEditProvider({ children }) {
6968
6921
  startTextEditing,
6969
6922
  commitTextEditing,
6970
6923
  groupSelection,
6924
+ deleteSelection,
6971
6925
  insertElement,
6972
6926
  toggleCanvas: toggleCanvasWithPreference,
6973
6927
  setCanvasZoom,
@@ -7020,6 +6974,7 @@ function DirectEditProvider({ children }) {
7020
6974
  startTextEditing,
7021
6975
  commitTextEditing,
7022
6976
  groupSelection,
6977
+ deleteSelection,
7023
6978
  insertElement,
7024
6979
  toggleCanvasWithPreference,
7025
6980
  setCanvasZoom,
@@ -7643,6 +7598,8 @@ function useMove({ onMoveComplete }) {
7643
7598
  React12.useEffect(() => {
7644
7599
  if (!dragState.isDragging) return;
7645
7600
  function handlePointerMove(e) {
7601
+ e.stopPropagation();
7602
+ e.preventDefault();
7646
7603
  const current = dragStateRef.current;
7647
7604
  const { draggedElement, dragOffset, originalParent } = current;
7648
7605
  setDragState((prev) => ({
@@ -7730,12 +7687,17 @@ function useMove({ onMoveComplete }) {
7730
7687
  clearReorderPreview();
7731
7688
  }
7732
7689
  }
7733
- function handlePointerUp() {
7690
+ function handlePointerUp(e) {
7691
+ e.stopPropagation();
7734
7692
  completeDrag();
7735
7693
  }
7736
- function handlePointerCancel() {
7694
+ function handlePointerCancel(e) {
7695
+ e.stopPropagation();
7737
7696
  cancelDrag();
7738
7697
  }
7698
+ function blockMouseEvent(e) {
7699
+ e.stopPropagation();
7700
+ }
7739
7701
  function handleKeyDown(e) {
7740
7702
  if (e.key === "Escape") {
7741
7703
  cancelDrag();
@@ -7744,15 +7706,19 @@ function useMove({ onMoveComplete }) {
7744
7706
  function handleBlur() {
7745
7707
  cancelDrag();
7746
7708
  }
7747
- window.addEventListener("pointermove", handlePointerMove);
7748
- window.addEventListener("pointerup", handlePointerUp);
7749
- window.addEventListener("pointercancel", handlePointerCancel);
7709
+ window.addEventListener("pointermove", handlePointerMove, true);
7710
+ window.addEventListener("pointerup", handlePointerUp, true);
7711
+ window.addEventListener("pointercancel", handlePointerCancel, true);
7712
+ window.addEventListener("mousemove", blockMouseEvent, true);
7713
+ window.addEventListener("mouseup", blockMouseEvent, true);
7750
7714
  window.addEventListener("keydown", handleKeyDown);
7751
7715
  window.addEventListener("blur", handleBlur);
7752
7716
  return () => {
7753
- window.removeEventListener("pointermove", handlePointerMove);
7754
- window.removeEventListener("pointerup", handlePointerUp);
7755
- window.removeEventListener("pointercancel", handlePointerCancel);
7717
+ window.removeEventListener("pointermove", handlePointerMove, true);
7718
+ window.removeEventListener("pointerup", handlePointerUp, true);
7719
+ window.removeEventListener("pointercancel", handlePointerCancel, true);
7720
+ window.removeEventListener("mousemove", blockMouseEvent, true);
7721
+ window.removeEventListener("mouseup", blockMouseEvent, true);
7756
7722
  window.removeEventListener("keydown", handleKeyDown);
7757
7723
  window.removeEventListener("blur", handleBlur);
7758
7724
  };
@@ -8534,7 +8500,7 @@ function SelectedCommentComposer({
8534
8500
  React17.useLayoutEffect(() => {
8535
8501
  updatePosition();
8536
8502
  }, [text, updatePosition]);
8537
- React17.useEffect(() => {
8503
+ const handleComposerClick = React17.useCallback(() => {
8538
8504
  inputRef.current?.focus();
8539
8505
  }, []);
8540
8506
  React17.useEffect(() => {
@@ -8585,7 +8551,10 @@ function SelectedCommentComposer({
8585
8551
  width: position.width,
8586
8552
  pointerEvents: "auto"
8587
8553
  },
8588
- onClick: (e) => e.stopPropagation(),
8554
+ onClick: (e) => {
8555
+ e.stopPropagation();
8556
+ handleComposerClick();
8557
+ },
8589
8558
  children: [
8590
8559
  /* @__PURE__ */ jsx7(
8591
8560
  "textarea",
@@ -12883,7 +12852,8 @@ function DirectEditPanelContent() {
12883
12852
  sendCommentToAgent: sendCommentToAgent2,
12884
12853
  setActiveCommentId,
12885
12854
  startTextEditing,
12886
- toggleEditMode
12855
+ toggleEditMode,
12856
+ deleteSelection
12887
12857
  } = useDirectEditActions();
12888
12858
  const {
12889
12859
  position,