Bug 1110276 - Log on Events (UI). r=davidwalsh

Differential Revision: https://phabricator.services.mozilla.com/D46077

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Jason Laster 2019-09-17 21:17:58 +00:00
Родитель 62b0e230d6
Коммит 5cb8b24f19
18 изменённых файлов: 138 добавлений и 21 удалений

Просмотреть файл

@ -9,6 +9,7 @@ import { uniq, remove } from "lodash";
import { import {
getActiveEventListeners, getActiveEventListeners,
getEventListenerExpanded, getEventListenerExpanded,
shouldLogEventBreakpoints,
} from "../selectors"; } from "../selectors";
import type { ThunkArgs } from "./types"; import type { ThunkArgs } from "./types";
@ -48,6 +49,14 @@ export function removeEventListenerBreakpoints(eventsToRemove: string[]) {
}; };
} }
export function toggleEventLogging() {
return async ({ dispatch, getState, client }: ThunkArgs) => {
const logEventBreakpoints = !shouldLogEventBreakpoints(getState());
await client.toggleEventLogging(logEventBreakpoints);
dispatch({ type: "TOGGLE_EVENT_LISTENERS", logEventBreakpoints });
};
}
export function addEventListenerExpanded(category: string) { export function addEventListenerExpanded(category: string) {
return async ({ dispatch, getState }: ThunkArgs) => { return async ({ dispatch, getState }: ThunkArgs) => {
const expanded = await getEventListenerExpanded(getState()); const expanded = await getEventListenerExpanded(getState());

Просмотреть файл

@ -181,6 +181,10 @@ export type EventListenerAction =
| {| | {|
+type: "UPDATE_EVENT_LISTENER_EXPANDED", +type: "UPDATE_EVENT_LISTENER_EXPANDED",
+expanded: EventListenerExpandedList, +expanded: EventListenerExpandedList,
|}
| {|
+type: "TOGGLE_EVENT_LISTENERS",
+logEventBreakpoints: boolean,
|}; |};
/** /**

Просмотреть файл

@ -45,7 +45,7 @@ export async function onConnect(connection: any, actions: Object) {
pauseWorkersUntilAttach: true, pauseWorkersUntilAttach: true,
wasmBinarySource: supportsWasm, wasmBinarySource: supportsWasm,
skipBreakpoints: prefs.skipPausing, skipBreakpoints: prefs.skipPausing,
logEventBreakpoints: features.logEventBreakpoints, logEventBreakpoints: prefs.logEventBreakpoints,
}); });
// Retrieve possible event listener breakpoints // Retrieve possible event listener breakpoints

Просмотреть файл

@ -419,6 +419,12 @@ async function getSources(
return sources.map(source => prepareSourcePayload(client, source)); return sources.map(source => prepareSourcePayload(client, source));
} }
async function toggleEventLogging(logEventBreakpoints: boolean) {
return forEachThread(thread =>
thread.toggleEventLogging(logEventBreakpoints)
);
}
async function fetchSources(): Promise<Array<GeneratedSourceData>> { async function fetchSources(): Promise<Array<GeneratedSourceData>> {
return getSources(currentThreadFront); return getSources(currentThreadFront);
} }
@ -544,6 +550,7 @@ const clientCommands = {
getProperties, getProperties,
getFrameScopes, getFrameScopes,
pauseOnExceptions, pauseOnExceptions,
toggleEventLogging,
fetchSources, fetchSources,
registerSourceActor, registerSourceActor,
fetchThreads, fetchThreads,

Просмотреть файл

@ -27,6 +27,7 @@ import {
getThreadContext, getThreadContext,
getSourceFromId, getSourceFromId,
getSkipPausing, getSkipPausing,
shouldLogEventBreakpoints,
} from "../../selectors"; } from "../../selectors";
import AccessibleImage from "../shared/AccessibleImage"; import AccessibleImage from "../shared/AccessibleImage";
@ -99,6 +100,7 @@ type Props = {
shouldPauseOnCaughtExceptions: boolean, shouldPauseOnCaughtExceptions: boolean,
workers: ThreadList, workers: ThreadList,
skipPausing: boolean, skipPausing: boolean,
logEventBreakpoints: boolean,
source: ?Source, source: ?Source,
toggleShortcutsModal: () => void, toggleShortcutsModal: () => void,
toggleAllBreakpoints: typeof actions.toggleAllBreakpoints, toggleAllBreakpoints: typeof actions.toggleAllBreakpoints,
@ -106,6 +108,7 @@ type Props = {
evaluateExpressions: typeof actions.evaluateExpressions, evaluateExpressions: typeof actions.evaluateExpressions,
pauseOnExceptions: typeof actions.pauseOnExceptions, pauseOnExceptions: typeof actions.pauseOnExceptions,
breakOnNext: typeof actions.breakOnNext, breakOnNext: typeof actions.breakOnNext,
toggleEventLogging: typeof actions.toggleEventLogging,
}; };
const mdnLink = const mdnLink =
@ -277,6 +280,26 @@ class SecondaryPanes extends Component<Props, State> {
]; ];
} }
getEventButtons() {
const { logEventBreakpoints } = this.props;
return [
<div key="events-buttons">
<label
className="events-header"
title={L10N.getStr("eventlisteners.log.label")}
onClick={e => e.stopPropagation()}
>
<input
type="checkbox"
checked={logEventBreakpoints ? "checked" : ""}
onChange={e => this.props.toggleEventLogging()}
/>
{L10N.getStr("eventlisteners.log")}
</label>
</div>,
];
}
getWatchItem(): AccordionPaneItem { getWatchItem(): AccordionPaneItem {
return { return {
header: L10N.getStr("watchExpressions.header"), header: L10N.getStr("watchExpressions.header"),
@ -366,7 +389,7 @@ class SecondaryPanes extends Component<Props, State> {
return { return {
header: L10N.getStr("eventListenersHeader1"), header: L10N.getStr("eventListenersHeader1"),
className: "event-listeners-pane", className: "event-listeners-pane",
buttons: [], buttons: this.getEventButtons(),
component: <EventListeners />, component: <EventListeners />,
opened: prefs.eventListenersVisible, opened: prefs.eventListenersVisible,
onToggle: opened => { onToggle: opened => {
@ -540,6 +563,7 @@ const mapStateToProps = state => {
shouldPauseOnCaughtExceptions: getShouldPauseOnCaughtExceptions(state), shouldPauseOnCaughtExceptions: getShouldPauseOnCaughtExceptions(state),
workers: getThreads(state), workers: getThreads(state),
skipPausing: getSkipPausing(state), skipPausing: getSkipPausing(state),
logEventBreakpoints: shouldLogEventBreakpoints(state),
source: source:
selectedFrame && getSourceFromId(state, selectedFrame.location.sourceId), selectedFrame && getSourceFromId(state, selectedFrame.location.sourceId),
}; };
@ -553,5 +577,6 @@ export default connect(
pauseOnExceptions: actions.pauseOnExceptions, pauseOnExceptions: actions.pauseOnExceptions,
toggleMapScopes: actions.toggleMapScopes, toggleMapScopes: actions.toggleMapScopes,
breakOnNext: actions.breakOnNext, breakOnNext: actions.breakOnNext,
toggleEventLogging: actions.toggleEventLogging,
} }
)(SecondaryPanes); )(SecondaryPanes);

Просмотреть файл

@ -4,6 +4,8 @@
// @flow // @flow
import { prefs } from "../utils/prefs";
import type { State } from "./types"; import type { State } from "./types";
import type { import type {
EventListenerAction, EventListenerAction,
@ -16,6 +18,7 @@ export type EventListenersState = {|
+active: EventListenerActiveList, +active: EventListenerActiveList,
+categories: EventListenerCategoryList, +categories: EventListenerCategoryList,
+expanded: EventListenerExpandedList, +expanded: EventListenerExpandedList,
+logEventBreakpoints: boolean,
|}; |};
export function initialEventListenerState(): EventListenersState { export function initialEventListenerState(): EventListenersState {
@ -23,6 +26,7 @@ export function initialEventListenerState(): EventListenersState {
active: [], active: [],
categories: [], categories: [],
expanded: [], expanded: [],
logEventBreakpoints: prefs.logEventBreakpoints,
}; };
} }
@ -40,6 +44,12 @@ function update(
case "UPDATE_EVENT_LISTENER_EXPANDED": case "UPDATE_EVENT_LISTENER_EXPANDED":
return { ...state, expanded: action.expanded }; return { ...state, expanded: action.expanded };
case "TOGGLE_EVENT_LISTENERS": {
const { logEventBreakpoints } = action;
prefs.logEventBreakpoints = logEventBreakpoints;
return { ...state, logEventBreakpoints };
}
default: default:
return state; return state;
} }
@ -61,4 +71,8 @@ export function getEventListenerExpanded(
return state.eventListenerBreakpoints.expanded; return state.eventListenerBreakpoints.expanded;
} }
export function shouldLogEventBreakpoints(state: State) {
return state.eventListenerBreakpoints.logEventBreakpoints;
}
export default update; export default update;

Просмотреть файл

@ -88,7 +88,7 @@ export function setupHelper(obj: Object) {
evaluate: expression => evaluate(dbg, expression), evaluate: expression => evaluate(dbg, expression),
sendPacketToThread: packet => sendPacketToThread(dbg, packet), sendPacketToThread: packet => sendPacketToThread(dbg, packet),
sendPacket: packet => sendPacket(dbg, packet), sendPacket: packet => sendPacket(dbg, packet),
dumpThread: () => sendPacketToThread(dbg, { type: "dumpThread" }), dumpThread: () => dbg.connection.tabConnection.threadFront.dumpThread(),
getDocument: url => getDocumentForUrl(dbg, url), getDocument: url => getDocumentForUrl(dbg, url),
}, },
formatters: { formatters: {

Просмотреть файл

@ -48,6 +48,8 @@ if (isDevelopment()) {
pref("devtools.debugger.map-scopes-enabled", false); pref("devtools.debugger.map-scopes-enabled", false);
pref("devtools.debugger.prefs-schema-version", prefsSchemaVersion); pref("devtools.debugger.prefs-schema-version", prefsSchemaVersion);
pref("devtools.debugger.skip-pausing", false); pref("devtools.debugger.skip-pausing", false);
pref("devtools.debugger.log-actions", true);
pref("devtools.debugger.log-event-breakpoints", false);
pref("devtools.debugger.features.workers", true); pref("devtools.debugger.features.workers", true);
pref("devtools.debugger.features.async-stepping", false); pref("devtools.debugger.features.async-stepping", false);
pref("devtools.debugger.features.wasm", true); pref("devtools.debugger.features.wasm", true);
@ -69,9 +71,7 @@ if (isDevelopment()) {
pref("devtools.debugger.features.dom-mutation-breakpoints", true); pref("devtools.debugger.features.dom-mutation-breakpoints", true);
pref("devtools.debugger.features.log-points", true); pref("devtools.debugger.features.log-points", true);
pref("devtools.debugger.features.inline-preview", true); pref("devtools.debugger.features.inline-preview", true);
pref("devtools.debugger.log-actions", true);
pref("devtools.debugger.features.overlay-step-buttons", true); pref("devtools.debugger.features.overlay-step-buttons", true);
pref("devtools.debugger.features.log-event-breakpoints", false);
pref("devtools.debugger.features.watchpoints", false); pref("devtools.debugger.features.watchpoints", false);
} }
@ -114,6 +114,7 @@ export const prefs = new PrefsHelper("devtools", {
skipPausing: ["Bool", "debugger.skip-pausing"], skipPausing: ["Bool", "debugger.skip-pausing"],
mapScopes: ["Bool", "debugger.map-scopes-enabled"], mapScopes: ["Bool", "debugger.map-scopes-enabled"],
logActions: ["Bool", "debugger.log-actions"], logActions: ["Bool", "debugger.log-actions"],
logEventBreakpoints: ["Bool", "debugger.log-event-breakpoints"],
}); });
export const features = new PrefsHelper("devtools.debugger.features", { export const features = new PrefsHelper("devtools.debugger.features", {
@ -140,7 +141,6 @@ export const features = new PrefsHelper("devtools.debugger.features", {
logPoints: ["Bool", "log-points"], logPoints: ["Bool", "log-points"],
showOverlayStepButtons: ["Bool", "overlay-step-buttons"], showOverlayStepButtons: ["Bool", "overlay-step-buttons"],
inlinePreview: ["Bool", "inline-preview"], inlinePreview: ["Bool", "inline-preview"],
logEventBreakpoints: ["Bool", "log-event-breakpoints"],
watchpoints: ["Bool", "watchpoints"], watchpoints: ["Bool", "watchpoints"],
}); });

Просмотреть файл

@ -79,6 +79,7 @@ skip-if = ccov && os == 'win' # Bug 1443132
[browser_dbg-keyboard-shortcuts.js] [browser_dbg-keyboard-shortcuts.js]
skip-if = os == "linux" # bug 1351952 skip-if = os == "linux" # bug 1351952
[browser_dbg-layout-changes.js] [browser_dbg-layout-changes.js]
[browser_dbg-log-events.js]
[browser_dbg-log-points.js] [browser_dbg-log-points.js]
[browser_dbg-outline.js] [browser_dbg-outline.js]
skip-if = verify skip-if = verify

Просмотреть файл

@ -14,9 +14,15 @@ function assertPauseLocation(dbg, line) {
} }
add_task(async function() { add_task(async function() {
await pushPref("devtools.debugger.features.event-listeners-breakpoints", true); await pushPref(
"devtools.debugger.features.event-listeners-breakpoints",
true
);
const dbg = await initDebugger("doc-event-breakpoints.html", "event-breakpoints"); const dbg = await initDebugger(
"doc-event-breakpoints.html",
"event-breakpoints"
);
await selectSource(dbg, "event-breakpoints"); await selectSource(dbg, "event-breakpoints");
await waitForSelectedSource(dbg, "event-breakpoints"); await waitForSelectedSource(dbg, "event-breakpoints");
@ -43,6 +49,6 @@ add_task(async function() {
await resume(dbg); await resume(dbg);
await waitForPaused(dbg); await waitForPaused(dbg);
assertPauseLocation(dbg, 29); assertPauseLocation(dbg, 28);
await resume(dbg); await resume(dbg);
}); });

Просмотреть файл

@ -0,0 +1,23 @@
/* 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/>. */
/*
* Tests that we can log event listeners calls
*/
add_task(async function() {
Services.prefs.setBoolPref("devtools.toolbox.splitconsoleEnabled", true);
const dbg = await initDebugger(
"doc-event-breakpoints.html",
"event-breakpoints.js"
);
await clickElement(dbg, "logEventsCheckbox");
await dbg.actions.addEventListenerBreakpoints(["event.mouse.click"]);
clickElementInTab("#click-target");
await hasConsoleMessage(dbg, "click");
await waitForRequestsToSettle(dbg);
ok(true);
});

Просмотреть файл

@ -16,7 +16,7 @@ document.getElementById("xhr-button").onmousedown = xhrHandler;
function xhrHandler() { function xhrHandler() {
var xhr = new XMLHttpRequest(); var xhr = new XMLHttpRequest();
xhr.open("GET", "doc-event-breakpoints.html", true); xhr.open("GET", "doc-event-breakpoints.html", true);
xhr.onload = function(){ xhr.onload = function() {
console.log("xhr load"); console.log("xhr load");
}; };
xhr.send(); xhr.send();
@ -24,11 +24,8 @@ function xhrHandler() {
document.getElementById("timer-button").onmousedown = timerHandler; document.getElementById("timer-button").onmousedown = timerHandler;
function timerHandler() { function timerHandler() {
setTimeout( setTimeout(() => {
() => { console.log("timer callback");
console.log("timer callback"); }, 50);
},
50
);
console.log("timer set"); console.log("timer set");
} }

Просмотреть файл

@ -1036,6 +1036,17 @@ function invokeInTab(fnc, ...args) {
}); });
} }
function clickElementInTab(selector) {
info(`click element ${selector} in tab`);
return ContentTask.spawn(gBrowser.selectedBrowser, { selector }, function*({
selector
}) {
content.wrappedJSObject.document.querySelector(selector).click();
});
}
const isLinux = Services.appinfo.OS === "Linux"; const isLinux = Services.appinfo.OS === "Linux";
const isMac = Services.appinfo.OS === "Darwin"; const isMac = Services.appinfo.OS === "Darwin";
const cmdOrCtrl = isLinux ? { ctrlKey: true } : { metaKey: true }; const cmdOrCtrl = isLinux ? { ctrlKey: true } : { metaKey: true };
@ -1293,7 +1304,8 @@ const selectors = {
inlinePreviewOpenInspector: ".inline-preview-value button.open-inspector", inlinePreviewOpenInspector: ".inline-preview-value button.open-inspector",
addGetWatchpoint: "#node-menu-add-get-watchpoint", addGetWatchpoint: "#node-menu-add-get-watchpoint",
addSetWatchpoint: "#node-menu-add-set-watchpoint", addSetWatchpoint: "#node-menu-add-set-watchpoint",
removeWatchpoint: "#node-menu-remove-watchpoint" removeWatchpoint: "#node-menu-remove-watchpoint",
logEventsCheckbox: ".events-header input",
}; };
function getSelector(elementName, ...args) { function getSelector(elementName, ...args) {

Просмотреть файл

@ -598,7 +598,7 @@ Toolbox.prototype = {
"devtools.debugger.skip-pausing" "devtools.debugger.skip-pausing"
), ),
logEventBreakpoints: Services.prefs.getBoolPref( logEventBreakpoints: Services.prefs.getBoolPref(
"devtools.debugger.features.log-event-breakpoints" "devtools.debugger.log-event-breakpoints"
), ),
}); });

