From 1dec2eff88dc0a02f8ccb2492b5cdbe1bbb6ac13 Mon Sep 17 00:00:00 2001 From: Pluto Date: Sat, 30 May 2026 15:45:52 +0530 Subject: [PATCH 1/6] 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/6] 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/6] 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/6] 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/6] 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", From 3e31be07fa0a9e3540e69afa11eb8f378df33d75 Mon Sep 17 00:00:00 2001 From: Pluto Date: Thu, 11 Jun 2026 00:32:02 +0530 Subject: [PATCH 6/6] feat: add styler bar strings with tooltips --- src/nls/root/strings.js | 107 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) diff --git a/src/nls/root/strings.js b/src/nls/root/strings.js index f057f2c2b5..bba8842d02 100644 --- a/src/nls/root/strings.js +++ b/src/nls/root/strings.js @@ -195,6 +195,113 @@ define({ "LIVE_DEV_TOOLBOX_DELETE": "Delete", "LIVE_DEV_TOOLBOX_IMAGE_GALLERY": "Image Gallery", "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_TEXT_STYLE": "Text style", + "LIVE_DEV_STYLER_DOCK_TOP": "Move bar to top", + "LIVE_DEV_STYLER_DOCK_BOTTOM": "Move bar to bottom", + "LIVE_DEV_STYLER_SELECT_ELEMENT": "Select an ancestor element", + "LIVE_DEV_STYLER_SEARCH_FONTS": "Search fonts…", + "LIVE_DEV_STYLER_FONTS_GOOGLE": "Google", + "LIVE_DEV_STYLER_FONTS_SYSTEM": "System", + "LIVE_DEV_STYLER_FONTS_CUSTOM": "Custom", + "LIVE_DEV_STYLER_FONT_CUSTOM_PLACEHOLDER": "Enter font name", + "LIVE_DEV_STYLER_APPLY": "Apply", + "LIVE_DEV_STYLER_NO_FONTS_FOUND": "No fonts found", + "LIVE_DEV_STYLER_WEIGHT_THIN": "Thin", + "LIVE_DEV_STYLER_WEIGHT_EXTRA_LIGHT": "Extra Light", + "LIVE_DEV_STYLER_WEIGHT_LIGHT": "Light", + "LIVE_DEV_STYLER_WEIGHT_REGULAR": "Regular", + "LIVE_DEV_STYLER_WEIGHT_MEDIUM": "Medium", + "LIVE_DEV_STYLER_WEIGHT_SEMI_BOLD": "Semibold", + "LIVE_DEV_STYLER_WEIGHT_BOLD": "Bold", + "LIVE_DEV_STYLER_WEIGHT_EXTRA_BOLD": "Extra Bold", + "LIVE_DEV_STYLER_WEIGHT_BLACK": "Black", + "LIVE_DEV_STYLER_LINE_HEIGHT": "Line height", + "LIVE_DEV_STYLER_LETTER_SPACING": "Letter spacing", + "LIVE_DEV_STYLER_WORD_SPACING": "Word spacing", + "LIVE_DEV_STYLER_CASE": "Case", + "LIVE_DEV_STYLER_BOLD": "Bold", + "LIVE_DEV_STYLER_ITALIC": "Italic", + "LIVE_DEV_STYLER_UNDERLINE": "Underline", + "LIVE_DEV_STYLER_STRIKETHROUGH": "Strikethrough", + "LIVE_DEV_STYLER_NONE": "None", + "LIVE_DEV_STYLER_UPPERCASE": "Uppercase", + "LIVE_DEV_STYLER_LOWERCASE": "Lowercase", + "LIVE_DEV_STYLER_CAPITALIZE": "Capitalize", + "LIVE_DEV_STYLER_ALIGN_LEFT": "Align left", + "LIVE_DEV_STYLER_ALIGN_CENTER": "Align center", + "LIVE_DEV_STYLER_ALIGN_RIGHT": "Align right", + "LIVE_DEV_STYLER_ALIGN_JUSTIFY": "Justify", + "LIVE_DEV_STYLER_CLEAR": "Clear", + "LIVE_DEV_STYLER_RADIUS": "Radius", + "LIVE_DEV_STYLER_WIDTH": "Width", + "LIVE_DEV_STYLER_COLOR": "Color", + "LIVE_DEV_STYLER_STYLE": "Style", + "LIVE_DEV_STYLER_SOLID": "Solid", + "LIVE_DEV_STYLER_DASHED": "Dashed", + "LIVE_DEV_STYLER_DOTTED": "Dotted", + "LIVE_DEV_STYLER_DOUBLE": "Double", + "LIVE_DEV_STYLER_PADDING": "Padding", + "LIVE_DEV_STYLER_MARGIN": "Margin", + "LIVE_DEV_STYLER_SIDES_LINKED": "Edit all sides together", + "LIVE_DEV_STYLER_SIDES_INDEPENDENT": "Edit sides independently", + "LIVE_DEV_STYLER_ALL_SIDES": "All", + "LIVE_DEV_STYLER_TOP": "Top", + "LIVE_DEV_STYLER_RIGHT": "Right", + "LIVE_DEV_STYLER_BOTTOM": "Bottom", + "LIVE_DEV_STYLER_LEFT": "Left", + "LIVE_DEV_STYLER_DISPLAY": "Display", + "LIVE_DEV_STYLER_DIRECTION": "Direction", + "LIVE_DEV_STYLER_JUSTIFY": "Justify", + "LIVE_DEV_STYLER_ALIGN_ITEMS": "Align items", + "LIVE_DEV_STYLER_WRAP": "Wrap", + "LIVE_DEV_STYLER_GAP": "Gap", + "LIVE_DEV_STYLER_COLUMNS": "Columns", + "LIVE_DEV_STYLER_ROWS": "Rows", + "LIVE_DEV_STYLER_POSITION": "Position", + "LIVE_DEV_STYLER_Z_INDEX": "Z-index", + "LIVE_DEV_STYLER_BLOCK": "Block", + "LIVE_DEV_STYLER_INLINE": "Inline", + "LIVE_DEV_STYLER_INLINE_BLOCK": "Inline Block", + "LIVE_DEV_STYLER_FLEX": "Flex", + "LIVE_DEV_STYLER_INLINE_FLEX": "Inline Flex", + "LIVE_DEV_STYLER_GRID": "Grid", + "LIVE_DEV_STYLER_HIDDEN": "Hidden", + "LIVE_DEV_STYLER_ROW": "Row", + "LIVE_DEV_STYLER_COLUMN": "Column", + "LIVE_DEV_STYLER_ROW_REVERSE": "Row Reverse", + "LIVE_DEV_STYLER_COLUMN_REVERSE": "Column Reverse", + "LIVE_DEV_STYLER_START": "Start", + "LIVE_DEV_STYLER_CENTER": "Center", + "LIVE_DEV_STYLER_END": "End", + "LIVE_DEV_STYLER_SPACE_BETWEEN": "Space Between", + "LIVE_DEV_STYLER_SPACE_AROUND": "Space Around", + "LIVE_DEV_STYLER_SPACE_EVENLY": "Space Evenly", + "LIVE_DEV_STYLER_STRETCH": "Stretch", + "LIVE_DEV_STYLER_BASELINE": "Baseline", + "LIVE_DEV_STYLER_NO_WRAP": "No Wrap", + "LIVE_DEV_STYLER_WRAP_REVERSE": "Wrap Reverse", + "LIVE_DEV_STYLER_STATIC": "Static", + "LIVE_DEV_STYLER_RELATIVE": "Relative", + "LIVE_DEV_STYLER_ABSOLUTE": "Absolute", + "LIVE_DEV_STYLER_STICKY": "Sticky", + "LIVE_DEV_STYLER_FIXED": "Fixed", + "LIVE_DEV_STYLER_APPLIES_TO": "Applies to", + "LIVE_DEV_STYLER_INLINE_STYLE": "Inline style", + "LIVE_DEV_STYLER_ADD_SELECTOR": "Add a new selector", + "LIVE_DEV_STYLER_SELECTOR_PLACEHOLDER": "e.g. .card or #hero", + "LIVE_DEV_STYLER_HEIGHT": "Height", + "LIVE_DEV_STYLER_OPACITY": "Opacity", + "LIVE_DEV_STYLER_CHANGE_UNIT": "Change unit", + "LIVE_DEV_STYLER_EYEDROPPER": "Pick color from page", "LIVE_DEV_MORE_OPTIONS_CUT": "Cut", "LIVE_DEV_MORE_OPTIONS_COPY": "Copy", "LIVE_DEV_MORE_OPTIONS_PASTE": "Paste",