From f0aa3bb81d429b9ee88cc61d3d8491ed856b7f42 Mon Sep 17 00:00:00 2001 From: Pluto Date: Sat, 30 May 2026 15:45:52 +0530 Subject: [PATCH 1/4] fix: hover box doesn't get dismissed when cursor leaves the preview slowly --- .../BrowserScripts/RemoteFunctions.js | 37 +++++++++++++------ src/LiveDevelopment/LiveDevMultiBrowser.js | 11 ++++++ .../Phoenix-live-preview/main.js | 5 +++ 3 files changed, 41 insertions(+), 12 deletions(-) diff --git a/src/LiveDevelopment/BrowserScripts/RemoteFunctions.js b/src/LiveDevelopment/BrowserScripts/RemoteFunctions.js index 3ae76fb3c8..b79eae6201 100644 --- a/src/LiveDevelopment/BrowserScripts/RemoteFunctions.js +++ b/src/LiveDevelopment/BrowserScripts/RemoteFunctions.js @@ -595,14 +595,13 @@ function RemoteFunctions(config = {}) { } const element = event.target; - if(!LivePreviewView.isElementInspectable(element) || element.nodeType !== Node.ELEMENT_NODE) { - return; - } - // Same element as last hover — nothing changed, skip entirely if (element === _lastHoverTarget) { return; } + if(!LivePreviewView.isElementInspectable(element) || element.nodeType !== Node.ELEMENT_NODE) { + return; + } _lastHoverTarget = element; // if _hoverHighlight is uninitialized, initialize it @@ -615,21 +614,30 @@ function RemoteFunctions(config = {}) { } } - function onElementHoverOut(event) { - // don't want highlighting and stuff when auto scrolling - if (SHARED_STATE.isAutoScrolling) { return; } + function _clearHoverState() { + if (SHARED_STATE.isAutoScrolling) { + return; + } + if (_hoverHighlight && shouldShowHighlightOnHover()) { + _lastHoverTarget = null; + _scheduleHoverUpdate(); + } + } + function onElementHoverOut(event) { const element = event.target; // Use isElementInspectable (not isElementEditable) so that JS-rendered // elements also get their hover highlight and hover box properly dismissed. if(LivePreviewView.isElementInspectable(element) && element.nodeType === Node.ELEMENT_NODE) { - if (_hoverHighlight && shouldShowHighlightOnHover()) { - _lastHoverTarget = null; - _scheduleHoverUpdate(); - } + _clearHoverState(); } } + // for popped out window: the in-panel iframe case is forwarded parent-side via _LD.clearHoverState(). + function onDocumentMouseLeave() { + _clearHoverState(); + } + function scrollElementToViewPort(element) { if (!element) { return; @@ -711,7 +719,9 @@ function RemoteFunctions(config = {}) { function disableHoverListeners() { window.document.removeEventListener("mouseover", onElementHover); + window.document.removeEventListener("mousemove", onElementHover); window.document.removeEventListener("mouseout", onElementHoverOut); + window.document.documentElement.removeEventListener("mouseleave", onDocumentMouseLeave); // Cancel any pending rAF hover update so stale callbacks don't fire if (_pendingHoverRAF) { cancelAnimationFrame(_pendingHoverRAF); @@ -732,7 +742,9 @@ function RemoteFunctions(config = {}) { if (config.mode === 'edit' && shouldShowHighlightOnHover()) { disableHoverListeners(); window.document.addEventListener("mouseover", onElementHover); + window.document.addEventListener("mousemove", onElementHover); window.document.addEventListener("mouseout", onElementHoverOut); + window.document.documentElement.addEventListener("mouseleave", onDocumentMouseLeave); } } @@ -1714,7 +1726,8 @@ function RemoteFunctions(config = {}) { "getHighlightCount": getHighlightCount, "getHighlightTrackingElement": getHighlightTrackingElement, "getHighlightStyle": getHighlightStyle, - "setHotCornerHidden": setHotCornerHidden + "setHotCornerHidden": setHotCornerHidden, + "clearHoverState": _clearHoverState }; // the below code comment is replaced by added scripts for extensibility diff --git a/src/LiveDevelopment/LiveDevMultiBrowser.js b/src/LiveDevelopment/LiveDevMultiBrowser.js index 2b0f8bc417..6a0f36deb2 100644 --- a/src/LiveDevelopment/LiveDevMultiBrowser.js +++ b/src/LiveDevelopment/LiveDevMultiBrowser.js @@ -733,6 +733,16 @@ define(function (require, exports, module) { } } + /** + * Clear hover highlight and hover box in the preview. Forwarded from the parent because the + * previewed iframe does not reliably receive mouseout/mouseleave on a slow pointer exit. + */ + function clearHoverState() { + if (_protocol) { + _protocol.evaluate("_LD.clearHoverState && _LD.clearHoverState()"); + } + } + /** * Update configuration in the remote browser */ @@ -860,6 +870,7 @@ define(function (require, exports, module) { exports.showHighlight = showHighlight; exports.hideHighlight = hideHighlight; exports.redrawHighlight = redrawHighlight; + exports.clearHoverState = clearHoverState; exports.getConfig = getConfig; exports.updateConfig = updateConfig; exports.refreshConfig = refreshConfig; diff --git a/src/extensionsIntegrated/Phoenix-live-preview/main.js b/src/extensionsIntegrated/Phoenix-live-preview/main.js index e4482312a1..2a9e9e4152 100644 --- a/src/extensionsIntegrated/Phoenix-live-preview/main.js +++ b/src/extensionsIntegrated/Phoenix-live-preview/main.js @@ -828,6 +828,11 @@ define(function (require, exports, module) { $panel.find(".custom-server-banner-close-icon").on("click", ()=>{ $panel.find(".live-preview-custom-banner").addClass("forced-hidden"); }); + // The previewed iframe does not reliably fire mouseout/mouseleave on a slow pointer exit, + // leaving the hover highlight/box stuck. Detect the leave parent-side and forward a clear. + $panel.on("mouseleave", "#panel-live-preview-frame", function () { + MultiBrowserLiveDev.clearHoverState(); + }); $iframe[0].onload = function () { $iframe.attr('srcdoc', null); }; From 7dfc78e200d8bf8b94b8df10dea4563a7c97b1d9 Mon Sep 17 00:00:00 2001 From: Pluto Date: Mon, 1 Jun 2026 13:06:51 +0530 Subject: [PATCH 2/4] feat: add live preview styler box strings --- src/nls/root/strings.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/nls/root/strings.js b/src/nls/root/strings.js index 7729c46e1e..d96dd58b0f 100644 --- a/src/nls/root/strings.js +++ b/src/nls/root/strings.js @@ -194,7 +194,18 @@ define({ "LIVE_DEV_TOOLBOX_DUPLICATE": "Duplicate", "LIVE_DEV_TOOLBOX_DELETE": "Delete", "LIVE_DEV_TOOLBOX_IMAGE_GALLERY": "Image Gallery", + "LIVE_DEV_TOOLBOX_STYLER": "Styles", "LIVE_DEV_TOOLBOX_MORE_OPTIONS": "More Options", + "LIVE_DEV_STYLER_FILL": "Fill", + "LIVE_DEV_STYLER_TEXT": "Text", + "LIVE_DEV_STYLER_FONT": "Font", + "LIVE_DEV_STYLER_SIZE": "Size", + "LIVE_DEV_STYLER_WEIGHT": "Weight", + "LIVE_DEV_STYLER_ALIGN": "Align", + "LIVE_DEV_STYLER_BORDER": "Border", + "LIVE_DEV_STYLER_SPACING": "Spacing", + "LIVE_DEV_STYLER_LAYOUT": "Layout", + "LIVE_DEV_STYLER_FIT": "Fit", "LIVE_DEV_MORE_OPTIONS_CUT": "Cut", "LIVE_DEV_MORE_OPTIONS_COPY": "Copy", "LIVE_DEV_MORE_OPTIONS_PASTE": "Paste", From 44ea39fae11ada4b8183f34c403736fa35561fc0 Mon Sep 17 00:00:00 2001 From: Pluto Date: Mon, 1 Jun 2026 15:09:31 +0530 Subject: [PATCH 3/4] refactor: better strings naming for styler box --- src/nls/root/strings.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/nls/root/strings.js b/src/nls/root/strings.js index d96dd58b0f..291a53ee74 100644 --- a/src/nls/root/strings.js +++ b/src/nls/root/strings.js @@ -196,16 +196,16 @@ define({ "LIVE_DEV_TOOLBOX_IMAGE_GALLERY": "Image Gallery", "LIVE_DEV_TOOLBOX_STYLER": "Styles", "LIVE_DEV_TOOLBOX_MORE_OPTIONS": "More Options", - "LIVE_DEV_STYLER_FILL": "Fill", - "LIVE_DEV_STYLER_TEXT": "Text", - "LIVE_DEV_STYLER_FONT": "Font", - "LIVE_DEV_STYLER_SIZE": "Size", - "LIVE_DEV_STYLER_WEIGHT": "Weight", - "LIVE_DEV_STYLER_ALIGN": "Align", + "LIVE_DEV_STYLER_FILL": "Background color", + "LIVE_DEV_STYLER_TEXT": "Text color", + "LIVE_DEV_STYLER_FONT": "Font family", + "LIVE_DEV_STYLER_SIZE": "Font size", + "LIVE_DEV_STYLER_WEIGHT": "Font weight", + "LIVE_DEV_STYLER_ALIGN": "Text alignment", "LIVE_DEV_STYLER_BORDER": "Border", - "LIVE_DEV_STYLER_SPACING": "Spacing", + "LIVE_DEV_STYLER_SPACING": "Margin & padding", "LIVE_DEV_STYLER_LAYOUT": "Layout", - "LIVE_DEV_STYLER_FIT": "Fit", + "LIVE_DEV_STYLER_FIT": "Image fit", "LIVE_DEV_MORE_OPTIONS_CUT": "Cut", "LIVE_DEV_MORE_OPTIONS_COPY": "Copy", "LIVE_DEV_MORE_OPTIONS_PASTE": "Paste", From 76f83308c4b5049d5797ce809ba57cf0dcb1d789 Mon Sep 17 00:00:00 2001 From: Pluto Date: Mon, 1 Jun 2026 16:37:04 +0530 Subject: [PATCH 4/4] refactor: improve string naming --- src/nls/root/strings.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/nls/root/strings.js b/src/nls/root/strings.js index 291a53ee74..51b877e2fe 100644 --- a/src/nls/root/strings.js +++ b/src/nls/root/strings.js @@ -196,8 +196,8 @@ define({ "LIVE_DEV_TOOLBOX_IMAGE_GALLERY": "Image Gallery", "LIVE_DEV_TOOLBOX_STYLER": "Styles", "LIVE_DEV_TOOLBOX_MORE_OPTIONS": "More Options", - "LIVE_DEV_STYLER_FILL": "Background color", - "LIVE_DEV_STYLER_TEXT": "Text color", + "LIVE_DEV_STYLER_BACKGROUND": "Background color", + "LIVE_DEV_STYLER_TEXT_COLOR": "Text color", "LIVE_DEV_STYLER_FONT": "Font family", "LIVE_DEV_STYLER_SIZE": "Font size", "LIVE_DEV_STYLER_WEIGHT": "Font weight",