diff options
author | Ben Murdoch <benm@google.com> | 2010-10-22 13:02:20 +0100 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2010-10-26 15:21:41 +0100 |
commit | a94275402997c11dd2e778633dacf4b7e630a35d (patch) | |
tree | e66f56c67e3b01f22c9c23cd932271ee9ac558ed /WebCore/inspector/front-end/BreakpointManager.js | |
parent | 09e26c78506587b3f5d930d7bc72a23287ffbec0 (diff) | |
download | external_webkit-a94275402997c11dd2e778633dacf4b7e630a35d.zip external_webkit-a94275402997c11dd2e778633dacf4b7e630a35d.tar.gz external_webkit-a94275402997c11dd2e778633dacf4b7e630a35d.tar.bz2 |
Merge WebKit at r70209: Initial merge by Git
Change-Id: Id23a68efa36e9d1126bcce0b137872db00892c8e
Diffstat (limited to 'WebCore/inspector/front-end/BreakpointManager.js')
-rw-r--r-- | WebCore/inspector/front-end/BreakpointManager.js | 387 |
1 files changed, 334 insertions, 53 deletions
diff --git a/WebCore/inspector/front-end/BreakpointManager.js b/WebCore/inspector/front-end/BreakpointManager.js index ec4e7cf..77ba89d 100644 --- a/WebCore/inspector/front-end/BreakpointManager.js +++ b/WebCore/inspector/front-end/BreakpointManager.js @@ -27,7 +27,8 @@ WebInspector.BreakpointManager = function() { this._breakpoints = {}; - this._xhrBreakpoints = {}; + this._nativeBreakpoints = {}; + this._domBreakpoints = {}; } WebInspector.BreakpointManager.prototype = { @@ -87,6 +88,7 @@ WebInspector.BreakpointManager.prototype = { { this._breakpoints = {}; delete this._oneTimeBreakpoint; + this._nativeBreakpoints = {}; }, _setBreakpoint: function(sourceID, url, line, enabled, condition) @@ -127,20 +129,144 @@ WebInspector.BreakpointManager.prototype = { InspectorBackend.setBreakpoint(breakpoint.sourceID, breakpoint.line, breakpoint.enabled, breakpoint.condition, didSetBreakpoint.bind(this)); }, - createXHRBreakpoint: function(url) + createDOMBreakpoint: function(nodeId, domEventType, disabled) { - if (url in this._xhrBreakpoints) + var frontendId = "dom:" + nodeId + ":" + domEventType; + if (frontendId in this._nativeBreakpoints) return; - this._xhrBreakpoints[url] = true; - var breakpoint = new WebInspector.XHRBreakpoint(url); - breakpoint.addEventListener("removed", this._xhrBreakpointRemoved.bind(this)); + var breakpoint = new WebInspector.DOMBreakpoint(this, frontendId, nodeId, domEventType); + this._nativeBreakpoints[frontendId] = breakpoint; + this._domBreakpoints[frontendId] = breakpoint; + this.dispatchEventToListeners("dom-breakpoint-added", breakpoint); + breakpoint.enabled = !disabled; + return breakpoint; + }, + + createEventListenerBreakpoint: function(eventName, disabled) + { + var frontendId = eventName; + if (frontendId in this._nativeBreakpoints) + return; + + var breakpoint = new WebInspector.EventListenerBreakpoint(this, frontendId, eventName); + this._nativeBreakpoints[frontendId] = breakpoint; + breakpoint.enabled = !disabled; + return breakpoint; + }, + + createXHRBreakpoint: function(url, disabled) + { + var frontendId = url; + if (frontendId in this._nativeBreakpoints) + return; + + var breakpoint = new WebInspector.XHRBreakpoint(this, frontendId, url); + this._nativeBreakpoints[frontendId] = breakpoint; this.dispatchEventToListeners("xhr-breakpoint-added", breakpoint); + breakpoint.enabled = !disabled + return breakpoint; }, - _xhrBreakpointRemoved: function(event) + _removeNativeBreakpoint: function(breakpoint) { - delete this._xhrBreakpoints[event.target.url]; + if (breakpoint._beingSetOnBackend) + return; + if (breakpoint.enabled) + this._removeNativeBreakpointFromBackend(breakpoint); + delete this._nativeBreakpoints[breakpoint._frontendId]; + if (breakpoint._type === "DOM") + delete this._domBreakpoints[breakpoint._frontendId]; + breakpoint.dispatchEventToListeners("removed"); + }, + + _setNativeBreakpointEnabled: function(breakpoint, enabled) + { + if (breakpoint._beingSetOnBackend) + return; + if (breakpoint.enabled === enabled) + return; + if (enabled) + this._setNativeBreakpointOnBackend(breakpoint); + else + this._removeNativeBreakpointFromBackend(breakpoint); + }, + + _setNativeBreakpointOnBackend: function(breakpoint) + { + breakpoint._beingSetOnBackend = true; + var data = { type: breakpoint._type, condition: breakpoint._condition() }; + InspectorBackend.setNativeBreakpoint(data, didSetNativeBreakpoint.bind(this)); + + function didSetNativeBreakpoint(backendBreakpointId) + { + breakpoint._beingSetOnBackend = false; + if (backendBreakpointId !== "") { + breakpoint._backendId = backendBreakpointId; + this._breakpoints[backendBreakpointId] = breakpoint; + } + breakpoint.dispatchEventToListeners("enable-changed"); + } + }, + + _removeNativeBreakpointFromBackend: function(breakpoint) + { + InspectorBackend.removeNativeBreakpoint(breakpoint._backendId); + delete this._breakpoints[breakpoint._backendId] + delete breakpoint._backendId; + breakpoint.dispatchEventToListeners("enable-changed"); + }, + + debuggerPaused: function(details) + { + if (details.eventType !== WebInspector.DebuggerEventTypes.NativeBreakpoint) + return; + + var breakpoint = this._breakpoints[details.eventData.breakpointId]; + if (!breakpoint) + return; + + breakpoint.hit = true; + breakpoint.dispatchEventToListeners("hit-state-changed"); + this._lastHitBreakpoint = breakpoint; + + this.dispatchEventToListeners("breakpoint-hit", { breakpoint: breakpoint, eventData: details.eventData }); + }, + + debuggerResumed: function() + { + if (!this._lastHitBreakpoint) + return; + this._lastHitBreakpoint.hit = false; + this._lastHitBreakpoint.dispatchEventToListeners("hit-state-changed"); + delete this._lastHitBreakpoint; + }, + + restoreDOMBreakpoints: function() + { + var domBreakpoints = this._domBreakpoints; + this._domBreakpoints = {}; + + var breakpointsToRestore = {}; + for (var frontendId in domBreakpoints) { + var breakpoint = domBreakpoints[frontendId]; + var path = breakpoint._path; + if (!path) + continue; + if (!breakpointsToRestore[path]) { + breakpointsToRestore[path] = []; + InspectorBackend.pushNodeByPathToFrontend(path, restoreBreakpointsForNode.bind(this, breakpointsToRestore[path])); + } + breakpointsToRestore[path].push(breakpoint); + } + + function restoreBreakpointsForNode(breakpoints, nodeId) + { + if (!nodeId) + return; + for (var i = 0; i < breakpoints.length; ++i) + this.createDOMBreakpoint(nodeId, breakpoints[i]._domEventType, !breakpoints[i].enabled); + } } } @@ -226,82 +352,237 @@ WebInspector.Breakpoint.prototype = { WebInspector.Breakpoint.prototype.__proto__ = WebInspector.Object.prototype; -WebInspector.XHRBreakpoint = function(url) +WebInspector.NativeBreakpoint = function(manager, frontendId, type) { - this._url = url; - this._locked = false; - this.enabled = true; + this._manager = manager; + this.__frontendId = frontendId; + this.__type = type; } -WebInspector.XHRBreakpoint.prototype = { +WebInspector.NativeBreakpoint.prototype = { get enabled() { - return "_id" in this; + return "_backendId" in this; }, set enabled(enabled) { - if (this._locked) - return; - if (this.enabled === enabled) - return; - if (enabled) - this._setOnBackend(); - else - this._removeFromBackend(); + this._manager._setNativeBreakpointEnabled(this, enabled); }, - get url() + remove: function() { - return this._url; + this._manager._removeNativeBreakpoint(this); + this._onRemove(); }, - formatLabel: function() + get _frontendId() { - var label = ""; - if (!this.url.length) - label = WebInspector.UIString("Any XHR"); - else - label = WebInspector.UIString("URL contains \"%s\"", this.url); - return label; + return this.__frontendId; }, - compareTo: function(other) + get _type() { - if (this.url != other.url) - return this.url < other.url ? -1 : 1; + return this.__type; + }, + + _compare: function(x, y) + { + if (x !== y) + return x < y ? -1 : 1; return 0; }, - remove: function() + _onRemove: function() { - if (this._locked) - return; - if (this.enabled) - this._removeFromBackend(); - this.dispatchEventToListeners("removed"); + } +} + +WebInspector.NativeBreakpoint.prototype.__proto__ = WebInspector.Object.prototype; + +WebInspector.DOMBreakpoint = function(manager, frontendId, nodeId, domEventType) +{ + WebInspector.NativeBreakpoint.call(this, manager, frontendId, "DOM"); + this._nodeId = nodeId; + this._domEventType = domEventType; + + var node = WebInspector.domAgent.nodeForId(this._nodeId); + if (node) { + node.breakpoints[this._domEventType] = this; + this._path = node.path(); + } +} + +WebInspector.DOMBreakpoint.prototype = { + click: function() + { + WebInspector.updateFocusedNode(this._nodeId); }, - _setOnBackend: function() + compareTo: function(other) { - this._locked = true; - var data = { type: "XHR", condition: { url: this.url } }; - InspectorBackend.setNativeBreakpoint(data, didSet.bind(this)); + return this._compare(this._domEventType, other._domEventType); + }, - function didSet(breakpointId) + populateLabelElement: function(element) + { + element.appendChild(WebInspector.panels.elements.linkifyNodeById(this._nodeId)); + element.appendChild(document.createTextNode(" - ")); + element.appendChild(document.createTextNode(WebInspector.domBreakpointTypeLabel(this._domEventType))); + }, + + populateStatusMessageElement: function(element, eventData) + { + var substitutions = [WebInspector.domBreakpointTypeLabel(this._domEventType), WebInspector.panels.elements.linkifyNodeById(this._nodeId)]; + var formatters = { + s: function(substitution) + { + return substitution; + } + }; + function append(a, b) { - this._locked = false; - this._id = breakpointId; - this.dispatchEventToListeners("enable-changed"); + if (typeof b === "string") + b = document.createTextNode(b); + element.appendChild(b); } + if (this._domEventType === WebInspector.DOMBreakpointTypes.SubtreeModified) { + var targetNode = WebInspector.panels.elements.linkifyNodeById(eventData.targetNodeId); + if (eventData.insertion) { + if (eventData.targetNodeId !== this._nodeId) + WebInspector.formatLocalized("Paused on a \"%s\" breakpoint set on %s, because a new child was added to its descendant %s.", substitutions.concat(targetNode), formatters, "", append); + else + WebInspector.formatLocalized("Paused on a \"%s\" breakpoint set on %s, because a new child was added to that node.", substitutions, formatters, "", append); + } else + WebInspector.formatLocalized("Paused on a \"%s\" breakpoint set on %s, because its descendant %s was removed.", substitutions.concat(targetNode), formatters, "", append); + } else + WebInspector.formatLocalized("Paused on a \"%s\" breakpoint set on %s.", substitutions, formatters, "", append); }, - _removeFromBackend: function() + _condition: function() { - InspectorBackend.removeNativeBreakpoint(this._id); - delete this._id; - this.dispatchEventToListeners("enable-changed"); + return { nodeId: this._nodeId, type: this._domEventType }; + }, + + _onRemove: function() + { + var node = WebInspector.domAgent.nodeForId(this._nodeId); + if (node) + delete node.breakpoints[this._domEventType]; } } -WebInspector.XHRBreakpoint.prototype.__proto__ = WebInspector.Object.prototype; +WebInspector.DOMBreakpoint.prototype.__proto__ = WebInspector.NativeBreakpoint.prototype; + +WebInspector.EventListenerBreakpoint = function(manager, frontendId, eventName) +{ + WebInspector.NativeBreakpoint.call(this, manager, frontendId, "EventListener"); + this._eventName = eventName; +} + +WebInspector.EventListenerBreakpoint.prototype = { + compareTo: function(other) + { + return this._compare(this._eventName, other._eventName); + }, + + populateLabelElement: function(element) + { + element.appendChild(document.createTextNode(this._uiEventName())); + }, + + populateStatusMessageElement: function(element, eventData) + { + var status = WebInspector.UIString("Paused on a \"%s\" Event Listener.", this._uiEventName()); + element.appendChild(document.createTextNode(status)); + }, + + _condition: function() + { + return { eventName: this._eventName }; + }, + + _uiEventName: function() + { + if (!WebInspector.EventListenerBreakpoint._uiEventNames) { + WebInspector.EventListenerBreakpoint._uiEventNames = { + "instrumentation:setTimer": WebInspector.UIString("Set Timer"), + "instrumentation:clearTimer": WebInspector.UIString("Clear Timer"), + "instrumentation:timerFired": WebInspector.UIString("Timer Fired") + }; + } + return WebInspector.EventListenerBreakpoint._uiEventNames[this._eventName] || this._eventName.substring(this._eventName.indexOf(":") + 1); + } +} + +WebInspector.EventListenerBreakpoint.prototype.__proto__ = WebInspector.NativeBreakpoint.prototype; + +WebInspector.XHRBreakpoint = function(manager, frontendId, url) +{ + WebInspector.NativeBreakpoint.call(this, manager, frontendId, "XHR"); + this._url = url; +} + +WebInspector.XHRBreakpoint.prototype = { + compareTo: function(other) + { + return this._compare(this._url, other._url); + }, + + populateLabelElement: function(element) + { + var label; + if (!this._url.length) + label = WebInspector.UIString("Any XHR"); + else + label = WebInspector.UIString("URL contains \"%s\"", this._url); + element.appendChild(document.createTextNode(label)); + }, + + populateStatusMessageElement: function(element) + { + var status = WebInspector.UIString("Paused on a XMLHttpRequest."); + element.appendChild(document.createTextNode(status)); + }, + + _condition: function() + { + return { url: this._url }; + } +} + +WebInspector.XHRBreakpoint.prototype.__proto__ = WebInspector.NativeBreakpoint.prototype; + +WebInspector.DebuggerEventTypes = { + JavaScriptPause: 0, + JavaScriptBreakpoint: 1, + NativeBreakpoint: 2 +}; + +WebInspector.DOMBreakpointTypes = { + SubtreeModified: 0, + AttributeModified: 1, + NodeRemoved: 2 +}; + +WebInspector.domBreakpointTypeLabel = function(type) +{ + if (!WebInspector._DOMBreakpointTypeLabels) { + WebInspector._DOMBreakpointTypeLabels = {}; + WebInspector._DOMBreakpointTypeLabels[WebInspector.DOMBreakpointTypes.SubtreeModified] = WebInspector.UIString("Subtree Modified"); + WebInspector._DOMBreakpointTypeLabels[WebInspector.DOMBreakpointTypes.AttributeModified] = WebInspector.UIString("Attribute Modified"); + WebInspector._DOMBreakpointTypeLabels[WebInspector.DOMBreakpointTypes.NodeRemoved] = WebInspector.UIString("Node Removed"); + } + return WebInspector._DOMBreakpointTypeLabels[type]; +} + +WebInspector.domBreakpointTypeContextMenuLabel = function(type) +{ + if (!WebInspector._DOMBreakpointTypeContextMenuLabels) { + WebInspector._DOMBreakpointTypeContextMenuLabels = {}; + WebInspector._DOMBreakpointTypeContextMenuLabels[WebInspector.DOMBreakpointTypes.SubtreeModified] = WebInspector.UIString("Break on Subtree Modifications"); + WebInspector._DOMBreakpointTypeContextMenuLabels[WebInspector.DOMBreakpointTypes.AttributeModified] = WebInspector.UIString("Break on Attributes Modifications"); + WebInspector._DOMBreakpointTypeContextMenuLabels[WebInspector.DOMBreakpointTypes.NodeRemoved] = WebInspector.UIString("Break on Node Removal"); + } + return WebInspector._DOMBreakpointTypeContextMenuLabels[type]; +} |