tenfourfox/devtools/client/debugger/content/actions/event-listeners.js
Cameron Kaiser c9b2922b70 hello FPR
2017-04-19 00:56:45 -07:00

117 lines
3.8 KiB
JavaScript

/* 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 constants = require("../constants");
const { rdpInvoke, asPaused } = require("../utils");
const { reportException } = require("devtools/shared/DevToolsUtils");
const FETCH_EVENT_LISTENERS_DELAY = 200; // ms
function fetchEventListeners() {
return (dispatch, getState) => {
// Make sure we"re not sending a batch of closely repeated requests.
// This can easily happen whenever new sources are fetched.
setNamedTimeout("event-listeners-fetch", FETCH_EVENT_LISTENERS_DELAY, () => {
// 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: services.WAIT_UNTIL,
predicate: action => (
action.type === constants.FETCH_EVENT_LISTENERS &&
action.status === "done"
),
run: dispatch => dispatch(fetchEventListeners())
});
return;
}
dispatch({
type: constants.FETCH_EVENT_LISTENERS,
status: "begin"
});
asPaused(gThreadClient, _getListeners).then(listeners => {
// Notify that event listeners were fetched and shown in the view,
// and callback to resume the active thread if necessary.
window.emit(EVENTS.EVENT_LISTENERS_FETCHED);
dispatch({
type: constants.FETCH_EVENT_LISTENERS,
status: "done",
listeners: listeners
});
});
});
};
}
const _getListeners = Task.async(function*() {
const response = yield rdpInvoke(gThreadClient, gThreadClient.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.
let fetchedDefinitions = new Map();
let listeners = [];
for (let 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 = yield _getDefinitionSite(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;
});
const _getDefinitionSite = Task.async(function*(aFunction) {
const grip = gThreadClient.pauseGrip(aFunction);
let response;
try {
response = yield rdpInvoke(grip, grip.getDefinitionSite);
}
catch(e) {
// Don't make this error fatal, because it would break the entire events pane.
reportException("_getDefinitionSite", e);
return null;
}
return response.source.url;
});
function updateEventBreakpoints(eventNames) {
return dispatch => {
setNamedTimeout("event-breakpoints-update", 0, () => {
gThreadClient.pauseOnDOMEvents(eventNames, function() {
// Notify that event breakpoints were added/removed on the server.
window.emit(EVENTS.EVENT_BREAKPOINTS_UPDATED);
dispatch({
type: constants.UPDATE_EVENT_BREAKPOINTS,
eventNames: eventNames
});
});
});
}
}
module.exports = { updateEventBreakpoints, fetchEventListeners };