# HG changeset patch # User Mahdi Dibaiee # Parent 1d4f44ee51668865945db95c5fbd898e71955a33 Bug 1004678 - Break on DOM mutation; r=past diff --git a/browser/devtools/debugger/debugger-controller.js b/browser/devtools/debugger/debugger-controller.js --- a/browser/devtools/debugger/debugger-controller.js +++ b/browser/devtools/debugger/debugger-controller.js @@ -1671,16 +1671,86 @@ EventListeners.prototype = { } }); return deferred.promise; } }; /** + * Handles breaking on DOM mutations on the selected nodes. + */ +function DOMMutations() { +} + +DOMMutations.prototype = { + nodes: [], + /** + * A list of nodes which the debuggee will automatically pause + * when mutated. + */ + activeNodes: [], + + /** + * Updates the list of nodes with listeners that, when invoked, + * will automatically pause the debuggee. The respective nodes are + * retrieved from the UI. + */ + scheduleEventBreakpointsUpdate: function() { + // Make sure we're not sending a batch of closely repeated requests. + // This can easily happen when toggling all events of a certain type. + setNamedTimeout("dom-mutation-breakpoints-update", 0, () => { + this.activeNodes = DebuggerView.DOMMutations.getCheckedNodes(); + gThreadClient.pauseOnDOMMutations(this.activeNodes); + + // Notify that event breakpoints were added/removed on the server. + // window.emit(EVENTS.DOM_MUTATIONS_BREAKPOINTS_UPDATED); + }); + }, + + /** + * A semaphore that is used to ensure only a single protocol request for event + * listeners will be ongoing at any given time. + */ + _parsingListeners: false, + + /** + * A flag the indicates whether a new request to fetch updated event listeners + * has arrived, while another one was in progress. + */ + _eventListenersUpdateNeeded: false, + + /** + * Gets a function's source-mapped definiton site. + * + * @param object aFunction + * The grip of the function to get the definition site for. + * @return object + * A promise that is resolved with the function's owner source url. + */ + _getDefinitionSite: function(aFunction) { + let deferred = promise.defer(); + + gThreadClient.pauseGrip(aFunction).getDefinitionSite(aResponse => { + if (aResponse.error) { + // Don't make this error fatal, because it would break the entire events pane. + const msg = "Error getting function definition site: " + aResponse.message; + DevToolsUtils.reportException("_getDefinitionSite", msg); + deferred.resolve(null); + } else { + deferred.resolve(aResponse.source.url); + } + }); + + return deferred.promise; + } +}; + + +/** * Handles all the breakpoints in the current debugger. */ function Breakpoints() { this._onEditorBreakpointAdd = this._onEditorBreakpointAdd.bind(this); this._onEditorBreakpointRemove = this._onEditorBreakpointRemove.bind(this); this.addBreakpoint = this.addBreakpoint.bind(this); this.removeBreakpoint = this.removeBreakpoint.bind(this); } @@ -2197,16 +2267,17 @@ EventEmitter.decorate(this); DebuggerController.initialize(); DebuggerController.Parser = new Parser(); DebuggerController.Workers = new Workers(); DebuggerController.ThreadState = new ThreadState(); DebuggerController.StackFrames = new StackFrames(); DebuggerController.SourceScripts = new SourceScripts(); DebuggerController.Breakpoints = new Breakpoints(); DebuggerController.Breakpoints.DOM = new EventListeners(); +DebuggerController.Breakpoints.Mutations = new DOMMutations(); /** * Export some properties to the global scope for easier access. */ Object.defineProperties(window, { "gTarget": { get: function() { return DebuggerController._target; diff --git a/browser/devtools/debugger/debugger-view.js b/browser/devtools/debugger/debugger-view.js --- a/browser/devtools/debugger/debugger-view.js +++ b/browser/devtools/debugger/debugger-view.js @@ -57,16 +57,17 @@ let DebuggerView = { this.Filtering.initialize(); this.StackFrames.initialize(); this.StackFramesClassicList.initialize(); this.Workers.initialize(); this.Sources.initialize(); this.VariableBubble.initialize(); this.WatchExpressions.initialize(); this.EventListeners.initialize(); + this.DOMMutations.initialize(); this.GlobalSearch.initialize(); this._initializeVariablesView(); this._initializeEditor(deferred.resolve); document.title = L10N.getStr("DebuggerWindowTitle"); return deferred.promise; }, diff --git a/browser/devtools/debugger/debugger.xul b/browser/devtools/debugger/debugger.xul --- a/browser/devtools/debugger/debugger.xul +++ b/browser/devtools/debugger/debugger.xul @@ -28,16 +28,17 @@