Skip to content

Commit 1373bca

Browse files
committed
feat: show info box even for JS rendered elements
1 parent 90a34c2 commit 1373bca

File tree

1 file changed

+39
-20
lines changed

1 file changed

+39
-20
lines changed

src/LiveDevelopment/BrowserScripts/RemoteFunctions.js

Lines changed: 39 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -117,20 +117,16 @@ function RemoteFunctions(config = {}) {
117117
}
118118

119119
/**
120-
* This is a checker function for editable elements, it makes sure that the element satisfies all the required checks
121-
* - When onlyHighlight is false → config.isProUser must be true
122-
* - When onlyHighlight is true → config.isProUser can be true or false (doesn't matter)
123-
* @param {DOMElement} element
124-
* @param {boolean} [onlyHighlight=false] - If true, bypasses the isProUser check
125-
* @returns {boolean} - True if the element is editable else false
120+
* check if an element is inspectable.
121+
* inspectable elements are those which doesn't have data-brackets-id,
122+
* this normally happens when content is DOM content is inserted by some scripting language
126123
*/
127-
function isElementEditable(element, onlyHighlight = false) {
124+
function isElementInspectable(element, onlyHighlight = false) {
128125
if(!config.isProUser && !onlyHighlight) {
129126
return false;
130127
}
131128

132129
if(element && // element should exist
133-
element.hasAttribute("data-brackets-id") && // should have the data-brackets-id attribute
134130
element.tagName.toLowerCase() !== "body" && // shouldn't be the body tag
135131
element.tagName.toLowerCase() !== "html" && // shouldn't be the HTML tag
136132
!_isInsideHeadTag(element)) { // shouldn't be inside the head tag like meta tags and all
@@ -139,6 +135,20 @@ function RemoteFunctions(config = {}) {
139135
return false;
140136
}
141137

138+
/**
139+
* This is a checker function for editable elements, it makes sure that the element satisfies all the required check
140+
* - When onlyHighlight is false → config.isProUser must be true
141+
* - When onlyHighlight is true → config.isProUser can be true or false (doesn't matter)
142+
* @param {DOMElement} element
143+
* @param {boolean} [onlyHighlight=false] - If true, bypasses the isProUser check
144+
* @returns {boolean} - True if the element is editable else false
145+
*/
146+
function isElementEditable(element, onlyHighlight = false) {
147+
// for an element to be editable it should satisfy all inspectable checks and should also have data-brackets-id
148+
return isElementInspectable(element, onlyHighlight) &&
149+
element.hasAttribute("data-brackets-id");
150+
}
151+
142152
// helper function to check if an element is inside the HEAD tag
143153
// we need this because we don't wanna trigger the element highlights on head tag and its children,
144154
// except for <style> tags which should be allowed
@@ -1781,13 +1791,16 @@ function RemoteFunctions(config = {}) {
17811791
const offset = _screenOffset(this.element);
17821792
const leftPos = offset.left;
17831793

1794+
// if element is non-editable we use gray bg color in info box, otherwise normal blue color
1795+
const bgColor = this.element.hasAttribute('data-brackets-id') ? '#4285F4' : '#666666';
1796+
17841797
const styles = `
17851798
:host {
17861799
all: initial !important;
17871800
}
17881801
17891802
.phoenix-node-info-box {
1790-
background-color: #4285F4 !important;
1803+
background-color: ${bgColor} !important;
17911804
color: white !important;
17921805
border-radius: 3px !important;
17931806
padding: 5px 8px !important;
@@ -3747,7 +3760,7 @@ function RemoteFunctions(config = {}) {
37473760
}
37483761

37493762
const element = event.target;
3750-
if(!isElementEditable(element) || element.nodeType !== Node.ELEMENT_NODE) {
3763+
if(!isElementInspectable(element) || element.nodeType !== Node.ELEMENT_NODE) {
37513764
return false;
37523765
}
37533766

@@ -3814,16 +3827,15 @@ function RemoteFunctions(config = {}) {
38143827
dismissNodeInfoBox();
38153828
cleanupPreviousElementState();
38163829

3817-
// this should always happen before isElementEditable check because this is not a live preview edit feature
38183830
// this should also be there when users are in highlight mode
38193831
scrollElementToViewPort(element);
38203832

3821-
if(!isElementEditable(element)) {
3833+
if(!isElementInspectable(element)) {
38223834
return false;
38233835
}
38243836

3825-
// if imageGallerySelected is true, show the image gallery directly
3826-
if(element && element.tagName.toLowerCase() === 'img' && imageGallerySelected) {
3837+
// if imageGallerySelected is true, show the image gallery directly (only for editable images)
3838+
if(isElementEditable(element) && element && element.tagName.toLowerCase() === 'img' && imageGallerySelected) {
38273839
if (!_imageRibbonGallery || _imageRibbonGallery.element !== element) {
38283840
dismissImageRibbonGallery(); // Dismiss only when creating new
38293841
_imageRibbonGallery = new ImageRibbonGallery(element);
@@ -3836,7 +3848,11 @@ function RemoteFunctions(config = {}) {
38363848

38373849
// make sure that the element is actually visible to the user
38383850
if (isElementVisible(element)) {
3839-
_nodeMoreOptionsBox = new NodeMoreOptionsBox(element);
3851+
// Only show more options box for editable elements (have data-brackets-id)
3852+
if (isElementEditable(element)) {
3853+
_nodeMoreOptionsBox = new NodeMoreOptionsBox(element);
3854+
}
3855+
// Always show info box for inspectable elements
38403856
_nodeInfoBox = new NodeInfoBox(element);
38413857
} else {
38423858
// Element is hidden, so don't show UI boxes but still apply visual styling
@@ -3846,10 +3862,13 @@ function RemoteFunctions(config = {}) {
38463862
element._originalOutline = element.style.outline;
38473863
element.style.outline = "1px solid #4285F4";
38483864

3849-
if (element._originalBackgroundColor === undefined) {
3850-
element._originalBackgroundColor = element.style.backgroundColor;
3865+
// Only apply background tint for editable elements (not for dynamic/read-only)
3866+
if (element.hasAttribute("data-brackets-id")) {
3867+
if (element._originalBackgroundColor === undefined) {
3868+
element._originalBackgroundColor = element.style.backgroundColor;
3869+
}
3870+
element.style.backgroundColor = "rgba(0, 162, 255, 0.2)";
38513871
}
3852-
element.style.backgroundColor = "rgba(0, 162, 255, 0.2)";
38533872

38543873
if (_hoverHighlight) {
38553874
_hoverHighlight.clear();
@@ -3962,7 +3981,7 @@ function RemoteFunctions(config = {}) {
39623981
if (clear) {
39633982
_clickHighlight.clear();
39643983
}
3965-
if (isElementEditable(element, true) && element.nodeType === Node.ELEMENT_NODE) {
3984+
if (isElementInspectable(element, true) && element.nodeType === Node.ELEMENT_NODE) {
39663985
_clickHighlight.add(element, true);
39673986
}
39683987
}
@@ -3982,7 +4001,7 @@ function RemoteFunctions(config = {}) {
39824001
// select the first valid highlighted element
39834002
var foundValidElement = false;
39844003
for (i = 0; i < nodes.length; i++) {
3985-
if(isElementEditable(nodes[i], true) && nodes[i].tagName !== "BR") {
4004+
if(isElementInspectable(nodes[i], true) && nodes[i].tagName !== "BR") {
39864005
_selectElement(nodes[i]);
39874006
foundValidElement = true;
39884007
break;

0 commit comments

Comments
 (0)