Skip to content

Commit 77e4825

Browse files
committed
fix: highlighting animation not working as expected
1 parent 40e55cb commit 77e4825

File tree

1 file changed

+87
-105
lines changed

1 file changed

+87
-105
lines changed

src/LiveDevelopment/BrowserScripts/RemoteFunctions.js

Lines changed: 87 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -19,27 +19,6 @@ function RemoteFunctions(config = {}) {
1919
__description: "Use this to keep shared state for Live Preview Edit instead of window.*"
2020
};
2121

22-
let _hoverHighlight;
23-
let _clickHighlight;
24-
let _hoverLockTimer = null;
25-
26-
// this will store the element that was clicked previously (before the new click)
27-
// we need this so that we can remove click styling from the previous element when a new element is clicked
28-
let previouslyClickedElement = null;
29-
30-
var req, timeout;
31-
function animateHighlight(time) {
32-
if(req) {
33-
window.cancelAnimationFrame(req);
34-
window.clearTimeout(timeout);
35-
}
36-
req = window.requestAnimationFrame(redrawHighlights);
37-
38-
timeout = setTimeout(function () {
39-
window.cancelAnimationFrame(req);
40-
req = null;
41-
}, time * 1000);
42-
}
4322

4423
// the following fucntions can be in the handler and live preview will call those functions when the below
4524
// events happen
@@ -72,6 +51,7 @@ function RemoteFunctions(config = {}) {
7251
];
7352

