Skip to content

Commit f0c7eb9

Browse files
committed
refactor: improved code readability
1 parent 738737c commit f0c7eb9

File tree

1 file changed

+86
-141
lines changed

1 file changed

+86
-141
lines changed

src/LiveDevelopment/BrowserScripts/RemoteFunctions.js

Lines changed: 86 additions & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,29 @@ function RemoteFunctions(config = {}) {
113113
return event.ctrlKey;
114114
}
115115

116+
/**
117+
* This is a checker function for editable elements, it makes sure that the element satisfies all the required checks
118+
* - When onlyHighlight is false → config.isLPEditFeaturesActive must be true
119+
* - When onlyHighlight is true → config.isLPEditFeaturesActive can be true or false (doesn't matter)
120+
* @param {DOMElement} element
121+
* @param {boolean} [onlyHighlight=false] - If true, bypasses the isLPEditFeaturesActive check
122+
* @returns {boolean} - True if the element is editable else false
123+
*/
124+
function isElementEditable(element, onlyHighlight = false) {
125+
if(!config.isLPEditFeaturesActive && !onlyHighlight) {
126+
return false;
127+
}
128+
129+
if(element && // element should exist
130+
element.hasAttribute("data-brackets-id") && // should have the data-brackets-id attribute
131+
element.tagName !== "BODY" && // shouldn't be the body tag
132+
element.tagName !== "HTML" && // shouldn't be the HTML tag
133+
!_isInsideHeadTag(element)) { // shouldn't be inside the head tag like meta tags and all
134+
return true;
135+
}
136+
return false;
137+
}
138+
116139
// helper function to check if an element is inside the HEAD tag
117140
// we need this because we don't wanna trigger the element highlights on head tag and its children
118141
function _isInsideHeadTag(element) {
@@ -224,9 +247,9 @@ function RemoteFunctions(config = {}) {
224247
* @param {DOMElement} element - the HTML DOM element that was clicked. it is to get the data-brackets-id attribute
225248
*/
226249
function _handleDeleteOptionClick(event, element) {
227-
const tagId = element.getAttribute("data-brackets-id");
250+
if (isElementEditable(element)) {
251+
const tagId = element.getAttribute("data-brackets-id");
228252

229-
if (tagId && element.tagName !== "BODY" && element.tagName !== "HTML" && !_isInsideHeadTag(element)) {
230253
window._Brackets_MessageBroker.send({
231254
livePreviewEditEnabled: true,
232255
element: element,
@@ -245,9 +268,9 @@ function RemoteFunctions(config = {}) {
245268
* @param {DOMElement} element - the HTML DOM element that was clicked. it is to get the data-brackets-id attribute
246269
*/
247270
function _handleDuplicateOptionClick(event, element) {
248-
const tagId = element.getAttribute("data-brackets-id");
271+
if (isElementEditable(element)) {
272+
const tagId = element.getAttribute("data-brackets-id");
249273

250-
if (tagId && element.tagName !== "BODY" && element.tagName !== "HTML" && !_isInsideHeadTag(element)) {
251274
window._Brackets_MessageBroker.send({
252275
livePreviewEditEnabled: true,
253276
element: element,
@@ -267,23 +290,12 @@ function RemoteFunctions(config = {}) {
267290
* @param {DOMElement} element - the HTML DOM element that was clicked. it is to get the data-brackets-id attribute
268291
*/
269292
function _handleSelectParentOptionClick(event, element) {
270-
if (!element) {
293+
if (!isElementEditable(element)) {
271294
return;
272295
}
273296

274297
const parentElement = element.parentElement;
275-
if (!parentElement) {
276-
return;
277-
}
278-
279-
// we need to make sure that the parent element is not the body tag or the html.
280-
// also we expect it to have the 'data-brackets-id'
281-
if (
282-
parentElement.tagName !== "BODY" &&
283-
parentElement.tagName !== "HTML" &&
284-
!_isInsideHeadTag(parentElement) &&
285-
parentElement.hasAttribute("data-brackets-id")
286-
) {
298+
if (isElementEditable(parentElement)) {
287299
parentElement.click();
288300
} else {
289301
console.error("The TagID might be unavailable or the parent element tag is directly body or html");
@@ -1072,19 +1084,14 @@ function RemoteFunctions(config = {}) {
10721084
* @returns {boolean} - true if we should show the select parent option otherwise false
10731085
*/
10741086
function _shouldShowSelectParentOption(element) {
1075-
if (!element || !element.parentElement) {
1087+
if(!isElementEditable(element)) {
10761088
return false;
10771089
}
10781090

10791091
const parentElement = element.parentElement;
1080-
1081-
if (parentElement.tagName === "HTML" || parentElement.tagName === "BODY" || _isInsideHeadTag(parentElement)) {
1082-
return false;
1083-
}
1084-
if (!parentElement.hasAttribute("data-brackets-id")) {
1092+
if(!isElementEditable(parentElement)) {
10851093
return false;
10861094
}
1087-
10881095
return true;
10891096
}
10901097

@@ -1825,7 +1832,7 @@ function RemoteFunctions(config = {}) {
18251832

18261833
_handleSend: function(event, prompt) {
18271834
const element = this.element;
1828-
if(!element) {
1835+
if(!isElementEditable(element)) {
18291836
return;
18301837
}
18311838
const tagId = element.getAttribute("data-brackets-id");
@@ -2173,10 +2180,9 @@ function RemoteFunctions(config = {}) {
21732180

21742181
function onMouseOver(event) {
21752182
if (_validEvent(event)) {
2176-
// Skip highlighting for HTML, BODY tags and elements inside HEAD
2177-
if (event.target && event.target.nodeType === Node.ELEMENT_NODE &&
2178-
event.target.tagName !== "HTML" && event.target.tagName !== "BODY" && !_isInsideHeadTag(event.target)) {
2179-
_localHighlight.add(event.target, true, false); // false means no-auto scroll
2183+
const element = event.target;
2184+
if(isElementEditable(element) && element.nodeType === Node.ELEMENT_NODE ) {
2185+
_localHighlight.add(element, true, false); // false means no-auto scroll
21802186
}
21812187
}
21822188
}
@@ -2205,17 +2211,6 @@ function RemoteFunctions(config = {}) {
22052211

22062212
// helper function to clear element background highlighting
22072213
function clearElementBackground(element) {
2208-
// make sure that the feature is enabled and also the element has the attribute 'data-brackets-id'
2209-
if (
2210-
!config.isLPEditFeaturesActive ||
2211-
!element.hasAttribute("data-brackets-id") ||
2212-
element.tagName === "BODY" ||
2213-
element.tagName === "HTML" ||
2214-
_isInsideHeadTag(element)
2215-
) {
2216-
return;
2217-
}
2218-
22192214
if (element._originalBackgroundColor !== undefined) {
22202215
element.style.backgroundColor = element._originalBackgroundColor;
22212216
} else {
@@ -2235,36 +2230,29 @@ function RemoteFunctions(config = {}) {
22352230
return;
22362231
}
22372232

2233+
const element = event.target;
2234+
if(!isElementEditable(element) || element.nodeType !== Node.ELEMENT_NODE) {
2235+
return false;
2236+
}
2237+
22382238
// if _hoverHighlight is uninitialized, initialize it
2239-
if (!_hoverHighlight && config.isLPEditFeaturesActive && shouldShowHighlightOnHover()) {
2239+
if (!_hoverHighlight && shouldShowHighlightOnHover()) {
22402240
_hoverHighlight = new Highlight("#c8f9c5", true);
22412241
}
22422242

22432243
// this is to check the user's settings, if they want to show the elements highlights on hover or click
2244-
if (_hoverHighlight && config.isLPEditFeaturesActive && shouldShowHighlightOnHover()) {
2244+
if (_hoverHighlight && shouldShowHighlightOnHover()) {
22452245
_hoverHighlight.clear();
22462246

2247-
// Skip highlighting for HTML, BODY tags and elements inside HEAD
2248-
// and for DOM elements which doesn't have 'data-brackets-id'
2249-
// NOTE: Don't remove 'data-brackets-id' check else hover will also target internal live preview elements
2250-
if (
2251-
event.target &&
2252-
event.target.nodeType === Node.ELEMENT_NODE &&
2253-
event.target.tagName !== "HTML" &&
2254-
event.target.tagName !== "BODY" &&
2255-
!_isInsideHeadTag(event.target) &&
2256-
event.target.hasAttribute("data-brackets-id")
2257-
) {
2258-
// Store original background color to restore on hover out
2259-
event.target._originalBackgroundColor = event.target.style.backgroundColor;
2260-
event.target.style.backgroundColor = "rgba(0, 162, 255, 0.2)";
2261-
2262-
_hoverHighlight.add(event.target, false, false); // false means no auto-scroll
2263-
2264-
// Create info box for the hovered element
2265-
dismissNodeInfoBox();
2266-
_nodeInfoBox = new NodeInfoBox(event.target);
2267-
}
2247+
// Store original background color to restore on hover out
2248+
element._originalBackgroundColor = element.style.backgroundColor;
2249+
element.style.backgroundColor = "rgba(0, 162, 255, 0.2)";
2250+
2251+
_hoverHighlight.add(element, false, false); // false means no auto-scroll
2252+
2253+
// Create info box for the hovered element
2254+
dismissNodeInfoBox();
2255+
_nodeInfoBox = new NodeInfoBox(element);
22682256
}
22692257
}
22702258

@@ -2274,23 +2262,15 @@ function RemoteFunctions(config = {}) {
22742262
return;
22752263
}
22762264

2277-
// this is to check the user's settings, if they want to show the elements highlights on hover or click
2278-
if (_hoverHighlight && config.isLPEditFeaturesActive && shouldShowHighlightOnHover()) {
2279-
_hoverHighlight.clear();
2280-
2281-
// Restore original background color
2282-
if (
2283-
event &&
2284-
event.target &&
2285-
event.target.nodeType === Node.ELEMENT_NODE &&
2286-
event.target.hasAttribute("data-brackets-id")
2287-
) {
2288-
clearElementBackground(event.target);
2265+
const element = event.target;
2266+
if(isElementEditable(element) && element.nodeType === Node.ELEMENT_NODE) {
2267+
// this is to check the user's settings, if they want to show the elements highlights on hover or click
2268+
if (_hoverHighlight && shouldShowHighlightOnHover()) {
2269+
_hoverHighlight.clear();
2270+
clearElementBackground(element);
22892271
}
2290-
2291-
// Remove info box when mouse leaves the element
2292-
dismissNodeInfoBox();
22932272
}
2273+
dismissNodeInfoBox();
22942274
}
22952275

22962276
/**
@@ -2300,16 +2280,8 @@ function RemoteFunctions(config = {}) {
23002280
function _selectElement(element) {
23012281
// dismiss all UI boxes and cleanup previous element state when selecting a different element
23022282
dismissUIAndCleanupState();
2303-
2304-
// make sure that the feature is enabled and also the element has the attribute 'data-brackets-id'
2305-
if (
2306-
!config.isLPEditFeaturesActive ||
2307-
!element.hasAttribute("data-brackets-id") ||
2308-
element.tagName === "BODY" ||
2309-
element.tagName === "HTML" ||
2310-
_isInsideHeadTag(element)
2311-
) {
2312-
return;
2283+
if(!isElementEditable(element)) {
2284+
return false;
23132285
}
23142286

23152287
// make sure that the element is actually visible to the user
@@ -2344,25 +2316,17 @@ function RemoteFunctions(config = {}) {
23442316
*/
23452317
function onClick(event) {
23462318
dismissAIPromptBox();
2319+
const element = event.target;
23472320

2348-
// make sure that the feature is enabled and also the clicked element has the attribute 'data-brackets-id'
2349-
if (
2350-
config.isLPEditFeaturesActive &&
2351-
event.target.hasAttribute("data-brackets-id") &&
2352-
event.target.tagName !== "BODY" &&
2353-
event.target.tagName !== "HTML" &&
2354-
!_isInsideHeadTag(event.target)
2355-
) {
2321+
// when user clicks on the HTML, BODY tags or elements inside HEAD, we want to remove the boxes
2322+
if(_nodeMoreOptionsBox && !isElementEditable(element)) {
2323+
dismissUIAndCleanupState();
2324+
} else if(isElementEditable(element)) {
23562325
event.preventDefault();
23572326
event.stopPropagation();
23582327
event.stopImmediatePropagation();
23592328

2360-
_selectElement(event.target);
2361-
} else if ( // when user clicks on the HTML, BODY tags or elements inside HEAD, we want to remove the boxes
2362-
_nodeMoreOptionsBox &&
2363-
(event.target.tagName === "HTML" || event.target.tagName === "BODY" || _isInsideHeadTag(event.target))
2364-
) {
2365-
dismissUIAndCleanupState();
2329+
_selectElement(element);
23662330
}
23672331
}
23682332

@@ -2371,18 +2335,13 @@ function RemoteFunctions(config = {}) {
23712335
* @param {Event} event
23722336
*/
23732337
function onDoubleClick(event) {
2374-
if (
2375-
config.isLPEditFeaturesActive &&
2376-
event.target.hasAttribute("data-brackets-id") &&
2377-
event.target.tagName !== "BODY" &&
2378-
event.target.tagName !== "HTML" &&
2379-
!_isInsideHeadTag(event.target)
2380-
) {
2338+
const element = event.target;
2339+
if (isElementEditable(element)) {
23812340
// because we only want to allow double click text editing where we show the edit option
2382-
if (_shouldShowEditTextOption(event.target)) {
2341+
if (_shouldShowEditTextOption(element)) {
23832342
event.preventDefault();
23842343
event.stopPropagation();
2385-
startEditing(event.target);
2344+
startEditing(element);
23862345
}
23872346
}
23882347
}
@@ -2425,18 +2384,16 @@ function RemoteFunctions(config = {}) {
24252384
}
24262385
}
24272386

2428-
// highlight a node
2429-
function highlight(node, clear) {
2387+
// highlight an element
2388+
function highlight(element, clear) {
24302389
if (!_clickHighlight) {
24312390
_clickHighlight = new Highlight("#cfc");
24322391
}
24332392
if (clear) {
24342393
_clickHighlight.clear();
24352394
}
2436-
// Skip highlighting for HTML, BODY tags and elements inside HEAD
2437-
if (node && node.nodeType === Node.ELEMENT_NODE &&
2438-
node.tagName !== "HTML" && node.tagName !== "BODY" && !_isInsideHeadTag(node)) {
2439-
_clickHighlight.add(node, true, true); // 3rd arg is for auto-scroll
2395+
if (isElementEditable(element, true) && element.nodeType === Node.ELEMENT_NODE) {
2396+
_clickHighlight.add(element, true, true); // 3rd arg is for auto-scroll
24402397
}
24412398
}
24422399

@@ -2455,12 +2412,7 @@ function RemoteFunctions(config = {}) {
24552412
// select the first valid highlighted element
24562413
var foundValidElement = false;
24572414
for (i = 0; i < nodes.length; i++) {
2458-
if (nodes[i].hasAttribute("data-brackets-id") &&
2459-
nodes[i].tagName !== "HTML" &&
2460-
nodes[i].tagName !== "BODY" &&
2461-
!_isInsideHeadTag(nodes[i]) &&
2462-
nodes[i].tagName !== "BR"
2463-
) {
2415+
if(isElementEditable(nodes[i], true) && nodes[i].tagName !== "BR") {
24642416
_selectElement(nodes[i]);
24652417
foundValidElement = true;
24662418
break;
@@ -3015,12 +2967,7 @@ function RemoteFunctions(config = {}) {
30152967

30162968
// Function to handle direct editing of elements in the live preview
30172969
function startEditing(element) {
3018-
if (!config.isLPEditFeaturesActive
3019-
|| !element
3020-
|| element.tagName === "BODY"
3021-
|| element.tagName === "HTML"
3022-
|| _isInsideHeadTag(element)
3023-
|| !element.hasAttribute("data-brackets-id")) {
2970+
if (!isElementEditable(element)) {
30242971
return;
30252972
}
30262973

@@ -3065,7 +3012,7 @@ function RemoteFunctions(config = {}) {
30653012
// Function to finish editing and apply changes
30663013
// isEditSuccessful: this is a boolean value, defaults to true. false only when the edit operation is cancelled
30673014
function finishEditing(element, isEditSuccessful = true) {
3068-
if (!config.isLPEditFeaturesActive || !element || !element.hasAttribute("contenteditable")) {
3015+
if (!isElementEditable(element) || !element.hasAttribute("contenteditable")) {
30693016
return;
30703017
}
30713018

@@ -3080,17 +3027,15 @@ function RemoteFunctions(config = {}) {
30803027
delete element._editListeners;
30813028
}
30823029

3083-
if (element.hasAttribute("data-brackets-id")) {
3084-
const tagId = element.getAttribute("data-brackets-id");
3085-
window._Brackets_MessageBroker.send({
3086-
livePreviewEditEnabled: true,
3087-
livePreviewTextEdit: true,
3088-
element: element,
3089-
newContent: element.outerHTML,
3090-
tagId: Number(tagId),
3091-
isEditSuccessful: isEditSuccessful
3092-
});
3093-
}
3030+
const tagId = element.getAttribute("data-brackets-id");
3031+
window._Brackets_MessageBroker.send({
3032+
livePreviewEditEnabled: true,
3033+
livePreviewTextEdit: true,
3034+
element: element,
3035+
newContent: element.outerHTML,
3036+
tagId: Number(tagId),
3037+
isEditSuccessful: isEditSuccessful
3038+
});
30943039
}
30953040

30963041
// init

0 commit comments

Comments
 (0)