From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- .../framework/actions/dom-mutation-breakpoints.js | 155 +++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 devtools/client/framework/actions/dom-mutation-breakpoints.js (limited to 'devtools/client/framework/actions/dom-mutation-breakpoints.js') diff --git a/devtools/client/framework/actions/dom-mutation-breakpoints.js b/devtools/client/framework/actions/dom-mutation-breakpoints.js new file mode 100644 index 0000000000..1e1273d711 --- /dev/null +++ b/devtools/client/framework/actions/dom-mutation-breakpoints.js @@ -0,0 +1,155 @@ +/* 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 . */ +"use strict"; + +const { assert } = require("resource://devtools/shared/DevToolsUtils.js"); +const { + getDOMMutationBreakpoint, + getDOMMutationBreakpoints, +} = require("resource://devtools/client/framework/reducers/dom-mutation-breakpoints.js"); + +exports.registerWalkerListeners = registerWalkerListeners; +function registerWalkerListeners(store, walker) { + walker.on("mutations", mutations => handleWalkerMutations(mutations, store)); +} + +/** + * Called when a target is destroyed. This will allow the reducer to remove breakpoints on + * nodeFront associated with the passed target + * + * @param {ToolboxStore} store: The toolbox redux store + * @param {TargetFront} targetFront + */ +function removeTarget(store, targetFront) { + store.dispatch({ + type: "REMOVE_TARGET", + targetFront, + }); +} +exports.removeTarget = removeTarget; + +function handleWalkerMutations(mutations, store) { + // If we got BP updates for detach/unload, we want to drop those nodes from + // the list of active DOM mutation breakpoints. We explicitly check these + // cases because BP updates could also happen due to explicitly API + // operations to add/remove bps. + const mutationItems = mutations.filter( + mutation => mutation.type === "mutationBreakpoint" + ); + if (mutationItems.length) { + store.dispatch(updateBreakpointsForMutations(mutationItems)); + } +} + +exports.createDOMMutationBreakpoint = createDOMMutationBreakpoint; +function createDOMMutationBreakpoint(nodeFront, mutationType) { + assert(typeof nodeFront === "object" && nodeFront); + assert(typeof mutationType === "string"); + + return async function ({ dispatch, getState }) { + const walker = nodeFront.walkerFront; + + dispatch({ + type: "ADD_DOM_MUTATION_BREAKPOINT", + nodeFront, + mutationType, + }); + + await walker.setMutationBreakpoints(nodeFront, { + [mutationType]: true, + }); + }; +} + +exports.deleteDOMMutationBreakpoint = deleteDOMMutationBreakpoint; +function deleteDOMMutationBreakpoint(nodeFront, mutationType) { + assert(typeof nodeFront === "object" && nodeFront); + assert(typeof mutationType === "string"); + + return async function ({ dispatch, getState }) { + const walker = nodeFront.walkerFront; + await walker.setMutationBreakpoints(nodeFront, { + [mutationType]: false, + }); + + dispatch({ + type: "REMOVE_DOM_MUTATION_BREAKPOINT", + nodeFront, + mutationType, + }); + }; +} + +function updateBreakpointsForMutations(mutationItems) { + return async function ({ dispatch, getState }) { + const removedNodeFronts = []; + const changedNodeFronts = new Set(); + + for (const { target: nodeFront, mutationReason } of mutationItems) { + switch (mutationReason) { + case "api": + changedNodeFronts.add(nodeFront); + break; + default: + console.error( + "Unexpected mutation reason", + mutationReason, + ", removing" + ); + // Fall Through + case "detach": + case "unload": + removedNodeFronts.push(nodeFront); + break; + } + } + + if (removedNodeFronts.length) { + dispatch({ + type: "REMOVE_DOM_MUTATION_BREAKPOINTS_FOR_FRONTS", + nodeFronts: removedNodeFronts, + }); + } + if (changedNodeFronts.size > 0) { + const enabledStates = []; + for (const { + id, + nodeFront, + mutationType, + enabled, + } of getDOMMutationBreakpoints(getState())) { + if (changedNodeFronts.has(nodeFront)) { + const bpEnabledOnFront = nodeFront.mutationBreakpoints[mutationType]; + if (bpEnabledOnFront !== enabled) { + // Sync the bp state from the front into the store. + enabledStates.push([id, bpEnabledOnFront]); + } + } + } + + dispatch({ + type: "SET_DOM_MUTATION_BREAKPOINTS_ENABLED_STATE", + enabledStates, + }); + } + }; +} + +exports.toggleDOMMutationBreakpointState = toggleDOMMutationBreakpointState; +function toggleDOMMutationBreakpointState(id, enabled) { + assert(typeof id === "string"); + assert(typeof enabled === "boolean"); + + return async function ({ dispatch, getState }) { + const bp = getDOMMutationBreakpoint(getState(), id); + if (!bp) { + throw new Error(`No DOM mutation BP with ID ${id}`); + } + + const walker = bp.nodeFront.getParent(); + await walker.setMutationBreakpoints(bp.nodeFront, { + [bp.mutationType]: enabled, + }); + }; +} -- cgit v1.2.3