diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /devtools/client/inspector/shared/style-change-tracker.js | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'devtools/client/inspector/shared/style-change-tracker.js')
-rw-r--r-- | devtools/client/inspector/shared/style-change-tracker.js | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/devtools/client/inspector/shared/style-change-tracker.js b/devtools/client/inspector/shared/style-change-tracker.js new file mode 100644 index 0000000000..348918cd56 --- /dev/null +++ b/devtools/client/inspector/shared/style-change-tracker.js @@ -0,0 +1,100 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +const EventEmitter = require("resource://devtools/shared/event-emitter.js"); +const WalkerEventListener = require("resource://devtools/client/inspector/shared/walker-event-listener.js"); + +/** + * The InspectorStyleChangeTracker simply emits an event when it detects any changes in + * the page that may cause the current inspector selection to have different style applied + * to it. + * It currently tracks: + * - markup mutations, because they may cause different CSS rules to apply to the current + * node. + * - window resize, because they may cause media query changes and therefore also + * different CSS rules to apply to the current node. + */ +class InspectorStyleChangeTracker { + constructor(inspector) { + this.selection = inspector.selection; + + this.onMutations = this.onMutations.bind(this); + this.onResized = this.onResized.bind(this); + + this.walkerEventListener = new WalkerEventListener(inspector, { + mutations: this.onMutations, + resize: this.onResized, + }); + + EventEmitter.decorate(this); + } + + destroy() { + this.walkerEventListener.destroy(); + this.walkerEventListener = null; + this.selection = null; + } + + /** + * When markup mutations occur, if an attribute of the selected node, one of its + * ancestors or siblings changes, we need to consider this as potentially causing a + * style change for the current node. + */ + onMutations(mutations) { + const canMutationImpactCurrentStyles = ({ + type, + target: mutationTarget, + }) => { + // Only attributes mutations are interesting here. + if (type !== "attributes") { + return false; + } + + // Is the mutation on the current selected node? + const currentNode = this.selection.nodeFront; + if (mutationTarget === currentNode) { + return true; + } + + // Is the mutation on one of the current selected node's siblings? + // We can't know the order of nodes on the client-side without calling + // walker.children, so don't attempt to check the previous or next element siblings. + // It's good enough to know that one sibling changed. + let parent = currentNode.parentNode(); + const siblings = parent.treeChildren(); + if (siblings.includes(mutationTarget)) { + return true; + } + + // Is the mutation on one of the current selected node's parents? + while (parent) { + if (mutationTarget === parent) { + return true; + } + parent = parent.parentNode(); + } + + return false; + }; + + for (const mutation of mutations) { + if (canMutationImpactCurrentStyles(mutation)) { + this.emit("style-changed"); + break; + } + } + } + + /** + * When the window gets resized, this may cause media-queries to match, and we therefore + * need to consider this as a style change for the current node. + */ + onResized() { + this.emit("style-changed"); + } +} + +module.exports = InspectorStyleChangeTracker; |