@@ -127,9 +127,8 @@ function RemoteFunctions(config = {}) {
127127 * inspectable elements are those which doesn't have GLOBALS.DATA_BRACKETS_ID_ATTR ('data-brackets-id'),
128128 * this normally happens when content is DOM content is inserted by some scripting language
129129 *
130- * Elements opted out via `phcode-no-lp-edit` (cascades to descendants) or
131- * `phcode-no-lp-edit-this` (this element only) are also non-inspectable so
132- * every downstream tool inherits the opt-out automatically.
130+ * The `phcode-no-lp-edit` opt-out is not part of this check: it only keeps the
131+ * pointer off an element, see isPointerEditOptedOut.
133132 *
134133 * @param {DOMElement } element
135134 * @param {boolean } [onlyHighlight=false] - If true, bypasses the mode check
@@ -144,8 +143,7 @@ function RemoteFunctions(config = {}) {
144143 element . tagName . toLowerCase ( ) !== "html" && // shouldn't be the HTML tag
145144 // this attribute is used by phoenix internal elements
146145 ! element . closest ( `[${ GLOBALS . PHCODE_INTERNAL_ATTR } ]` ) &&
147- ! _isInsideHeadTag ( element ) && // shouldn't be inside the head tag like meta tags and all
148- ! _isEditOptedOut ( element ) ) {
146+ ! _isInsideHeadTag ( element ) ) { // shouldn't be inside the head tag like meta tags and all
149147 return true ;
150148 }
151149 return false ;
@@ -157,21 +155,24 @@ function RemoteFunctions(config = {}) {
157155 return ! ! ( element && element . tagName && element . tagName . toLowerCase ( ) === "body" ) ;
158156 }
159157
160- // a named selection lifts the `phcode-no-lp-edit` opt-out and the body block, both pointer-only guards
158+ // a named selection lifts the body block, a pointer-only guard
161159 function _isNamedSelection ( element ) {
162160 return ! ! element && element === _namedSelection ;
163161 }
164162
165163 /**
164+ * Whether the page keeps pointer actions on this element to itself: hover,
165+ * click, double click and drops in the live preview leave it alone, so its
166+ * own widgets keep working. It is still an element like any other to every
167+ * path that is not the pointer - the layers panel, the caret, the tools.
166168 * `phcode-no-lp-edit` cascades to descendants, `phcode-no-lp-edit-this` covers
167169 * the one element.
170+ * @param {DOMElement } element
171+ * @returns {boolean }
168172 */
169- function _isEditOptedOut ( element ) {
170- if ( _isNamedSelection ( element ) ) {
171- return false ;
172- }
173- return ! ! ( element . closest ( '.phcode-no-lp-edit' ) ||
174- ( element . classList && element . classList . contains ( 'phcode-no-lp-edit-this' ) ) ) ;
173+ function isPointerEditOptedOut ( element ) {
174+ return ! ! ( element && element . closest && ( element . closest ( '.phcode-no-lp-edit' ) ||
175+ ( element . classList && element . classList . contains ( 'phcode-no-lp-edit-this' ) ) ) ) ;
175176 }
176177
177178 /**
@@ -250,6 +251,7 @@ function RemoteFunctions(config = {}) {
250251 getAllToolHandlers : getAllToolHandlers ,
251252 isElementEditable : isElementEditable ,
252253 isElementInspectable : isElementInspectable ,
254+ isPointerEditOptedOut : isPointerEditOptedOut ,
253255 isBodyElement : isBodyElement ,
254256 isSourceless : isSourceless ,
255257 getElementRef : getElementRef ,
@@ -751,7 +753,7 @@ function RemoteFunctions(config = {}) {
751753 return ;
752754 }
753755 if ( isBodyElement ( element ) || ! LivePreviewView . isElementInspectable ( element ) ||
754- element . nodeType !== Node . ELEMENT_NODE ) {
756+ isPointerEditOptedOut ( element ) || element . nodeType !== Node . ELEMENT_NODE ) {
755757 return ;
756758 }
757759 _lastHoverTarget = element ;
@@ -830,7 +832,7 @@ function RemoteFunctions(config = {}) {
830832 }
831833
832834 dismissUIAndCleanupState ( ) ;
833- // set after the dismissal, which clears the previous selection's exemption
835+ // set after the dismissal, which clears the previous selection's body exemption
834836 _namedSelection = byName ? element : null ;
835837 // this should also be there when users are in highlight mode
836838 scrollElementToViewPort ( element ) ;
@@ -1008,8 +1010,7 @@ function RemoteFunctions(config = {}) {
10081010 return ;
10091011 }
10101012 // Opted-out elements: silent no-op so the user's existing selection isn't dismissed.
1011- // (isElementInspectable would also reject them, but that path runs dismissUIAndCleanupState.)
1012- if ( element && ( element . closest ( '.phcode-no-lp-edit' ) || element . classList . contains ( 'phcode-no-lp-edit-this' ) ) ) {
1013+ if ( isPointerEditOptedOut ( element ) ) {
10131014 return ;
10141015 }
10151016 // a blank-space click lands on the body and deselects, even a body selected by name
@@ -1037,8 +1038,10 @@ function RemoteFunctions(config = {}) {
10371038 * the same way without a pointer gesture ever touching the page.
10381039 *
10391040 * @param {HTMLElement } element
1041+ * @param {boolean= } requested - the editor side asked for this selection, so it keeps its
1042+ * focus and reads the report as the echo of its own pick
10401043 */
1041- function sendSelectionToEditor ( element ) {
1044+ function sendSelectionToEditor ( element , requested ) {
10421045 if ( config . syncSourceAndPreview === false ) {
10431046 return ;
10441047 }
@@ -1052,7 +1055,8 @@ function RemoteFunctions(config = {}) {
10521055 "nodeName" : element . nodeName ,
10531056 "allSelectors" : window . getAllInheritedSelectorsInOrder ( element ) ,
10541057 "contentEditable" : element . contentEditable === "true" ,
1055- "clicked" : true
1058+ "clicked" : true ,
1059+ "requested" : ! ! requested
10561060 } ) ;
10571061 }
10581062
0 commit comments