Loading devtools/client/debugger/new/dist/debugger.css +38 −0 Original line number Diff line number Diff line Loading @@ -4111,6 +4111,44 @@ html[dir="rtl"] .command-bar { * 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/>. */ .event-listeners-pane ul { padding: 0; } .event-listener-group { user-select: none; } .event-listener-category { font-weight: bold; } .event-listeners-pane .arrow { margin-inline-start: 4px; margin-top: 1px; } html[dir="ltr"] .event-listeners-pane .arrow.expanded { transform: rotate(0deg); } html[dir="rtl"] .event-listeners-pane .arrow.expanded { transform: rotate(90deg); } .event-listener-event { display: flex; align-items: center; } .event-listener-event input { margin-inline-end: 6px; margin-inline-start: 40px; } /* 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/>. */ .object-node.default-property { opacity: 0.6; } Loading devtools/client/debugger/new/src/actions/event-listeners.js +19 −155 Original line number Diff line number Diff line Loading @@ -2,167 +2,31 @@ * 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/>. */ /* global window gThreadClient setNamedTimeout EVENTS */ /* eslint no-shadow: 0 */ // @flow /** * Redux actions for the event listeners state * @module actions/event-listeners */ import { asyncStore } from "../utils/prefs"; import { reportException } from "../utils/DevToolsUtils"; import { isPaused, getSourceByURL } from "../selectors"; import { NAME as WAIT_UNTIL } from "./utils/middleware/wait-service"; import type { ThunkArgs } from "./types"; import type { EventListenerBreakpoints } from "../types"; // delay is in ms const FETCH_EVENT_LISTENERS_DELAY = 200; let fetchListenersTimerID; /** * @memberof utils/utils * @static */ async function asPaused(state: any, client: any, func: any) { if (!isPaused(state)) { await client.interrupt(); let result; try { result = await func(client); } catch (e) { // Try to put the debugger back in a working state by resuming // it await client.resume(); throw e; } await client.resume(); return result; } return func(client); } /** * @memberof actions/event-listeners * @static */ export function fetchEventListeners() { return ({ dispatch, getState, client }) => { // Make sure we"re not sending a batch of closely repeated requests. // This can easily happen whenever new sources are fetched. if (fetchListenersTimerID) { clearTimeout(fetchListenersTimerID); } fetchListenersTimerID = setTimeout(() => { // In case there is still a request of listeners going on (it // takes several RDP round trips right now), make sure we wait // on a currently running request if (getState().eventListeners.fetchingListeners) { dispatch({ type: WAIT_UNTIL, predicate: action => action.type === "FETCH_EVENT_LISTENERS" && action.status === "done", run: dispatch => dispatch(fetchEventListeners()) export function addEventListeners(events: EventListenerBreakpoints) { return async ({ dispatch, client }: ThunkArgs) => { await dispatch({ type: "ADD_EVENT_LISTENERS", events }); return; } dispatch({ type: "FETCH_EVENT_LISTENERS", status: "begin" }); asPaused(getState(), client, _getEventListeners).then(listeners => { dispatch({ type: "FETCH_EVENT_LISTENERS", status: "done", listeners: formatListeners(getState(), listeners) }); }); }, FETCH_EVENT_LISTENERS_DELAY); const newList = await asyncStore.eventListenerBreakpoints; client.setEventListenerBreakpoints(newList); }; } function formatListeners(state, listeners) { return listeners.map(l => { return { selector: l.node.selector, type: l.type, sourceId: getSourceByURL(state, l.function.location.url).id, line: l.function.location.line }; }); } async function _getEventListeners(threadClient) { const response = await threadClient.eventListeners(); // Make sure all the listeners are sorted by the event type, since // they"re not guaranteed to be clustered together. response.listeners.sort((a, b) => (a.type > b.type ? 1 : -1)); // Add all the listeners in the debugger view event linsteners container. const fetchedDefinitions = new Map(); const listeners = []; for (const listener of response.listeners) { let definitionSite; if (fetchedDefinitions.has(listener.function.actor)) { definitionSite = fetchedDefinitions.get(listener.function.actor); } else if (listener.function.class == "Function") { definitionSite = await _getDefinitionSite( threadClient, listener.function ); if (!definitionSite) { // We don"t know where this listener comes from so don"t show it in // the UI as breaking on it doesn"t work (bug 942899). continue; } fetchedDefinitions.set(listener.function.actor, definitionSite); } listener.function.url = definitionSite; listeners.push(listener); } fetchedDefinitions.clear(); return listeners; } async function _getDefinitionSite(threadClient, func) { const grip = threadClient.pauseGrip(func); let response; try { response = await grip.getDefinitionSite(); } catch (e) { // Don't make this error fatal, it would break the entire events pane. reportException("_getDefinitionSite", e); return null; } return response.source.url; } /** * @memberof actions/event-listeners * @static * @param {string} eventNames */ export function updateEventBreakpoints(eventNames) { return dispatch => { setNamedTimeout("event-breakpoints-update", 0, () => { gThreadClient.pauseOnDOMEvents(eventNames, () => { // Notify that event breakpoints were added/removed on the server. window.emit(EVENTS.EVENT_BREAKPOINTS_UPDATED); dispatch({ type: "UPDATE_EVENT_BREAKPOINTS", eventNames: eventNames }); }); export function removeEventListeners(events: EventListenerBreakpoints) { return async ({ dispatch, client }: ThunkArgs) => { await dispatch({ type: "REMOVE_EVENT_LISTENERS", events }); const newList = await asyncStore.eventListenerBreakpoints; client.setEventListenerBreakpoints(newList); }; } devtools/client/debugger/new/src/actions/index.js +2 −0 Original line number Diff line number Diff line Loading @@ -6,6 +6,7 @@ import * as breakpoints from "./breakpoints"; import * as expressions from "./expressions"; import * as eventListeners from "./event-listeners"; import * as pause from "./pause"; import * as navigation from "./navigation"; import * as ui from "./ui"; Loading @@ -24,6 +25,7 @@ export default { ...navigation, ...breakpoints, ...expressions, ...eventListeners, ...sources, ...tabs, ...pause, Loading devtools/client/debugger/new/src/actions/moz.build +1 −0 Original line number Diff line number Diff line Loading @@ -14,6 +14,7 @@ DIRS += [ DebuggerModules( 'ast.js', 'debuggee.js', 'event-listeners.js', 'expressions.js', 'file-search.js', 'index.js', Loading devtools/client/debugger/new/src/client/firefox/commands.js +6 −0 Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ import type { BreakpointId, BreakpointResult, EventListenerBreakpoints, Frame, FrameId, SourceLocation, Loading Loading @@ -386,6 +387,10 @@ function eventListeners(): Promise<*> { return threadClient.eventListeners(); } function setEventListenerBreakpoints(eventTypes: EventListenerBreakpoints) { // TODO: Figure out what sendpoint we want to hit } function pauseGrip(thread: string, func: Function): ObjectClient { return lookupThreadClient(thread).pauseGrip(func); } Loading Loading @@ -483,6 +488,7 @@ const clientCommands = { sendPacket, setPausePoints, setSkipPausing, setEventListenerBreakpoints, registerSource }; Loading Loading
devtools/client/debugger/new/dist/debugger.css +38 −0 Original line number Diff line number Diff line Loading @@ -4111,6 +4111,44 @@ html[dir="rtl"] .command-bar { * 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/>. */ .event-listeners-pane ul { padding: 0; } .event-listener-group { user-select: none; } .event-listener-category { font-weight: bold; } .event-listeners-pane .arrow { margin-inline-start: 4px; margin-top: 1px; } html[dir="ltr"] .event-listeners-pane .arrow.expanded { transform: rotate(0deg); } html[dir="rtl"] .event-listeners-pane .arrow.expanded { transform: rotate(90deg); } .event-listener-event { display: flex; align-items: center; } .event-listener-event input { margin-inline-end: 6px; margin-inline-start: 40px; } /* 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/>. */ .object-node.default-property { opacity: 0.6; } Loading
devtools/client/debugger/new/src/actions/event-listeners.js +19 −155 Original line number Diff line number Diff line Loading @@ -2,167 +2,31 @@ * 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/>. */ /* global window gThreadClient setNamedTimeout EVENTS */ /* eslint no-shadow: 0 */ // @flow /** * Redux actions for the event listeners state * @module actions/event-listeners */ import { asyncStore } from "../utils/prefs"; import { reportException } from "../utils/DevToolsUtils"; import { isPaused, getSourceByURL } from "../selectors"; import { NAME as WAIT_UNTIL } from "./utils/middleware/wait-service"; import type { ThunkArgs } from "./types"; import type { EventListenerBreakpoints } from "../types"; // delay is in ms const FETCH_EVENT_LISTENERS_DELAY = 200; let fetchListenersTimerID; /** * @memberof utils/utils * @static */ async function asPaused(state: any, client: any, func: any) { if (!isPaused(state)) { await client.interrupt(); let result; try { result = await func(client); } catch (e) { // Try to put the debugger back in a working state by resuming // it await client.resume(); throw e; } await client.resume(); return result; } return func(client); } /** * @memberof actions/event-listeners * @static */ export function fetchEventListeners() { return ({ dispatch, getState, client }) => { // Make sure we"re not sending a batch of closely repeated requests. // This can easily happen whenever new sources are fetched. if (fetchListenersTimerID) { clearTimeout(fetchListenersTimerID); } fetchListenersTimerID = setTimeout(() => { // In case there is still a request of listeners going on (it // takes several RDP round trips right now), make sure we wait // on a currently running request if (getState().eventListeners.fetchingListeners) { dispatch({ type: WAIT_UNTIL, predicate: action => action.type === "FETCH_EVENT_LISTENERS" && action.status === "done", run: dispatch => dispatch(fetchEventListeners()) export function addEventListeners(events: EventListenerBreakpoints) { return async ({ dispatch, client }: ThunkArgs) => { await dispatch({ type: "ADD_EVENT_LISTENERS", events }); return; } dispatch({ type: "FETCH_EVENT_LISTENERS", status: "begin" }); asPaused(getState(), client, _getEventListeners).then(listeners => { dispatch({ type: "FETCH_EVENT_LISTENERS", status: "done", listeners: formatListeners(getState(), listeners) }); }); }, FETCH_EVENT_LISTENERS_DELAY); const newList = await asyncStore.eventListenerBreakpoints; client.setEventListenerBreakpoints(newList); }; } function formatListeners(state, listeners) { return listeners.map(l => { return { selector: l.node.selector, type: l.type, sourceId: getSourceByURL(state, l.function.location.url).id, line: l.function.location.line }; }); } async function _getEventListeners(threadClient) { const response = await threadClient.eventListeners(); // Make sure all the listeners are sorted by the event type, since // they"re not guaranteed to be clustered together. response.listeners.sort((a, b) => (a.type > b.type ? 1 : -1)); // Add all the listeners in the debugger view event linsteners container. const fetchedDefinitions = new Map(); const listeners = []; for (const listener of response.listeners) { let definitionSite; if (fetchedDefinitions.has(listener.function.actor)) { definitionSite = fetchedDefinitions.get(listener.function.actor); } else if (listener.function.class == "Function") { definitionSite = await _getDefinitionSite( threadClient, listener.function ); if (!definitionSite) { // We don"t know where this listener comes from so don"t show it in // the UI as breaking on it doesn"t work (bug 942899). continue; } fetchedDefinitions.set(listener.function.actor, definitionSite); } listener.function.url = definitionSite; listeners.push(listener); } fetchedDefinitions.clear(); return listeners; } async function _getDefinitionSite(threadClient, func) { const grip = threadClient.pauseGrip(func); let response; try { response = await grip.getDefinitionSite(); } catch (e) { // Don't make this error fatal, it would break the entire events pane. reportException("_getDefinitionSite", e); return null; } return response.source.url; } /** * @memberof actions/event-listeners * @static * @param {string} eventNames */ export function updateEventBreakpoints(eventNames) { return dispatch => { setNamedTimeout("event-breakpoints-update", 0, () => { gThreadClient.pauseOnDOMEvents(eventNames, () => { // Notify that event breakpoints were added/removed on the server. window.emit(EVENTS.EVENT_BREAKPOINTS_UPDATED); dispatch({ type: "UPDATE_EVENT_BREAKPOINTS", eventNames: eventNames }); }); export function removeEventListeners(events: EventListenerBreakpoints) { return async ({ dispatch, client }: ThunkArgs) => { await dispatch({ type: "REMOVE_EVENT_LISTENERS", events }); const newList = await asyncStore.eventListenerBreakpoints; client.setEventListenerBreakpoints(newList); }; }
devtools/client/debugger/new/src/actions/index.js +2 −0 Original line number Diff line number Diff line Loading @@ -6,6 +6,7 @@ import * as breakpoints from "./breakpoints"; import * as expressions from "./expressions"; import * as eventListeners from "./event-listeners"; import * as pause from "./pause"; import * as navigation from "./navigation"; import * as ui from "./ui"; Loading @@ -24,6 +25,7 @@ export default { ...navigation, ...breakpoints, ...expressions, ...eventListeners, ...sources, ...tabs, ...pause, Loading
devtools/client/debugger/new/src/actions/moz.build +1 −0 Original line number Diff line number Diff line Loading @@ -14,6 +14,7 @@ DIRS += [ DebuggerModules( 'ast.js', 'debuggee.js', 'event-listeners.js', 'expressions.js', 'file-search.js', 'index.js', Loading
devtools/client/debugger/new/src/client/firefox/commands.js +6 −0 Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ import type { BreakpointId, BreakpointResult, EventListenerBreakpoints, Frame, FrameId, SourceLocation, Loading Loading @@ -386,6 +387,10 @@ function eventListeners(): Promise<*> { return threadClient.eventListeners(); } function setEventListenerBreakpoints(eventTypes: EventListenerBreakpoints) { // TODO: Figure out what sendpoint we want to hit } function pauseGrip(thread: string, func: Function): ObjectClient { return lookupThreadClient(thread).pauseGrip(func); } Loading Loading @@ -483,6 +488,7 @@ const clientCommands = { sendPacket, setPausePoints, setSkipPausing, setEventListenerBreakpoints, registerSource }; Loading