From 1dec2eff88dc0a02f8ccb2492b5cdbe1bbb6ac13 Mon Sep 17 00:00:00 2001 From: Pluto Date: Sat, 30 May 2026 15:45:52 +0530 Subject: [PATCH 1/5] 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 0c0b4de4eaa2022541323489edd1eab7bb1a2f9e Mon Sep 17 00:00:00 2001 From: Pluto Date: Mon, 1 Jun 2026 13:06:51 +0530 Subject: [PATCH 2/5] 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 f057f2c2b5..c88b4982ab 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 5961d36d2a1ae5caa9b88cd6a29a582323e57450 Mon Sep 17 00:00:00 2001 From: Pluto Date: Mon, 1 Jun 2026 15:09:31 +0530 Subject: [PATCH 3/5] 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 c88b4982ab..f481d32795 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 83fce14ab4ebba94c018e89577efe72f32d8306d Mon Sep 17 00:00:00 2001 From: Pluto Date: Mon, 1 Jun 2026 16:37:04 +0530 Subject: [PATCH 4/5] 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 f481d32795..3462242c35 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", From 448a7542a6dfe2b7e3ac9d2f664b9d12c43c84c0 Mon Sep 17 00:00:00 2001 From: Pluto Date: Tue, 9 Jun 2026 21:41:14 +0530 Subject: [PATCH 5/5] fix: remove styler box strings --- src/nls/root/strings.js | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/nls/root/strings.js b/src/nls/root/strings.js index 3462242c35..f057f2c2b5 100644 --- a/src/nls/root/strings.js +++ b/src/nls/root/strings.js @@ -194,18 +194,7 @@ 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_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", - "LIVE_DEV_STYLER_ALIGN": "Text alignment", - "LIVE_DEV_STYLER_BORDER": "Border", - "LIVE_DEV_STYLER_SPACING": "Margin & padding", - "LIVE_DEV_STYLER_LAYOUT": "Layout", - "LIVE_DEV_STYLER_FIT": "Image fit", "LIVE_DEV_MORE_OPTIONS_CUT": "Cut", "LIVE_DEV_MORE_OPTIONS_COPY": "Copy", "LIVE_DEV_MORE_OPTIONS_PASTE": "Paste",