7453
const _toolHandlers = new Map();
54+
7555
function registerToolHandler(handlerName, handler) {
7656
if(_toolHandlers.get(handlerName)) {
7757
console.error(`lp: Tool handler '${handlerName}' already registered. Ignoring new registration`);
@@ -90,13 +70,49 @@ function RemoteFunctions(config = {}) {
9070
}
9171
_toolHandlers.set(handlerName, handler);
9272
}
73+
9374
function getToolHandler(handlerName) {
9475
return _toolHandlers.get(handlerName);
9576
}
77+
9678
function getAllToolHandlers() {
9779
return Array.from(_toolHandlers.values());
9880
}
9981

82+
const LivePreviewView = {
83+
registerToolHandler: registerToolHandler,
84+
getToolHandler: getToolHandler,
85+
getAllToolHandlers: getAllToolHandlers,
86+
isElementEditable: isElementEditable,
87+
isElementInspectable: isElementInspectable,
88+
isElementVisible: isElementVisible,
89+
screenOffset: screenOffset,
90+
selectElement: selectElement,
91+
brieflyDisableHoverListeners: brieflyDisableHoverListeners,
92+
handleElementClick: handleElementClick,
93+
cleanupPreviousElementState: cleanupPreviousElementState
94+
};
95+
96+
97+
// this will store the element that was clicked previously (before the new click)
98+
// we need this so that we can remove click styling from the previous element when a new element is clicked
99+
let previouslyClickedElement = null;
100+
101+
// helper function to check if an element is inside the HEAD tag
102+
// we need this because we don't wanna trigger the element highlights on head tag and its children,
103+
// except for <style> tags which should be allowed
104+
function _isInsideHeadTag(element) {
105+
let parent = element;
106+
while (parent && parent !== window.document) {
107+
if (parent.tagName.toLowerCase() === "head") {
108+
// allow <style> tags inside <head>
109+
return element.tagName.toLowerCase() !== "style";
110+
}
111+
parent = parent.parentElement;
112+
}
113+
return false;
114+
}
115+
100116
/**
101117
* check if an element is inspectable.
102118
* inspectable elements are those which doesn't have GLOBALS.DATA_BRACKETS_ID_ATTR ('data-brackets-id'),
@@ -154,56 +170,6 @@ function RemoteFunctions(config = {}) {
154170
return { left: offsetLeft, top: offsetTop };
155171
}
156172

157-
const LivePreviewView = {
158-
registerToolHandler: registerToolHandler,
159-
getToolHandler: getToolHandler,
160-
getAllToolHandlers: getAllToolHandlers,
161-
isElementEditable: isElementEditable,
162-
isElementInspectable: isElementInspectable,
163-
isElementVisible: isElementVisible,
164-
screenOffset: screenOffset,
165-
selectElement: selectElement,
166-
brieflyDisableHoverListeners: brieflyDisableHoverListeners,
167-
handleElementClick: handleElementClick,
168-
cleanupPreviousElementState: cleanupPreviousElementState
169-
};
170-
171-
/**
172-
* @type {DOMEditHandler}
173-
*/
174-
var _editHandler;
175-
176-
// the below code comment is replaced by added scripts for extensibility
177-
// DONT_STRIP_MINIFY:REPLACE_WITH_ADDED_REMOTE_CONSTANT_SCRIPTS
178-
179-
// helper function to check if an element is inside the HEAD tag
180-
// we need this because we don't wanna trigger the element highlights on head tag and its children,
181-
// except for <style> tags which should be allowed
182-
function _isInsideHeadTag(element) {
183-
let parent = element;
184-
while (parent && parent !== window.document) {
185-
if (parent.tagName.toLowerCase() === "head") {
186-
// allow <style> tags inside <head>
187-
return element.tagName.toLowerCase() !== "style";
188-
}
189-
parent = parent.parentElement;
190-
}
191-
return false;
192-
}
193-
194-
// set an event on a element
195-
function _trigger(element, name, value, autoRemove) {
196-
var key = "data-ld-" + name;
197-
if (value !== undefined && value !== null) {
198-
element.setAttribute(key, value);
199-
if (autoRemove) {
200-
window.setTimeout(element.removeAttribute.bind(element, key));
201-
}
202-
} else {
203-
element.removeAttribute(key);
204-
}
205-
}
206-
207173
// Checks if the element is in Viewport in the client browser
208174
function isInViewport(element) {
209175
var rect = element.getBoundingClientRect();
@@ -249,6 +215,42 @@ function RemoteFunctions(config = {}) {
249215
return element.offsetTop + (element.offsetParent ? getDocumentOffsetTop(element.offsetParent) : 0);
250216
}
251217

218+
// the below code comment is replaced by added scripts for extensibility
219+
// DONT_STRIP_MINIFY:REPLACE_WITH_ADDED_REMOTE_CONSTANT_SCRIPTS
220+
221+
222+
223+
let _hoverHighlight;
224+
let _clickHighlight;
225+
let _hoverLockTimer = null;
226+
227+
// set an event on a element
228+
function _trigger(element, name, value, autoRemove) {
229+
var key = "data-ld-" + name;
230+
if (value !== undefined && value !== null) {
231+
element.setAttribute(key, value);
232+
if (autoRemove) {
233+
window.setTimeout(element.removeAttribute.bind(element, key));
234+
}
235+
} else {
236+
element.removeAttribute(key);
237+
}
238+
}
239+
240+
var req, timeout;
241+
function animateHighlight(time) {
242+
if(req) {
243+
window.cancelAnimationFrame(req);
244+
window.clearTimeout(timeout);
245+
}
246+
req = window.requestAnimationFrame(redrawHighlights);
247+
248+
timeout = setTimeout(function () {
249+
window.cancelAnimationFrame(req);
250+
req = null;
251+
}, time * 1000);
252+
}
253+
252254
function Highlight(color, trigger) {
253255
this.color = color;
254256
this.trigger = !!trigger;
@@ -479,7 +481,7 @@ function RemoteFunctions(config = {}) {
479481

480482
var transitionValues = {
481483
"transition-property": "opacity, background-color, transform",
482-
"transition-duration": "300ms, 2.3s"
484+
"transition-duration": "300ms, 2.6s"
483485
};
484486

485487
function _setStyleValues(styleValues, obj) {
@@ -594,21 +596,16 @@ function RemoteFunctions(config = {}) {
594596
return false;
595597
}
596598

597-
// if _hoverHighlight is uninitialized, initialize it
598-
if (!_hoverHighlight && shouldShowHighlightOnHover()) {
599-
_hoverHighlight = new Highlight("#c8f9c5", true);
600-
}
601-
602599
// this is to check the user's settings, if they want to show the elements highlights on hover or click
603-
if (_hoverHighlight && shouldShowHighlightOnHover()) {
604-
_hoverHighlight.clear();
600+
if (shouldShowHighlightOnHover()) {
601+
hideHighlight();
602+
_hoverHighlight = new Highlight("#c8f9c5", true);
603+
_hoverHighlight.add(element, false);
605604

606605
// Store original background color to restore on hover out
607606
element._originalBackgroundColor = element.style.backgroundColor;
608607
element.style.backgroundColor = "rgba(0, 162, 255, 0.2)";
609608

610-
_hoverHighlight.add(element, false);
611-
612609
// create the info box for the hovered element
613610
const infoBoxHandler = LivePreviewView.getToolHandler("InfoBox");
614611
if (infoBoxHandler) {
@@ -657,6 +654,7 @@ function RemoteFunctions(config = {}) {
657654
* @param {Element} element - The DOM element to select
658655
*/
659656
function selectElement(element) {
657+
hideHighlight();
660658
dismissUIAndCleanupState();
661659
// this should also be there when users are in highlight mode
662660
scrollElementToViewPort(element);
@@ -688,18 +686,7 @@ function RemoteFunctions(config = {}) {
688686
const outlineColor = element.hasAttribute(GLOBALS.DATA_BRACKETS_ID_ATTR) ? "#4285F4" : "#3C3F41";
689687
element.style.outline = `1px solid ${outlineColor}`;
690688

691-
// Only apply background tint for editable elements (not for dynamic/read-only)
692-
if (element.hasAttribute(GLOBALS.DATA_BRACKETS_ID_ATTR)) {
693-
if (element._originalBackgroundColor === undefined) {
694-
element._originalBackgroundColor = element.style.backgroundColor;
695-
}
696-
element.style.backgroundColor = "rgba(0, 162, 255, 0.2)";
697-
}
698-
699-
if (!_clickHighlight) {
700-
_clickHighlight = new Highlight("#cfc");
701-
}
702-
_clickHighlight.clear();
689+
_clickHighlight = new Highlight("#cfc");
703690
_clickHighlight.add(element, true);
704691

705692
previouslyClickedElement = element;
@@ -731,7 +718,7 @@ function RemoteFunctions(config = {}) {
731718
_hoverLockTimer = setTimeout(() => {
732719
enableHoverListeners();
733720
_hoverLockTimer = null;
734-
}, 800);
721+
}, 600);
735722
}
736723

737724
/**
@@ -871,6 +858,11 @@ function RemoteFunctions(config = {}) {
871858

872859
window.addEventListener("resize", redrawEverything);
873860

861+
/**
862+
* @type {DOMEditHandler}
863+
*/
864+
var _editHandler;
865+
874866
/**
875867
* Constructor
876868
* @param {Document} htmlDocument
@@ -1194,16 +1186,7 @@ function RemoteFunctions(config = {}) {
11941186
* when config is changed we clear all the highlighting and stuff
11951187
*/
11961188
function _handleConfigurationChange() {
1197-
if (_hoverHighlight) {
1198-
_hoverHighlight.clear();
1199-
}
1200-
cleanupPreviousElementState();
1201-
const allElements = window.document.querySelectorAll(`[${GLOBALS.DATA_BRACKETS_ID_ATTR}]`);
1202-
for (let i = 0; i < allElements.length; i++) {
1203-
if (allElements[i]._originalBackgroundColor !== undefined) {
1204-
clearElementBackground(allElements[i]);
1205-
}
1206-
}
1189+
hideHighlight();
12071190
dismissUIAndCleanupState();
12081191
}
12091192

@@ -1219,7 +1202,6 @@ function RemoteFunctions(config = {}) {
12191202
}
12201203
delete previouslyClickedElement._originalOutline;
12211204

1222-
clearElementBackground(previouslyClickedElement);
12231205
hideHighlight();
12241206

12251207
// Notify handlers about cleanup

0 commit comments

Comments
 (0)