Просмотреть файл

@ -583,6 +583,13 @@ scopes.notPaused=Not paused
# tooltip for checkbox and label # tooltip for checkbox and label
scopes.mapping.label=Map original variable names scopes.mapping.label=Map original variable names
# LOCALIZATION NOTE (eventlisteners.log.label): Event listeners tooltip for
# checkbox and label
eventlisteners.log.label=Log events to the console
# LOCALIZATION NOTE (eventlisteners.log): Checkbox label for logging events
eventlisteners.log=Log
# LOCALIZATION NOTE (scopes.helpTooltip.label): Scopes right sidebar pane # LOCALIZATION NOTE (scopes.helpTooltip.label): Scopes right sidebar pane
# icon tooltip for link to MDN # icon tooltip for link to MDN
scopes.helpTooltip.label=Learn more about map scopes scopes.helpTooltip.label=Learn more about map scopes

Просмотреть файл

@ -60,6 +60,7 @@ pref("devtools.debugger.skip-pausing", false);
pref("devtools.debugger.logging", false); pref("devtools.debugger.logging", false);
pref("devtools.debugger.map-scopes-enabled", false); pref("devtools.debugger.map-scopes-enabled", false);
pref("devtools.debugger.log-actions", false); pref("devtools.debugger.log-actions", false);
pref("devtools.debugger.log-event-breakpoints", false);
pref("devtools.debugger.features.wasm", true); pref("devtools.debugger.features.wasm", true);
pref("devtools.debugger.features.shortcuts", true); pref("devtools.debugger.features.shortcuts", true);
@ -85,5 +86,4 @@ pref("devtools.debugger.features.log-points", true);
pref("devtools.debugger.features.overlay-step-buttons", false); pref("devtools.debugger.features.overlay-step-buttons", false);
pref("devtools.debugger.features.overlay-step-buttons", true); pref("devtools.debugger.features.overlay-step-buttons", true);
pref("devtools.debugger.features.inline-preview", true); pref("devtools.debugger.features.inline-preview", true);
pref("devtools.debugger.features.log-event-breakpoints", false);
pref("devtools.debugger.features.watchpoints", false); pref("devtools.debugger.features.watchpoints", false);

