diff --git a/docs/API-Reference/command/Commands.md b/docs/API-Reference/command/Commands.md index 24bad4cd08..d535db0d51 100644 --- a/docs/API-Reference/command/Commands.md +++ b/docs/API-Reference/command/Commands.md @@ -986,7 +986,7 @@ Opens git settings ## CMD\_GIT\_CLOSE\_UNMODIFIED Closes unmodified files -**Kind**: global variable +**Kind**: global variable ## CMD\_GIT\_OPEN\_CHANGED\_FILES diff --git a/src-node/package-lock.json b/src-node/package-lock.json index 673a465423..a9fac4c791 100644 --- a/src-node/package-lock.json +++ b/src-node/package-lock.json @@ -88,9 +88,6 @@ "cpu": [ "arm64" ], - "libc": [ - "glibc" - ], "license": "SEE LICENSE IN LICENSE.md", "optional": true, "os": [ @@ -104,9 +101,6 @@ "cpu": [ "arm64" ], - "libc": [ - "musl" - ], "license": "SEE LICENSE IN LICENSE.md", "optional": true, "os": [ @@ -120,9 +114,6 @@ "cpu": [ "x64" ], - "libc": [ - "glibc" - ], "license": "SEE LICENSE IN LICENSE.md", "optional": true, "os": [ @@ -136,9 +127,6 @@ "cpu": [ "x64" ], - "libc": [ - "musl" - ], "license": "SEE LICENSE IN LICENSE.md", "optional": true, "os": [ diff --git a/src/LiveDevelopment/BrowserScripts/RemoteFunctions.js b/src/LiveDevelopment/BrowserScripts/RemoteFunctions.js index b09735221d..29862d96b7 100644 --- a/src/LiveDevelopment/BrowserScripts/RemoteFunctions.js +++ b/src/LiveDevelopment/BrowserScripts/RemoteFunctions.js @@ -26,7 +26,8 @@ function RemoteFunctions(config = {}) { const SHARED_STATE = { __description: "Use this to keep shared state for Live Preview Edit instead of window.*", _suppressDOMEditDismissal: false, - _suppressDOMEditDismissalTimeout: null + _suppressDOMEditDismissalTimeout: null, + _boxModelHighlightHidden: false }; let _hoverHighlight; @@ -190,7 +191,10 @@ function RemoteFunctions(config = {}) { disableHoverListeners: disableHoverListeners, enableHoverListeners: enableHoverListeners, redrawHighlights: redrawHighlights, - redrawEverything: redrawEverything + redrawEverything: redrawEverything, + getTreePath: _getTreePath, + getElementByTreePath: _getElementByTreePath, + getSourceChildren: _instrumentedChildren }; /** @@ -446,15 +450,17 @@ function RemoteFunctions(config = {}) { s.backgroundColor = color; } - // Padding region - const padColor = COLORS.highlightPadding; + // Padding region. Rects stay in place when hidden, only their fill goes away, + // so nothing has to be rebuilt when they come back. + const boxModelHidden = SHARED_STATE._boxModelHighlightHidden; + const padColor = boxModelHidden ? "transparent" : COLORS.highlightPadding; setRect(refs.padTop, paddingBox.left, paddingBox.top, paddingBox.width, pt, padColor); setRect(refs.padBottom, paddingBox.left, contentBox.top + contentBox.height, paddingBox.width, pb, padColor); setRect(refs.padLeft, paddingBox.left, contentBox.top, pl, contentBox.height, padColor); setRect(refs.padRight, contentBox.left + contentBox.width, contentBox.top, pr, contentBox.height, padColor); // Margin region - const margColor = COLORS.highlightMargin; + const margColor = boxModelHidden ? "transparent" : COLORS.highlightMargin; setRect(refs.marTop, marginBox.left, marginBox.top, marginBox.width, mt, margColor); setRect(refs.marBottom, marginBox.left, borderBox.top + borderBox.height, marginBox.width, mb, margColor); setRect(refs.marLeft, marginBox.left, borderBox.top, ml, borderBox.height, margColor); @@ -1054,6 +1060,25 @@ function RemoteFunctions(config = {}) { return results && results[0]; }; + // True for elements Phoenix adds to the page itself, like the tool boxes and + // the highlight overlays. They are not part of the user's source file. + function _isPhoenixInternalNode(node) { + return !!node && node.nodeType === Node.ELEMENT_NODE && + (node.hasAttribute(GLOBALS.PHCODE_INTERNAL_ATTR) || + node.className === GLOBALS.HIGHLIGHT_CLASSNAME); + } + + /** The first of the Phoenix elements sitting at the end of `parent`, else null. */ + function _firstTrailingInternalNode(parent) { + let node = parent.lastChild; + let first = null; + while (_isPhoenixInternalNode(node)) { + first = node; + node = node.previousSibling; + } + return first; + } + /** * @private * Insert a new child element @@ -1068,7 +1093,12 @@ function RemoteFunctions(config = {}) { if (edit.firstChild) { before = targetElement.firstChild; } else if (edit.lastChild) { - after = targetElement.lastChild; + // Phoenix's tool boxes are the last children of
, so appending + // here would put the new element after them, in the wrong place. + before = _firstTrailingInternalNode(targetElement); + if (!before) { + after = targetElement.lastChild; + } } if (before) { @@ -1479,6 +1509,9 @@ function RemoteFunctions(config = {}) { _pendingHoverRAF = null; } + // the selection is gone, so a popover can no longer turn the fills back on + SHARED_STATE._boxModelHighlightHidden = false; + // Highlight.clear() removes all overlay divs (outline + margin/padding rects) hideHighlight(); @@ -1492,27 +1525,38 @@ function RemoteFunctions(config = {}) { } } + // Only the children that came from the source file. Phoenix's own elements have + // no data-brackets-id, and counting them would shift the tree path indexes. + function _instrumentedChildren(parent) { + const result = []; + const children = (parent && parent.children) || []; + for (let i = 0; i < children.length; i++) { + if (children[i].hasAttribute(GLOBALS.DATA_BRACKETS_ID_ATTR)) { + result.push(children[i]); + } + } + return result; + } + /** * Compute the tree path of an element as an array of child indices * from down. Used to re-locate the element after re-instrumentation * when data-brackets-id changes and text matching is ambiguous. * E.g. [1, 0, 0, 1] means html > 2nd child > 1st child > 1st child > 2nd child. + * @return {?Array.