react-grab 0.0.14 → 0.0.15
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.global.js +284 -146
- package/package.json +1 -1
package/dist/index.global.js
CHANGED
|
@@ -129,6 +129,7 @@ var ReactGrab = (function (exports) {
|
|
|
129
129
|
var watchKeyHeldFor = (key, duration, onHeld) => {
|
|
130
130
|
let timeoutId = null;
|
|
131
131
|
let unsubscribe = null;
|
|
132
|
+
const watchStartTime = Date.now();
|
|
132
133
|
const cleanup = () => {
|
|
133
134
|
if (timeoutId !== null) {
|
|
134
135
|
clearTimeout(timeoutId);
|
|
@@ -153,29 +154,9 @@ var ReactGrab = (function (exports) {
|
|
|
153
154
|
}
|
|
154
155
|
return checkSingleKeyPressed(key, pressedKeys);
|
|
155
156
|
};
|
|
156
|
-
const getKeyFromTimestamps = (keyToFind, timestamps) => {
|
|
157
|
-
if (keyToFind.length === 1) {
|
|
158
|
-
return timestamps.get(keyToFind.toLowerCase()) || timestamps.get(keyToFind.toUpperCase());
|
|
159
|
-
}
|
|
160
|
-
return timestamps.get(keyToFind);
|
|
161
|
-
};
|
|
162
|
-
const getEarliestPressTime = (timestamps) => {
|
|
163
|
-
const keysToInspect = Array.isArray(key) ? key : [key];
|
|
164
|
-
let earliest;
|
|
165
|
-
for (const keyFromCombo of keysToInspect) {
|
|
166
|
-
const timestamp = getKeyFromTimestamps(keyFromCombo, timestamps);
|
|
167
|
-
if (timestamp === void 0) {
|
|
168
|
-
return void 0;
|
|
169
|
-
}
|
|
170
|
-
if (earliest === void 0 || timestamp < earliest) {
|
|
171
|
-
earliest = timestamp;
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
return earliest;
|
|
175
|
-
};
|
|
176
157
|
const scheduleCallback = () => {
|
|
177
158
|
const state = libStore.getState();
|
|
178
|
-
const {
|
|
159
|
+
const { pressedKeys } = state;
|
|
179
160
|
if (!checkAllKeysPressed(pressedKeys)) {
|
|
180
161
|
if (timeoutId !== null) {
|
|
181
162
|
clearTimeout(timeoutId);
|
|
@@ -183,15 +164,7 @@ var ReactGrab = (function (exports) {
|
|
|
183
164
|
}
|
|
184
165
|
return;
|
|
185
166
|
}
|
|
186
|
-
const
|
|
187
|
-
if (earliestPressTime === void 0) {
|
|
188
|
-
if (timeoutId !== null) {
|
|
189
|
-
clearTimeout(timeoutId);
|
|
190
|
-
timeoutId = null;
|
|
191
|
-
}
|
|
192
|
-
return;
|
|
193
|
-
}
|
|
194
|
-
const elapsed = Date.now() - earliestPressTime;
|
|
167
|
+
const elapsed = Date.now() - watchStartTime;
|
|
195
168
|
const remaining = duration - elapsed;
|
|
196
169
|
if (remaining <= 0) {
|
|
197
170
|
onHeld();
|
|
@@ -2469,7 +2442,6 @@ ${error.stack}`;
|
|
|
2469
2442
|
var INDICATOR_CLAMP_PADDING_PX = 4;
|
|
2470
2443
|
var INDICATOR_SUCCESS_VISIBLE_MS = 1500;
|
|
2471
2444
|
var INDICATOR_FADE_MS = 200;
|
|
2472
|
-
var INDICATOR_TOTAL_HIDE_DELAY_MS = INDICATOR_SUCCESS_VISIBLE_MS + INDICATOR_FADE_MS;
|
|
2473
2445
|
var lerp = (start, end, factor) => {
|
|
2474
2446
|
return start + (end - start) * factor;
|
|
2475
2447
|
};
|
|
@@ -2554,6 +2526,30 @@ ${error.stack}`;
|
|
|
2554
2526
|
}
|
|
2555
2527
|
};
|
|
2556
2528
|
};
|
|
2529
|
+
var createGrabbedOverlay = (root, selection) => {
|
|
2530
|
+
const element = document.createElement("div");
|
|
2531
|
+
element.style.position = "fixed";
|
|
2532
|
+
element.style.top = `${selection.y}px`;
|
|
2533
|
+
element.style.left = `${selection.x}px`;
|
|
2534
|
+
element.style.width = `${selection.width}px`;
|
|
2535
|
+
element.style.height = `${selection.height}px`;
|
|
2536
|
+
element.style.borderRadius = selection.borderRadius;
|
|
2537
|
+
element.style.transform = selection.transform;
|
|
2538
|
+
element.style.pointerEvents = "none";
|
|
2539
|
+
element.style.border = "1px solid rgb(210, 57, 192)";
|
|
2540
|
+
element.style.backgroundColor = "rgba(210, 57, 192, 0.2)";
|
|
2541
|
+
element.style.zIndex = "2147483646";
|
|
2542
|
+
element.style.boxSizing = "border-box";
|
|
2543
|
+
element.style.transition = "opacity 0.3s ease-out";
|
|
2544
|
+
element.style.opacity = "1";
|
|
2545
|
+
root.appendChild(element);
|
|
2546
|
+
requestAnimationFrame(() => {
|
|
2547
|
+
element.style.opacity = "0";
|
|
2548
|
+
});
|
|
2549
|
+
setTimeout(() => {
|
|
2550
|
+
element.remove();
|
|
2551
|
+
}, 300);
|
|
2552
|
+
};
|
|
2557
2553
|
var createSpinner = () => {
|
|
2558
2554
|
const spinner = document.createElement("span");
|
|
2559
2555
|
spinner.style.display = "inline-block";
|
|
@@ -2599,12 +2595,12 @@ ${error.stack}`;
|
|
|
2599
2595
|
indicator.style.whiteSpace = "nowrap";
|
|
2600
2596
|
return indicator;
|
|
2601
2597
|
};
|
|
2602
|
-
var showLabel = (selectionLeftPx, selectionTopPx, tagName) => {
|
|
2598
|
+
var showLabel = (root, selectionLeftPx, selectionTopPx, tagName) => {
|
|
2603
2599
|
let indicator = activeIndicator;
|
|
2604
2600
|
let isNewIndicator = false;
|
|
2605
2601
|
if (!indicator) {
|
|
2606
2602
|
indicator = createIndicator();
|
|
2607
|
-
|
|
2603
|
+
root.appendChild(indicator);
|
|
2608
2604
|
activeIndicator = indicator;
|
|
2609
2605
|
isNewIndicator = true;
|
|
2610
2606
|
isProcessing = false;
|
|
@@ -2658,22 +2654,47 @@ ${error.stack}`;
|
|
|
2658
2654
|
}
|
|
2659
2655
|
};
|
|
2660
2656
|
var isProcessing = false;
|
|
2661
|
-
var
|
|
2662
|
-
|
|
2657
|
+
var activeGrabbedIndicators = /* @__PURE__ */ new Set();
|
|
2658
|
+
var updateLabelToProcessing = (root, selectionLeftPx, selectionTopPx) => {
|
|
2659
|
+
const indicator = createIndicator();
|
|
2660
|
+
indicator.style.zIndex = "2147483648";
|
|
2661
|
+
root.appendChild(indicator);
|
|
2662
|
+
activeGrabbedIndicators.add(indicator);
|
|
2663
|
+
const positionIndicator = () => {
|
|
2664
|
+
if (selectionLeftPx === void 0 || selectionTopPx === void 0) return;
|
|
2665
|
+
const indicatorRect = indicator.getBoundingClientRect();
|
|
2666
|
+
const viewportWidthPx = window.innerWidth;
|
|
2667
|
+
const viewportHeightPx = window.innerHeight;
|
|
2668
|
+
let indicatorLeftPx = Math.round(selectionLeftPx);
|
|
2669
|
+
let indicatorTopPx = Math.round(selectionTopPx) - indicatorRect.height - LABEL_OFFSET_PX;
|
|
2670
|
+
const CLAMPED_PADDING = INDICATOR_CLAMP_PADDING_PX;
|
|
2671
|
+
const minLeft = VIEWPORT_MARGIN_PX;
|
|
2672
|
+
const minTop = VIEWPORT_MARGIN_PX;
|
|
2673
|
+
const maxLeft = viewportWidthPx - indicatorRect.width - VIEWPORT_MARGIN_PX;
|
|
2674
|
+
const maxTop = viewportHeightPx - indicatorRect.height - VIEWPORT_MARGIN_PX;
|
|
2675
|
+
const willClampLeft = indicatorLeftPx < minLeft;
|
|
2676
|
+
const willClampTop = indicatorTopPx < minTop;
|
|
2677
|
+
const isClamped = willClampLeft || willClampTop;
|
|
2678
|
+
indicatorLeftPx = Math.max(minLeft, Math.min(indicatorLeftPx, maxLeft));
|
|
2679
|
+
indicatorTopPx = Math.max(minTop, Math.min(indicatorTopPx, maxTop));
|
|
2680
|
+
if (isClamped) {
|
|
2681
|
+
indicatorLeftPx += CLAMPED_PADDING;
|
|
2682
|
+
indicatorTopPx += CLAMPED_PADDING;
|
|
2683
|
+
}
|
|
2684
|
+
indicator.style.left = `${indicatorLeftPx}px`;
|
|
2685
|
+
indicator.style.top = `${indicatorTopPx}px`;
|
|
2686
|
+
indicator.style.right = "auto";
|
|
2663
2687
|
};
|
|
2664
|
-
isProcessing = true;
|
|
2665
|
-
const indicator = activeIndicator;
|
|
2666
|
-
indicator.innerHTML = "";
|
|
2667
2688
|
const loadingSpinner = createSpinner();
|
|
2668
2689
|
const labelText = document.createElement("span");
|
|
2669
2690
|
labelText.textContent = "Grabbing\u2026";
|
|
2670
2691
|
indicator.appendChild(loadingSpinner);
|
|
2671
2692
|
indicator.appendChild(labelText);
|
|
2693
|
+
positionIndicator();
|
|
2694
|
+
requestAnimationFrame(() => {
|
|
2695
|
+
indicator.style.opacity = "1";
|
|
2696
|
+
});
|
|
2672
2697
|
return (tagName) => {
|
|
2673
|
-
if (!activeIndicator) {
|
|
2674
|
-
isProcessing = false;
|
|
2675
|
-
return;
|
|
2676
|
-
}
|
|
2677
2698
|
indicator.textContent = "";
|
|
2678
2699
|
const checkmarkIcon = document.createElement("span");
|
|
2679
2700
|
checkmarkIcon.textContent = "\u2713";
|
|
@@ -2689,14 +2710,14 @@ ${error.stack}`;
|
|
|
2689
2710
|
newLabelText.appendChild(tagNameMonospace);
|
|
2690
2711
|
indicator.appendChild(checkmarkIcon);
|
|
2691
2712
|
indicator.appendChild(newLabelText);
|
|
2713
|
+
requestAnimationFrame(() => {
|
|
2714
|
+
positionIndicator();
|
|
2715
|
+
});
|
|
2692
2716
|
setTimeout(() => {
|
|
2693
2717
|
indicator.style.opacity = "0";
|
|
2694
2718
|
setTimeout(() => {
|
|
2695
2719
|
indicator.remove();
|
|
2696
|
-
|
|
2697
|
-
activeIndicator = null;
|
|
2698
|
-
}
|
|
2699
|
-
isProcessing = false;
|
|
2720
|
+
activeGrabbedIndicators.delete(indicator);
|
|
2700
2721
|
}, INDICATOR_FADE_MS);
|
|
2701
2722
|
}, INDICATOR_SUCCESS_VISIBLE_MS);
|
|
2702
2723
|
};
|
|
@@ -2708,6 +2729,88 @@ ${error.stack}`;
|
|
|
2708
2729
|
}
|
|
2709
2730
|
isProcessing = false;
|
|
2710
2731
|
};
|
|
2732
|
+
var cleanupGrabbedIndicators = () => {
|
|
2733
|
+
for (const indicator of activeGrabbedIndicators) {
|
|
2734
|
+
indicator.remove();
|
|
2735
|
+
}
|
|
2736
|
+
activeGrabbedIndicators.clear();
|
|
2737
|
+
};
|
|
2738
|
+
var activeProgressIndicator = null;
|
|
2739
|
+
var createProgressIndicatorElement = () => {
|
|
2740
|
+
const container = document.createElement("div");
|
|
2741
|
+
container.style.position = "fixed";
|
|
2742
|
+
container.style.zIndex = "2147483647";
|
|
2743
|
+
container.style.pointerEvents = "none";
|
|
2744
|
+
container.style.opacity = "0";
|
|
2745
|
+
container.style.transition = "opacity 0.1s ease-in-out";
|
|
2746
|
+
const progressBarContainer = document.createElement("div");
|
|
2747
|
+
progressBarContainer.style.width = "32px";
|
|
2748
|
+
progressBarContainer.style.height = "2px";
|
|
2749
|
+
progressBarContainer.style.backgroundColor = "rgba(178, 28, 142, 0.2)";
|
|
2750
|
+
progressBarContainer.style.borderRadius = "1px";
|
|
2751
|
+
progressBarContainer.style.overflow = "hidden";
|
|
2752
|
+
progressBarContainer.style.position = "relative";
|
|
2753
|
+
const progressBarFill = document.createElement("div");
|
|
2754
|
+
progressBarFill.style.width = "0%";
|
|
2755
|
+
progressBarFill.style.height = "100%";
|
|
2756
|
+
progressBarFill.style.backgroundColor = "#b21c8e";
|
|
2757
|
+
progressBarFill.style.borderRadius = "1px";
|
|
2758
|
+
progressBarFill.style.transition = "width 0.05s linear";
|
|
2759
|
+
progressBarFill.setAttribute("data-progress-fill", "true");
|
|
2760
|
+
progressBarContainer.appendChild(progressBarFill);
|
|
2761
|
+
container.appendChild(progressBarContainer);
|
|
2762
|
+
return container;
|
|
2763
|
+
};
|
|
2764
|
+
var showProgressIndicator = (root, progress, mouseX, mouseY) => {
|
|
2765
|
+
if (!activeProgressIndicator) {
|
|
2766
|
+
activeProgressIndicator = createProgressIndicatorElement();
|
|
2767
|
+
root.appendChild(activeProgressIndicator);
|
|
2768
|
+
requestAnimationFrame(() => {
|
|
2769
|
+
if (activeProgressIndicator) {
|
|
2770
|
+
activeProgressIndicator.style.opacity = "1";
|
|
2771
|
+
}
|
|
2772
|
+
});
|
|
2773
|
+
}
|
|
2774
|
+
const indicator = activeProgressIndicator;
|
|
2775
|
+
const indicatorRect = indicator.getBoundingClientRect();
|
|
2776
|
+
const viewportWidth = window.innerWidth;
|
|
2777
|
+
const viewportHeight = window.innerHeight;
|
|
2778
|
+
const CURSOR_OFFSET = 14;
|
|
2779
|
+
const VIEWPORT_MARGIN = 8;
|
|
2780
|
+
let indicatorLeft = mouseX - indicatorRect.width / 2;
|
|
2781
|
+
let indicatorTop = mouseY + CURSOR_OFFSET;
|
|
2782
|
+
if (indicatorTop + indicatorRect.height + VIEWPORT_MARGIN > viewportHeight) {
|
|
2783
|
+
indicatorTop = mouseY - indicatorRect.height - CURSOR_OFFSET;
|
|
2784
|
+
}
|
|
2785
|
+
indicatorTop = Math.max(
|
|
2786
|
+
VIEWPORT_MARGIN,
|
|
2787
|
+
Math.min(indicatorTop, viewportHeight - indicatorRect.height - VIEWPORT_MARGIN)
|
|
2788
|
+
);
|
|
2789
|
+
indicatorLeft = Math.max(
|
|
2790
|
+
VIEWPORT_MARGIN,
|
|
2791
|
+
Math.min(indicatorLeft, viewportWidth - indicatorRect.width - VIEWPORT_MARGIN)
|
|
2792
|
+
);
|
|
2793
|
+
indicator.style.top = `${indicatorTop}px`;
|
|
2794
|
+
indicator.style.left = `${indicatorLeft}px`;
|
|
2795
|
+
const progressFill = indicator.querySelector(
|
|
2796
|
+
"[data-progress-fill]"
|
|
2797
|
+
);
|
|
2798
|
+
if (progressFill) {
|
|
2799
|
+
const percentage = Math.min(100, Math.max(0, progress * 100));
|
|
2800
|
+
progressFill.style.width = `${percentage}%`;
|
|
2801
|
+
}
|
|
2802
|
+
};
|
|
2803
|
+
var hideProgressIndicator = () => {
|
|
2804
|
+
if (activeProgressIndicator) {
|
|
2805
|
+
activeProgressIndicator.style.opacity = "0";
|
|
2806
|
+
setTimeout(() => {
|
|
2807
|
+
if (activeProgressIndicator) {
|
|
2808
|
+
activeProgressIndicator.remove();
|
|
2809
|
+
activeProgressIndicator = null;
|
|
2810
|
+
}
|
|
2811
|
+
}, 100);
|
|
2812
|
+
}
|
|
2813
|
+
};
|
|
2711
2814
|
|
|
2712
2815
|
// src/utils/copy-text.ts
|
|
2713
2816
|
var IS_NAVIGATOR_CLIPBOARD_AVAILABLE = typeof window !== "undefined" && window.navigator.clipboard && window.isSecureContext;
|
|
@@ -2773,19 +2876,6 @@ ${error.stack}`;
|
|
|
2773
2876
|
return root;
|
|
2774
2877
|
};
|
|
2775
2878
|
|
|
2776
|
-
// src/utils/schedule-run-when-idle.ts
|
|
2777
|
-
var scheduleRunWhenIdle = (callback) => {
|
|
2778
|
-
if ("scheduler" in globalThis) {
|
|
2779
|
-
return globalThis.scheduler.postTask(callback, {
|
|
2780
|
-
priority: "background"
|
|
2781
|
-
});
|
|
2782
|
-
}
|
|
2783
|
-
if ("requestIdleCallback" in window) {
|
|
2784
|
-
return requestIdleCallback(callback);
|
|
2785
|
-
}
|
|
2786
|
-
return setTimeout(callback, 0);
|
|
2787
|
-
};
|
|
2788
|
-
|
|
2789
2879
|
// src/utils/store.ts
|
|
2790
2880
|
var createStore = (initializer) => {
|
|
2791
2881
|
const subscriberMap = /* @__PURE__ */ new Map();
|
|
@@ -2857,29 +2947,7 @@ ${error.stack}`;
|
|
|
2857
2947
|
return store;
|
|
2858
2948
|
};
|
|
2859
2949
|
|
|
2860
|
-
// src/utils/throttle.ts
|
|
2861
|
-
var throttle = (fn, delay) => {
|
|
2862
|
-
let timeout = null;
|
|
2863
|
-
const throttled = (...args) => {
|
|
2864
|
-
if (timeout) {
|
|
2865
|
-
return;
|
|
2866
|
-
}
|
|
2867
|
-
timeout = window.setTimeout(() => {
|
|
2868
|
-
fn(...args);
|
|
2869
|
-
timeout = null;
|
|
2870
|
-
}, delay);
|
|
2871
|
-
};
|
|
2872
|
-
throttled.cancel = () => {
|
|
2873
|
-
if (timeout) {
|
|
2874
|
-
window.clearTimeout(timeout);
|
|
2875
|
-
timeout = null;
|
|
2876
|
-
}
|
|
2877
|
-
};
|
|
2878
|
-
return throttled;
|
|
2879
|
-
};
|
|
2880
|
-
|
|
2881
2950
|
// src/index.ts
|
|
2882
|
-
var THROTTLE_DELAY = 16;
|
|
2883
2951
|
var libStore = createStore(() => ({
|
|
2884
2952
|
keyPressTimestamps: /* @__PURE__ */ new Map(),
|
|
2885
2953
|
mouseX: -1e3,
|
|
@@ -2899,7 +2967,10 @@ ${error.stack}`;
|
|
|
2899
2967
|
const root = mountRoot();
|
|
2900
2968
|
const selectionOverlay = createSelectionOverlay(root);
|
|
2901
2969
|
let hoveredElement = null;
|
|
2970
|
+
let lastGrabbedElement = null;
|
|
2902
2971
|
let isCopying = false;
|
|
2972
|
+
let progressAnimationFrame = null;
|
|
2973
|
+
let progressStartTime = null;
|
|
2903
2974
|
const checkIsActivationHotkeyPressed = () => {
|
|
2904
2975
|
if (Array.isArray(resolvedOptions.hotkey)) {
|
|
2905
2976
|
for (const key of resolvedOptions.hotkey) {
|
|
@@ -2911,6 +2982,31 @@ ${error.stack}`;
|
|
|
2911
2982
|
}
|
|
2912
2983
|
return isKeyPressed(resolvedOptions.hotkey);
|
|
2913
2984
|
};
|
|
2985
|
+
const updateProgressIndicator = () => {
|
|
2986
|
+
if (progressStartTime === null) return;
|
|
2987
|
+
const elapsed = Date.now() - progressStartTime;
|
|
2988
|
+
const progress = Math.min(1, elapsed / resolvedOptions.keyHoldDuration);
|
|
2989
|
+
const { mouseX, mouseY } = libStore.getState();
|
|
2990
|
+
showProgressIndicator(root, progress, mouseX, mouseY);
|
|
2991
|
+
if (progress < 1) {
|
|
2992
|
+
progressAnimationFrame = requestAnimationFrame(updateProgressIndicator);
|
|
2993
|
+
}
|
|
2994
|
+
};
|
|
2995
|
+
const startProgressTracking = () => {
|
|
2996
|
+
if (progressAnimationFrame !== null) return;
|
|
2997
|
+
progressStartTime = Date.now();
|
|
2998
|
+
const { mouseX, mouseY } = libStore.getState();
|
|
2999
|
+
showProgressIndicator(root, 0, mouseX, mouseY);
|
|
3000
|
+
progressAnimationFrame = requestAnimationFrame(updateProgressIndicator);
|
|
3001
|
+
};
|
|
3002
|
+
const stopProgressTracking = () => {
|
|
3003
|
+
if (progressAnimationFrame !== null) {
|
|
3004
|
+
cancelAnimationFrame(progressAnimationFrame);
|
|
3005
|
+
progressAnimationFrame = null;
|
|
3006
|
+
}
|
|
3007
|
+
progressStartTime = null;
|
|
3008
|
+
hideProgressIndicator();
|
|
3009
|
+
};
|
|
2914
3010
|
let cleanupActivationHotkeyWatcher = null;
|
|
2915
3011
|
const handleKeyStateChange = (pressedKeys) => {
|
|
2916
3012
|
const { overlayMode } = libStore.getState();
|
|
@@ -2945,6 +3041,7 @@ ${error.stack}`;
|
|
|
2945
3041
|
cleanupActivationHotkeyWatcher();
|
|
2946
3042
|
cleanupActivationHotkeyWatcher = null;
|
|
2947
3043
|
}
|
|
3044
|
+
stopProgressTracking();
|
|
2948
3045
|
return;
|
|
2949
3046
|
}
|
|
2950
3047
|
const isActivationHotkeyPressed = checkIsActivationHotkeyPressed();
|
|
@@ -2959,9 +3056,11 @@ ${error.stack}`;
|
|
|
2959
3056
|
overlayMode: "hidden"
|
|
2960
3057
|
}));
|
|
2961
3058
|
}
|
|
3059
|
+
stopProgressTracking();
|
|
2962
3060
|
return;
|
|
2963
3061
|
}
|
|
2964
3062
|
if (overlayMode === "hidden" && !cleanupActivationHotkeyWatcher) {
|
|
3063
|
+
startProgressTracking();
|
|
2965
3064
|
cleanupActivationHotkeyWatcher = watchKeyHeldFor(
|
|
2966
3065
|
resolvedOptions.hotkey,
|
|
2967
3066
|
resolvedOptions.keyHoldDuration,
|
|
@@ -2970,6 +3069,7 @@ ${error.stack}`;
|
|
|
2970
3069
|
...state,
|
|
2971
3070
|
overlayMode: "visible"
|
|
2972
3071
|
}));
|
|
3072
|
+
stopProgressTracking();
|
|
2973
3073
|
cleanupActivationHotkeyWatcher = null;
|
|
2974
3074
|
}
|
|
2975
3075
|
);
|
|
@@ -2979,13 +3079,23 @@ ${error.stack}`;
|
|
|
2979
3079
|
handleKeyStateChange,
|
|
2980
3080
|
(state) => state.pressedKeys
|
|
2981
3081
|
);
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
3082
|
+
let mouseMoveScheduled = false;
|
|
3083
|
+
let pendingMouseX = -1e3;
|
|
3084
|
+
let pendingMouseY = -1e3;
|
|
3085
|
+
const handleMouseMove = (event) => {
|
|
3086
|
+
pendingMouseX = event.clientX;
|
|
3087
|
+
pendingMouseY = event.clientY;
|
|
3088
|
+
if (mouseMoveScheduled) return;
|
|
3089
|
+
mouseMoveScheduled = true;
|
|
3090
|
+
requestAnimationFrame(() => {
|
|
3091
|
+
mouseMoveScheduled = false;
|
|
3092
|
+
libStore.setState((state) => ({
|
|
3093
|
+
...state,
|
|
3094
|
+
mouseX: pendingMouseX,
|
|
3095
|
+
mouseY: pendingMouseY
|
|
3096
|
+
}));
|
|
3097
|
+
});
|
|
3098
|
+
};
|
|
2989
3099
|
const handleMouseDown = (event) => {
|
|
2990
3100
|
if (event.button !== 0) {
|
|
2991
3101
|
return;
|
|
@@ -3002,8 +3112,15 @@ ${error.stack}`;
|
|
|
3002
3112
|
overlayMode: "copying"
|
|
3003
3113
|
}));
|
|
3004
3114
|
};
|
|
3115
|
+
const handleVisibilityChange = () => {
|
|
3116
|
+
if (document.hidden) {
|
|
3117
|
+
cleanupGrabbedIndicators();
|
|
3118
|
+
hideLabel();
|
|
3119
|
+
}
|
|
3120
|
+
};
|
|
3005
3121
|
window.addEventListener("mousemove", handleMouseMove);
|
|
3006
3122
|
window.addEventListener("mousedown", handleMouseDown);
|
|
3123
|
+
document.addEventListener("visibilitychange", handleVisibilityChange);
|
|
3007
3124
|
const cleanupTrackHotkeys = trackHotkeys();
|
|
3008
3125
|
const getElementAtPosition = (x, y) => {
|
|
3009
3126
|
const elements = document.elementsFromPoint(x, y);
|
|
@@ -3020,70 +3137,75 @@ ${error.stack}`;
|
|
|
3020
3137
|
return null;
|
|
3021
3138
|
};
|
|
3022
3139
|
const handleCopy = async (element) => {
|
|
3023
|
-
const
|
|
3140
|
+
const tagName = (element.tagName || "").toLowerCase();
|
|
3141
|
+
const rect = element.getBoundingClientRect();
|
|
3142
|
+
const cleanupIndicator = updateLabelToProcessing(root, rect.left, rect.top);
|
|
3024
3143
|
try {
|
|
3025
|
-
const stack = await getStack(element);
|
|
3026
3144
|
const htmlSnippet = getHTMLSnippet(element);
|
|
3027
|
-
|
|
3145
|
+
await copyTextToClipboard(
|
|
3146
|
+
`
|
|
3147
|
+
|
|
3148
|
+
<referenced_element>
|
|
3149
|
+
${htmlSnippet}
|
|
3150
|
+
</referenced_element>`
|
|
3151
|
+
);
|
|
3152
|
+
cleanupIndicator(tagName);
|
|
3153
|
+
const stack = await getStack(element);
|
|
3028
3154
|
if (stack) {
|
|
3029
3155
|
const filteredStack = filterStack(stack);
|
|
3030
3156
|
const serializedStack = serializeStack(filteredStack);
|
|
3031
|
-
|
|
3157
|
+
const fullText = `${htmlSnippet}
|
|
3032
3158
|
|
|
3033
3159
|
Component owner stack:
|
|
3034
3160
|
${serializedStack}`;
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
`
|
|
3161
|
+
await copyTextToClipboard(
|
|
3162
|
+
`
|
|
3038
3163
|
|
|
3039
3164
|
<referenced_element>
|
|
3040
|
-
${
|
|
3165
|
+
${fullText}
|
|
3041
3166
|
</referenced_element>`
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
3167
|
+
).catch(() => {
|
|
3168
|
+
});
|
|
3169
|
+
}
|
|
3045
3170
|
} catch {
|
|
3046
|
-
cleanupIndicator();
|
|
3171
|
+
cleanupIndicator(tagName);
|
|
3047
3172
|
}
|
|
3048
3173
|
};
|
|
3049
|
-
const handleRender =
|
|
3174
|
+
const handleRender = (state) => {
|
|
3050
3175
|
const { mouseX, mouseY, overlayMode } = state;
|
|
3051
3176
|
if (overlayMode === "hidden") {
|
|
3052
3177
|
if (selectionOverlay.isVisible()) {
|
|
3053
3178
|
selectionOverlay.hide();
|
|
3054
|
-
if (!isCopying) {
|
|
3055
|
-
hideLabel();
|
|
3056
|
-
}
|
|
3057
|
-
hoveredElement = null;
|
|
3058
3179
|
}
|
|
3180
|
+
if (!isCopying) {
|
|
3181
|
+
hideLabel();
|
|
3182
|
+
}
|
|
3183
|
+
hoveredElement = null;
|
|
3184
|
+
lastGrabbedElement = null;
|
|
3059
3185
|
return;
|
|
3060
3186
|
}
|
|
3061
3187
|
if (overlayMode === "copying" && hoveredElement) {
|
|
3062
|
-
const computedStyle2 = window.getComputedStyle(hoveredElement);
|
|
3063
|
-
const rect2 = hoveredElement.getBoundingClientRect();
|
|
3064
|
-
selectionOverlay.update({
|
|
3065
|
-
borderRadius: computedStyle2.borderRadius || "0px",
|
|
3066
|
-
height: rect2.height,
|
|
3067
|
-
transform: computedStyle2.transform || "none",
|
|
3068
|
-
width: rect2.width,
|
|
3069
|
-
x: rect2.left,
|
|
3070
|
-
y: rect2.top
|
|
3071
|
-
});
|
|
3072
|
-
if (!selectionOverlay.isVisible()) {
|
|
3073
|
-
selectionOverlay.show();
|
|
3074
|
-
}
|
|
3075
3188
|
if (!isCopying) {
|
|
3076
3189
|
isCopying = true;
|
|
3190
|
+
lastGrabbedElement = hoveredElement;
|
|
3191
|
+
const computedStyle2 = window.getComputedStyle(hoveredElement);
|
|
3192
|
+
const rect2 = hoveredElement.getBoundingClientRect();
|
|
3193
|
+
createGrabbedOverlay(root, {
|
|
3194
|
+
borderRadius: computedStyle2.borderRadius || "0px",
|
|
3195
|
+
height: rect2.height,
|
|
3196
|
+
transform: computedStyle2.transform || "none",
|
|
3197
|
+
width: rect2.width,
|
|
3198
|
+
x: rect2.left,
|
|
3199
|
+
y: rect2.top
|
|
3200
|
+
});
|
|
3077
3201
|
void handleCopy(hoveredElement).finally(() => {
|
|
3078
|
-
|
|
3079
|
-
...state2,
|
|
3080
|
-
overlayMode: "hidden"
|
|
3081
|
-
}));
|
|
3082
|
-
selectionOverlay.hide();
|
|
3083
|
-
window.setTimeout(() => {
|
|
3084
|
-
isCopying = false;
|
|
3085
|
-
}, INDICATOR_TOTAL_HIDE_DELAY_MS);
|
|
3202
|
+
isCopying = false;
|
|
3086
3203
|
});
|
|
3204
|
+
const isStillPressed = checkIsActivationHotkeyPressed();
|
|
3205
|
+
libStore.setState((state2) => ({
|
|
3206
|
+
...state2,
|
|
3207
|
+
overlayMode: isStillPressed ? "visible" : "hidden"
|
|
3208
|
+
}));
|
|
3087
3209
|
}
|
|
3088
3210
|
return;
|
|
3089
3211
|
}
|
|
@@ -3091,13 +3213,26 @@ ${text}
|
|
|
3091
3213
|
if (!element) {
|
|
3092
3214
|
if (selectionOverlay.isVisible()) {
|
|
3093
3215
|
selectionOverlay.hide();
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
|
|
3216
|
+
}
|
|
3217
|
+
if (!isCopying) {
|
|
3218
|
+
hideLabel();
|
|
3097
3219
|
}
|
|
3098
3220
|
hoveredElement = null;
|
|
3099
3221
|
return;
|
|
3100
3222
|
}
|
|
3223
|
+
if (lastGrabbedElement && element !== lastGrabbedElement) {
|
|
3224
|
+
lastGrabbedElement = null;
|
|
3225
|
+
}
|
|
3226
|
+
if (element === lastGrabbedElement) {
|
|
3227
|
+
if (selectionOverlay.isVisible()) {
|
|
3228
|
+
selectionOverlay.hide();
|
|
3229
|
+
}
|
|
3230
|
+
if (!isCopying) {
|
|
3231
|
+
hideLabel();
|
|
3232
|
+
}
|
|
3233
|
+
hoveredElement = element;
|
|
3234
|
+
return;
|
|
3235
|
+
}
|
|
3101
3236
|
const tagName = (element.tagName || "").toLowerCase();
|
|
3102
3237
|
hoveredElement = element;
|
|
3103
3238
|
const rect = element.getBoundingClientRect();
|
|
@@ -3115,35 +3250,38 @@ ${text}
|
|
|
3115
3250
|
if (!selectionOverlay.isVisible()) {
|
|
3116
3251
|
selectionOverlay.show();
|
|
3117
3252
|
}
|
|
3118
|
-
showLabel(rect.left, rect.top, tagName);
|
|
3119
|
-
}
|
|
3120
|
-
|
|
3121
|
-
|
|
3122
|
-
|
|
3253
|
+
showLabel(root, rect.left, rect.top, tagName);
|
|
3254
|
+
};
|
|
3255
|
+
let renderScheduled = false;
|
|
3256
|
+
const scheduleRender = () => {
|
|
3257
|
+
if (renderScheduled) return;
|
|
3258
|
+
renderScheduled = true;
|
|
3259
|
+
requestAnimationFrame(() => {
|
|
3260
|
+
renderScheduled = false;
|
|
3261
|
+
handleRender(libStore.getState());
|
|
3123
3262
|
});
|
|
3263
|
+
};
|
|
3264
|
+
const cleanupRenderSubscription = libStore.subscribe(() => {
|
|
3265
|
+
scheduleRender();
|
|
3124
3266
|
});
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
scheduleRunWhenIdle(() => {
|
|
3129
|
-
handleRender(libStore.getState());
|
|
3130
|
-
render();
|
|
3131
|
-
});
|
|
3132
|
-
}, 100);
|
|
3267
|
+
const continuousRender = () => {
|
|
3268
|
+
scheduleRender();
|
|
3269
|
+
requestAnimationFrame(continuousRender);
|
|
3133
3270
|
};
|
|
3134
|
-
|
|
3271
|
+
continuousRender();
|
|
3135
3272
|
return () => {
|
|
3136
3273
|
window.removeEventListener("mousemove", handleMouseMove);
|
|
3137
3274
|
window.removeEventListener("mousedown", handleMouseDown);
|
|
3275
|
+
document.removeEventListener("visibilitychange", handleVisibilityChange);
|
|
3138
3276
|
cleanupTrackHotkeys();
|
|
3139
3277
|
cleanupRenderSubscription();
|
|
3140
3278
|
cleanupKeyStateChangeSubscription();
|
|
3141
|
-
if (timeout) {
|
|
3142
|
-
window.clearTimeout(timeout);
|
|
3143
|
-
}
|
|
3144
3279
|
if (cleanupActivationHotkeyWatcher) {
|
|
3145
3280
|
cleanupActivationHotkeyWatcher();
|
|
3146
3281
|
}
|
|
3282
|
+
stopProgressTracking();
|
|
3283
|
+
cleanupGrabbedIndicators();
|
|
3284
|
+
hideLabel();
|
|
3147
3285
|
};
|
|
3148
3286
|
};
|
|
3149
3287
|
if (typeof window !== "undefined" && typeof document !== "undefined") {
|