Просмотреть файл

@ -406,6 +406,11 @@ const ThreadActor = ActorClassWithSpec(threadSpec, {
} }
}, },
toggleEventLogging(logEventBreakpoints) {
this._options.logEventBreakpoints = logEventBreakpoints;
return this._options.logEventBreakpoints;
},
_setBreakpointsOnAttach(breakpoints) { _setBreakpointsOnAttach(breakpoints) {
for (const { location, options } of Object.values(breakpoints)) { for (const { location, options } of Object.values(breakpoints)) {
this.setBreakpoint(location, options); this.setBreakpoint(location, options);
@ -2082,6 +2087,7 @@ const ThreadActor = ActorClassWithSpec(threadSpec, {
return { return {
pauseOnExceptions: this._options.pauseOnExceptions, pauseOnExceptions: this._options.pauseOnExceptions,
ignoreCaughtExceptions: this._options.ignoreCaughtExceptions, ignoreCaughtExceptions: this._options.ignoreCaughtExceptions,
logEventBreakpoints: this._options.logEventBreakpoints,
skipBreakpoints: this.skipBreakpoints, skipBreakpoints: this.skipBreakpoints,
breakpoints: this.breakpointActorMap.listKeys(), breakpoints: this.breakpointActorMap.listKeys(),
}; };

Просмотреть файл

@ -159,6 +159,12 @@ const threadSpec = generateActorSpec({
request: {}, request: {},
}, },
toggleEventLogging: {
request: {
logEventBreakpoints: Arg(0, "string"),
},
},
// For testing. // For testing.
debuggerRequests: { debuggerRequests: {
response: { response: {