diff options
Diffstat (limited to 'WebCore/inspector/front-end')
50 files changed, 2246 insertions, 1551 deletions
diff --git a/WebCore/inspector/front-end/AuditLauncherView.js b/WebCore/inspector/front-end/AuditLauncherView.js index 3ec4ba2..d4bbf90 100644 --- a/WebCore/inspector/front-end/AuditLauncherView.js +++ b/WebCore/inspector/front-end/AuditLauncherView.js @@ -53,6 +53,24 @@ WebInspector.AuditLauncherView = function(runnerCallback) } WebInspector.AuditLauncherView.prototype = { + updateResourceTrackingState: function(isTracking) + { + if (!this._auditPresentStateLabelElement) + return; + + if (isTracking) { + this._auditPresentStateLabelElement.nodeValue = WebInspector.UIString("Audit Present State"); + this._auditPresentStateElement.disabled = false; + this._auditPresentStateElement.parentElement.removeStyleClass("disabled"); + } else { + this._resetResourceCount(); + this._auditPresentStateLabelElement.nodeValue = WebInspector.UIString("Audit Present State (Resource Tracking must be enabled)"); + this._auditPresentStateElement.disabled = true; + this._auditPresentStateElement.parentElement.addStyleClass("disabled"); + this.auditReloadedStateElement.checked = true; + } + }, + get totalResources() { return this._totalResources; @@ -219,7 +237,7 @@ WebInspector.AuditLauncherView.prototype = { this._auditPresentStateElement.name = "audit-mode"; this._auditPresentStateElement.type = "radio"; this._auditPresentStateElement.checked = true; - this._auditPresentStateLabelElement = document.createTextNode(WebInspector.UIString("Audit Present State")); + this._auditPresentStateLabelElement = document.createTextNode(""); labelElement.appendChild(this._auditPresentStateElement); labelElement.appendChild(this._auditPresentStateLabelElement); this._buttonContainerElement.appendChild(labelElement); @@ -249,6 +267,7 @@ WebInspector.AuditLauncherView.prototype = { this._contentElement.appendChild(this._buttonContainerElement); this._selectAllClicked(this._selectAllCheckboxElement.checked); + this.updateResourceTrackingState(); this._updateButton(); this._updateResourceProgress(); }, diff --git a/WebCore/inspector/front-end/AuditsPanel.js b/WebCore/inspector/front-end/AuditsPanel.js index c42077f..096f8ce 100644 --- a/WebCore/inspector/front-end/AuditsPanel.js +++ b/WebCore/inspector/front-end/AuditsPanel.js @@ -248,6 +248,12 @@ WebInspector.AuditsPanel.prototype = { x.show(this.viewsContainerElement); }, + show: function() + { + WebInspector.Panel.prototype.show.call(this); + this._updateLauncherViewControls(!WebInspector.panels.resources || WebInspector.panels.resources.resourceTrackingEnabled); + }, + reset: function() { this._launcherView.reset(); @@ -265,6 +271,12 @@ WebInspector.AuditsPanel.prototype = { this.viewsContainerElement.style.left = width + "px"; }, + _updateLauncherViewControls: function(isTracking) + { + if (this._launcherView) + this._launcherView.updateResourceTrackingState(isTracking); + }, + _clearButtonClicked: function() { this.auditsItemTreeElement.reveal(); diff --git a/WebCore/inspector/front-end/Breakpoint.js b/WebCore/inspector/front-end/Breakpoint.js new file mode 100644 index 0000000..dd0ce12 --- /dev/null +++ b/WebCore/inspector/front-end/Breakpoint.js @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +WebInspector.Breakpoint = function(debuggerModel, breakpointId, sourceID, url, line, enabled, condition) +{ + this.id = breakpointId; + this.url = url; + this.line = line; + this.sourceID = sourceID; + this._enabled = enabled; + this._condition = condition || ""; + this._sourceText = ""; + this._hit = false; + this._debuggerModel = debuggerModel; +} + +WebInspector.Breakpoint.prototype = { + get enabled() + { + return this._enabled; + }, + + get sourceText() + { + return this._sourceText; + }, + + set sourceText(text) + { + this._sourceText = text; + this.dispatchEventToListeners("label-changed"); + }, + + get condition() + { + return this._condition; + }, + + get hit() + { + return this._hit; + }, + + set hit(hit) + { + this._hit = hit; + this.dispatchEventToListeners("hit-state-changed"); + }, + + click: function(event) + { + WebInspector.panels.scripts.showSourceLine(this.url, this.line); + }, + + compareTo: function(other) + { + if (this.url != other.url) + return this.url < other.url ? -1 : 1; + if (this.line != other.line) + return this.line < other.line ? -1 : 1; + return 0; + }, + + populateLabelElement: function(element) + { + var displayName = this.url ? WebInspector.displayNameForURL(this.url) : WebInspector.UIString("(program)"); + var labelElement = document.createTextNode(displayName + ":" + this.line); + element.appendChild(labelElement); + + var sourceTextElement = document.createElement("div"); + sourceTextElement.textContent = this.sourceText; + sourceTextElement.className = "source-text monospace"; + element.appendChild(sourceTextElement); + }, + + remove: function() + { + this._debuggerModel.removeBreakpoint(this.id); + this.dispatchEventToListeners("removed"); + this.removeAllListeners(); + delete this._debuggerModel; + } +} + +WebInspector.Breakpoint.prototype.__proto__ = WebInspector.Object.prototype; diff --git a/WebCore/inspector/front-end/BreakpointManager.js b/WebCore/inspector/front-end/BreakpointManager.js index 3d51092..67ef112 100644 --- a/WebCore/inspector/front-end/BreakpointManager.js +++ b/WebCore/inspector/front-end/BreakpointManager.js @@ -1,273 +1,249 @@ /* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. * Copyright (C) 2010 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. + * modification, are permitted provided that the following conditions are + * met: * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ WebInspector.BreakpointManager = function() { + this._stickyBreakpoints = {}; + var breakpoints = WebInspector.settings.findSettingForAllProjects("nativeBreakpoints"); + for (var projectId in breakpoints) + this._stickyBreakpoints[projectId] = this._validateBreakpoints(breakpoints[projectId]); + InspectorBackend.setStickyBreakpoints(this._stickyBreakpoints); + this._breakpoints = {}; - this._nativeBreakpoints = {}; + this._domBreakpointsRestored = false; + this._scriptBreakpoints = {}; + + WebInspector.settings.addEventListener(WebInspector.Settings.Events.ProjectChanged, this._projectChanged, this); + WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointAdded, this._scriptBreakpointAdded, this); + WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointRemoved, this._scriptBreakpointRemoved, this); + WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this); + WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerResumed, this._debuggerResumed, this); +} + +WebInspector.BreakpointManager.BreakpointTypes = { + DOM: "DOM", + JS: "JS", + EventListener: "EventListener", + XHR: "XHR" +} + +WebInspector.BreakpointManager.Events = { + DOMBreakpointAdded: "dom-breakpoint-added", + EventListenerBreakpointAdded: "event-listener-breakpoint-added", + XHRBreakpointAdded: "xhr-breakpoint-added", + ProjectChanged: "project-changed" } WebInspector.BreakpointManager.prototype = { - setOneTimeBreakpoint: function(sourceID, line) + createDOMBreakpoint: function(nodeId, type) { - var breakpoint = new WebInspector.Breakpoint(this, sourceID, undefined, line, true, undefined); - if (this._breakpoints[breakpoint.id]) - return; - if (this._oneTimeBreakpoint) - InspectorBackend.removeBreakpoint(this._oneTimeBreakpoint.sourceID, this._oneTimeBreakpoint.line); - this._oneTimeBreakpoint = breakpoint; - // FIXME(40669): one time breakpoint will be persisted in inspector settings if not hit. - this._setBreakpointOnBackend(breakpoint, true); + this._createDOMBreakpoint(nodeId, type, true, false); }, - removeOneTimeBreakpoint: function() + _createDOMBreakpoint: function(nodeId, type, enabled, restored) { - if (this._oneTimeBreakpoint) { - InspectorBackend.removeBreakpoint(this._oneTimeBreakpoint.sourceID, this._oneTimeBreakpoint.line); - delete this._oneTimeBreakpoint; - } - }, + var node = WebInspector.domAgent.nodeForId(nodeId); + if (!node) + return; - setBreakpoint: function(sourceID, url, line, enabled, condition) - { - var breakpoint = this._setBreakpoint(sourceID, url, line, enabled, condition); - if (breakpoint) - this._setBreakpointOnBackend(breakpoint); - }, + var breakpointId = this._createDOMBreakpointId(nodeId, type); + if (breakpointId in this._breakpoints) + return; - restoredBreakpoint: function(sourceID, url, line, enabled, condition) - { - this._setBreakpoint(sourceID, url, line, enabled, condition); - }, + var breakpoint = new WebInspector.DOMBreakpoint(node, type); + this._setBreakpoint(breakpointId, breakpoint, enabled, restored); + if (enabled && restored) + breakpoint._enable(); - breakpointsForSourceID: function(sourceID) - { - var breakpoints = []; - for (var id in this._breakpoints) { - if (this._breakpoints[id].sourceID === sourceID) - breakpoints.push(this._breakpoints[id]); - } - return breakpoints; + breakpoint.view = new WebInspector.DOMBreakpointView(this, breakpointId, enabled, node, type); + this.dispatchEventToListeners(WebInspector.BreakpointManager.Events.DOMBreakpointAdded, breakpoint.view); }, - breakpointsForURL: function(url) + createEventListenerBreakpoint: function(eventName) { - var breakpoints = []; - for (var id in this._breakpoints) { - if (this._breakpoints[id].url === url) - breakpoints.push(this._breakpoints[id]); - } - return breakpoints; + this._createEventListenerBreakpoint(eventName, true, false); }, - reset: function() + _createEventListenerBreakpoint: function(eventName, enabled, restored) { - this._breakpoints = {}; - delete this._oneTimeBreakpoint; - this._nativeBreakpoints = {}; + var breakpointId = this._createEventListenerBreakpointId(eventName); + if (breakpointId in this._breakpoints) + return; + + var breakpoint = new WebInspector.EventListenerBreakpoint(eventName); + this._setBreakpoint(breakpointId, breakpoint, enabled, restored); + + breakpoint.view = new WebInspector.EventListenerBreakpointView(this, breakpointId, enabled, eventName); + this.dispatchEventToListeners(WebInspector.BreakpointManager.Events.EventListenerBreakpointAdded, breakpoint.view); }, - _setBreakpoint: function(sourceID, url, line, enabled, condition) + _createJavaScriptBreakpoint: function(url, lineNumber, condition, enabled, restored) { - var breakpoint = new WebInspector.Breakpoint(this, sourceID, url, line, enabled, condition); - if (this._breakpoints[breakpoint.id]) + var breakpointId = this._createJavaScriptBreakpointId(url, lineNumber); + if (breakpointId in this._breakpoints) return; - if (this._oneTimeBreakpoint && (this._oneTimeBreakpoint.id == breakpoint.id)) - delete this._oneTimeBreakpoint; - this._breakpoints[breakpoint.id] = breakpoint; - breakpoint.addEventListener("removed", this._breakpointRemoved, this); - this.dispatchEventToListeners("breakpoint-added", breakpoint); - return breakpoint; - }, - _breakpointRemoved: function(event) - { - delete this._breakpoints[event.target.id]; + var breakpoint = new WebInspector.JavaScriptBreakpoint(url, lineNumber, condition); + this._setBreakpoint(breakpointId, breakpoint, enabled, restored); }, - _setBreakpointOnBackend: function(breakpoint, isOneTime) + _scriptBreakpointAdded: function(event) { - function didSetBreakpoint(success, line) - { - if (success && line == breakpoint.line) - return; - if (isOneTime) { - if (success) - this._oneTimeBreakpoint.line = line; - else - delete this._oneTimeBreakpoint; - } else { - breakpoint.remove(); - if (success) - this._setBreakpoint(breakpoint.sourceID, breakpoint.url, line, breakpoint.enabled, breakpoint.condition); - } - } - InspectorBackend.setBreakpoint(breakpoint.sourceID, breakpoint.line, breakpoint.enabled, breakpoint.condition, didSetBreakpoint.bind(this)); - }, + var scriptBreakpoint = event.data; - createDOMBreakpoint: function(nodeId, domEventType, disabled) - { - var frontendId = "dom:" + nodeId + ":" + domEventType; - if (frontendId in this._nativeBreakpoints) + if (!scriptBreakpoint.url) return; - var breakpoint = new WebInspector.DOMBreakpoint(this, frontendId, nodeId, domEventType); - this._nativeBreakpoints[frontendId] = breakpoint; - this.dispatchEventToListeners("dom-breakpoint-added", breakpoint); - breakpoint.enabled = !disabled; - return breakpoint; + if (!scriptBreakpoint.restored) + this._createJavaScriptBreakpoint(scriptBreakpoint.url, scriptBreakpoint.originalLineNumber, scriptBreakpoint.condition, scriptBreakpoint.enabled, false); + var breakpointId = this._createJavaScriptBreakpointId(scriptBreakpoint.url, scriptBreakpoint.originalLineNumber); + this._scriptBreakpoints[scriptBreakpoint.id] = breakpointId; }, - createEventListenerBreakpoint: function(eventName) + _scriptBreakpointRemoved: function(event) { - var frontendId = eventName; - if (frontendId in this._nativeBreakpoints) - return; + var scriptBreakpointId = event.data; + var breakpointId = this._scriptBreakpoints[scriptBreakpointId]; + delete this._scriptBreakpoints[scriptBreakpointId]; + if (breakpointId in this._breakpoints) + this._removeBreakpoint(breakpointId); + }, - var breakpoint = new WebInspector.EventListenerBreakpoint(this, frontendId, eventName); - this._nativeBreakpoints[frontendId] = breakpoint; - this.dispatchEventToListeners("event-listener-breakpoint-added", { breakpoint: breakpoint, eventName: eventName }); - breakpoint.enabled = true; - return breakpoint; + createXHRBreakpoint: function(url) + { + this._createXHRBreakpoint(url, true, false); }, - createXHRBreakpoint: function(url, disabled) + _createXHRBreakpoint: function(url, enabled, restored) { - var frontendId = url; - if (frontendId in this._nativeBreakpoints) + var breakpointId = this._createXHRBreakpointId(url); + if (breakpointId in this._breakpoints) return; - var breakpoint = new WebInspector.XHRBreakpoint(this, frontendId, url); - this._nativeBreakpoints[frontendId] = breakpoint; - this.dispatchEventToListeners("xhr-breakpoint-added", breakpoint); - breakpoint.enabled = !disabled - return breakpoint; + var breakpoint = new WebInspector.XHRBreakpoint(url); + this._setBreakpoint(breakpointId, breakpoint, enabled, restored); + + breakpoint.view = new WebInspector.XHRBreakpointView(this, breakpointId, enabled, url); + this.dispatchEventToListeners(WebInspector.BreakpointManager.Events.XHRBreakpointAdded, breakpoint.view); }, - _removeNativeBreakpoint: function(breakpoint) + _setBreakpoint: function(breakpointId, breakpoint, enabled, restored) { - if (breakpoint._beingSetOnBackend) + this._breakpoints[breakpointId] = breakpoint; + breakpoint.enabled = enabled; + if (restored) return; - if (breakpoint.enabled) - this._removeNativeBreakpointFromBackend(breakpoint); - delete this._nativeBreakpoints[breakpoint._frontendId]; - this._updateNativeBreakpointsInSettings(); - breakpoint.dispatchEventToListeners("removed"); + if (enabled) + breakpoint._enable(); + this._saveBreakpoints(); }, - _setNativeBreakpointEnabled: function(breakpoint, enabled) + _setBreakpointEnabled: function(breakpointId, enabled) { - if (breakpoint._beingSetOnBackend) - return; + var breakpoint = this._breakpoints[breakpointId]; if (breakpoint.enabled === enabled) return; if (enabled) - this._setNativeBreakpointOnBackend(breakpoint); + breakpoint._enable(); else - this._removeNativeBreakpointFromBackend(breakpoint); + breakpoint._disable(); + breakpoint.enabled = enabled; + this._saveBreakpoints(); }, - _setNativeBreakpointOnBackend: function(breakpoint) + _removeBreakpoint: function(breakpointId) { - 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"); - this._updateNativeBreakpointsInSettings(); - } + var breakpoint = this._breakpoints[breakpointId]; + if (breakpoint.enabled) + breakpoint._disable(); + delete this._breakpoints[breakpointId]; + this._saveBreakpoints(); }, - _removeNativeBreakpointFromBackend: function(breakpoint) + breakpointViewForEventData: function(eventData) { - InspectorBackend.removeNativeBreakpoint(breakpoint._backendId); - delete this._breakpoints[breakpoint._backendId] - delete breakpoint._backendId; - breakpoint.dispatchEventToListeners("enable-changed"); - this._updateNativeBreakpointsInSettings(); - }, + var breakpointId; + if (eventData.breakpointType === WebInspector.BreakpointManager.BreakpointTypes.DOM) + breakpointId = this._createDOMBreakpointId(eventData.nodeId, eventData.type); + else if (eventData.breakpointType === WebInspector.BreakpointManager.BreakpointTypes.EventListener) + breakpointId = this._createEventListenerBreakpointId(eventData.eventName); + else if (eventData.breakpointType === WebInspector.BreakpointManager.BreakpointTypes.XHR) + breakpointId = this._createXHRBreakpointId(eventData.breakpointURL); + else + return; - _updateNativeBreakpointsInSettings: function() - { - var persistentBreakpoints = []; - for (var id in this._nativeBreakpoints) { - var breakpoint = this._nativeBreakpoints[id]; - if (breakpoint._persistentCondition) - persistentBreakpoints.push({ type: breakpoint._type, enabled: breakpoint.enabled, condition: breakpoint._persistentCondition }); - } - WebInspector.settings.nativeBreakpoints = persistentBreakpoints; + var breakpoint = this._breakpoints[breakpointId]; + if (breakpoint) + return breakpoint.view; }, - debuggerPaused: function(details) + _debuggerPaused: function(event) { - if (details.eventType === WebInspector.DebuggerEventTypes.JavaScriptPause) - return; + var eventType = event.data.eventType; + var eventData = event.data.eventData; - if (details.eventData && details.eventData.breakpointId) - var breakpointId = details.eventData.breakpointId; - else if (details.callFrames && details.callFrames.length) - var breakpointId = WebInspector.Breakpoint.jsBreakpointId(details.callFrames[0].sourceID, details.callFrames[0].line); - else + if (eventType !== WebInspector.DebuggerEventTypes.NativeBreakpoint) return; - var breakpoint = this._breakpoints[breakpointId]; - if (!breakpoint) + var breakpointView = this.breakpointViewForEventData(eventData); + if (!breakpointView) return; - breakpoint.hit = true; - breakpoint.dispatchEventToListeners("hit-state-changed"); - this._lastHitBreakpoint = breakpoint; - - this.dispatchEventToListeners("breakpoint-hit", { breakpoint: breakpoint, eventData: details.eventData }); + breakpointView.hit = true; + this._lastHitBreakpointView = breakpointView; }, - debuggerResumed: function() + _debuggerResumed: function(event) { - if (!this._lastHitBreakpoint) + if (!this._lastHitBreakpointView) return; - this._lastHitBreakpoint.hit = false; - this._lastHitBreakpoint.dispatchEventToListeners("hit-state-changed"); - delete this._lastHitBreakpoint; + this._lastHitBreakpointView.hit = false; + delete this._lastHitBreakpointView; }, - restoreBreakpoints: function() + _projectChanged: function(event) { - var breakpoints = this._persistentBreakpoints(); + this._breakpoints = {}; + this._domBreakpointsRestored = false; + this._scriptBreakpoints = {}; + this.dispatchEventToListeners(WebInspector.BreakpointManager.Events.ProjectChanged); + + var breakpoints = this._stickyBreakpoints[WebInspector.settings.projectId] || []; for (var i = 0; i < breakpoints.length; ++i) { - if (breakpoints[i].type === "EventListener") - this.createEventListenerBreakpoint(breakpoints[i].condition.eventName); - else if (breakpoints[i].type === "XHR") - this.createXHRBreakpoint(breakpoints[i].condition.url, !breakpoints[i].enabled); + var breakpoint = breakpoints[i]; + if (breakpoint.type === WebInspector.BreakpointManager.BreakpointTypes.EventListener) + this._createEventListenerBreakpoint(breakpoint.condition.eventName, breakpoint.enabled, true); + else if (breakpoint.type === WebInspector.BreakpointManager.BreakpointTypes.JS) + this._createJavaScriptBreakpoint(breakpoint.condition.url, breakpoint.condition.lineNumber, breakpoint.condition.condition, breakpoint.enabled, true); + else if (breakpoint.type === WebInspector.BreakpointManager.BreakpointTypes.XHR) + this._createXHRBreakpoint(breakpoint.condition.url, breakpoint.enabled, true); } }, @@ -281,17 +257,21 @@ WebInspector.BreakpointManager.prototype = { return; for (var i = 0; i < breakpoints.length; ++i) { var breakpoint = breakpoints[i]; + if (breakpoint.type !== WebInspector.BreakpointManager.BreakpointTypes.DOM) + continue; var nodeId = pathToNodeId[breakpoint.condition.path]; if (nodeId) - this.createDOMBreakpoint(nodeId, breakpoint.condition.type, !breakpoint.enabled); + this._createDOMBreakpoint(nodeId, breakpoint.condition.type, breakpoint.enabled, true); } + this._domBreakpointsRestored = true; + this._saveBreakpoints(); } - var breakpoints = this._persistentBreakpoints(); + var breakpoints = this._stickyBreakpoints[WebInspector.settings.projectId] || []; var pathToNodeId = {}; var pendingCalls = 0; for (var i = 0; i < breakpoints.length; ++i) { - if (breakpoints[i].type !== "DOM") + if (breakpoints[i].type !== WebInspector.BreakpointManager.BreakpointTypes.DOM) continue; var path = breakpoints[i].condition.path; if (path in pathToNodeId) @@ -300,159 +280,223 @@ WebInspector.BreakpointManager.prototype = { pendingCalls += 1; InspectorBackend.pushNodeByPathToFrontend(path, didPushNodeByPathToFrontend.bind(this, path)); } + if (!pendingCalls) + this._domBreakpointsRestored = true; }, - _persistentBreakpoints: function() + _saveBreakpoints: function() { - var result = []; - var breakpoints = WebInspector.settings.nativeBreakpoints; - if (breakpoints instanceof Array) { - for (var i = 0; i < breakpoints.length; ++i) { - var breakpoint = breakpoints[i]; - if ("type" in breakpoint && "condition" in breakpoint) - result.push(breakpoint) + var breakpoints = []; + for (var breakpointId in this._breakpoints) { + var breakpoint = this._breakpoints[breakpointId]; + var persistentBreakpoint = breakpoint._serializeToJSON(); + persistentBreakpoint.enabled = breakpoint.enabled; + breakpoints.push(persistentBreakpoint); + } + if (!this._domBreakpointsRestored) { + var stickyBreakpoints = this._stickyBreakpoints[WebInspector.settings.projectId] || []; + for (var i = 0; i < stickyBreakpoints.length; ++i) { + if (stickyBreakpoints[i].type === WebInspector.BreakpointManager.BreakpointTypes.DOM) + breakpoints.push(stickyBreakpoints[i]); } } - return result; + WebInspector.settings.nativeBreakpoints = breakpoints; + + this._stickyBreakpoints[WebInspector.settings.projectId] = breakpoints; + InspectorBackend.setStickyBreakpoints(this._stickyBreakpoints); + }, + + _validateBreakpoints: function(persistentBreakpoints) + { + var breakpoints = []; + var breakpointsSet = {}; + for (var i = 0; i < persistentBreakpoints.length; ++i) { + var breakpoint = persistentBreakpoints[i]; + if (!("type" in breakpoint && "enabled" in breakpoint && "condition" in breakpoint)) + continue; + var id = breakpoint.type + ":"; + var condition = breakpoint.condition; + if (breakpoint.type === WebInspector.BreakpointManager.BreakpointTypes.DOM) { + if (typeof condition.path !== "string" || typeof condition.type !== "number") + continue; + id += condition.path + ":" + condition.type; + } else if (breakpoint.type === WebInspector.BreakpointManager.BreakpointTypes.EventListener) { + if (typeof condition.eventName !== "string") + continue; + id += condition.eventName; + } else if (breakpoint.type === WebInspector.BreakpointManager.BreakpointTypes.JS) { + if (typeof condition.url !== "string" || typeof condition.lineNumber !== "number" || typeof condition.condition !== "string") + continue; + id += condition.url + ":" + condition.lineNumber; + } else if (breakpoint.type === WebInspector.BreakpointManager.BreakpointTypes.XHR) { + if (typeof condition.url !== "string") + continue; + id += condition.url; + } + if (id in breakpointsSet) + continue; + breakpointsSet[id] = true; + breakpoints.push(breakpoint); + } + return breakpoints; + }, + + _createDOMBreakpointId: function(nodeId, type) + { + return "dom:" + nodeId + ":" + type; + }, + + _createJavaScriptBreakpointId: function(url, lineNumber) + { + return "js:" + url + ":" + lineNumber; + }, + + _createEventListenerBreakpointId: function(eventName) + { + return "eventListner:" + eventName; + }, + + _createXHRBreakpointId: function(url) + { + return "xhr:" + url; } } WebInspector.BreakpointManager.prototype.__proto__ = WebInspector.Object.prototype; -WebInspector.Breakpoint = function(breakpointManager, sourceID, url, line, enabled, condition) +WebInspector.DOMBreakpoint = function(node, type) { - this.url = url; - this.line = line; - this.sourceID = sourceID; - this._enabled = enabled; - this._condition = condition || ""; - this._sourceText = ""; - this._breakpointManager = breakpointManager; + this._nodeId = node.id; + this._path = node.path(); + this._type = type; } -WebInspector.Breakpoint.jsBreakpointId = function(sourceID, line) -{ - return sourceID + ":" + line; -} +WebInspector.DOMBreakpoint.prototype = { + _enable: function() + { + InspectorBackend.setDOMBreakpoint(this._nodeId, this._type); + }, -WebInspector.Breakpoint.prototype = { - get enabled() + _disable: function() { - return this._enabled; + InspectorBackend.removeDOMBreakpoint(this._nodeId, this._type); }, - set enabled(x) + _serializeToJSON: function() { - if (this._enabled === x) - return; + var type = WebInspector.BreakpointManager.BreakpointTypes.DOM; + return { type: type, condition: { path: this._path, type: this._type } }; + } +} - this._enabled = x; - this._breakpointManager._setBreakpointOnBackend(this); - this.dispatchEventToListeners("enable-changed"); - }, +WebInspector.JavaScriptBreakpoint = function(url, lineNumber, condition) +{ + this._url = url; + this._lineNumber = lineNumber; + this._condition = condition; +} - get sourceText() +WebInspector.JavaScriptBreakpoint.prototype = { + _enable: function() { - return this._sourceText; }, - set sourceText(text) + _disable: function() { - this._sourceText = text; - this.dispatchEventToListeners("label-changed"); }, - get id() + _serializeToJSON: function() { - return WebInspector.Breakpoint.jsBreakpointId(this.sourceID, this.line); - }, + var type = WebInspector.BreakpointManager.BreakpointTypes.JS; + return { type: type, condition: { url: this._url, lineNumber: this._lineNumber, condition: this._condition } }; + } +} + +WebInspector.EventListenerBreakpoint = function(eventName) +{ + this._eventName = eventName; +} - get condition() +WebInspector.EventListenerBreakpoint.prototype = { + _enable: function() { - return this._condition; + InspectorBackend.setEventListenerBreakpoint(this._eventName); }, - set condition(c) + _disable: function() { - c = c || ""; - if (this._condition === c) - return; - - this._condition = c; - if (this.enabled) - this._breakpointManager._setBreakpointOnBackend(this); - this.dispatchEventToListeners("condition-changed"); + InspectorBackend.removeEventListenerBreakpoint(this._eventName); }, - click: function(event) + _serializeToJSON: function() { - WebInspector.panels.scripts.showSourceLine(this.url, this.line); - }, + var type = WebInspector.BreakpointManager.BreakpointTypes.EventListener; + return { type: type, condition: { eventName: this._eventName } }; + } +} - compareTo: function(other) +WebInspector.XHRBreakpoint = function(url) +{ + this._url = url; +} + +WebInspector.XHRBreakpoint.prototype = { + _enable: function() { - if (this.url != other.url) - return this.url < other.url ? -1 : 1; - if (this.line != other.line) - return this.line < other.line ? -1 : 1; - return 0; + InspectorBackend.setXHRBreakpoint(this._url); }, - populateLabelElement: function(element) + _disable: function() { - var displayName = this.url ? WebInspector.displayNameForURL(this.url) : WebInspector.UIString("(program)"); - var labelElement = document.createTextNode(displayName + ":" + this.line); - element.appendChild(labelElement); - - var sourceTextElement = document.createElement("div"); - sourceTextElement.textContent = this.sourceText; - sourceTextElement.className = "source-text monospace"; - element.appendChild(sourceTextElement); + InspectorBackend.removeXHRBreakpoint(this._url); }, - remove: function() + _serializeToJSON: function() { - InspectorBackend.removeBreakpoint(this.sourceID, this.line); - this.dispatchEventToListeners("removed"); - this.removeAllListeners(); - delete this._breakpointManager; + var type = WebInspector.BreakpointManager.BreakpointTypes.XHR; + return { type: type, condition: { url: this._url } }; } } -WebInspector.Breakpoint.prototype.__proto__ = WebInspector.Object.prototype; -WebInspector.NativeBreakpoint = function(manager, frontendId, type) + +WebInspector.NativeBreakpointView = function(manager, id, enabled) { this._manager = manager; - this.__frontendId = frontendId; - this.__type = type; + this._id = id; + this._enabled = enabled; + this._hit = false; } -WebInspector.NativeBreakpoint.prototype = { +WebInspector.NativeBreakpointView.prototype = { get enabled() { - return "_backendId" in this; + return this._enabled; }, set enabled(enabled) { - this._manager._setNativeBreakpointEnabled(this, enabled); + this._manager._setBreakpointEnabled(this._id, enabled); + this._enabled = enabled; + this.dispatchEventToListeners("enable-changed"); }, - remove: function() + get hit() { - this._manager._removeNativeBreakpoint(this); - this._onRemove(); + return this._hit; }, - get _frontendId() + set hit(hit) { - return this.__frontendId; + this._hit = hit; + this.dispatchEventToListeners("hit-state-changed"); }, - get _type() + remove: function() { - return this.__type; + this._manager._removeBreakpoint(this._id); + this._onRemove(); + this.dispatchEventToListeners("removed"); }, _compare: function(x, y) @@ -467,26 +511,21 @@ WebInspector.NativeBreakpoint.prototype = { } } -WebInspector.NativeBreakpoint.prototype.__proto__ = WebInspector.Object.prototype; +WebInspector.NativeBreakpointView.prototype.__proto__ = WebInspector.Object.prototype; -WebInspector.DOMBreakpoint = function(manager, frontendId, nodeId, domEventType) +WebInspector.DOMBreakpointView = function(manager, id, enabled, node, type) { - WebInspector.NativeBreakpoint.call(this, manager, frontendId, "DOM"); - this._nodeId = nodeId; - this._domEventType = domEventType; - this._condition = { nodeId: this._nodeId, type: this._domEventType }; - - var node = WebInspector.domAgent.nodeForId(this._nodeId); - if (node) { - node.breakpoints[this._domEventType] = this; - this._persistentCondition = { path: node.path(), type: this._domEventType }; - } + WebInspector.NativeBreakpointView.call(this, manager, id, enabled); + this._node = node; + this._nodeId = node.id; + this._type = type; + node.breakpoints[this._type] = this; } -WebInspector.DOMBreakpoint.prototype = { +WebInspector.DOMBreakpointView.prototype = { compareTo: function(other) { - return this._compare(this._domEventType, other._domEventType); + return this._compare(this._type, other._type); }, populateLabelElement: function(element) @@ -497,13 +536,13 @@ WebInspector.DOMBreakpoint.prototype = { element.appendChild(linkifiedNode); var description = document.createElement("div"); description.className = "source-text"; - description.textContent = WebInspector.domBreakpointTypeLabel(this._domEventType); + description.textContent = WebInspector.domBreakpointTypeLabel(this._type); element.appendChild(description); }, populateStatusMessageElement: function(element, eventData) { - var substitutions = [WebInspector.domBreakpointTypeLabel(this._domEventType), WebInspector.panels.elements.linkifyNodeById(this._nodeId)]; + var substitutions = [WebInspector.domBreakpointTypeLabel(this._type), WebInspector.panels.elements.linkifyNodeById(this._nodeId)]; var formatters = { s: function(substitution) { @@ -516,7 +555,7 @@ WebInspector.DOMBreakpoint.prototype = { b = document.createTextNode(b); element.appendChild(b); } - if (this._domEventType === WebInspector.DOMBreakpointTypes.SubtreeModified) { + if (this._type === WebInspector.DOMBreakpointTypes.SubtreeModified) { var targetNode = WebInspector.panels.elements.linkifyNodeById(eventData.targetNodeId); if (eventData.insertion) { if (eventData.targetNodeId !== this._nodeId) @@ -531,35 +570,36 @@ WebInspector.DOMBreakpoint.prototype = { _onRemove: function() { - var node = WebInspector.domAgent.nodeForId(this._nodeId); - if (node) - delete node.breakpoints[this._domEventType]; + delete this._node.breakpoints[this._type]; } } -WebInspector.DOMBreakpoint.prototype.__proto__ = WebInspector.NativeBreakpoint.prototype; +WebInspector.DOMBreakpointView.prototype.__proto__ = WebInspector.NativeBreakpointView.prototype; -WebInspector.EventListenerBreakpoint = function(manager, frontendId, eventName) +WebInspector.EventListenerBreakpointView = function(manager, id, enabled, eventName) { - WebInspector.NativeBreakpoint.call(this, manager, frontendId, "EventListener"); + WebInspector.NativeBreakpointView.call(this, manager, id, enabled); this._eventName = eventName; - this._condition = { eventName: this._eventName }; - this._persistentCondition = this._condition; } -WebInspector.EventListenerBreakpoint.eventNameForUI = function(eventName) +WebInspector.EventListenerBreakpointView.eventNameForUI = function(eventName) { - if (!WebInspector.EventListenerBreakpoint._eventNamesForUI) { - WebInspector.EventListenerBreakpoint._eventNamesForUI = { + if (!WebInspector.EventListenerBreakpointView._eventNamesForUI) { + WebInspector.EventListenerBreakpointView._eventNamesForUI = { "instrumentation:setTimer": WebInspector.UIString("Set Timer"), "instrumentation:clearTimer": WebInspector.UIString("Clear Timer"), "instrumentation:timerFired": WebInspector.UIString("Timer Fired") }; } - return WebInspector.EventListenerBreakpoint._eventNamesForUI[eventName] || eventName.substring(eventName.indexOf(":") + 1); + return WebInspector.EventListenerBreakpointView._eventNamesForUI[eventName] || eventName.substring(eventName.indexOf(":") + 1); } -WebInspector.EventListenerBreakpoint.prototype = { +WebInspector.EventListenerBreakpointView.prototype = { + get eventName() + { + return this._eventName; + }, + compareTo: function(other) { return this._compare(this._eventName, other._eventName); @@ -578,21 +618,19 @@ WebInspector.EventListenerBreakpoint.prototype = { _uiEventName: function() { - return WebInspector.EventListenerBreakpoint.eventNameForUI(this._eventName); + return WebInspector.EventListenerBreakpointView.eventNameForUI(this._eventName); } } -WebInspector.EventListenerBreakpoint.prototype.__proto__ = WebInspector.NativeBreakpoint.prototype; +WebInspector.EventListenerBreakpointView.prototype.__proto__ = WebInspector.NativeBreakpointView.prototype; -WebInspector.XHRBreakpoint = function(manager, frontendId, url) +WebInspector.XHRBreakpointView = function(manager, id, enabled, url) { - WebInspector.NativeBreakpoint.call(this, manager, frontendId, "XHR"); + WebInspector.NativeBreakpointView.call(this, manager, id, enabled); this._url = url; - this._condition = { url: this._url }; - this._persistentCondition = this._condition; } -WebInspector.XHRBreakpoint.prototype = { +WebInspector.XHRBreakpointView.prototype = { compareTo: function(other) { return this._compare(this._url, other._url); @@ -621,13 +659,7 @@ WebInspector.XHRBreakpoint.prototype = { } } -WebInspector.XHRBreakpoint.prototype.__proto__ = WebInspector.NativeBreakpoint.prototype; - -WebInspector.DebuggerEventTypes = { - JavaScriptPause: 0, - JavaScriptBreakpoint: 1, - NativeBreakpoint: 2 -}; +WebInspector.XHRBreakpointView.prototype.__proto__ = WebInspector.NativeBreakpointView.prototype; WebInspector.DOMBreakpointTypes = { SubtreeModified: 0, diff --git a/WebCore/inspector/front-end/BreakpointsSidebarPane.js b/WebCore/inspector/front-end/BreakpointsSidebarPane.js index 47194da..619525c 100644 --- a/WebCore/inspector/front-end/BreakpointsSidebarPane.js +++ b/WebCore/inspector/front-end/BreakpointsSidebarPane.js @@ -35,18 +35,11 @@ WebInspector.BreakpointsSidebarPane = function(title) this.emptyElement.textContent = WebInspector.UIString("No Breakpoints"); this.bodyElement.appendChild(this.emptyElement); + + WebInspector.breakpointManager.addEventListener(WebInspector.BreakpointManager.Events.ProjectChanged, this._projectChanged, this); } WebInspector.BreakpointsSidebarPane.prototype = { - reset: function() - { - this.listElement.removeChildren(); - if (this.listElement.parentElement) { - this.bodyElement.removeChild(this.listElement); - this.bodyElement.appendChild(this.emptyElement); - } - }, - addBreakpointItem: function(breakpointItem) { var element = breakpointItem.element; @@ -97,6 +90,15 @@ WebInspector.BreakpointsSidebarPane.prototype = { this.bodyElement.removeChild(this.listElement); this.bodyElement.appendChild(this.emptyElement); } + }, + + _projectChanged: function() + { + this.listElement.removeChildren(); + if (this.listElement.parentElement) { + this.bodyElement.removeChild(this.listElement); + this.bodyElement.appendChild(this.emptyElement); + } } } @@ -145,7 +147,10 @@ WebInspector.XHRBreakpointsSidebarPane.prototype = { var commitHandler = this._hideEditBreakpointDialog.bind(this, inputElement, true, breakpointItem); var cancelHandler = this._hideEditBreakpointDialog.bind(this, inputElement, false, breakpointItem); - WebInspector.startEditing(inputElement, commitHandler, cancelHandler); + WebInspector.startEditing(inputElement, { + commitHandler: commitHandler, + cancelHandler: cancelHandler + }); }, _hideEditBreakpointDialog: function(inputElement, accept, breakpointItem) @@ -256,7 +261,8 @@ WebInspector.EventListenerBreakpointsSidebarPane = function() this.categoriesTreeOutline = new TreeOutline(this.categoriesElement); this.bodyElement.appendChild(this.categoriesElement); - WebInspector.breakpointManager.addEventListener("event-listener-breakpoint-added", this._breakpointAdded, this); + WebInspector.breakpointManager.addEventListener(WebInspector.BreakpointManager.Events.ProjectChanged, this._projectChanged, this); + WebInspector.breakpointManager.addEventListener(WebInspector.BreakpointManager.Events.EventListenerBreakpointAdded, this._breakpointAdded, this); this._breakpointItems = {}; this._createCategory("Keyboard", "listener", ["keydown", "keyup", "keypress", "textInput"]); @@ -289,7 +295,7 @@ WebInspector.EventListenerBreakpointsSidebarPane.prototype = { var eventName = type + ":" + eventNames[i]; var breakpointItem = {}; - var title = WebInspector.EventListenerBreakpoint.eventNameForUI(eventName); + var title = WebInspector.EventListenerBreakpointView.eventNameForUI(eventName); breakpointItem.element = new TreeElement(title); categoryItem.element.appendChild(breakpointItem.element); var hitMarker = document.createElement("div"); @@ -339,10 +345,9 @@ WebInspector.EventListenerBreakpointsSidebarPane.prototype = { _breakpointAdded: function(event) { - var breakpoint = event.data.breakpoint; - var eventName = event.data.eventName; + var breakpoint = event.data; - var breakpointItem = this._breakpointItems[eventName]; + var breakpointItem = this._breakpointItems[breakpoint.eventName]; breakpointItem.breakpoint = breakpoint; breakpoint.addEventListener("hit-state-changed", this._breakpointHitStateChanged.bind(this, breakpointItem)); breakpoint.addEventListener("removed", this._breakpointRemoved.bind(this, breakpointItem)); @@ -383,7 +388,7 @@ WebInspector.EventListenerBreakpointsSidebarPane.prototype = { categoryItem.checkbox.indeterminate = hasEnabled && hasDisabled; }, - reset: function() + _projectChanged: function() { for (var eventName in this._breakpointItems) { var breakpointItem = this._breakpointItems[eventName]; diff --git a/WebCore/inspector/front-end/CSSCompletions.js b/WebCore/inspector/front-end/CSSCompletions.js index 9480467..e8d7556 100644 --- a/WebCore/inspector/front-end/CSSCompletions.js +++ b/WebCore/inspector/front-end/CSSCompletions.js @@ -1,88 +1,124 @@ -WebInspector.CSSCompletions = []; - -WebInspector.CSSCompletions.startsWith = function(prefix) -{ - var firstIndex = this._firstIndexOfPrefix(prefix); - if (firstIndex === -1) - return []; - - var results = []; - while (this[firstIndex].indexOf(prefix) === 0) - results.push(this[firstIndex++]); - return results; -} - -WebInspector.CSSCompletions.firstStartsWith = function(prefix) +/* + * Copyright (C) 2010 Nikita Vasilyev. All rights reserved. + * Copyright (C) 2010 Joseph Pecoraro. All rights reserved. + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +WebInspector.CSSCompletions = function(values) { - var foundIndex = this._firstIndexOfPrefix(prefix); - return (foundIndex === -1 ? "" : this[foundIndex]); + this._values = values.slice(); + this._values.sort(); } -WebInspector.CSSCompletions._firstIndexOfPrefix = function(prefix) -{ - if (!prefix) - return -1; - if (!this.length) - return -1; - - var maxIndex = this.length - 1; - var minIndex = 0; - var foundIndex; - - do { - var middleIndex = (maxIndex + minIndex) >> 1; - if (this[middleIndex].indexOf(prefix) === 0) { - foundIndex = middleIndex; - break; +WebInspector.CSSCompletions.prototype = { + startsWith: function(prefix) + { + var firstIndex = this._firstIndexOfPrefix(prefix); + if (firstIndex === -1) + return []; + + var results = []; + while (this._values[firstIndex].indexOf(prefix) === 0) + results.push(this._values[firstIndex++]); + return results; + }, + + firstStartsWith: function(prefix) + { + var foundIndex = this._firstIndexOfPrefix(prefix); + return (foundIndex === -1 ? "" : this._values[foundIndex]); + }, + + _firstIndexOfPrefix: function(prefix) + { + if (!prefix) + return -1; + if (!this._values.length) + return -1; + + var maxIndex = this._values.length - 1; + var minIndex = 0; + var foundIndex; + + do { + var middleIndex = (maxIndex + minIndex) >> 1; + if (this._values[middleIndex].indexOf(prefix) === 0) { + foundIndex = middleIndex; + break; + } + if (this._values[middleIndex] < prefix) + minIndex = middleIndex + 1; + else + maxIndex = middleIndex - 1; + } while (minIndex <= maxIndex); + + if (foundIndex === undefined) + return -1; + + while (foundIndex && this._values[foundIndex - 1].indexOf(prefix) === 0) + foundIndex--; + + return foundIndex; + }, + + keySet: function() + { + return this._values.keySet(); + }, + + next: function(str, prefix) + { + return this._closest(str, prefix, 1); + }, + + previous: function(str, prefix) + { + return this._closest(str, prefix, -1); + }, + + _closest: function(str, prefix, shift) + { + if (!str) + return ""; + + var index = this._values.indexOf(str); + if (index === -1) + return ""; + + if (!prefix) { + index = (index + this._values.length + shift) % this._values.length; + return this._values[index]; } - if (this[middleIndex] < prefix) - minIndex = middleIndex + 1; - else - maxIndex = middleIndex - 1; - } while (minIndex <= maxIndex); - - if (!foundIndex) - return -1; - - while (foundIndex && this[foundIndex - 1].indexOf(prefix) === 0) - foundIndex--; - - return foundIndex; -} - -WebInspector.CSSCompletions.next = function(str, prefix) -{ - return WebInspector.CSSCompletions._closest(str, prefix, 1); -} - -WebInspector.CSSCompletions.previous = function(str, prefix) -{ - return WebInspector.CSSCompletions._closest(str, prefix, -1); -} - -WebInspector.CSSCompletions._closest = function(str, prefix, shift) -{ - if (!str) - return ""; - var index = this.indexOf(str); - if (index === -1) - return ""; - - if (!prefix) { - index = (index + this.length + shift) % this.length; - return this[index]; + var propertiesWithPrefix = this.startsWith(prefix); + var j = propertiesWithPrefix.indexOf(str); + j = (j + propertiesWithPrefix.length + shift) % propertiesWithPrefix.length; + return propertiesWithPrefix[j]; } - - var propertiesWithPrefix = this.startsWith(prefix); - var j = propertiesWithPrefix.indexOf(str); - j = (j + propertiesWithPrefix.length + shift) % propertiesWithPrefix.length; - return propertiesWithPrefix[j]; -} - -WebInspector.CSSCompletions._load = function(properties) -{ - for (var i = 0; i < properties.length; ++i) - WebInspector.CSSCompletions.push(properties[i]); - WebInspector.CSSCompletions.sort(); } diff --git a/WebCore/inspector/front-end/CSSStyleModel.js b/WebCore/inspector/front-end/CSSStyleModel.js index 23ed7a8..2d15582 100644 --- a/WebCore/inspector/front-end/CSSStyleModel.js +++ b/WebCore/inspector/front-end/CSSStyleModel.js @@ -174,11 +174,14 @@ WebInspector.CSSStyleModel.prototype = { function callback(success) { this._styleSheetChanged(styleSheetId, true); + this.dispatchEventToListeners("stylesheet changed"); } InspectorBackend.setStyleSheetText2(styleSheetId, contentToRevertTo, callback.bind(this)); } } +WebInspector.CSSStyleModel.prototype.__proto__ = WebInspector.Object.prototype; + WebInspector.CSSStyleDeclaration = function(payload) { this.id = payload.styleId; diff --git a/WebCore/inspector/front-end/CallStackSidebarPane.js b/WebCore/inspector/front-end/CallStackSidebarPane.js index b2e6a5c..432260e 100644 --- a/WebCore/inspector/front-end/CallStackSidebarPane.js +++ b/WebCore/inspector/front-end/CallStackSidebarPane.js @@ -26,11 +26,10 @@ WebInspector.CallStackSidebarPane = function() { WebInspector.SidebarPane.call(this, WebInspector.UIString("Call Stack")); - WebInspector.breakpointManager.addEventListener("breakpoint-hit", this._breakpointHit, this); } WebInspector.CallStackSidebarPane.prototype = { - update: function(callFrames, sourceIDMap) + update: function(callFrames, eventType, eventData) { this.bodyElement.removeChildren(); @@ -47,7 +46,7 @@ WebInspector.CallStackSidebarPane.prototype = { var title; var subtitle; - var scriptOrResource; + var script; for (var i = 0; i < callFrames.length; ++i) { var callFrame = callFrames[i]; @@ -60,9 +59,9 @@ WebInspector.CallStackSidebarPane.prototype = { break; } - scriptOrResource = sourceIDMap[callFrame.sourceID]; - if (scriptOrResource) - subtitle = WebInspector.displayNameForURL(scriptOrResource.sourceURL || scriptOrResource.url); + script = WebInspector.debuggerModel.scriptForSourceID(callFrame.sourceID); + if (script) + subtitle = WebInspector.displayNameForURL(script.sourceURL); else subtitle = WebInspector.UIString("(internal script)"); @@ -81,6 +80,19 @@ WebInspector.CallStackSidebarPane.prototype = { this.placards.push(placard); this.bodyElement.appendChild(placard.element); } + + if (eventType === WebInspector.DebuggerEventTypes.JavaScriptPause) + return; + + var statusMessageElement = document.createElement("div"); + statusMessageElement.className = "info"; + if (eventType === WebInspector.DebuggerEventTypes.NativeBreakpoint) { + var breakpoint = WebInspector.breakpointManager.breakpointViewForEventData(eventData); + if (breakpoint) + breakpoint.populateStatusMessageElement(statusMessageElement, eventData); + } else + statusMessageElement.appendChild(document.createTextNode(WebInspector.UIString("Paused on a JavaScript breakpoint."))); + this.bodyElement.appendChild(statusMessageElement); }, get selectedCallFrame() @@ -168,17 +180,6 @@ WebInspector.CallStackSidebarPane.prototype = { this._shortcuts[prevCallFrame.key] = this._selectPreviousCallFrameOnStack.bind(this); section.addRelatedKeys([ nextCallFrame.name, prevCallFrame.name ], WebInspector.UIString("Next/previous call frame")); - }, - - _breakpointHit: function(event) - { - var breakpoint = event.data.breakpoint; - if (breakpoint.populateStatusMessageElement) { - var statusMessageElement = document.createElement("div"); - statusMessageElement.className = "info"; - breakpoint.populateStatusMessageElement(statusMessageElement, event.data.eventData); - this.bodyElement.appendChild(statusMessageElement); - } } } diff --git a/WebCore/inspector/front-end/Callback.js b/WebCore/inspector/front-end/Callback.js deleted file mode 100644 index 0621fd1..0000000 --- a/WebCore/inspector/front-end/Callback.js +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2009 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -WebInspector.Callback = function() -{ - this._lastCallbackId = 1; - this._callbacks = {}; -} - -WebInspector.Callback.prototype = { - wrap: function(callback) - { - var callbackId = this._lastCallbackId++; - this._callbacks[callbackId] = callback || function() {}; - return callbackId; - }, - - processResponse: function(callbackId, args) - { - var callback = this._callbacks[callbackId]; - callback.apply(null, args); - delete this._callbacks[callbackId]; - }, - - removeResponseCallbackEntry: function(callbackId) - { - delete this._callbacks[callbackId]; - } -} - -WebInspector.Callback._INSTANCE = new WebInspector.Callback(); -WebInspector.Callback.wrap = WebInspector.Callback._INSTANCE.wrap.bind(WebInspector.Callback._INSTANCE); -WebInspector.processResponse = WebInspector.Callback._INSTANCE.processResponse.bind(WebInspector.Callback._INSTANCE); -WebInspector.removeResponseCallbackEntry = WebInspector.Callback._INSTANCE.removeResponseCallbackEntry.bind(WebInspector.Callback._INSTANCE); diff --git a/WebCore/inspector/front-end/ConsoleView.js b/WebCore/inspector/front-end/ConsoleView.js index 737b84f..03fe14a 100644 --- a/WebCore/inspector/front-end/ConsoleView.js +++ b/WebCore/inspector/front-end/ConsoleView.js @@ -7,13 +7,13 @@ * are met: * * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. + * documentation and/or other materials provided with the distribution. * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. + * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -50,9 +50,8 @@ WebInspector.ConsoleView = function(drawer) this.prompt = new WebInspector.TextPrompt(this.promptElement, this.completions.bind(this), ExpressionStopCharacters + "."); this.prompt.history = WebInspector.settings.consoleHistory; - this.topGroup = new WebInspector.ConsoleGroup(null, 0); + this.topGroup = new WebInspector.ConsoleGroup(null); this.messagesElement.insertBefore(this.topGroup.element, this.promptElement); - this.groupLevel = 0; this.currentGroup = this.topGroup; this.toggleConsoleButton = document.getElementById("console-status-bar-item"); @@ -69,30 +68,29 @@ WebInspector.ConsoleView = function(drawer) } var updateFilterHandler = this._updateFilter.bind(this); - function createFilterElement(category) { + function createFilterElement(category, label) { var categoryElement = document.createElement("li"); categoryElement.category = category; - categoryElement.addStyleClass(categoryElement.category); + categoryElement.className = category; categoryElement.addEventListener("click", updateFilterHandler, false); - - var label = category.toString(); - categoryElement.appendChild(document.createTextNode(label)); + categoryElement.textContent = label; this.filterBarElement.appendChild(categoryElement); + return categoryElement; } - - this.allElement = createFilterElement.call(this, WebInspector.UIString("All")); + + this.allElement = createFilterElement.call(this, "all", WebInspector.UIString("All")); createDividerElement.call(this); - this.errorElement = createFilterElement.call(this, WebInspector.UIString("Errors")); - this.warningElement = createFilterElement.call(this, WebInspector.UIString("Warnings")); - this.logElement = createFilterElement.call(this, WebInspector.UIString("Logs")); + this.errorElement = createFilterElement.call(this, "errors", WebInspector.UIString("Errors")); + this.warningElement = createFilterElement.call(this, "warnings", WebInspector.UIString("Warnings")); + this.logElement = createFilterElement.call(this, "logs", WebInspector.UIString("Logs")); this.filter(this.allElement, false); this._registerShortcuts(); this.messagesElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), true); - + this._customFormatters = { "object": this._formatobject, "array": this._formatarray, @@ -113,7 +111,7 @@ WebInspector.ConsoleView.prototype = { this.filter(e.target, selectMultiple); }, - + filter: function(target, selectMultiple) { function unselectAll() @@ -122,16 +120,16 @@ WebInspector.ConsoleView.prototype = { this.errorElement.removeStyleClass("selected"); this.warningElement.removeStyleClass("selected"); this.logElement.removeStyleClass("selected"); - + this.messagesElement.removeStyleClass("filter-all"); this.messagesElement.removeStyleClass("filter-errors"); this.messagesElement.removeStyleClass("filter-warnings"); this.messagesElement.removeStyleClass("filter-logs"); } - - var targetFilterClass = "filter-" + target.category.toLowerCase(); - if (target.category == "All") { + var targetFilterClass = "filter-" + target.category; + + if (target.category === "all") { if (target.hasStyleClass("selected")) { // We can't unselect all, so we break early here return; @@ -145,18 +143,18 @@ WebInspector.ConsoleView.prototype = { this.messagesElement.removeStyleClass("filter-all"); } } - + if (!selectMultiple) { // If multiple selection is off, we want to unselect everything else // and just select ourselves. unselectAll.call(this); - + target.addStyleClass("selected"); this.messagesElement.addStyleClass(targetFilterClass); - + return; } - + if (target.hasStyleClass("selected")) { // If selectMultiple is turned on, and we were selected, we just // want to unselect ourselves. @@ -169,7 +167,7 @@ WebInspector.ConsoleView.prototype = { this.messagesElement.addStyleClass(targetFilterClass); } }, - + _toggleConsoleButtonClicked: function() { this.drawer.visibleView = this; @@ -192,7 +190,7 @@ WebInspector.ConsoleView.prototype = { afterShow: function() { - WebInspector.currentFocusElement = this.promptElement; + WebInspector.currentFocusElement = this.promptElement; }, hide: function() @@ -208,7 +206,7 @@ WebInspector.ConsoleView.prototype = { function scrollIntoView() { - this.promptElement.scrollIntoView(false); + this.promptElement.scrollIntoView(true); delete this._scrollIntoViewTimer; } this._scrollIntoViewTimer = setTimeout(scrollIntoView.bind(this), 20); @@ -216,6 +214,8 @@ WebInspector.ConsoleView.prototype = { addMessage: function(msg) { + var shouldScrollToLastMessage = this.messagesElement.isScrolledToBottom(); + if (msg instanceof WebInspector.ConsoleMessage && !(msg instanceof WebInspector.ConsoleCommandResult)) { this._incrementErrorWarningCount(msg); WebInspector.resourceManager.addConsoleMessage(msg); @@ -230,17 +230,12 @@ WebInspector.ConsoleView.prototype = { this.messages.push(msg); if (msg.type === WebInspector.ConsoleMessage.MessageType.EndGroup) { - if (this.groupLevel < 1) - return; - - this.groupLevel--; - - this.currentGroup = this.currentGroup.parentGroup; + var parentGroup = this.currentGroup.parentGroup + if (parentGroup) + this.currentGroup = parentGroup; } else { if (msg.type === WebInspector.ConsoleMessage.MessageType.StartGroup || msg.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed) { - this.groupLevel++; - - var group = new WebInspector.ConsoleGroup(this.currentGroup, this.groupLevel); + var group = new WebInspector.ConsoleGroup(this.currentGroup); this.currentGroup.messagesElement.appendChild(group.element); this.currentGroup = group; } @@ -248,14 +243,15 @@ WebInspector.ConsoleView.prototype = { this.currentGroup.addMessage(msg); } - this._scheduleScrollIntoView(); + if (shouldScrollToLastMessage) + this._scheduleScrollIntoView(); }, updateMessageRepeatCount: function(count) { var msg = this.previousMessage; var prevRepeatCount = msg.totalRepeatCount; - + if (!this.commandSincePreviousMessage) { msg.repeatDelta = count - prevRepeatCount; msg.repeatCount = msg.repeatCount + msg.repeatDelta; @@ -263,7 +259,7 @@ WebInspector.ConsoleView.prototype = { msg._updateRepeatCount(); this._incrementErrorWarningCount(msg); } else { - var msgCopy = new WebInspector.ConsoleMessage(msg.source, msg.type, msg.level, msg.line, msg.url, msg.groupLevel, count - prevRepeatCount, msg._messageText, msg._parameters, msg._stackTrace); + var msgCopy = new WebInspector.ConsoleMessage(msg.source, msg.type, msg.level, msg.line, msg.url, count - prevRepeatCount, msg._messageText, msg._parameters, msg._stackTrace, msg._requestId); msgCopy.totalRepeatCount = count; msgCopy._formatMessage(); this.addMessage(msgCopy); @@ -293,7 +289,6 @@ WebInspector.ConsoleView.prototype = { this.messages = []; - this.groupLevel = 0; this.currentGroup = this.topGroup; this.topGroup.messagesElement.removeChildren(); @@ -568,8 +563,12 @@ WebInspector.ConsoleView.prototype = { { function printNode(nodeId) { - if (!nodeId) + if (!nodeId) { + // Sometimes DOM is loaded after the sync message is being formatted, so we get no + // nodeId here. So we fall back to object formatting here. + this._formatobject(object, elem); return; + } var treeOutline = new WebInspector.ElementsTreeOutline(); treeOutline.showInElementsPanelEnabled = true; treeOutline.rootDOMNode = WebInspector.domAgent.nodeForId(nodeId); @@ -578,8 +577,7 @@ WebInspector.ConsoleView.prototype = { treeOutline.element.addStyleClass("single-node"); elem.appendChild(treeOutline.element); } - - object.pushNodeToFrontend(printNode); + object.pushNodeToFrontend(printNode.bind(this)); }, _formatarray: function(arr, elem) @@ -634,70 +632,117 @@ WebInspector.ConsoleView.prototype = { WebInspector.ConsoleView.prototype.__proto__ = WebInspector.View.prototype; -WebInspector.ConsoleMessage = function(source, type, level, line, url, groupLevel, repeatCount, message, parameters, stackTrace) +WebInspector.ConsoleMessage = function(source, type, level, line, url, repeatCount, message, parameters, stackTrace, requestId) { this.source = source; this.type = type; this.level = level; this.line = line; this.url = url; - this.groupLevel = groupLevel; this.repeatCount = repeatCount; this.repeatDelta = repeatCount; this.totalRepeatCount = repeatCount; this._messageText = message; this._parameters = parameters; this._stackTrace = stackTrace; + this._requestId = requestId; this._formatMessage(); } WebInspector.ConsoleMessage.createTextMessage = function(text, level) { level = level || WebInspector.ConsoleMessage.MessageLevel.Log; - return new WebInspector.ConsoleMessage(WebInspector.ConsoleMessage.MessageSource.JS, WebInspector.ConsoleMessage.MessageType.Log, level, 0, null, null, 1, null, [text], null); + return new WebInspector.ConsoleMessage(WebInspector.ConsoleMessage.MessageSource.JS, WebInspector.ConsoleMessage.MessageType.Log, level, 0, null, 1, null, [text], null); } WebInspector.ConsoleMessage.prototype = { _formatMessage: function() { + var stackTrace = this._stackTrace; + var messageText; switch (this.type) { - case WebInspector.ConsoleMessage.MessageType.Assert: case WebInspector.ConsoleMessage.MessageType.Trace: + messageText = document.createTextNode("console.trace()"); + break; case WebInspector.ConsoleMessage.MessageType.UncaughtException: - var ol = document.createElement("ol"); - ol.className = "outline-disclosure"; - var treeOutline = new TreeOutline(ol); - var messageText; - if (this.type === WebInspector.ConsoleMessage.MessageType.Assert) - messageText = this._format(this._parameters); - else if (this.type === WebInspector.ConsoleMessage.MessageType.Trace) - messageText = document.createTextNode("console.trace()"); - else - messageText = document.createTextNode(this._messageText); - - var content = document.createElement("div"); - this._addMessageHeader(content, messageText); - var root = new TreeElement(content, null, true); - content.treeElementForTest = root; - treeOutline.appendChild(root); - if (this.type === WebInspector.ConsoleMessage.MessageType.Trace) - root.expand(); - - this._populateStackTraceTreeElement(root); - this.formattedMessage = ol; + messageText = document.createTextNode(this._messageText); + break; + case WebInspector.ConsoleMessage.MessageType.NetworkError: + var resource = this._requestId && WebInspector.panels.network.resources[this._requestId]; + if (resource) { + stackTrace = resource.stackTrace; + + messageText = document.createElement("span"); + messageText.appendChild(document.createTextNode(resource.requestMethod + " ")); + messageText.appendChild(WebInspector.linkifyURLAsNode(resource.url)); + if (resource.failed) + messageText.appendChild(document.createTextNode(" " + resource.localizedFailDescription)); + else + messageText.appendChild(document.createTextNode(" " + resource.statusCode + " (" + resource.statusText + ")")); + } else + messageText = this._format([this._messageText]); + break; + case WebInspector.ConsoleMessage.MessageType.Assert: + var args = [WebInspector.UIString("Assertion failed:")]; + if (this._parameters) + args = args.concat(this._parameters); + messageText = this._format(args); break; case WebInspector.ConsoleMessage.MessageType.Object: var obj = this._parameters ? this._parameters[0] : undefined; - this.formattedMessage = this._format(["%O", obj]); + var args = ["%O", obj]; + messageText = this._format(args); break; default: var args = this._parameters || [this._messageText]; - this.formattedMessage = this._format(args); + messageText = this._format(args); break; } + this._formattedMessage = document.createElement("span"); + this._formattedMessage.className = "console-message-text source-code"; + + if (stackTrace && stackTrace.length) { + var topCallFrame = stackTrace[0]; + var sourceName = topCallFrame.scriptName; + var sourceLine = topCallFrame.lineNumber; + } else { + var sourceName = this.url; + var sourceLine = this.line; + } + + if (sourceName && sourceName !== "undefined") { + var urlElement = WebInspector.linkifyResourceAsNode(sourceName, "scripts", sourceLine, "console-message-url"); + this._formattedMessage.appendChild(urlElement); + } + + this._formattedMessage.appendChild(messageText); + + if (this._stackTrace) { + switch (this.type) { + case WebInspector.ConsoleMessage.MessageType.Trace: + case WebInspector.ConsoleMessage.MessageType.UncaughtException: + case WebInspector.ConsoleMessage.MessageType.NetworkError: + case WebInspector.ConsoleMessage.MessageType.Assert: { + var ol = document.createElement("ol"); + ol.className = "outline-disclosure"; + var treeOutline = new TreeOutline(ol); + + var content = this._formattedMessage; + var root = new TreeElement(content, null, true); + content.treeElementForTest = root; + treeOutline.appendChild(root); + if (this.type === WebInspector.ConsoleMessage.MessageType.Trace) + root.expand(); + + this._populateStackTraceTreeElement(root); + this._formattedMessage = ol; + } + } + } + // This is used for inline message bubbles in SourceFrames, or other plain-text representations. - this.message = this.formattedMessage.textContent; + this.message = this._formattedMessage.textContent; }, isErrorOrWarning: function() @@ -790,27 +835,6 @@ WebInspector.ConsoleMessage.prototype = { this._element = element; - switch (this.source) { - case WebInspector.ConsoleMessage.MessageSource.HTML: - element.addStyleClass("console-html-source"); - break; - case WebInspector.ConsoleMessage.MessageSource.WML: - element.addStyleClass("console-wml-source"); - break; - case WebInspector.ConsoleMessage.MessageSource.XML: - element.addStyleClass("console-xml-source"); - break; - case WebInspector.ConsoleMessage.MessageSource.JS: - element.addStyleClass("console-js-source"); - break; - case WebInspector.ConsoleMessage.MessageSource.CSS: - element.addStyleClass("console-css-source"); - break; - case WebInspector.ConsoleMessage.MessageSource.Other: - element.addStyleClass("console-other-source"); - break; - } - switch (this.level) { case WebInspector.ConsoleMessage.MessageLevel.Tip: element.addStyleClass("console-tip-level"); @@ -838,12 +862,7 @@ WebInspector.ConsoleMessage.prototype = { return element; } - if (this.type === WebInspector.ConsoleMessage.MessageType.Trace || - this.type === WebInspector.ConsoleMessage.MessageType.Assert || - this.type === WebInspector.ConsoleMessage.MessageType.UncaughtException) - element.appendChild(this.formattedMessage); - else - this._addMessageHeader(element, this.formattedMessage); + element.appendChild(this._formattedMessage); if (this.repeatCount > 1) this._updateRepeatCount(); @@ -863,7 +882,7 @@ WebInspector.ConsoleMessage.prototype = { messageTextElement.appendChild(document.createTextNode(functionName)); content.appendChild(messageTextElement); - var urlElement = WebInspector.linkifyResourceAsNode(frame.sourceURL, "scripts", frame.lineNumber, "console-message-url"); + var urlElement = WebInspector.linkifyResourceAsNode(frame.scriptName, "scripts", frame.lineNumber, "console-message-url"); content.appendChild(urlElement); var treeElement = new TreeElement(content); @@ -871,26 +890,11 @@ WebInspector.ConsoleMessage.prototype = { } }, - _addMessageHeader: function(parentElement, formattedMessage) - { - if (this.url && this.url !== "undefined") { - var urlElement = WebInspector.linkifyResourceAsNode(this.url, "scripts", this.line, "console-message-url"); - parentElement.appendChild(urlElement); - } - - var messageTextElement = document.createElement("span"); - messageTextElement.className = "console-message-text source-code"; - if (this.type === WebInspector.ConsoleMessage.MessageType.Assert) - messageTextElement.appendChild(document.createTextNode(WebInspector.UIString("Assertion failed: "))); - messageTextElement.appendChild(formattedMessage); - parentElement.appendChild(messageTextElement); - }, - _updateRepeatCount: function() { if (!this.repeatCountElement) { this.repeatCountElement = document.createElement("span"); this.repeatCountElement.className = "bubble"; - + this._element.insertBefore(this.repeatCountElement, this._element.firstChild); this._element.addStyleClass("repeated-message"); } @@ -925,6 +929,7 @@ WebInspector.ConsoleMessage.prototype = { switch (this.type) { case WebInspector.ConsoleMessage.MessageType.Log: case WebInspector.ConsoleMessage.MessageType.UncaughtException: + case WebInspector.ConsoleMessage.MessageType.NetworkError: typeString = "Log"; break; case WebInspector.ConsoleMessage.MessageType.Object: @@ -947,7 +952,7 @@ WebInspector.ConsoleMessage.prototype = { typeString = "Result"; break; } - + var levelString; switch (this.level) { case WebInspector.ConsoleMessage.MessageLevel.Tip: @@ -967,22 +972,35 @@ WebInspector.ConsoleMessage.prototype = { break; } - return sourceString + " " + typeString + " " + levelString + ": " + this.formattedMessage.textContent + "\n" + this.url + " line " + this.line; + return sourceString + " " + typeString + " " + levelString + ": " + this._formattedMessage.textContent + "\n" + this.url + " line " + this.line; }, - isEqual: function(msg, disreguardGroup) + isEqual: function(msg) { if (!msg) return false; - var ret = (this.source == msg.source) - && (this.type == msg.type) - && (this.level == msg.level) - && (this.line == msg.line) - && (this.url == msg.url) - && (this.message == msg.message); + if (this._stackTrace) { + if (!msg._stackTrace) + return false; + var l = this._stackTrace; + var r = msg._stackTrace; + for (var i = 0; i < l.length; i++) { + if (l[i].scriptName !== r[i].scriptName || + l[i].functionName !== r[i].functionName || + l[i].lineNumber !== r[i].lineNumber || + l[i].column !== r[i].column) + return false; + } + } - return (disreguardGroup ? ret : (ret && (this.groupLevel == msg.groupLevel))); + return (this.source === msg.source) + && (this.type === msg.type) + && (this.level === msg.level) + && (this.line === msg.line) + && (this.url === msg.url) + && (this.message === msg.message) + && (this._requestId === msg._requestId); } } @@ -1005,7 +1023,8 @@ WebInspector.ConsoleMessage.MessageType = { EndGroup: 5, Assert: 6, UncaughtException: 7, - Result: 8 + NetworkError:8, + Result: 9 } WebInspector.ConsoleMessage.MessageLevel = { @@ -1041,7 +1060,7 @@ WebInspector.ConsoleCommandResult = function(result, originatingCommand) { var level = (result.isError() ? WebInspector.ConsoleMessage.MessageLevel.Error : WebInspector.ConsoleMessage.MessageLevel.Log); this.originatingCommand = originatingCommand; - WebInspector.ConsoleMessage.call(this, WebInspector.ConsoleMessage.MessageSource.JS, WebInspector.ConsoleMessage.MessageType.Result, level, -1, null, null, 1, null, [result]); + WebInspector.ConsoleMessage.call(this, WebInspector.ConsoleMessage.MessageSource.JS, WebInspector.ConsoleMessage.MessageType.Result, level, -1, null, 1, null, [result]); } WebInspector.ConsoleCommandResult.prototype = { @@ -1055,10 +1074,9 @@ WebInspector.ConsoleCommandResult.prototype = { WebInspector.ConsoleCommandResult.prototype.__proto__ = WebInspector.ConsoleMessage.prototype; -WebInspector.ConsoleGroup = function(parentGroup, level) +WebInspector.ConsoleGroup = function(parentGroup) { this.parentGroup = parentGroup; - this.level = level; var element = document.createElement("div"); element.className = "console-group"; diff --git a/WebCore/inspector/front-end/DOMAgent.js b/WebCore/inspector/front-end/DOMAgent.js index 37bf549..432ac3f 100644 --- a/WebCore/inspector/front-end/DOMAgent.js +++ b/WebCore/inspector/front-end/DOMAgent.js @@ -300,6 +300,7 @@ WebInspector.DOMAgent = function() { this._window = new WebInspector.DOMWindow(this); this._idToDOMNode = null; this.document = null; + InspectorBackend.registerDomainDispatcher("DOM", this); } WebInspector.DOMAgent.prototype = { @@ -350,7 +351,7 @@ WebInspector.DOMAgent.prototype = { elem.updateTitle(); }, - _attributesUpdated: function(nodeId, attrsArray) + attributesUpdated: function(nodeId, attrsArray) { var node = this._idToDOMNode[nodeId]; node._setAttributesPayload(attrsArray); @@ -358,7 +359,7 @@ WebInspector.DOMAgent.prototype = { this.document._fireDomEvent("DOMAttrModified", event); }, - _characterDataModified: function(nodeId, newValue) + characterDataModified: function(nodeId, newValue) { var node = this._idToDOMNode[nodeId]; node._nodeValue = newValue; @@ -372,7 +373,13 @@ WebInspector.DOMAgent.prototype = { return this._idToDOMNode[nodeId]; }, - _setDocument: function(payload) + didCommitLoad: function() + { + // Cleanup elements panel early on inspected page refresh. + this.setDocument(null); + }, + + setDocument: function(payload) { this._idToDOMNode = {}; if (payload && "id" in payload) { @@ -385,13 +392,13 @@ WebInspector.DOMAgent.prototype = { WebInspector.panels.elements.setDocument(this.document); }, - _setDetachedRoot: function(payload) + setDetachedRoot: function(payload) { var root = new WebInspector.DOMNode(this.document, payload); this._idToDOMNode[payload.id] = root; }, - _setChildNodes: function(parentId, payloads) + setChildNodes: function(parentId, payloads) { var parent = this._idToDOMNode[parentId]; parent._setChildrenPayload(payloads); @@ -408,7 +415,7 @@ WebInspector.DOMAgent.prototype = { } }, - _childNodeCountUpdated: function(nodeId, newValue) + childNodeCountUpdated: function(nodeId, newValue) { var node = this._idToDOMNode[nodeId]; node._childNodeCount = newValue; @@ -418,7 +425,7 @@ WebInspector.DOMAgent.prototype = { treeElement.hasChildren = newValue; }, - _childNodeInserted: function(parentId, prevId, payload) + childNodeInserted: function(parentId, prevId, payload) { var parent = this._idToDOMNode[parentId]; var prev = this._idToDOMNode[prevId]; @@ -428,7 +435,7 @@ WebInspector.DOMAgent.prototype = { this.document._fireDomEvent("DOMNodeInserted", event); }, - _childNodeRemoved: function(parentId, nodeId) + childNodeRemoved: function(parentId, nodeId) { var parent = this._idToDOMNode[parentId]; var node = this._idToDOMNode[nodeId]; @@ -523,43 +530,3 @@ WebInspector.EventListeners.getEventListenersForNodeAsync = function(node, callb return; InspectorBackend.getEventListenersForNode(node.id, callback); } - -WebInspector.attributesUpdated = function() -{ - this.domAgent._attributesUpdated.apply(this.domAgent, arguments); -} - -WebInspector.characterDataModified = function() -{ - this.domAgent._characterDataModified.apply(this.domAgent, arguments); -} - -WebInspector.setDocument = function() -{ - this.domAgent._setDocument.apply(this.domAgent, arguments); -} - -WebInspector.setDetachedRoot = function() -{ - this.domAgent._setDetachedRoot.apply(this.domAgent, arguments); -} - -WebInspector.setChildNodes = function() -{ - this.domAgent._setChildNodes.apply(this.domAgent, arguments); -} - -WebInspector.childNodeCountUpdated = function() -{ - this.domAgent._childNodeCountUpdated.apply(this.domAgent, arguments); -} - -WebInspector.childNodeInserted = function() -{ - this.domAgent._childNodeInserted.apply(this.domAgent, arguments); -} - -WebInspector.childNodeRemoved = function() -{ - this.domAgent._childNodeRemoved.apply(this.domAgent, arguments); -} diff --git a/WebCore/inspector/front-end/DataGrid.js b/WebCore/inspector/front-end/DataGrid.js index 902062c..5831d1e 100644 --- a/WebCore/inspector/front-end/DataGrid.js +++ b/WebCore/inspector/front-end/DataGrid.js @@ -169,7 +169,11 @@ WebInspector.DataGrid.prototype = { this._editingNode.select(); var element = this._editingNode._element.children[column]; - WebInspector.startEditing(element, this._editingCommitted.bind(this), this._editingCancelled.bind(this), element.textContent); + WebInspector.startEditing(element, { + context: element.textContent, + commitHandler: this._editingCommitted.bind(this), + cancelHandler: this._editingCancelled.bind(this) + }); window.getSelection().setBaseAndExtent(element, 0, element, 1); }, @@ -191,7 +195,11 @@ WebInspector.DataGrid.prototype = { return this._startEditingColumnOfDataGridNode(this._editingNode, 0); this._editing = true; - WebInspector.startEditing(element, this._editingCommitted.bind(this), this._editingCancelled.bind(this), element.textContent); + WebInspector.startEditing(element, { + context: element.textContent, + commitHandler: this._editingCommitted.bind(this), + cancelHandler: this._editingCancelled.bind(this) + }); window.getSelection().setBaseAndExtent(element, 0, element, 1); }, @@ -487,7 +495,7 @@ WebInspector.DataGrid.prototype = { isScrolledToLastRow: function() { - return this._scrollContainer.scrollTop === this._scrollContainer.scrollHeight - this._scrollContainer.offsetHeight; + return this._scrollContainer.isScrolledToBottom(); }, scrollToLastRow: function() diff --git a/WebCore/inspector/front-end/Database.js b/WebCore/inspector/front-end/Database.js index ca3e968..7aac7d1 100644 --- a/WebCore/inspector/front-end/Database.js +++ b/WebCore/inspector/front-end/Database.js @@ -101,21 +101,3 @@ WebInspector.Database.prototype = { InspectorBackend.executeSQL(this._id, query, callback); } } - -WebInspector.sqlTransactionSucceeded = function(transactionId, columnNames, values) -{ - var callback = WebInspector.Database.successCallbacks[transactionId]; - if (!callback) - return; - delete WebInspector.Database.successCallbacks[transactionId]; - callback(columnNames, values); -} - -WebInspector.sqlTransactionFailed = function(transactionId, errorObj) -{ - var callback = WebInspector.Database.errorCallbacks[transactionId]; - if (!callback) - return; - delete WebInspector.Database.errorCallbacks[transactionId]; - callback(errorObj); -} diff --git a/WebCore/inspector/front-end/DebuggerModel.js b/WebCore/inspector/front-end/DebuggerModel.js new file mode 100644 index 0000000..5ab0e2d --- /dev/null +++ b/WebCore/inspector/front-end/DebuggerModel.js @@ -0,0 +1,243 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +WebInspector.DebuggerModel = function() +{ + InspectorBackend.registerDomainDispatcher("Debugger", this); + + this._paused = false; + this._breakpoints = {}; + this._sourceIDAndLineToBreakpointId = {}; + this._scripts = {}; +} + +WebInspector.DebuggerModel.Events = { + DebuggerPaused: "debugger-paused", + DebuggerResumed: "debugger-resumed", + ParsedScriptSource: "parsed-script-source", + FailedToParseScriptSource: "failed-to-parse-script-source", + BreakpointAdded: "breakpoint-added", + BreakpointRemoved: "breakpoint-removed" +} + +WebInspector.DebuggerModel.prototype = { + continueToLine: function(sourceID, lineNumber) + { + function didSetBreakpoint(breakpointId, actualLineNumber) + { + if (!breakpointId) + return; + if (this.findBreakpoint(sourceID, actualLineNumber)) { + InspectorBackend.removeBreakpoint(breakpointId); + return; + } + if ("_continueToLineBreakpointId" in this) + InspectorBackend.removeBreakpoint(this._continueToLineBreakpointId); + this._continueToLineBreakpointId = breakpointId; + } + InspectorBackend.setBreakpoint(sourceID, lineNumber, "", true, didSetBreakpoint.bind(this)); + if (this._paused) + InspectorBackend.resume(); + }, + + setBreakpoint: function(sourceID, lineNumber, enabled, condition) + { + function didSetBreakpoint(breakpointId, actualLineNumber) + { + if (breakpointId) + this._breakpointSetOnBackend(breakpointId, sourceID, actualLineNumber, condition, enabled, lineNumber, false); + } + InspectorBackend.setBreakpoint(sourceID, lineNumber, condition, enabled, didSetBreakpoint.bind(this)); + }, + + removeBreakpoint: function(breakpointId) + { + InspectorBackend.removeBreakpoint(breakpointId); + var breakpoint = this._breakpoints[breakpointId]; + delete this._breakpoints[breakpointId]; + delete this._sourceIDAndLineToBreakpointId[this._encodeSourceIDAndLine(breakpoint.sourceID, breakpoint.line)]; + this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.BreakpointRemoved, breakpointId); + }, + + breakpointResolved: function(breakpointId, sourceID, lineNumber, condition, enabled, originalLineNumber) + { + this._breakpointSetOnBackend(breakpointId, sourceID, lineNumber, condition, enabled, originalLineNumber, true); + }, + + _breakpointSetOnBackend: function(breakpointId, sourceID, lineNumber, condition, enabled, originalLineNumber, restored) + { + var sourceIDAndLine = this._encodeSourceIDAndLine(sourceID, lineNumber); + if (sourceIDAndLine in this._sourceIDAndLineToBreakpointId) { + InspectorBackend.removeBreakpoint(breakpointId); + return; + } + + var url = this._scripts[sourceID].sourceURL; + var breakpoint = new WebInspector.Breakpoint(this, breakpointId, sourceID, url, lineNumber, enabled, condition); + breakpoint.restored = restored; + breakpoint.originalLineNumber = originalLineNumber; + this._breakpoints[breakpointId] = breakpoint; + this._sourceIDAndLineToBreakpointId[sourceIDAndLine] = breakpointId; + this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.BreakpointAdded, breakpoint); + }, + + queryBreakpoints: function(filter) + { + var breakpoints = []; + for (var id in this._breakpoints) { + var breakpoint = this._breakpoints[id]; + if (filter(breakpoint)) + breakpoints.push(breakpoint); + } + return breakpoints; + }, + + findBreakpoint: function(sourceID, lineNumber) + { + var sourceIDAndLine = this._encodeSourceIDAndLine(sourceID, lineNumber); + var breakpointId = this._sourceIDAndLineToBreakpointId[sourceIDAndLine]; + return this._breakpoints[breakpointId]; + }, + + _encodeSourceIDAndLine: function(sourceID, lineNumber) + { + return sourceID + ":" + lineNumber; + }, + + reset: function() + { + this._paused = false; + this._breakpoints = {}; + delete this._oneTimeBreakpoint; + this._sourceIDAndLineToBreakpointId = {}; + this._scripts = {}; + }, + + scriptForSourceID: function(sourceID) + { + return this._scripts[sourceID]; + }, + + scriptsForURL: function(url) + { + return this.queryScripts(function(s) { return s.sourceURL === url; }); + }, + + queryScripts: function(filter) + { + var scripts = []; + for (var sourceID in this._scripts) { + var script = this._scripts[sourceID]; + if (filter(script)) + scripts.push(script); + } + return scripts; + }, + + // All the methods below are InspectorBackend notification handlers. + + pausedScript: function(details) + { + this._paused = true; + if ("_continueToLineBreakpointId" in this) { + InspectorBackend.removeBreakpoint(this._continueToLineBreakpointId); + delete this._continueToLineBreakpointId; + } + this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.DebuggerPaused, details); + + if (details.eventType === WebInspector.DebuggerEventTypes.JavaScriptPause || details.eventType === WebInspector.DebuggerEventTypes.NativeBreakpoint) + return; + + var breakpoint = this.findBreakpoint(details.callFrames[0].sourceID, details.callFrames[0].line); + if (!breakpoint) + return; + breakpoint.hit = true; + this._lastHitBreakpoint = breakpoint; + }, + + resumedScript: function() + { + this._paused = false; + this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.DebuggerResumed); + + if (!this._lastHitBreakpoint) + return; + this._lastHitBreakpoint.hit = false; + delete this._lastHitBreakpoint; + }, + + attachDebuggerWhenShown: function() + { + WebInspector.panels.scripts.attachDebuggerWhenShown(); + }, + + debuggerWasEnabled: function() + { + WebInspector.panels.scripts.debuggerWasEnabled(); + }, + + debuggerWasDisabled: function() + { + WebInspector.panels.scripts.debuggerWasDisabled(); + }, + + parsedScriptSource: function(sourceID, sourceURL, source, startingLine, scriptWorldType) + { + var script = new WebInspector.Script(sourceID, sourceURL, source, startingLine, undefined, undefined, scriptWorldType); + this._scripts[sourceID] = script; + this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.ParsedScriptSource, sourceID); + }, + + failedToParseScriptSource: function(sourceURL, source, startingLine, errorLine, errorMessage) + { + var script = new WebInspector.Script(null, sourceURL, source, startingLine, errorLine, errorMessage, undefined); + this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.FailedToParseScriptSource, script); + }, + + didCreateWorker: function() + { + var workersPane = WebInspector.panels.scripts.sidebarPanes.workers; + workersPane.addWorker.apply(workersPane, arguments); + }, + + didDestroyWorker: function() + { + var workersPane = WebInspector.panels.scripts.sidebarPanes.workers; + workersPane.removeWorker.apply(workersPane, arguments); + } +} + +WebInspector.DebuggerModel.prototype.__proto__ = WebInspector.Object.prototype; + +WebInspector.DebuggerEventTypes = { + JavaScriptPause: 0, + JavaScriptBreakpoint: 1, + NativeBreakpoint: 2 +}; diff --git a/WebCore/inspector/front-end/ElementsPanel.js b/WebCore/inspector/front-end/ElementsPanel.js index 61ba33e..9299479 100644 --- a/WebCore/inspector/front-end/ElementsPanel.js +++ b/WebCore/inspector/front-end/ElementsPanel.js @@ -88,6 +88,7 @@ WebInspector.ElementsPanel = function() this.sidebarPanes.styles.addEventListener("style edited", this._stylesPaneEdited, this); this.sidebarPanes.styles.addEventListener("style property toggled", this._stylesPaneEdited, this); this.sidebarPanes.metrics.addEventListener("metrics edited", this._metricsPaneEdited, this); + WebInspector.cssModel.addEventListener("stylesheet changed", this._styleSheetChanged, this); this.sidebarElement = document.createElement("div"); this.sidebarElement.id = "elements-sidebar"; @@ -169,9 +170,6 @@ WebInspector.ElementsPanel.prototype = { this.recentlyModifiedNodes = []; delete this.currentQuery; - - if (Preferences.nativeInstrumentationEnabled) - this.sidebarPanes.domBreakpoints.reset(); }, setDocument: function(inspectedRootDocument) @@ -447,16 +445,24 @@ WebInspector.ElementsPanel.prototype = { _stylesPaneEdited: function() { + // Once styles are edited, the Metrics pane should be updated. this.sidebarPanes.metrics.needsUpdate = true; this.updateMetrics(); }, _metricsPaneEdited: function() { + // Once metrics are edited, the Styles pane should be updated. this.sidebarPanes.styles.needsUpdate = true; this.updateStyles(true); }, + _styleSheetChanged: function() + { + this._metricsPaneEdited(); + this._stylesPaneEdited(); + }, + _mouseMovedInCrumbs: function(event) { var nodeUnderMouse = document.elementFromPoint(event.pageX, event.pageY); diff --git a/WebCore/inspector/front-end/ElementsTreeOutline.js b/WebCore/inspector/front-end/ElementsTreeOutline.js index f893ca0..f25f858 100644 --- a/WebCore/inspector/front-end/ElementsTreeOutline.js +++ b/WebCore/inspector/front-end/ElementsTreeOutline.js @@ -268,6 +268,7 @@ WebInspector.ElementsTreeOutline.prototype = { if (this.showInElementsPanelEnabled) { function focusElement() { + WebInspector.currentPanel = WebInspector.panels.elements; WebInspector.panels.elements.focusedDOMNode = listItem.treeElement.representedObject; } contextMenu.appendItem(WebInspector.UIString("Reveal in Elements Panel"), focusElement.bind(this)); @@ -871,7 +872,11 @@ WebInspector.ElementsTreeElement.prototype = { // Remove zero-width spaces that were added by nodeTitleInfo. removeZeroWidthSpaceRecursive(attribute); - this._editing = WebInspector.startEditing(attribute, this._attributeEditingCommitted.bind(this), this._editingCancelled.bind(this), attributeName); + this._editing = WebInspector.startEditing(attribute, { + context: attributeName, + commitHandler: this._attributeEditingCommitted.bind(this), + cancelHandler: this._editingCancelled.bind(this) + }); window.getSelection().setBaseAndExtent(elementForSelection, 0, elementForSelection, 1); return true; @@ -882,7 +887,11 @@ WebInspector.ElementsTreeElement.prototype = { if (WebInspector.isBeingEdited(textNode)) return true; - this._editing = WebInspector.startEditing(textNode, this._textNodeEditingCommitted.bind(this), this._editingCancelled.bind(this)); + this._editing = WebInspector.startEditing(textNode, { + context: null, + commitHandler: this._textNodeEditingCommitted.bind(this), + cancelHandler: this._editingCancelled.bind(this) + }); window.getSelection().setBaseAndExtent(textNode, 0, textNode, 1); return true; @@ -925,7 +934,11 @@ WebInspector.ElementsTreeElement.prototype = { tagNameElement.addEventListener('keyup', keyupListener, false); - this._editing = WebInspector.startEditing(tagNameElement, editingComitted.bind(this), editingCancelled.bind(this), tagName); + this._editing = WebInspector.startEditing(tagNameElement, { + context: tagName, + commitHandler: editingComitted.bind(this), + cancelHandler: editingCancelled.bind(this) + }); window.getSelection().setBaseAndExtent(tagNameElement, 0, tagNameElement, 1); return true; }, @@ -979,7 +992,12 @@ WebInspector.ElementsTreeElement.prototype = { this.updateSelection(); } - this._editing = WebInspector.startEditing(this._htmlEditElement, commit.bind(this), dispose.bind(this), null, true); + this._editing = WebInspector.startEditing(this._htmlEditElement, { + context: null, + commitHandler: commit.bind(this), + cancelHandler: dispose.bind(this), + multiline: true + }); }, _attributeEditingCommitted: function(element, newText, oldText, attributeName, moveDirection) @@ -1015,8 +1033,12 @@ WebInspector.ElementsTreeElement.prototype = { if (!found) { if (moveDirection === "backward" && attributes.length > 0) moveToAttribute = attributes[attributes.length - 1].name; - else if (moveDirection === "forward" && !/^\s*$/.test(newText)) - moveToNewAttribute = true; + else if (moveDirection === "forward") { + if (!/^\s*$/.test(newText)) + moveToNewAttribute = true; + else + moveToTagName = true; + } } } @@ -1094,8 +1116,10 @@ WebInspector.ElementsTreeElement.prototype = { function moveToNextAttributeIfNeeded() { - if (moveDirection !== "forward") + if (moveDirection !== "forward") { + this._addNewAttribute(); return; + } var attributes = this.representedObject.attributes; if (attributes.length > 0) diff --git a/WebCore/inspector/front-end/ExtensionAPI.js b/WebCore/inspector/front-end/ExtensionAPI.js index 0234994..a9a2423 100644 --- a/WebCore/inspector/front-end/ExtensionAPI.js +++ b/WebCore/inspector/front-end/ExtensionAPI.js @@ -126,6 +126,11 @@ Resources.prototype = { callback(result); } return extensionServer.sendRequest({ command: "getHAR" }, callback && callbackWrapper); + }, + + addRequestHeaders: function(headers) + { + return extensionServer.sendRequest({ command: "addRequestHeaders", headers: headers, extensionId: location.hostname }); } } diff --git a/WebCore/inspector/front-end/ExtensionServer.js b/WebCore/inspector/front-end/ExtensionServer.js index 1050c6f..373c855 100644 --- a/WebCore/inspector/front-end/ExtensionServer.js +++ b/WebCore/inspector/front-end/ExtensionServer.js @@ -33,8 +33,10 @@ WebInspector.ExtensionServer = function() this._clientObjects = {}; this._handlers = {}; this._subscribers = {}; + this._extraHeaders = {}; this._status = new WebInspector.ExtensionStatus(); + this._registerHandler("addRequestHeaders", this._onAddRequestHeaders.bind(this)); this._registerHandler("addAuditCategory", this._onAddAuditCategory.bind(this)); this._registerHandler("addAuditResult", this._onAddAuditResult.bind(this)); this._registerHandler("createPanel", this._onCreatePanel.bind(this)); @@ -144,6 +146,29 @@ WebInspector.ExtensionServer.prototype = { delete this._subscribers[message.type]; }, + _onAddRequestHeaders: function(message) + { + var id = message.extensionId; + if (typeof id !== "string") + return this._status.E_BADARGTYPE("extensionId", typeof id, "string"); + var extensionHeaders = this._extraHeaders[id]; + if (!extensionHeaders) { + extensionHeaders = {}; + this._extraHeaders[id] = extensionHeaders; + } + for (name in message.headers) + extensionHeaders[name] = message.headers[name]; + var allHeaders = {}; + for (extension in this._extraHeaders) { + var headers = this._extraHeaders[extension]; + for (name in headers) { + if (typeof headers[name] === "string") + allHeaders[name] = headers[name]; + } + } + InspectorBackend.setExtraHeaders(allHeaders); + }, + _onCreatePanel: function(message, port) { var id = message.id; diff --git a/WebCore/inspector/front-end/HeapSnapshotView.js b/WebCore/inspector/front-end/HeapSnapshotView.js index 6bcc0ff..f349361 100644 --- a/WebCore/inspector/front-end/HeapSnapshotView.js +++ b/WebCore/inspector/front-end/HeapSnapshotView.js @@ -27,6 +27,154 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +WebInspector.HeapSnapshotEdgesIterator = function(snapshot, edges) +{ + this._snapshot = snapshot; + this._edges = edges; + this._edgeIndex = 0; +} + +WebInspector.HeapSnapshotEdgesIterator.prototype = { + get done() + { + return this._edgeIndex >= this._edges.length; + }, + + get isElement() + { + return this._getType() === this._snapshot._edgeElementType; + }, + + get isHidden() + { + return this._getType() === this._snapshot._edgeHiddenType; + }, + + get name() + { + return this.isElement || this.isHidden ? this._getNameOrIndex() : this._snapshot._strings[this._getNameOrIndex()]; + }, + + next: function() + { + this._edgeIndex += this._snapshot._edgeFieldsCount; + }, + + get node() + { + return new WebInspector.HeapSnapshotNodeWrapper(this._snapshot, this.nodeIndex); + }, + + get nodeIndex() + { + return this._edges[this._edgeIndex + this._snapshot._edgeToNodeOffset]; + }, + + _getNameOrIndex: function() + { + return this._edges[this._edgeIndex + this._snapshot._edgeNameOffset]; + }, + + _getType: function() + { + return this._edges[this._edgeIndex + this._snapshot._edgeTypeOffset]; + } +}; + +WebInspector.HeapSnapshotNodeWrapper = function(snapshot, nodeIndex) +{ + this._snapshot = snapshot; + this._nodes = snapshot._nodes; + this._nodeIndex = nodeIndex; +} + +WebInspector.HeapSnapshotNodeWrapper.prototype = { + get edges() + { + return new WebInspector.HeapSnapshotEdgesIterator(this._snapshot, this._getEdges()); + }, + + get edgesCount() + { + return this._nodes[this._nodeIndex + this._snapshot._edgesCountOffset]; + }, + + get instancesCount() + { + return this._nodes[this._nodeIndex + this._snapshot._nodeInstancesCountOffset]; + }, + + get isHidden() + { + return this._getType() === this._snapshot._nodeHiddenType; + }, + + get name() + { + return this._snapshot._strings[this._getName()]; + }, + + get selfSize() + { + return this._nodes[this._nodeIndex + this._snapshot._nodeSelfSizeOffset]; + }, + + _getName: function() + { + return this._nodes[this._nodeIndex + this._snapshot._nodeNameOffset]; + }, + + _getEdges: function() + { + var firstEdgeIndex = this._nodeIndex + this._snapshot._firstEdgeOffset; + return this._nodes.slice(firstEdgeIndex, firstEdgeIndex + this.edgesCount * this._snapshot._edgeFieldsCount); + }, + + _getType: function() + { + return this._nodes[this._nodeIndex + this._snapshot._nodeTypeOffset]; + } +}; + +WebInspector.HeapSnapshot = function(profile) +{ + this._profile = profile; + this._nodes = profile.nodes; + this._strings = profile.strings; + + this._init(); +} + +WebInspector.HeapSnapshot.prototype = { + _init: function() + { + this._metaNodeIndex = 0; + this._rootNodeIndex = 1; + var meta = this._nodes[this._metaNodeIndex]; + this._nodeTypeOffset = meta.fields.indexOf("type"); + this._nodeNameOffset = meta.fields.indexOf("name"); + this._nodeIdOffset = meta.fields.indexOf("id"); + this._nodeInstancesCountOffset = this._nodeIdOffset; + this._nodeSelfSizeOffset = meta.fields.indexOf("self_size"); + this._edgesCountOffset = meta.fields.indexOf("children_count"); + this._firstEdgeOffset = meta.fields.indexOf("children"); + this._nodeTypes = meta.types[this._nodeTypeOffset]; + this._nodeHiddenType = this._nodeTypes.indexOf("hidden"); + var edgesMeta = meta.types[this._firstEdgeOffset]; + this._edgeFieldsCount = edgesMeta.fields.length; + this._edgeTypeOffset = edgesMeta.fields.indexOf("type"); + this._edgeNameOffset = edgesMeta.fields.indexOf("name_or_index"); + this._edgeToNodeOffset = edgesMeta.fields.indexOf("to_node"); + this._edgeTypes = edgesMeta.types[this._edgeTypeOffset]; + this._edgeElementType = this._edgeTypes.indexOf("element"); + this._edgeHiddenType = this._edgeTypes.indexOf("hidden"); + }, + + get rootEdges() + { + return (new WebInspector.HeapSnapshotNodeWrapper(this, this._rootNodeIndex)).edges; + } +}; WebInspector.HeapSnapshotView = function(parent, profile) { @@ -327,22 +475,16 @@ WebInspector.HeapSnapshotView.prototype = { _loadProfile: function(profile, callback) { - if (profile._loaded) { - callback(profile); - return; - } - - InspectorBackend.getProfile(profile.typeId, profile.uid, loadedCallback.bind(this)); + WebInspector.panels.profiles.loadHeapSnapshot(profile.uid, callback); + }, - function loadedCallback(loadedSnapshot) { - profile.children = loadedSnapshot.head.children; - profile.entries = loadedSnapshot.head.entries; - profile.lowlevels = loadedSnapshot.head.lowlevels; - this._prepareProfile(profile); - profile._loaded = true; - this.parent.updateProfile(profile); - callback(profile); - } + processLoadedSnapshot: function(profile, loadedSnapshot) + { + var snapshot = WebInspector.HeapSnapshotView.prototype._convertSnapshot(loadedSnapshot); + profile.children = snapshot.children; + profile.entries = snapshot.entries; + profile.lowlevels = snapshot.lowlevels; + WebInspector.HeapSnapshotView.prototype._prepareProfile(profile); }, _mouseDownInDataGrid: function(event) @@ -384,6 +526,26 @@ WebInspector.HeapSnapshotView.prototype = { this.refreshShowAsPercents(); }, + _convertSnapshot: function(loadedSnapshot) + { + var snapshot = new WebInspector.HeapSnapshot(loadedSnapshot); + var result = {lowlevels: {}, entries: {}, children: {}}; + for (var rootEdges = snapshot.rootEdges; !rootEdges.done; rootEdges.next()) { + var node = rootEdges.node; + if (node.isHidden) + result.lowlevels[node.name] = {count: node.instancesCount, size: node.selfSize, type: node.name}; + else if (node.instancesCount) + result.entries[node.name] = {constructorName: node.name, count: node.instancesCount, size: node.selfSize}; + else { + var entry = {constructorName: node.name}; + for (var edges = node.edges; !edges.done; edges.next()) + entry[edges.nodeIndex] = {constructorName: edges.node.name, count: edges.name}; + result.children[rootEdges.nodeIndex] = entry; + } + } + return result; + }, + _prepareProfile: function(profile) { for (var profileEntry in profile.entries) @@ -392,12 +554,12 @@ WebInspector.HeapSnapshotView.prototype = { for (var addr in profile.children) { var retainer = profile.children[addr]; - var retainerId = retainer.constructorName + ':' + addr; + var retainerId = retainer.constructorName + ":" + addr; for (var childAddr in retainer) { - if (childAddr === 'constructorName') continue; + if (childAddr === "constructorName") continue; var item = retainer[childAddr]; - var itemId = item.constructorName + ':' + childAddr; - if ((item.constructorName === 'Object' || item.constructorName === 'Array')) { + var itemId = item.constructorName + ":" + childAddr; + if ((item.constructorName === "Object" || item.constructorName === "Array")) { if (!(itemId in profile.clusters)) profile.clusters[itemId] = { constructorName: itemId, retainers: {} }; mergeRetainers(profile.clusters[itemId], item); @@ -412,7 +574,7 @@ WebInspector.HeapSnapshotView.prototype = { entry.retainers[retainer.constructorName] = { constructorName: retainer.constructorName, count: 0, clusters: {} }; var retainerEntry = entry.retainers[retainer.constructorName]; retainerEntry.count += item.count; - if (retainer.constructorName === 'Object' || retainer.constructorName === 'Array') + if (retainer.constructorName === "Object" || retainer.constructorName === "Array") retainerEntry.clusters[retainerId] = true; } }, @@ -438,7 +600,7 @@ WebInspector.HeapSnapshotView.prototype = { var sortAscending = this.dataGrid.sortOrder === "ascending"; var sortColumnIdentifier = this.dataGrid.sortColumnIdentifier; var sortProperty = { - cons: ["cons", null], + cons: ["constructorName", null], count: ["count", null], size: ["size", "count"], countDelta: this.showCountDeltaAsPercent ? ["countDeltaPercent", null] : ["countDelta", null], diff --git a/WebCore/inspector/front-end/MetricsSidebarPane.js b/WebCore/inspector/front-end/MetricsSidebarPane.js index 3784ce8..3c0f315 100644 --- a/WebCore/inspector/front-end/MetricsSidebarPane.js +++ b/WebCore/inspector/front-end/MetricsSidebarPane.js @@ -175,7 +175,11 @@ WebInspector.MetricsSidebarPane.prototype = { var context = { box: box, styleProperty: styleProperty }; - WebInspector.startEditing(targetElement, this.editingCommitted.bind(this), this.editingCancelled.bind(this), context); + WebInspector.startEditing(targetElement, { + context: context, + commitHandler: this.editingCommitted.bind(this), + cancelHandler: this.editingCancelled.bind(this) + }); }, editingCancelled: function(element, context) diff --git a/WebCore/inspector/front-end/NetworkItemView.js b/WebCore/inspector/front-end/NetworkItemView.js index 927e840..48e3b19 100644 --- a/WebCore/inspector/front-end/NetworkItemView.js +++ b/WebCore/inspector/front-end/NetworkItemView.js @@ -37,7 +37,6 @@ WebInspector.NetworkItemView = function(resource) this._headersView = new WebInspector.ResourceHeadersView(resource); // Do not store reference to content view - it can be recreated. var contentView = WebInspector.ResourceManager.resourceViewForResource(resource); - this._cookiesView = new WebInspector.ResourceCookiesView(resource); this._tabbedPane = new WebInspector.TabbedPane(this.element); this._tabbedPane.appendTab("headers", WebInspector.UIString("Headers"), this._headersView); @@ -46,8 +45,10 @@ WebInspector.NetworkItemView = function(resource) contentView.visible = false; this._tabbedPane.appendTab("content", WebInspector.UIString("Content"), contentView); } - this._tabbedPane.appendTab("cookies", WebInspector.UIString("Cookies"), this._cookiesView); - + if (Preferences.showCookiesTab) { + this._cookiesView = new WebInspector.ResourceCookiesView(resource); + this._tabbedPane.appendTab("cookies", WebInspector.UIString("Cookies"), this._cookiesView); + } if (Preferences.showTimingTab) { var timingView = new WebInspector.ResourceTimingView(resource); this._tabbedPane.appendTab("timing", WebInspector.UIString("Timing"), timingView); @@ -82,7 +83,7 @@ WebInspector.NetworkItemView.prototype = { resize: function() { - if (this._cookiesView.visible) + if (this._cookiesView && this._cookiesView.visible) this._cookiesView.resize(); } } diff --git a/WebCore/inspector/front-end/NetworkPanel.js b/WebCore/inspector/front-end/NetworkPanel.js index 8f3cfd6..9941dbf 100644 --- a/WebCore/inspector/front-end/NetworkPanel.js +++ b/WebCore/inspector/front-end/NetworkPanel.js @@ -8,13 +8,13 @@ * are met: * * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. + * documentation and/or other materials provided with the distribution. * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. + * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -210,6 +210,7 @@ WebInspector.NetworkPanel.prototype = { columns.timeline.sort = "ascending"; this._dataGrid = new WebInspector.DataGrid(columns); + this._dataGrid.element.addEventListener("contextmenu", this._contextMenu.bind(this), true); this.containerElement.appendChild(this._dataGrid.element); this._dataGrid.addEventListener("sorting changed", this._sortItems, this); this._dataGrid.addEventListener("width changed", this._updateDividersIfNeeded, this); @@ -397,7 +398,7 @@ WebInspector.NetworkPanel.prototype = { transferSize += (resource.cached || !resource.transferSize) ? 0 : resource.transferSize; if (resource.isMainResource) baseTime = resource.startTime; - if (resource.endTime > maxTime) + if (resource.endTime > maxTime) maxTime = resource.endTime; } var text = String.sprintf(WebInspector.UIString("%d requests"), numRequests); @@ -517,7 +518,7 @@ WebInspector.NetworkPanel.prototype = { proceed = false; } else proceed = this._timelineGrid.updateDividers(force, this.calculator); - + if (!proceed) return; @@ -545,13 +546,13 @@ WebInspector.NetworkPanel.prototype = { loadDividerPadding.style.left = percent + "%"; this._timelineGrid.addEventDivider(loadDividerPadding); } - + if (this._mainResourceDOMContentTime !== -1) { var percent = this.calculator.computePercentageFromEventTime(this._mainResourceDOMContentTime); var domContentDivider = document.createElement("div"); domContentDivider.className = "network-event-divider network-blue-divider"; - + var domContentDividerPadding = document.createElement("div"); domContentDividerPadding.className = "network-event-divider-padding"; domContentDividerPadding.title = WebInspector.UIString("DOMContent event fired"); @@ -625,7 +626,7 @@ WebInspector.NetworkPanel.prototype = { { if (this._mainResourceLoadTime === x) return; - + this._mainResourceLoadTime = x || -1; // Update the dividers to draw the new line this._updateDividersIfNeeded(true); @@ -762,7 +763,7 @@ WebInspector.NetworkPanel.prototype = { this._mainResourceLoadTime = -1; this._mainResourceDOMContentTime = -1; - + this._viewsContainerElement.removeChildren(); this._viewsContainerElement.appendChild(this._closeButtonElement); this._resetSummaryBar(); @@ -792,7 +793,7 @@ WebInspector.NetworkPanel.prototype = { this._staleResources.push(resource); this._scheduleRefresh(); - + if (!resource) return; @@ -972,6 +973,35 @@ WebInspector.NetworkPanel.prototype = { var widths = {}; widths.name = 100; this._dataGrid.applyColumnWidthsMap(widths); + }, + + _contextMenu: function(event) + { + // createBlobURL is enabled conditionally, do not expose resource export if it's not available. + if (typeof window.createObjectURL !== "function" || !Preferences.resourceExportEnabled) + return; + + var contextMenu = new WebInspector.ContextMenu(); + var gridNode = this._dataGrid.dataGridNodeFromNode(event.target); + var resource = gridNode && gridNode._resource; + if (resource) + contextMenu.appendItem(WebInspector.UIString("Export to HAR"), this._exportResource.bind(this, resource)); + contextMenu.appendItem(WebInspector.UIString("Export all to HAR"), this._exportAll.bind(this)); + contextMenu.show(event); + }, + + _exportAll: function() + { + var harArchive = { + log: (new WebInspector.HARLog()).build() + } + offerFileForDownload(JSON.stringify(harArchive)); + }, + + _exportResource: function(resource) + { + var har = (new WebInspector.HAREntry(resource)).build(); + offerFileForDownload(JSON.stringify(har)); } } @@ -1134,7 +1164,7 @@ WebInspector.NetworkTimeCalculator.prototype = { return {start: start, middle: middle, end: end}; }, - + computePercentageFromEventTime: function(eventTime) { // This function computes a percentage in terms of the total loading time @@ -1364,6 +1394,7 @@ WebInspector.NetworkDataGridNode.prototype = { if (this._resource.cached) this._graphElement.addStyleClass("resource-cached"); + this._element.addStyleClass("network-item"); if (!this._element.hasStyleClass("network-category-" + this._resource.category.name)) { this._element.removeMatchingStyleClasses("network-category-\\w+"); this._element.addStyleClass("network-category-" + this._resource.category.name); diff --git a/WebCore/inspector/front-end/ObjectPropertiesSection.js b/WebCore/inspector/front-end/ObjectPropertiesSection.js index e13e5eb..e4794f3 100644 --- a/WebCore/inspector/front-end/ObjectPropertiesSection.js +++ b/WebCore/inspector/front-end/ObjectPropertiesSection.js @@ -202,8 +202,10 @@ WebInspector.ObjectPropertyTreeElement.prototype = { { function selectNode(nodeId) { - if (nodeId) + if (nodeId) { + WebInspector.currentPanel = WebInspector.panels.elements; WebInspector.panels.elements.focusedDOMNode = WebInspector.domAgent.nodeForId(nodeId); + } } function revealElement() @@ -236,7 +238,11 @@ WebInspector.ObjectPropertyTreeElement.prototype = { this.listItemElement.addStyleClass("editing-sub-part"); - WebInspector.startEditing(this.valueElement, this.editingCommitted.bind(this), this.editingCancelled.bind(this), context); + WebInspector.startEditing(this.valueElement, { + context: context, + commitHandler: this.editingCommitted.bind(this), + cancelHandler: this.editingCancelled.bind(this) + }); }, editingEnded: function(context) diff --git a/WebCore/inspector/front-end/Placard.js b/WebCore/inspector/front-end/Placard.js index 69a168e..9a415c4 100644 --- a/WebCore/inspector/front-end/Placard.js +++ b/WebCore/inspector/front-end/Placard.js @@ -67,7 +67,7 @@ WebInspector.Placard.prototype = { if (this._subtitle === x) return; this._subtitle = x; - this.subtitleElement.innerHTML = x; + this.subtitleElement.textContent = x; }, get selected() diff --git a/WebCore/inspector/front-end/ProfilesPanel.js b/WebCore/inspector/front-end/ProfilesPanel.js index 0aa4174..3e31ba5 100644 --- a/WebCore/inspector/front-end/ProfilesPanel.js +++ b/WebCore/inspector/front-end/ProfilesPanel.js @@ -124,6 +124,7 @@ WebInspector.ProfilesPanel = function() this._profiles = []; this._profilerEnabled = Preferences.profilerAlwaysEnabled; this._reset(); + InspectorBackend.registerDomainDispatcher("Profiler", this); } WebInspector.ProfilesPanel.prototype = { @@ -411,6 +412,50 @@ WebInspector.ProfilesPanel.prototype = { } }, + loadHeapSnapshot: function(uid, callback) + { + var profile = this._profilesIdMap[this._makeKey(uid, WebInspector.HeapSnapshotProfileType.TypeId)]; + if (!profile) + return; + + if (profile._loaded) + callback(profile); + else if (profile._is_loading) + profile._callbacks.push(callback); + else { + profile._is_loading = true; + profile._callbacks = [callback]; + profile._json = ""; + InspectorBackend.getProfile(profile.typeId, profile.uid); + } + }, + + addHeapSnapshotChunk: function(uid, chunk) + { + var profile = this._profilesIdMap[this._makeKey(uid, WebInspector.HeapSnapshotProfileType.TypeId)]; + if (!profile || profile._loaded || !profile._is_loading) + return; + + profile._json += chunk; + }, + + finishHeapSnapshot: function(uid) + { + var profile = this._profilesIdMap[this._makeKey(uid, WebInspector.HeapSnapshotProfileType.TypeId)]; + if (!profile || profile._loaded || !profile._is_loading) + return; + + var callbacks = profile._callbacks; + delete profile._callbacks; + var loadedSnapshot = JSON.parse(profile._json); + delete profile._json; + delete profile._is_loading; + profile._loaded = true; + WebInspector.HeapSnapshotView.prototype.processLoadedSnapshot(profile, loadedSnapshot); + for (var i = 0; i < callbacks.length; ++i) + callbacks[i](profile); + }, + showView: function(view) { this.showProfile(view.profile); @@ -553,7 +598,7 @@ WebInspector.ProfilesPanel.prototype = { var profileHeadersLength = profileHeaders.length; for (var i = 0; i < profileHeadersLength; ++i) if (!this.hasProfile(profileHeaders[i])) - WebInspector.addProfileHeader(profileHeaders[i]); + WebInspector.panels.profiles.addProfileHeader(profileHeaders[i]); } InspectorBackend.getProfileHeaders(populateCallback.bind(this)); @@ -567,6 +612,26 @@ WebInspector.ProfilesPanel.prototype = { this.profileViews.style.left = width + "px"; this.profileViewStatusBarItemsContainer.style.left = Math.max(155, width) + "px"; this.resize(); + }, + + setRecordingProfile: function(isProfiling) + { + this.getProfileType(WebInspector.CPUProfileType.TypeId).setRecordingProfile(isProfiling); + if (this.hasTemporaryProfile(WebInspector.CPUProfileType.TypeId) !== isProfiling) { + if (!this._temporaryRecordingProfile) { + this._temporaryRecordingProfile = { + typeId: WebInspector.CPUProfileType.TypeId, + title: WebInspector.UIString("Recording"), + uid: -1, + isTemporary: true + }; + } + if (isProfiling) + this.addProfileHeader(this._temporaryRecordingProfile); + else + this.removeProfileHeader(this._temporaryRecordingProfile); + } + this.updateProfileTypeButtons(); } } diff --git a/WebCore/inspector/front-end/Resource.js b/WebCore/inspector/front-end/Resource.js index aefdd6c..da21092 100644 --- a/WebCore/inspector/front-end/Resource.js +++ b/WebCore/inspector/front-end/Resource.js @@ -497,48 +497,6 @@ WebInspector.Resource.prototype = { } }, - get scripts() - { - if (!("_scripts" in this)) - this._scripts = []; - return this._scripts; - }, - - addScript: function(script) - { - if (!script) - return; - this.scripts.unshift(script); - script.resource = this; - }, - - removeAllScripts: function() - { - if (!this._scripts) - return; - - for (var i = 0; i < this._scripts.length; ++i) { - if (this._scripts[i].resource === this) - delete this._scripts[i].resource; - } - - delete this._scripts; - }, - - removeScript: function(script) - { - if (!script) - return; - - if (script.resource === this) - delete script.resource; - - if (!this._scripts) - return; - - this._scripts.remove(script); - }, - get errors() { return this._errors || 0; @@ -608,7 +566,6 @@ WebInspector.Resource.prototype = { WebInspector.ConsoleMessage.MessageLevel.Warning, -1, this.url, - null, 1, String.sprintf(WebInspector.Warnings.IncorrectMIMEType.message, WebInspector.Resource.Type.toUIString(this.type), this.mimeType), null, diff --git a/WebCore/inspector/front-end/ResourceManager.js b/WebCore/inspector/front-end/ResourceManager.js index 992d8c7..7f1c574 100644 --- a/WebCore/inspector/front-end/ResourceManager.js +++ b/WebCore/inspector/front-end/ResourceManager.js @@ -30,39 +30,17 @@ WebInspector.ResourceManager = function() { - this._registerNotifyHandlers( - "identifierForInitialRequest", - "willSendRequest", - "markResourceAsCached", - "didReceiveResponse", - "didReceiveContentLength", - "didFinishLoading", - "didFailLoading", - "didLoadResourceFromMemoryCache", - "setInitialContent", - "didCommitLoadForFrame", - "frameDetachedFromParent", - "didCreateWebSocket", - "willSendWebSocketHandshakeRequest", - "didReceiveWebSocketHandshakeResponse", - "didCloseWebSocket"); - this._resourcesById = {}; this._resourcesByURL = {}; this._resourceTreeModel = new WebInspector.ResourceTreeModel(); InspectorBackend.cachedResources(this._processCachedResources.bind(this)); + InspectorBackend.registerDomainDispatcher("Resources", this); } WebInspector.ResourceManager.prototype = { - _registerNotifyHandlers: function() - { - for (var i = 0; i < arguments.length; ++i) - WebInspector[arguments[i]] = this[arguments[i]].bind(this); - }, - - identifierForInitialRequest: function(identifier, url, loader) + identifierForInitialRequest: function(identifier, url, loader, callStack) { - var resource = this._createResource(identifier, url, loader); + var resource = this._createResource(identifier, url, loader, callStack); // It is important to bind resource url early (before scripts compile). this._bindResourceURL(resource); @@ -71,12 +49,13 @@ WebInspector.ResourceManager.prototype = { WebInspector.panels.audits.resourceStarted(resource); }, - _createResource: function(identifier, url, loader) + _createResource: function(identifier, url, loader, stackTrace) { var resource = new WebInspector.Resource(identifier, url); resource.loader = loader; if (loader) resource.documentURL = loader.url; + resource.stackTrace = stackTrace; this._resourcesById[identifier] = resource; return resource; @@ -119,7 +98,7 @@ WebInspector.ResourceManager.prototype = { var originalResource = this._resourcesById[identifier]; originalResource.identifier = null; - var newResource = this._createResource(identifier, redirectURL, originalResource.loader); + var newResource = this._createResource(identifier, redirectURL, originalResource.loader, originalResource.stackTrace); newResource.redirects = originalResource.redirects || []; delete originalResource.redirects; newResource.redirects.push(originalResource); @@ -268,7 +247,6 @@ WebInspector.ResourceManager.prototype = { if (mainResource) { WebInspector.mainResource = mainResource; mainResource.isMainResource = true; - WebInspector.panels.network.refreshResource(mainResource); } } }, @@ -428,6 +406,89 @@ WebInspector.ResourceManager.prototype = { } delete this._resourcesByURL[resource.url]; + }, + + updateDOMStorage: function(storageId) + { + WebInspector.panels.resources.updateDOMStorage(storageId); + }, + + updateApplicationCacheStatus: function(status) + { + WebInspector.panels.resources.updateApplicationCacheStatus(status); + }, + + didGetFileSystemPath: function(root, type, origin) + { + WebInspector.panels.resources.updateFileSystemPath(root, type, origin); + }, + + didGetFileSystemError: function(type, origin) + { + WebInspector.panels.resources.updateFileSystemError(type, origin); + }, + + didGetFileSystemDisabled: function() + { + WebInspector.panels.resources.setFileSystemDisabled(); + }, + + updateNetworkState: function(isNowOnline) + { + WebInspector.panels.resources.updateNetworkState(isNowOnline); + }, + + addDOMStorage: function(payload) + { + if (!WebInspector.panels.resources) + return; + var domStorage = new WebInspector.DOMStorage( + payload.id, + payload.host, + payload.isLocalStorage); + WebInspector.panels.resources.addDOMStorage(domStorage); + }, + + selectDOMStorage: function(o) + { + WebInspector.showPanel("resources"); + WebInspector.panels.resources.selectDOMStorage(o); + }, + + addDatabase: function(payload) + { + if (!WebInspector.panels.resources) + return; + var database = new WebInspector.Database( + payload.id, + payload.domain, + payload.name, + payload.version); + WebInspector.panels.resources.addDatabase(database); + }, + + selectDatabase: function(o) + { + WebInspector.showPanel("resources"); + WebInspector.panels.resources.selectDatabase(o); + }, + + sqlTransactionSucceeded: function(transactionId, columnNames, values) + { + var callback = WebInspector.Database.successCallbacks[transactionId]; + if (!callback) + return; + delete WebInspector.Database.successCallbacks[transactionId]; + callback(columnNames, values); + }, + + sqlTransactionFailed: function(transactionId, errorObj) + { + var callback = WebInspector.Database.errorCallbacks[transactionId]; + if (!callback) + return; + delete WebInspector.Database.errorCallbacks[transactionId]; + callback(errorObj); } } diff --git a/WebCore/inspector/front-end/Script.js b/WebCore/inspector/front-end/Script.js index be3f020..184fe97 100644 --- a/WebCore/inspector/front-end/Script.js +++ b/WebCore/inspector/front-end/Script.js @@ -27,7 +27,7 @@ WebInspector.Script = function(sourceID, sourceURL, source, startingLine, errorL { this.sourceID = sourceID; this.sourceURL = sourceURL; - this.source = source; + this._source = source; this.startingLine = startingLine; this.errorLine = errorLine; this.errorMessage = errorMessage; @@ -57,6 +57,10 @@ WebInspector.Script.WorldType = { EXTENSIONS_WORLD: 1 } +WebInspector.Script.Events = { + SourceChanged: "source-changed" +} + WebInspector.Script.prototype = { get linesCount() { @@ -71,5 +75,18 @@ WebInspector.Script.prototype = { this._linesCount++; } return this._linesCount; + }, + + get source() + { + return this._source; + }, + + set source(source) + { + this._source = source; + this.dispatchEventToListeners(WebInspector.Script.Events.SourceChanged); } } + +WebInspector.Script.prototype.__proto__ = WebInspector.Object.prototype; diff --git a/WebCore/inspector/front-end/ScriptView.js b/WebCore/inspector/front-end/ScriptView.js index d878e9b..39dae55 100644 --- a/WebCore/inspector/front-end/ScriptView.js +++ b/WebCore/inspector/front-end/ScriptView.js @@ -30,11 +30,11 @@ WebInspector.ScriptView = function(script) this.element.addStyleClass("script-view"); this.script = script; + this.script.addEventListener(WebInspector.Script.Events.SourceChanged, this._scriptSourceChanged, this); this._frameNeedsSetup = true; this._sourceFrameSetup = false; - var canEditScripts = WebInspector.panels.scripts.canEditScripts(); - this.sourceFrame = new WebInspector.SourceFrame(this.element, this._addBreakpoint.bind(this), canEditScripts ? this._editLine.bind(this) : null, this._continueToLine.bind(this)); + this.sourceFrame = new WebInspector.SourceFrame(this.element, [script], WebInspector.panels.scripts.canEditScripts()); } WebInspector.ScriptView.prototype = { @@ -85,29 +85,9 @@ WebInspector.ScriptView.prototype = { document.getElementById("script-resource-views").appendChild(this.element); }, - _continueToLine: function(line) + _scriptSourceChanged: function(event) { - var scriptsPanel = WebInspector.panels.scripts; - if (scriptsPanel) - scriptsPanel.continueToLine(this.script.sourceID, line); - }, - - _addBreakpoint: function(line) - { - WebInspector.breakpointManager.setBreakpoint(this.script.sourceID, this.script.sourceURL, line, true, ""); - if (!WebInspector.panels.scripts.breakpointsActivated) - WebInspector.panels.scripts.toggleBreakpointsClicked(); - }, - - _editLineComplete: function(newBody) - { - this.script.source = newBody; - this.sourceFrame.updateContent(this._prependWhitespace(newBody)); - }, - - _sourceIDForLine: function(line) - { - return this.script.sourceID; + this.sourceFrame.updateContent(this._prependWhitespace(this.script.source)); }, // The following methods are pulled from SourceView, since they are @@ -127,9 +107,7 @@ WebInspector.ScriptView.prototype = { showingFirstSearchResult: WebInspector.SourceView.prototype.showingFirstSearchResult, showingLastSearchResult: WebInspector.SourceView.prototype.showingLastSearchResult, _jumpToSearchResult: WebInspector.SourceView.prototype._jumpToSearchResult, - _editLine: WebInspector.SourceView.prototype._editLine, resize: WebInspector.SourceView.prototype.resize } WebInspector.ScriptView.prototype.__proto__ = WebInspector.View.prototype; - diff --git a/WebCore/inspector/front-end/ScriptsPanel.js b/WebCore/inspector/front-end/ScriptsPanel.js index 30bd513..56facf2 100644 --- a/WebCore/inspector/front-end/ScriptsPanel.js +++ b/WebCore/inspector/front-end/ScriptsPanel.js @@ -175,9 +175,12 @@ WebInspector.ScriptsPanel = function() this._debuggerEnabled = Preferences.debuggerAlwaysEnabled; - WebInspector.breakpointManager.addEventListener("breakpoint-added", this._breakpointAdded, this); - this.reset(); + + WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.ParsedScriptSource, this._parsedScriptSource, this); + WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.FailedToParseScriptSource, this._failedToParseScriptSource, this); + WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this); + WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerResumed, this._debuggerResumed, this); } // Keep these in sync with WebCore::ScriptDebugServer @@ -234,17 +237,28 @@ WebInspector.ScriptsPanel.prototype = { return this.toggleBreakpointsButton.toggled; }, - addScript: function(sourceID, sourceURL, source, startingLine, errorLine, errorMessage, scriptWorldType) + _parsedScriptSource: function(event) { - var script = new WebInspector.Script(sourceID, sourceURL, source, startingLine, errorLine, errorMessage, scriptWorldType); - this._sourceIDMap[sourceID] = script; + var sourceID = event.data; + var script = WebInspector.debuggerModel.scriptForSourceID(sourceID); + this._addScript(script); + }, - var resource = WebInspector.resourceForURL(sourceURL); + _failedToParseScriptSource: function(event) + { + this._addScript(event.data); + }, + + _addScript: function(script) + { + var resource = WebInspector.resourceForURL(script.sourceURL); if (resource) { if (resource.finished) { // Resource is finished, bind the script right away. - resource.addScript(script); - this._sourceIDMap[sourceID] = resource; + script.resource = resource; + var view = WebInspector.ResourceManager.existingResourceViewForResource(resource); + if (view && view.sourceFrame) + view.sourceFrame.addScript(script); } else { // Resource is not finished, bind the script later. if (!resource._scriptsPendingResourceLoad) { @@ -257,21 +271,13 @@ WebInspector.ScriptsPanel.prototype = { this._addScriptToFilesMenu(script); }, - continueToLine: function(sourceID, line) - { - WebInspector.breakpointManager.setOneTimeBreakpoint(sourceID, line); - if (this.paused) - this._togglePause(); - }, - _resourceLoadingFinished: function(e) { var resource = e.target; for (var i = 0; i < resource._scriptsPendingResourceLoad.length; ++i) { // Bind script to resource. var script = resource._scriptsPendingResourceLoad[i]; - resource.addScript(script); - this._sourceIDMap[script.sourceID] = resource; + script.resource = resource; // Remove script from the files list. script.filesSelectOption.parentElement.removeChild(script.filesSelectOption); @@ -281,26 +287,6 @@ WebInspector.ScriptsPanel.prototype = { delete resource._scriptsPendingResourceLoad; }, - _breakpointAdded: function(event) - { - var breakpoint = event.data; - - var sourceFrame; - if (breakpoint.url) { - var resource = WebInspector.resourceForURL(breakpoint.url); - if (resource && resource.finished) - sourceFrame = this._sourceFrameForScriptOrResource(resource); - } - - if (breakpoint.sourceID && !sourceFrame) { - var object = this._sourceIDMap[breakpoint.sourceID] - sourceFrame = this._sourceFrameForScriptOrResource(object); - } - - if (sourceFrame) - sourceFrame.addBreakpoint(breakpoint); - }, - canEditScripts: function() { return Preferences.canEditScriptSource; @@ -312,7 +298,7 @@ WebInspector.ScriptsPanel.prototype = { return; // Need to clear breakpoints and re-create them later when editing source. - var breakpoints = WebInspector.breakpointManager.breakpointsForSourceID(editData.sourceID); + var breakpoints = WebInspector.debuggerModel.queryBreakpoints(function(b) { return b.sourceID === editData.sourceID }); for (var i = 0; i < breakpoints.length; ++i) breakpoints[i].remove(); @@ -321,7 +307,7 @@ WebInspector.ScriptsPanel.prototype = { if (success) { commitEditingCallback(newBodyOrErrorMessage); if (callFrames && callFrames.length) - this.debuggerPaused(callFrames); + this._debuggerPaused({ data: { callFrames: callFrames } }); } else { if (cancelEditingCallback) cancelEditingCallback(); @@ -332,7 +318,7 @@ WebInspector.ScriptsPanel.prototype = { var newLine = breakpoint.line; if (success && breakpoint.line >= editData.line) newLine += editData.linesCountToShift; - WebInspector.breakpointManager.setBreakpoint(editData.sourceID, breakpoint.url, newLine, breakpoint.enabled, breakpoint.condition); + WebInspector.debuggerModel.setBreakpoint(editData.sourceID, newLine, breakpoint.enabled, breakpoint.condition); } }; InspectorBackend.editScriptSource(editData.sourceID, editData.content, mycallback.bind(this)); @@ -375,9 +361,10 @@ WebInspector.ScriptsPanel.prototype = { InjectedScriptAccess.get(callFrame.worldId).evaluateInCallFrame(callFrame.id, code, objectGroup, evalCallback); }, - debuggerPaused: function(callFrames) + _debuggerPaused: function(event) { - WebInspector.breakpointManager.removeOneTimeBreakpoint(); + var callFrames = event.data.callFrames; + this._paused = true; this._waitingToPause = false; this._stepping = false; @@ -386,13 +373,14 @@ WebInspector.ScriptsPanel.prototype = { WebInspector.currentPanel = this; - this.sidebarPanes.callstack.update(callFrames, this._sourceIDMap); + this.sidebarPanes.callstack.update(callFrames, event.data.eventType, event.data.eventData); this.sidebarPanes.callstack.selectedCallFrame = callFrames[0]; window.focus(); + InspectorFrontendHost.bringToFront(); }, - debuggerResumed: function() + _debuggerResumed: function() { this._paused = false; this._waitingToPause = false; @@ -435,7 +423,7 @@ WebInspector.ScriptsPanel.prototype = { delete this.currentQuery; this.searchCanceled(); - this.debuggerResumed(); + this._debuggerResumed(); this._backForwardList = []; this._currentBackForwardIndex = -1; @@ -446,26 +434,13 @@ WebInspector.ScriptsPanel.prototype = { this.functionsSelectElement.removeChildren(); this.viewsContainerElement.removeChildren(); - if (this._sourceIDMap) { - for (var sourceID in this._sourceIDMap) { - var object = this._sourceIDMap[sourceID]; - if (object instanceof WebInspector.Resource) - object.removeAllScripts(); - } - } - - this._sourceIDMap = {}; + var scripts = WebInspector.debuggerModel.queryScripts(function(s) { return !!s.resource; }); + for (var i = 0; i < scripts.length; ++i) + delete scripts[i].resource._resourcesView; this.sidebarPanes.watchExpressions.refreshExpressions(); - if (!preserveItems) { - this.sidebarPanes.jsBreakpoints.reset(); - if (Preferences.nativeInstrumentationEnabled) { - this.sidebarPanes.domBreakpoints.reset(); - this.sidebarPanes.xhrBreakpoints.reset(); - this.sidebarPanes.eventListenerBreakpoints.reset(); - } + if (!preserveItems) this.sidebarPanes.workers.reset(); - } }, get visibleView() @@ -508,22 +483,15 @@ WebInspector.ScriptsPanel.prototype = { _scriptOrResourceForURLAndLine: function(url, line) { - var scriptWithMatchingUrl = null; - for (var sourceID in this._sourceIDMap) { - var scriptOrResource = this._sourceIDMap[sourceID]; - if (scriptOrResource instanceof WebInspector.Script) { - if (scriptOrResource.sourceURL !== url) - continue; - scriptWithMatchingUrl = scriptOrResource; - if (scriptWithMatchingUrl.startingLine <= line && scriptWithMatchingUrl.startingLine + scriptWithMatchingUrl.linesCount > line) - return scriptWithMatchingUrl; - } else { - var resource = scriptOrResource; - if (resource.url === url) - return resource; - } + var scripts = WebInspector.debuggerModel.scriptsForURL(url); + for (var i = 0; i < scripts.length; ++i) { + var script = scripts[i]; + if (script.resource) + return script.resource; + if (script.startingLine <= line && script.startingLine + script.linesCount > line) + return script; } - return scriptWithMatchingUrl; + return null; }, showView: function(view) @@ -742,7 +710,8 @@ WebInspector.ScriptsPanel.prototype = { this.sidebarPanes.scopechain.update(currentFrame); this.sidebarPanes.watchExpressions.refreshExpressions(); - var scriptOrResource = this._sourceIDMap[currentFrame.sourceID]; + var script = WebInspector.debuggerModel.scriptForSourceID(currentFrame.sourceID); + var scriptOrResource = script.resource || script; this._showScriptOrResource(scriptOrResource, {line: currentFrame.line}); this._executionSourceFrame = this._sourceFrameForScriptOrResource(scriptOrResource); @@ -1096,4 +1065,3 @@ WebInspector.ScriptsPanel.prototype = { } WebInspector.ScriptsPanel.prototype.__proto__ = WebInspector.Panel.prototype; - diff --git a/WebCore/inspector/front-end/Section.js b/WebCore/inspector/front-end/Section.js index a186d43..5caa78b 100644 --- a/WebCore/inspector/front-end/Section.js +++ b/WebCore/inspector/front-end/Section.js @@ -31,7 +31,7 @@ WebInspector.Section = function(title, subtitle) { this.element = document.createElement("div"); this.element.className = "section"; - this.element.sectionForTest = this; + this.element._section = this; this.headerElement = document.createElement("div"); this.headerElement.className = "header"; @@ -85,15 +85,15 @@ WebInspector.Section.prototype = { this.subtitleElement.textContent = x; }, - get subtitleAsTextForTest()
- {
- var result = this.subtitleElement.textContent;
- var child = this.subtitleElement.querySelector("[data-uncopyable]");
- if (child) {
- var linkData = child.getAttribute("data-uncopyable");
- if (linkData)
- result += linkData;
- }
+ get subtitleAsTextForTest() + { + var result = this.subtitleElement.textContent; + var child = this.subtitleElement.querySelector("[data-uncopyable]"); + if (child) { + var linkData = child.getAttribute("data-uncopyable"); + if (linkData) + result += linkData; + } return result; }, @@ -124,6 +124,26 @@ WebInspector.Section.prototype = { } }, + get nextSibling() + { + var curElement = this.element; + do { + curElement = curElement.nextSibling; + } while (curElement && !curElement._section); + + return curElement ? curElement._section : null; + }, + + get previousSibling() + { + var curElement = this.element; + do { + curElement = curElement.previousSibling; + } while (curElement && !curElement._section); + + return curElement ? curElement._section : null; + }, + expand: function() { if (this._expanded) diff --git a/WebCore/inspector/front-end/Settings.js b/WebCore/inspector/front-end/Settings.js index 9aac626..bc50ce9 100644 --- a/WebCore/inspector/front-end/Settings.js +++ b/WebCore/inspector/front-end/Settings.js @@ -48,6 +48,7 @@ var Preferences = { fileSystemEnabled: false, useDataURLForResourceImageIcons: true, showTimingTab: false, + showCookiesTab: false, debugMode: false } @@ -69,6 +70,10 @@ WebInspector.Settings = function() this.installProjectSetting("nativeBreakpoints", []); } +WebInspector.Settings.Events = { + ProjectChanged: "project-changed" +} + WebInspector.Settings.prototype = { installApplicationSetting: function(key, defaultValue) { @@ -90,7 +95,31 @@ WebInspector.Settings.prototype = { var fragmentIndex = url.indexOf("#"); if (fragmentIndex !== -1) url = url.substring(0, fragmentIndex); - this._inspectedURL = url; + this._projectId = url; + this.dispatchEventToListeners(WebInspector.Settings.Events.ProjectChanged); + }, + + get projectId() + { + return this._projectId; + }, + + findSettingForAllProjects: function(key) + { + var result = {}; + var regexp = "^" + key + ":(.*)"; + for (var i = 0; i < window.localStorage.length; ++i) { + var fullKey = window.localStorage.key(i); + var match = fullKey.match(regexp); + if (!match) + continue; + try { + result[match[1]] = JSON.parse(window.localStorage[fullKey]); + } catch(e) { + window.localStorage.removeItem(fullKey); + } + } + return result; }, _get: function(key, defaultValue) @@ -122,7 +151,7 @@ WebInspector.Settings.prototype = { _formatProjectKey: function(key) { - return key + ":" + this._inspectedURL; + return key + ":" + this._projectId; } } diff --git a/WebCore/inspector/front-end/SourceCSSTokenizer.js b/WebCore/inspector/front-end/SourceCSSTokenizer.js index 82149e0..7259dc1 100644 --- a/WebCore/inspector/front-end/SourceCSSTokenizer.js +++ b/WebCore/inspector/front-end/SourceCSSTokenizer.js @@ -1,4 +1,4 @@ -/* Generated by re2c 0.13.5 on Thu Feb 25 21:44:55 2010 */ +/* Generated by re2c 0.13.5 on Mon Dec 20 18:44:30 2010 */ /* * Copyright (C) 2009 Google Inc. All rights reserved. * @@ -45,11 +45,11 @@ WebInspector.SourceCSSTokenizer = function() { WebInspector.SourceTokenizer.call(this); - this._propertyKeywords = WebInspector.CSSCompletions.keySet(); + this._propertyKeywords = WebInspector.cssNameCompletions.keySet(); this._valueKeywords = [ "above", "absolute", "activeborder", "activecaption", "afar", "after-white-space", "ahead", "alias", "all", "all-scroll", - "alternate", "always","amharic", "amharic-abegede", "antialiased", "appworkspace", "aqua", "arabic-indic", "armenian", + "alternate", "always","amharic", "amharic-abegede", "antialiased", "appworkspace", "aqua", "arabic-indic", "armenian", "asterisks", "auto", "avoid", "background", "backwards", "baseline", "below", "bidi-override", "binary", "bengali", "black", "blink", "block", "block-axis", "blue", "bold", "bolder", "border", "border-box", "both", "bottom", "break-all", "break-word", "button", "button-bevel", "buttonface", "buttonhighlight", "buttonshadow", "buttontext", "cambodian", "capitalize", "caps-lock-indicator", @@ -62,16 +62,16 @@ WebInspector.SourceCSSTokenizer = function() "ethiopic-abegede-ti-er", "ethiopic-abegede-ti-et", "ethiopic-halehame-aa-er", "ethiopic-halehame-aa-et", "ethiopic-halehame-am-et", "ethiopic-halehame-gez", "ethiopic-halehame-om-et", "ethiopic-halehame-sid-et", "ethiopic-halehame-so-et", "ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et", "ethiopic-halehame-tig", "ew-resize", "expanded", - "extra-condensed", "extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "forwards", "from", "fuchsia", "geometricPrecision", + "extra-condensed", "extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "footnotes", "forwards", "from", "fuchsia", "geometricPrecision", "georgian", "gray", "graytext", "green", "grey", "groove", "gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hebrew", "help", "hidden", "hide", "higher", "highlight", "highlighttext", "hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "icon", "ignore", "inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite", "infobackground", "infotext", "inherit", "initial", "inline", "inline-axis", "inline-block", "inline-table", "inset", "inside", "intrinsic", "invert", "italic", "justify", "kannada", "katakana", "katakana-iroha", "khmer", "landscape", "lao", "large", "larger", "left", "level", "lighter", "lime", "line-through", "linear", "lines", - "list-button", "list-item", "listbox", "listitem", "local", "logical", "loud", "lower", "lower-alpha", "lower-greek", "lower-hexadecimal", "lower-latin", - "lower-norwegian", "lower-roman", "lowercase", "ltr", "malayalam", "maroon", "match", "media-controls-background", "media-current-time-display", - "media-fullscreen-button", "media-mute-button", "media-play-button", "media-return-to-realtime-button", "media-rewind-button", - "media-seek-back-button", "media-seek-forward-button", "media-slider", "media-sliderthumb", "media-time-remaining-display", + "list-button", "list-item", "listbox", "listitem", "local", "logical", "loud", "lower", "lower-alpha", "lower-armenian", "lower-greek", + "lower-hexadecimal", "lower-latin", "lower-norwegian", "lower-roman", "lowercase", "ltr", "malayalam", "maroon", "match", "media-controls-background", + "media-current-time-display", "media-fullscreen-button", "media-mute-button", "media-play-button", "media-return-to-realtime-button", + "media-rewind-button", "media-seek-back-button", "media-seek-forward-button", "media-slider", "media-sliderthumb", "media-time-remaining-display", "media-volume-slider", "media-volume-slider-container", "media-volume-sliderthumb", "medium", "menu", "menulist", "menulist-button", "menulist-text", "menulist-textfield", "menutext", "message-box", "middle", "min-intrinsic", "mix", "mongolian", "monospace", "move", "multiple", "myanmar", "n-resize", "narrower", "navy", "ne-resize", "nesw-resize", "no-close-quote", "no-drop", "no-open-quote", "no-repeat", "none", @@ -88,8 +88,8 @@ WebInspector.SourceCSSTokenizer = function() "sw-resize", "table", "table-caption", "table-cell", "table-column", "table-column-group", "table-footer-group", "table-header-group", "table-row", "table-row-group", "teal", "telugu", "text", "text-bottom", "text-top", "textarea", "textfield", "thai", "thick", "thin", "threeddarkshadow", "threedface", "threedhighlight", "threedlightshadow", "threedshadow", "tibetan", "tigre", "tigrinya-er", "tigrinya-er-abegede", - "tigrinya-et", "tigrinya-et-abegede", "to", "top", "transparent", "ultra-condensed", "ultra-expanded", "underline", "up", "upper-alpha", "upper-greek", - "upper-hexadecimal", "upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url", "vertical", "vertical-text", "visible", + "tigrinya-et", "tigrinya-et-abegede", "to", "top", "transparent", "ultra-condensed", "ultra-expanded", "underline", "up", "upper-alpha", "upper-armenian", + "upper-greek", "upper-hexadecimal", "upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url", "vertical", "vertical-text", "visible", "visibleFill", "visiblePainted", "visibleStroke", "visual", "w-resize", "wait", "wave", "white", "wider", "window", "windowframe", "windowtext", "x-large", "x-small", "xor", "xx-large", "xx-small", "yellow", "-wap-marquee", "-webkit-activelink", "-webkit-auto", "-webkit-baseline-middle", "-webkit-body", "-webkit-box", "-webkit-center", "-webkit-control", "-webkit-focus-ring-color", "-webkit-grab", "-webkit-grabbing", diff --git a/WebCore/inspector/front-end/SourceCSSTokenizer.re2js b/WebCore/inspector/front-end/SourceCSSTokenizer.re2js index f4628d2..1b84b43 100644 --- a/WebCore/inspector/front-end/SourceCSSTokenizer.re2js +++ b/WebCore/inspector/front-end/SourceCSSTokenizer.re2js @@ -44,7 +44,7 @@ WebInspector.SourceCSSTokenizer = function() { WebInspector.SourceTokenizer.call(this); - this._propertyKeywords = WebInspector.CSSCompletions.keySet(); + this._propertyKeywords = WebInspector.cssNameCompletions.keySet(); this._valueKeywords = [ "above", "absolute", "activeborder", "activecaption", "afar", "after-white-space", "ahead", "alias", "all", "all-scroll", @@ -67,10 +67,10 @@ WebInspector.SourceCSSTokenizer = function() "inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite", "infobackground", "infotext", "inherit", "initial", "inline", "inline-axis", "inline-block", "inline-table", "inset", "inside", "intrinsic", "invert", "italic", "justify", "kannada", "katakana", "katakana-iroha", "khmer", "landscape", "lao", "large", "larger", "left", "level", "lighter", "lime", "line-through", "linear", "lines", - "list-button", "list-item", "listbox", "listitem", "local", "logical", "loud", "lower", "lower-alpha", "lower-greek", "lower-hexadecimal", "lower-latin", - "lower-norwegian", "lower-roman", "lowercase", "ltr", "malayalam", "maroon", "match", "media-controls-background", "media-current-time-display", - "media-fullscreen-button", "media-mute-button", "media-play-button", "media-return-to-realtime-button", "media-rewind-button", - "media-seek-back-button", "media-seek-forward-button", "media-slider", "media-sliderthumb", "media-time-remaining-display", + "list-button", "list-item", "listbox", "listitem", "local", "logical", "loud", "lower", "lower-alpha", "lower-armenian", "lower-greek", + "lower-hexadecimal", "lower-latin", "lower-norwegian", "lower-roman", "lowercase", "ltr", "malayalam", "maroon", "match", "media-controls-background", + "media-current-time-display", "media-fullscreen-button", "media-mute-button", "media-play-button", "media-return-to-realtime-button", + "media-rewind-button", "media-seek-back-button", "media-seek-forward-button", "media-slider", "media-sliderthumb", "media-time-remaining-display", "media-volume-slider", "media-volume-slider-container", "media-volume-sliderthumb", "medium", "menu", "menulist", "menulist-button", "menulist-text", "menulist-textfield", "menutext", "message-box", "middle", "min-intrinsic", "mix", "mongolian", "monospace", "move", "multiple", "myanmar", "n-resize", "narrower", "navy", "ne-resize", "nesw-resize", "no-close-quote", "no-drop", "no-open-quote", "no-repeat", "none", @@ -87,8 +87,8 @@ WebInspector.SourceCSSTokenizer = function() "sw-resize", "table", "table-caption", "table-cell", "table-column", "table-column-group", "table-footer-group", "table-header-group", "table-row", "table-row-group", "teal", "telugu", "text", "text-bottom", "text-top", "textarea", "textfield", "thai", "thick", "thin", "threeddarkshadow", "threedface", "threedhighlight", "threedlightshadow", "threedshadow", "tibetan", "tigre", "tigrinya-er", "tigrinya-er-abegede", - "tigrinya-et", "tigrinya-et-abegede", "to", "top", "transparent", "ultra-condensed", "ultra-expanded", "underline", "up", "upper-alpha", "upper-greek", - "upper-hexadecimal", "upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url", "vertical", "vertical-text", "visible", + "tigrinya-et", "tigrinya-et-abegede", "to", "top", "transparent", "ultra-condensed", "ultra-expanded", "underline", "up", "upper-alpha", "upper-armenian", + "upper-greek", "upper-hexadecimal", "upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url", "vertical", "vertical-text", "visible", "visibleFill", "visiblePainted", "visibleStroke", "visual", "w-resize", "wait", "wave", "white", "wider", "window", "windowframe", "windowtext", "x-large", "x-small", "xor", "xx-large", "xx-small", "yellow", "-wap-marquee", "-webkit-activelink", "-webkit-auto", "-webkit-baseline-middle", "-webkit-body", "-webkit-box", "-webkit-center", "-webkit-control", "-webkit-focus-ring-color", "-webkit-grab", "-webkit-grabbing", diff --git a/WebCore/inspector/front-end/SourceFrame.js b/WebCore/inspector/front-end/SourceFrame.js index 8e077cd..fa8441d 100644 --- a/WebCore/inspector/front-end/SourceFrame.js +++ b/WebCore/inspector/front-end/SourceFrame.js @@ -28,9 +28,13 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -WebInspector.SourceFrame = function(parentElement, addBreakpointDelegate, editDelegate, continueToHereDelegate) +WebInspector.SourceFrame = function(parentElement, scripts, canEditScripts) { this._parentElement = parentElement; + this._scripts = {}; + for (var i = 0; i < scripts.length; ++i) + this._scripts[scripts[i].sourceID] = scripts[i]; + this._canEditScripts = canEditScripts; this._textModel = new WebInspector.TextEditorModel(); this._textModel.replaceTabsWithSpaces = true; @@ -38,13 +42,8 @@ WebInspector.SourceFrame = function(parentElement, addBreakpointDelegate, editDe this._messages = []; this._rowMessages = {}; this._messageBubbles = {}; - this.breakpoints = []; this._loaded = false; - - this._continueToHereDelegate = continueToHereDelegate; - this._addBreakpointDelegate = addBreakpointDelegate; - this._editDelegate = editDelegate; this._popoverObjectGroup = "popover"; } @@ -105,23 +104,6 @@ WebInspector.SourceFrame.prototype = { this._lineNumberToReveal = lineNumber; }, - addBreakpoint: function(breakpoint) - { - this.breakpoints.push(breakpoint); - breakpoint.addEventListener("removed", this._breakpointRemoved, this); - if (this._textViewer) - this._addBreakpointToSource(breakpoint); - }, - - _breakpointRemoved: function(event) - { - var breakpoint = event.target; - - this.breakpoints.remove(breakpoint); - if (this._textViewer) - this._removeBreakpointFromSource(breakpoint); - }, - addMessage: function(msg) { // Don't add the message if there is no message or valid line or if the msg isn't an error or warning. @@ -132,6 +114,11 @@ WebInspector.SourceFrame.prototype = { this._addMessageToSource(msg); }, + addScript: function(script) + { + this._scripts[script.sourceID] = script; + }, + clearMessages: function() { for (var line in this._messageBubbles) { @@ -211,14 +198,10 @@ WebInspector.SourceFrame.prototype = { element.addEventListener("scroll", this._scroll.bind(this), true); this._parentElement.appendChild(element); - this._needsProgramCounterImage = true; - this._needsBreakpointImages = true; - this._textViewer.beginUpdates(); this._textViewer.mimeType = this._mimeType; this._addExistingMessagesToSource(); - this._addExistingBreakpointsToSource(); this._updateExecutionLine(); this._updateDiffDecorations(); this._textViewer.resize(); @@ -238,9 +221,16 @@ WebInspector.SourceFrame.prototype = { this.highlightLine(this._lineToHighlight); delete this._lineToHighlight; } + + var breakpoints = this._breakpoints(); + for (var i = 0; i < breakpoints.length; ++i) + this._addBreakpoint(breakpoints[i]); + WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointAdded, this._breakpointAdded, this); + this._textViewer.endUpdates(); - if (this._editDelegate) - this._textViewer.editCallback = this._editDelegate; + + if (this._canEditScripts) + this._textViewer.editCallback = this._editLine.bind(this); }, findSearchMatches: function(query) @@ -309,24 +299,6 @@ WebInspector.SourceFrame.prototype = { msg._resourceMessageRepeatCountElement.textContent = WebInspector.UIString(" (repeated %d times)", msg.repeatCount); }, - _breakpointChanged: function(event) - { - var breakpoint = event.target; - var lineNumber = breakpoint.line - 1; - if (lineNumber >= this._textModel.linesCount) - return; - - if (breakpoint.enabled) - this._textViewer.removeDecoration(lineNumber, "webkit-breakpoint-disabled"); - else - this._textViewer.addDecoration(lineNumber, "webkit-breakpoint-disabled"); - - if (breakpoint.condition) - this._textViewer.addDecoration(lineNumber, "webkit-breakpoint-conditional"); - else - this._textViewer.removeDecoration(lineNumber, "webkit-breakpoint-conditional"); - }, - _updateExecutionLine: function(previousLine) { if (previousLine) { @@ -395,7 +367,7 @@ WebInspector.SourceFrame.prototype = { } for (var i = 0; i < rowMessages.length; ++i) { - if (rowMessages[i].isEqual(msg, true)) { + if (rowMessages[i].isEqual(msg)) { this._incrementMessageRepeatCount(rowMessages[i], msg.repeatDelta); return; } @@ -429,41 +401,64 @@ WebInspector.SourceFrame.prototype = { msg._resourceMessageLineElement = messageLineElement; }, - _addExistingBreakpointsToSource: function() + _breakpointAdded: function(event) { - for (var i = 0; i < this.breakpoints.length; ++i) - this._addBreakpointToSource(this.breakpoints[i]); + var breakpoint = event.data; + + if (breakpoint.sourceID in this._scripts) + this._addBreakpoint(breakpoint); }, - _addBreakpointToSource: function(breakpoint) + _addBreakpoint: function(breakpoint) { + if (breakpoint.line > this._textModel.linesCount) + return; + breakpoint.addEventListener("enable-changed", this._breakpointChanged, this); breakpoint.addEventListener("condition-changed", this._breakpointChanged, this); + breakpoint.addEventListener("removed", this._breakpointRemoved, this); - var lineNumber = breakpoint.line - 1; - if (lineNumber >= this._textModel.linesCount) - return; - - this._textModel.setAttribute(lineNumber, "breakpoint", breakpoint); breakpoint.sourceText = this._textModel.line(breakpoint.line - 1); + this._setBreakpointDecoration(breakpoint.line, breakpoint.enabled, !!breakpoint.condition); + }, + + _breakpointRemoved: function(event) + { + var breakpoint = event.target; + + breakpoint.removeEventListener("enable-changed", null, this); + breakpoint.removeEventListener("condition-changed", null, this); + breakpoint.removeEventListener("removed", null, this); + this._removeBreakpointDecoration(breakpoint.line); + }, + + _breakpointChanged: function(event) + { + var breakpoint = event.target; + this._setBreakpointDecoration(breakpoint.line, breakpoint.enabled, !!breakpoint.condition); + }, + + _setBreakpointDecoration: function(lineNumber, enabled, hasCondition) + { + lineNumber -= 1; this._textViewer.beginUpdates(); this._textViewer.addDecoration(lineNumber, "webkit-breakpoint"); - if (!breakpoint.enabled) + if (enabled) + this._textViewer.removeDecoration(lineNumber, "webkit-breakpoint-disabled"); + else this._textViewer.addDecoration(lineNumber, "webkit-breakpoint-disabled"); - if (breakpoint.condition) + if (hasCondition) this._textViewer.addDecoration(lineNumber, "webkit-breakpoint-conditional"); + else + this._textViewer.removeDecoration(lineNumber, "webkit-breakpoint-conditional"); this._textViewer.endUpdates(); }, - _removeBreakpointFromSource: function(breakpoint) + _removeBreakpointDecoration: function(lineNumber) { - breakpoint.removeEventListener("enable-changed", null, this); - breakpoint.removeEventListener("condition-changed", null, this); - - var lineNumber = breakpoint.line - 1; + lineNumber -= 1; this._textViewer.beginUpdates(); - this._textModel.removeAttribute(lineNumber, "breakpoint"); this._textViewer.removeDecoration(lineNumber, "webkit-breakpoint"); this._textViewer.removeDecoration(lineNumber, "webkit-breakpoint-disabled"); this._textViewer.removeDecoration(lineNumber, "webkit-breakpoint-conditional"); @@ -472,41 +467,59 @@ WebInspector.SourceFrame.prototype = { _contextMenu: function(event) { - var target = event.target.enclosingNodeOrSelfWithClass("webkit-line-number"); - if (!target) + if (!WebInspector.panels.scripts) return; - var row = target.parentElement; - if (!WebInspector.panels.scripts) + var target = event.target.enclosingNodeOrSelfWithClass("webkit-line-number"); + if (!target) return; + var lineNumber = target.parentElement.lineNumber + 1; - var lineNumber = row.lineNumber; var contextMenu = new WebInspector.ContextMenu(); - contextMenu.appendItem(WebInspector.UIString("Continue to Here"), this._continueToHereDelegate.bind(this, lineNumber + 1)); + contextMenu.appendItem(WebInspector.UIString("Continue to Here"), this._continueToLine.bind(this, lineNumber)); - var breakpoint = this._textModel.getAttribute(lineNumber, "breakpoint"); + var breakpoint = this._findBreakpoint(lineNumber); if (!breakpoint) { // This row doesn't have a breakpoint: We want to show Add Breakpoint and Add and Edit Breakpoint. - contextMenu.appendItem(WebInspector.UIString("Add Breakpoint"), this._addBreakpointDelegate.bind(this, lineNumber + 1)); + contextMenu.appendItem(WebInspector.UIString("Add Breakpoint"), this._setBreakpoint.bind(this, lineNumber, "", true)); function addConditionalBreakpoint() { - this._addBreakpointDelegate(lineNumber + 1); - var breakpoint = this._textModel.getAttribute(lineNumber, "breakpoint"); - if (breakpoint) - this._editBreakpointCondition(breakpoint); + this._setBreakpointDecoration(lineNumber, true, true); + function didEditBreakpointCondition(committed, condition) + { + this._removeBreakpointDecoration(lineNumber); + if (committed) + this._setBreakpoint(lineNumber, true, condition); + } + this._editBreakpointCondition(lineNumber, "", didEditBreakpointCondition.bind(this)); } - contextMenu.appendItem(WebInspector.UIString("Add Conditional Breakpoint…"), addConditionalBreakpoint.bind(this)); } else { // This row has a breakpoint, we want to show edit and remove breakpoint, and either disable or enable. contextMenu.appendItem(WebInspector.UIString("Remove Breakpoint"), breakpoint.remove.bind(breakpoint)); - contextMenu.appendItem(WebInspector.UIString("Edit Breakpoint…"), this._editBreakpointCondition.bind(this, breakpoint)); + function editBreakpointCondition() + { + function didEditBreakpointCondition(committed, condition) + { + if (committed) { + breakpoint.remove(); + this._setBreakpoint(breakpoint.line, breakpoint.enabled, condition); + } + } + this._editBreakpointCondition(lineNumber, breakpoint.condition, didEditBreakpointCondition.bind(this)); + } + contextMenu.appendItem(WebInspector.UIString("Edit Breakpoint…"), editBreakpointCondition.bind(this)); + function setBreakpointEnabled(enabled) + { + breakpoint.remove(); + this._setBreakpoint(breakpoint.line, enabled, breakpoint.condition); + } if (breakpoint.enabled) - contextMenu.appendItem(WebInspector.UIString("Disable Breakpoint"), function() { breakpoint.enabled = false; }); + contextMenu.appendItem(WebInspector.UIString("Disable Breakpoint"), setBreakpointEnabled.bind(this, false)); else - contextMenu.appendItem(WebInspector.UIString("Enable Breakpoint"), function() { breakpoint.enabled = true; }); + contextMenu.appendItem(WebInspector.UIString("Enable Breakpoint"), setBreakpointEnabled.bind(this, true)); } contextMenu.show(event); }, @@ -525,18 +538,15 @@ WebInspector.SourceFrame.prototype = { var target = event.target.enclosingNodeOrSelfWithClass("webkit-line-number"); if (!target) return; - var row = target.parentElement; - - var lineNumber = row.lineNumber; + var lineNumber = target.parentElement.lineNumber + 1; - var breakpoint = this._textModel.getAttribute(lineNumber, "breakpoint"); + var breakpoint = this._findBreakpoint(lineNumber); if (breakpoint) { + breakpoint.remove(); if (event.shiftKey) - breakpoint.enabled = !breakpoint.enabled; - else - breakpoint.remove(); + this._setBreakpoint(breakpoint.line, !breakpoint.enabled, breakpoint.condition); } else - this._addBreakpointDelegate(lineNumber + 1); + this._setBreakpoint(lineNumber, true, ""); event.preventDefault(); }, @@ -698,38 +708,29 @@ WebInspector.SourceFrame.prototype = { WebInspector.panels.scripts.evaluateInSelectedCallFrame(element.textContent, false, this._popoverObjectGroup, evaluateCallback.bind(this)); }, - _editBreakpointCondition: function(breakpoint) + _editBreakpointCondition: function(lineNumber, condition, callback) { - this._showBreakpointConditionPopup(breakpoint.line); - - function committed(element, newText) - { - breakpoint.condition = newText; - dismissed.call(this); - } + lineNumber -= 1; + this._conditionElement = this._createConditionElement(lineNumber); + this._textViewer.addDecoration(lineNumber, this._conditionElement); - function dismissed() + function finishEditing(committed, element, newText) { - if (this._conditionElement) - this._textViewer.removeDecoration(breakpoint.line - 1, this._conditionElement); + this._textViewer.removeDecoration(lineNumber, this._conditionElement); delete this._conditionEditorElement; delete this._conditionElement; + callback(committed, newText); } - var dismissedHandler = dismissed.bind(this); - this._conditionEditorElement.addEventListener("blur", dismissedHandler, false); - - WebInspector.startEditing(this._conditionEditorElement, committed.bind(this), dismissedHandler); - this._conditionEditorElement.value = breakpoint.condition; + WebInspector.startEditing(this._conditionEditorElement, { + context: null, + commitHandler: finishEditing.bind(this, true), + cancelHandler: finishEditing.bind(this, false) + }); + this._conditionEditorElement.value = condition; this._conditionEditorElement.select(); }, - _showBreakpointConditionPopup: function(lineNumber) - { - this._conditionElement = this._createConditionElement(lineNumber); - this._textViewer.addDecoration(lineNumber - 1, this._conditionElement); - }, - _createConditionElement: function(lineNumber) { var conditionElement = document.createElement("div"); @@ -773,8 +774,96 @@ WebInspector.SourceFrame.prototype = { { if (this._textViewer) this._textViewer.resize(); + }, + + _continueToLine: function(lineNumber) + { + var sourceID = this._sourceIDForLine(lineNumber); + if (!sourceID) + return; + WebInspector.debuggerModel.continueToLine(sourceID, lineNumber); + }, + + _editLine: function(lineNumber, newContent, cancelEditingCallback) + { + lineNumber += 1; + + var lines = []; + for (var i = 0; i < this._textModel.linesCount; ++i) { + if (i === lineNumber - 1) + lines.push(newContent); + else + lines.push(this._textModel.line(i)); + } + + var editData = {}; + editData.sourceID = this._sourceIDForLine(lineNumber); + editData.content = lines.join("\n"); + editData.line = lineNumber; + editData.linesCountToShift = newContent.split("\n").length - 1; + this._doEditLine(editData, cancelEditingCallback); + }, + + _revertEditLine: function(editData, contentToRevertTo) + { + var newEditData = {}; + newEditData.sourceID = editData.sourceID; + newEditData.content = contentToRevertTo; + newEditData.line = editData.line; + newEditData.linesCountToShift = -editData.linesCountToShift; + this._doEditLine(newEditData); + }, + + _doEditLine: function(editData, cancelEditingCallback) + { + var revertEditingCallback = this._revertEditLine.bind(this, editData); + var commitEditingCallback = this._commitEditLine.bind(this, editData, revertEditingCallback); + WebInspector.panels.scripts.editScriptSource(editData, commitEditingCallback, cancelEditingCallback); + }, + + _commitEditLine: function(editData, revertEditLineCallback, newContent) + { + var script = this._scripts[editData.sourceID]; + script.source = newContent; + if (script.resource) + script.resource.setContent(newContent, revertEditLineCallback); + }, + + _setBreakpoint: function(lineNumber, enabled, condition) + { + var sourceID = this._sourceIDForLine(lineNumber); + if (!sourceID) + return; + WebInspector.debuggerModel.setBreakpoint(sourceID, lineNumber, enabled, condition); + if (!WebInspector.panels.scripts.breakpointsActivated) + WebInspector.panels.scripts.toggleBreakpointsClicked(); + }, + + _breakpoints: function() + { + var scripts = this._scripts; + return WebInspector.debuggerModel.queryBreakpoints(function(b) { return b.sourceID in scripts; }); + }, + + _findBreakpoint: function(lineNumber) + { + var sourceID = this._sourceIDForLine(lineNumber); + return WebInspector.debuggerModel.findBreakpoint(sourceID, lineNumber); + }, + + _sourceIDForLine: function(lineNumber) + { + var sourceIDForLine = null; + var closestStartingLine = 0; + for (var sourceID in this._scripts) { + var script = this._scripts[sourceID]; + if (script.startingLine <= lineNumber && script.startingLine >= closestStartingLine) { + closestStartingLine = script.startingLine; + sourceIDForLine = sourceID; + } + } + return sourceIDForLine; } } - WebInspector.SourceFrame.prototype.__proto__ = WebInspector.Object.prototype; diff --git a/WebCore/inspector/front-end/SourceView.js b/WebCore/inspector/front-end/SourceView.js index 9616321..7a97db2 100644 --- a/WebCore/inspector/front-end/SourceView.js +++ b/WebCore/inspector/front-end/SourceView.js @@ -32,8 +32,9 @@ WebInspector.SourceView = function(resource) this.element.addStyleClass("source"); - var canEditScripts = WebInspector.panels.scripts && WebInspector.panels.scripts.canEditScripts() && resource.type === WebInspector.Resource.Type.Script; - this.sourceFrame = new WebInspector.SourceFrame(this.element, this._addBreakpoint.bind(this), canEditScripts ? this._editLine.bind(this) : null, this._continueToLine.bind(this)); + var scripts = WebInspector.debuggerModel.scriptsForURL(resource.url); + var canEditScripts = WebInspector.panels.scripts.canEditScripts() && resource.type === WebInspector.Resource.Type.Script; + this.sourceFrame = new WebInspector.SourceFrame(this.element, scripts, canEditScripts); resource.addEventListener("finished", this._resourceLoadingFinished, this); this._frameNeedsSetup = true; } @@ -100,9 +101,6 @@ WebInspector.SourceView.prototype = { var mimeType = this._canonicalMimeType(this.resource); this.sourceFrame.setContent(mimeType, content, this.resource.url); this._sourceFrameSetupFinished(); - var breakpoints = WebInspector.breakpointManager.breakpointsForURL(this.resource.url); - for (var i = 0; i < breakpoints.length; ++i) - this.sourceFrame.addBreakpoint(breakpoints[i]); }, _canonicalMimeType: function(resource) @@ -119,73 +117,6 @@ WebInspector.SourceView.prototype = { this.resource.removeEventListener("finished", this._resourceLoadingFinished, this); }, - _continueToLine: function(line) - { - var scriptsPanel = WebInspector.panels.scripts; - if (scriptsPanel) { - var sourceID = this._sourceIDForLine(line); - scriptsPanel.continueToLine(sourceID, line); - } - }, - - _addBreakpoint: function(line) - { - var sourceID = this._sourceIDForLine(line); - WebInspector.breakpointManager.setBreakpoint(sourceID, this.resource.url, line, true, ""); - if (!WebInspector.panels.scripts.breakpointsActivated) - WebInspector.panels.scripts.toggleBreakpointsClicked(); - }, - - _editLine: function(line, newContent, cancelEditingCallback) - { - var lines = []; - var textModel = this.sourceFrame.textModel; - for (var i = 0; i < textModel.linesCount; ++i) { - if (i === line) - lines.push(newContent); - else - lines.push(textModel.line(i)); - } - - var editData = {}; - editData.sourceID = this._sourceIDForLine(line); - editData.content = lines.join("\n"); - editData.line = line; - editData.linesCountToShift = newContent.split("\n").length - 1; - - WebInspector.panels.scripts.editScriptSource(editData, this._editLineComplete.bind(this, editData), cancelEditingCallback); - }, - - _editLineComplete: function(editData, newContent) - { - this.resource.setContent(newContent, this._revertEditLine.bind(this, editData)); - }, - - _revertEditLine: function(editData, contentToRevertTo) - { - var newEditData = {}; - newEditData.sourceID = editData.sourceID; - newEditData.content = editData.content; - newEditData.line = editData.line; - newEditData.linesCountToShift = -editData.linesCountToShift; - WebInspector.panels.scripts.editScriptSource(newEditData, this._editLineComplete.bind(this, newEditData)); - }, - - _sourceIDForLine: function(line) - { - var sourceID = null; - var closestStartingLine = 0; - var scripts = this.resource.scripts; - for (var i = 0; i < scripts.length; ++i) { - var script = scripts[i]; - if (script.startingLine <= line && script.startingLine >= closestStartingLine) { - closestStartingLine = script.startingLine; - sourceID = script.sourceID; - } - } - return sourceID; - }, - // The rest of the methods in this prototype need to be generic enough to work with a ScriptView. // The ScriptView prototype pulls these methods into it's prototype to avoid duplicate code. diff --git a/WebCore/inspector/front-end/StylesSidebarPane.js b/WebCore/inspector/front-end/StylesSidebarPane.js index 5399953..c89e452 100644 --- a/WebCore/inspector/front-end/StylesSidebarPane.js +++ b/WebCore/inspector/front-end/StylesSidebarPane.js @@ -704,6 +704,26 @@ WebInspector.StylePropertiesSection.prototype = { return true; }, + nextEditableSibling: function() + { + var curSection = this; + do { + curSection = curSection.nextSibling; + } while (curSection && !curSection.editable); + + return curSection; + }, + + previousEditableSibling: function() + { + var curSection = this; + do { + curSection = curSection.previousSibling; + } while (curSection && !curSection.editable); + + return curSection; + }, + update: function(full) { if (full) { @@ -795,6 +815,7 @@ WebInspector.StylePropertiesSection.prototype = { this.propertiesTreeOutline.appendChild(item); item.listItemElement.textContent = ""; item._newProperty = true; + item.updateTitle(); return item; }, @@ -875,22 +896,35 @@ WebInspector.StylePropertiesSection.prototype = { if (WebInspector.isBeingEdited(element)) return; - WebInspector.startEditing(this._selectorElement, this.editingSelectorCommitted.bind(this), this.editingSelectorCancelled.bind(this), null); + WebInspector.startEditing(this._selectorElement, { + context: null, + commitHandler: this.editingSelectorCommitted.bind(this), + cancelHandler: this.editingSelectorCancelled.bind(this) + }); window.getSelection().setBaseAndExtent(element, 0, element, 1); }, editingSelectorCommitted: function(element, newContent, oldContent, context, moveDirection) { function moveToNextIfNeeded() { - if (!moveDirection || moveDirection !== "forward") + if (!moveDirection) return; - this.expand(); - if (this.propertiesTreeOutline.children.length === 0) - this.addNewBlankProperty().startEditing(); - else { - var item = this.propertiesTreeOutline.children[0] - item.startEditing(item.valueElement); + if (moveDirection === "forward") { + this.expand(); + if (this.propertiesTreeOutline.children.length === 0) + this.addNewBlankProperty().startEditing(); + else { + var item = this.propertiesTreeOutline.children[0] + item.startEditing(item.nameElement); + } + } else { + var previousSection = this.previousEditableSibling(); + if (!previousSection) + return; + + previousSection.expand(); + previousSection.addNewBlankProperty().startEditing(); } } @@ -1202,8 +1236,6 @@ WebInspector.StylePropertyTreeElement.prototype = { this.valueElement = valueElement; if (value) { - var self = this; - function processValue(regex, processor, nextProcessor, valueText) { var container = document.createDocumentFragment(); @@ -1227,19 +1259,10 @@ WebInspector.StylePropertyTreeElement.prototype = { function linkifyURL(url) { - var hrefUrl = url; - var match = hrefUrl.match(/['"]?([^'"]+)/); - if (match) - hrefUrl = match[1]; var container = document.createDocumentFragment(); container.appendChild(document.createTextNode("url(")); - if (self._styleRule.sourceURL) - hrefUrl = WebInspector.completeURL(self._styleRule.sourceURL, hrefUrl); - else if (WebInspector.panels.elements.focusedDOMNode) - hrefUrl = WebInspector.resourceURLForRelatedNode(WebInspector.panels.elements.focusedDOMNode, hrefUrl); - var hasResource = !!WebInspector.resourceForURL(hrefUrl); - // FIXME: WebInspector.linkifyURLAsNode() should really use baseURI. - container.appendChild(WebInspector.linkifyURLAsNode(hrefUrl, url, null, hasResource)); + var hasResource = !!WebInspector.resourceForURL(url); + container.appendChild(WebInspector.linkifyURLAsNode(url, url, null, hasResource)); container.appendChild(document.createTextNode(")")); return container; } @@ -1341,7 +1364,7 @@ WebInspector.StylePropertyTreeElement.prototype = { var colorRegex = /((?:rgb|hsl)a?\([^)]+\)|#[0-9a-fA-F]{6}|#[0-9a-fA-F]{3}|\b\w+\b(?!-))/g; var colorProcessor = processValue.bind(window, colorRegex, processColor, null); - valueElement.appendChild(processValue(/url\(\s*([^)\s]+)\s*\)/g, linkifyURL, colorProcessor, value)); + valueElement.appendChild(processValue(/url\(([^)]+)\)/g, linkifyURL, colorProcessor, value)); } this.listItemElement.removeChildren(); @@ -1357,8 +1380,11 @@ WebInspector.StylePropertyTreeElement.prototype = { this.listItemElement.appendChild(valueElement); this.listItemElement.appendChild(document.createTextNode(";")); - if (!this.parsedOk) + if (!this.parsedOk) { + // Avoid having longhands under an invalid shorthand. + this.hasChildren = false; this.listItemElement.addStyleClass("not-parsed-ok"); + } if (this.property.inactive) this.listItemElement.addStyleClass("inactive"); @@ -1471,60 +1497,147 @@ WebInspector.StylePropertyTreeElement.prototype = { if (this.parent.shorthand) return; - if (WebInspector.isBeingEdited(this.listItemElement) || (this.treeOutline.section && !this.treeOutline.section.editable)) + if (this.treeOutline.section && !this.treeOutline.section.editable) + return; + + if (!selectElement) + selectElement = this.nameElement; // No arguments passed in - edit the name element by default. + else + selectElement = selectElement.enclosingNodeOrSelfWithClass("webkit-css-property") || selectElement.enclosingNodeOrSelfWithClass("value"); + + var isEditingName = selectElement === this.nameElement; + if (!isEditingName && selectElement !== this.valueElement) { + // Double-click in the LI - start editing value. + isEditingName = false; + selectElement = this.valueElement; + } + + if (WebInspector.isBeingEdited(selectElement)) return; var context = { expanded: this.expanded, hasChildren: this.hasChildren, - keyDownListener: this.editingKeyDown.bind(this), - keyPressListener: this.editingKeyPress.bind(this) + keyDownListener: isEditingName ? this.editingNameKeyDown.bind(this) : this.editingValueKeyDown.bind(this), + keyPressListener: isEditingName ? this.editingNameKeyPress.bind(this) : this.editingValueKeyPress.bind(this), + isEditingName: isEditingName, }; // Lie about our children to prevent expanding on double click and to collapse shorthands. this.hasChildren = false; - if (!selectElement) - selectElement = this.listItemElement; + selectElement.addEventListener("keydown", context.keyDownListener, false); + selectElement.addEventListener("keypress", context.keyPressListener, false); + if (selectElement.parentElement) + selectElement.parentElement.addStyleClass("child-editing"); + selectElement.textContent = selectElement.textContent; // remove color swatch and the like + + function shouldCommitValueSemicolon(text, cursorPosition) + { + // FIXME: should this account for semicolons inside comments? + var openQuote = ""; + for (var i = 0; i < cursorPosition; ++i) { + var ch = text[i]; + if (ch === "\\" && openQuote !== "") + ++i; // skip next character inside string + else if (!openQuote && (ch === "\"" || ch === "'")) + openQuote = ch; + else if (openQuote === ch) + openQuote = ""; + } + return !openQuote; + } - this.listItemElement.addEventListener("keydown", context.keyDownListener, false); - this.listItemElement.addEventListener("keypress", context.keyPressListener, false); + function nameValueFinishHandler(context, isEditingName, event) + { + // FIXME: the ":"/";" detection does not work for non-US layouts due to the event being keydown rather than keypress. + var isFieldInputTerminated = (event.keyCode === WebInspector.KeyboardShortcut.Keys.Semicolon.code) && + (isEditingName ? event.shiftKey : (!event.shiftKey && shouldCommitValueSemicolon(event.target.textContent, event.target.selectionLeftOffset))); + if (isEnterKey(event) || isFieldInputTerminated) { + // Enter or colon (for name)/semicolon outside of string (for value). + event.preventDefault(); + return "move-forward"; + } else if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code) + return "cancel"; + else if (event.keyIdentifier === "U+0009") // Tab key. + return "move-" + (event.shiftKey ? "backward" : "forward"); + } - WebInspector.startEditing(this.listItemElement, this.editingCommitted.bind(this), this.editingCancelled.bind(this), context); + WebInspector.startEditing(selectElement, { + context: context, + commitHandler: this.editingCommitted.bind(this), + cancelHandler: this.editingCancelled.bind(this), + customFinishHandler: nameValueFinishHandler.bind(this, context, isEditingName) + }); window.getSelection().setBaseAndExtent(selectElement, 0, selectElement, 1); }, - editingKeyPress: function(event) + editingNameKeyPress: function(event) { - var selection = window.getSelection(); - var colonIndex = this.listItemElement.textContent.indexOf(":"); - var selectionLeftOffset = event.target.selectionLeftOffset; - - if (colonIndex < 0 || selectionLeftOffset <= colonIndex) { - // Complete property names. - var character = event.data.toLowerCase(); - if (character && /[a-z-]/.test(character)) { - var prefix = selection.anchorNode.textContent.substring(0, selection.anchorOffset); - var property = WebInspector.CSSCompletions.firstStartsWith(prefix + character); - - if (!selection.isCollapsed) - selection.deleteFromDocument(); - - this.restoreNameElement(); - - if (property) { - if (property !== this.nameElement.textContent) - this.nameElement.textContent = property; - this.nameElement.firstChild.select(prefix.length + 1); - event.preventDefault(); - } + // Complete property names. + var character = event.data.toLowerCase(); + if (character && /[a-z-]/.test(character)) { + var selection = window.getSelection(); + var prefix = selection.anchorNode.textContent.substring(0, selection.anchorOffset); + var property = WebInspector.cssNameCompletions.firstStartsWith(prefix + character); + + if (!selection.isCollapsed) + selection.deleteFromDocument(); + + this.restoreNameElement(); + + if (property) { + if (property !== this.nameElement.textContent) + this.nameElement.textContent = property; + this.nameElement.firstChild.select(prefix.length + 1); + event.preventDefault(); } - } else { - // FIXME: This should complete property values. } }, - editingKeyDown: function(event) + editingValueKeyPress: function(event) + { + // FIXME: This should complete property values. + }, + + editingNameKeyDown: function(event) + { + var showNext; + if (event.keyIdentifier === "Up") + showNext = false; + else if (event.keyIdentifier === "Down") + showNext = true; + else + return; + + var selection = window.getSelection(); + if (!selection.rangeCount) + return; + + var selectionRange = selection.getRangeAt(0); + if (selectionRange.commonAncestorContainer !== this.nameElement && !selectionRange.commonAncestorContainer.isDescendant(this.nameElement)) + return; + + const styleValueDelimeters = " \t\n\"':;,/()"; + var wordRange = selectionRange.startContainer.rangeOfWord(selectionRange.startOffset, styleValueDelimeters, this.nameElement); + var wordString = wordRange.toString(); + var cursorPosition = selectionRange.startOffset != selectionRange.endOffset ? selectionRange.startOffset : 0; + var prefix = selectionRange.startContainer.textContent.substring(0, cursorPosition); + var property; + + if (showNext) + property = WebInspector.cssNameCompletions.next(wordString, prefix); + else + property = WebInspector.cssNameCompletions.previous(wordString, prefix); + + if (property) { + this.nameElement.textContent = property; + this.nameElement.firstChild.select(cursorPosition); + } + event.preventDefault(); + }, + + editingValueKeyDown: function(event) { var arrowKeyPressed = (event.keyIdentifier === "Up" || event.keyIdentifier === "Down"); var pageKeyPressed = (event.keyIdentifier === "PageUp" || event.keyIdentifier === "PageDown"); @@ -1536,33 +1649,11 @@ WebInspector.StylePropertyTreeElement.prototype = { return; var selectionRange = selection.getRangeAt(0); - if (selectionRange.commonAncestorContainer !== this.listItemElement && !selectionRange.commonAncestorContainer.isDescendant(this.listItemElement)) + if (selectionRange.commonAncestorContainer !== this.valueElement && !selectionRange.commonAncestorContainer.isDescendant(this.valueElement)) return; - // If there are several properties in the text, do not handle increments/decrements. - var text = event.target.textContent.trim(); - var openQuote; - var wasEscape = false; - // Exclude the last character from the check since it is allowed to be ";". - for (var i = 0; i < text.length - 1; ++i) { - var ch = text.charAt(i); - if (ch === "\\") { - wasEscape = true; - continue; - } - if (ch === ";" && !openQuote) - return; // Do not handle name/value shifts if the property is compound. - if ((ch === "'" || ch === "\"") && !wasEscape) { - if (!openQuote) - openQuote = ch; - else if (ch === openQuote) - openQuote = null; - } - wasEscape = false; - } - const styleValueDelimeters = " \t\n\"':;,/()"; - var wordRange = selectionRange.startContainer.rangeOfWord(selectionRange.startOffset, styleValueDelimeters, this.listItemElement); + var wordRange = selectionRange.startContainer.rangeOfWord(selectionRange.startOffset, styleValueDelimeters, this.valueElement); var wordString = wordRange.toString(); var replacementString = wordString; @@ -1604,22 +1695,6 @@ WebInspector.StylePropertyTreeElement.prototype = { } replacementString = prefix + number + suffix; - } else if (selection.containsNode(this.nameElement, true)) { - var prefix = selectionRange.startContainer.textContent.substring(0, selectionRange.startOffset); - var property; - - if (event.keyIdentifier === "Up") - property = WebInspector.CSSCompletions.previous(wordString, prefix); - else if (event.keyIdentifier === "Down") - property = WebInspector.CSSCompletions.next(wordString, prefix); - - var startOffset = selectionRange.startOffset; - if (property) { - this.nameElement.textContent = property; - this.nameElement.firstChild.select(startOffset); - } - event.preventDefault(); - return; } else { // FIXME: this should cycle through known keywords for the current property value. } @@ -1643,7 +1718,9 @@ WebInspector.StylePropertyTreeElement.prototype = { // if the editing is canceled and before each apply. this.originalPropertyText = this.property.propertyText; } - this.applyStyleText(this.listItemElement.textContent); + + // Synthesize property text disregarding any comments, custom whitespace etc. + this.applyStyleText(this.nameElement.textContent + ": " + this.valueElement.textContent); }, editingEnded: function(context) @@ -1651,8 +1728,12 @@ WebInspector.StylePropertyTreeElement.prototype = { this.hasChildren = context.hasChildren; if (context.expanded) this.expand(); - this.listItemElement.removeEventListener("keydown", context.keyDownListener, false); - this.listItemElement.removeEventListener("keypress", context.keyPressListener, false); + var editedElement = context.isEditingName ? this.nameElement : this.valueElement; + editedElement.removeEventListener("keydown", context.keyDownListener, false); + editedElement.removeEventListener("keypress", context.keyPressListener, false); + if (editedElement.parentElement) + editedElement.parentElement.removeStyleClass("child-editing"); + delete this.originalPropertyText; }, @@ -1672,61 +1753,96 @@ WebInspector.StylePropertyTreeElement.prototype = { editingCommitted: function(element, userInput, previousContent, context, moveDirection) { this.editingEnded(context); + var isEditingName = context.isEditingName; // Determine where to move to before making changes - var newProperty, moveToPropertyName, moveToSelector; + var createNewProperty, moveToPropertyName, moveToSelector; var moveTo = this; - do { - moveTo = (moveDirection === "forward" ? moveTo.nextSibling : moveTo.previousSibling); - } while(moveTo && !moveTo.selectable); - - if (moveTo) - moveToPropertyName = moveTo.name; - else if (moveDirection === "forward") - newProperty = true; - else if (moveDirection === "backward" && this.treeOutline.section.rule) - moveToSelector = true; + var moveToOther = (isEditingName ^ (moveDirection === "forward")); + var abandonNewProperty = this._newProperty && !userInput && (moveToOther || isEditingName); + if (moveDirection === "forward" && !isEditingName || moveDirection === "backward" && isEditingName) { + do { + moveTo = (moveDirection === "forward" ? moveTo.nextSibling : moveTo.previousSibling); + } while(moveTo && !moveTo.selectable); + + if (moveTo) + moveToPropertyName = moveTo.name; + else if (moveDirection === "forward" && (!this._newProperty || userInput)) + createNewProperty = true; + else if (moveDirection === "backward" && this.treeOutline.section.rule) + moveToSelector = true; + } - // Make the Changes and trigger the moveToNextCallback after updating + // Make the Changes and trigger the moveToNextCallback after updating. var blankInput = /^\s*$/.test(userInput); - if (userInput !== previousContent || (this._newProperty && blankInput)) { // only if something changed, or adding a new style and it was blank - this.treeOutline.section._afterUpdate = moveToNextCallback.bind(this, this._newProperty, !blankInput); - this.applyStyleText(userInput, true); - } else - moveToNextCallback(this._newProperty, false, this.treeOutline.section, false); + var shouldCommitNewProperty = this._newProperty && (moveToOther || (!moveDirection && !isEditingName) || (isEditingName && blankInput)); - // The Callback to start editing the next property + if ((userInput !== previousContent && !this._newProperty) || shouldCommitNewProperty) { + this.treeOutline.section._afterUpdate = moveToNextCallback.bind(this, this._newProperty, !blankInput, this.treeOutline.section); + var propertyText; + if (blankInput || (this._newProperty && /^\s*$/.test(this.valueElement.textContent))) + propertyText = ""; + else { + if (isEditingName) + propertyText = userInput + ": " + this.valueElement.textContent; + else + propertyText = this.nameElement.textContent + ": " + userInput; + } + this.applyStyleText(propertyText, true); + } else { + if (!this._newProperty) + this.updateTitle(); + moveToNextCallback(this._newProperty, false, this.treeOutline.section); + } + + var moveToIndex = moveTo && this.treeOutline ? this.treeOutline.children.indexOf(moveTo) : -1; + + // The Callback to start editing the next/previous property/selector. function moveToNextCallback(alreadyNew, valueChanged, section) { if (!moveDirection) return; - // User just tabbed through without changes + // User just tabbed through without changes. if (moveTo && moveTo.parent) { - moveTo.startEditing(moveTo.valueElement); + moveTo.startEditing(!isEditingName ? moveTo.nameElement : moveTo.valueElement); return; } - // User has made a change then tabbed, wiping all the original treeElements, - // recalculate the new treeElement for the same property we were going to edit next - // FIXME(apavlov): this will not work for multiple same-named properties in a style - // (the first one will always be returned). + // User has made a change then tabbed, wiping all the original treeElements. + // Recalculate the new treeElement for the same property we were going to edit next. if (moveTo && !moveTo.parent) { - var treeElement = section.findTreeElementWithName(moveToPropertyName); - if (treeElement) - treeElement.startEditing(treeElement.valueElement); - return; + var propertyElements = section.propertiesTreeOutline.children; + if (moveDirection === "forward" && blankInput && !isEditingName) + --moveToIndex; + if (moveToIndex >= propertyElements.length && !this._newProperty) + createNewProperty = true; + else { + var treeElement = moveToIndex >= 0 ? propertyElements[moveToIndex] : null; + if (treeElement) { + treeElement.startEditing(!isEditingName ? treeElement.nameElement : treeElement.valueElement); + return; + } else if (!alreadyNew) + moveToSelector = true; + } } - // Create a new attribute in this section - if (newProperty) { - if (alreadyNew && !valueChanged) + // Create a new attribute in this section (or move to next editable selector if possible). + if (createNewProperty) { + if (alreadyNew && !valueChanged && (isEditingName ^ (moveDirection === "backward"))) return; section.addNewBlankProperty().startEditing(); return; } + if (abandonNewProperty) { + var sectionToEdit = moveDirection === "backward" ? section : section.nextEditableSibling(); + if (sectionToEdit && sectionToEdit.rule) + sectionToEdit.startEditingSelector(); + return; + } + if (moveToSelector) section.startEditingSelector(); } @@ -1736,16 +1852,13 @@ WebInspector.StylePropertyTreeElement.prototype = { { var section = this.treeOutline.section; var elementsPanel = WebInspector.panels.elements; - styleText = styleText.replace(/\s/g, " ").trim(); // replace with whitespace. + styleText = styleText.replace(/\s/g, " ").trim(); // Replace with whitespace. var styleTextLength = styleText.length; - if (!styleTextLength && updateInterface) { - if (this._newProperty) { - // The user deleted everything, so remove the tree element and update. - this.parent.removeChild(this); - section.afterUpdate(); - return; - } else - delete section._afterUpdate; + if (!styleTextLength && updateInterface && this._newProperty) { + // The user deleted everything, so remove the tree element and update. + this.parent.removeChild(this); + section.afterUpdate(); + return; } function callback(newStyle) diff --git a/WebCore/inspector/front-end/TextPrompt.js b/WebCore/inspector/front-end/TextPrompt.js index e9a73fe..21a5bde 100644 --- a/WebCore/inspector/front-end/TextPrompt.js +++ b/WebCore/inspector/front-end/TextPrompt.js @@ -419,7 +419,7 @@ WebInspector.TextPrompt.prototype = { ++this.historyOffset; this.text = this.history[this.history.length - this.historyOffset]; - this.element.scrollIntoViewIfNeeded(); + this.element.scrollIntoView(true); var firstNewlineIndex = this.text.indexOf("\n"); if (firstNewlineIndex === -1) this.moveCaretToEndOfPrompt(); @@ -451,6 +451,6 @@ WebInspector.TextPrompt.prototype = { } this.text = this.history[this.history.length - this.historyOffset]; - this.element.scrollIntoViewIfNeeded(); + this.element.scrollIntoView(); } } diff --git a/WebCore/inspector/front-end/TextViewer.js b/WebCore/inspector/front-end/TextViewer.js index 9ad5e49..f116dea 100644 --- a/WebCore/inspector/front-end/TextViewer.js +++ b/WebCore/inspector/front-end/TextViewer.js @@ -268,7 +268,12 @@ WebInspector.TextViewer.prototype = { var oldContent = lineRow.lastChild.innerHTML; var cancelEditingCallback = this._cancelEditingLine.bind(this, lineRow.lastChild, oldContent); var commitEditingCallback = this._commitEditingLine.bind(this, lineRow.lineNumber, lineRow.lastChild, cancelEditingCallback); - this._editingLine = WebInspector.startEditing(lineRow.lastChild, commitEditingCallback, cancelEditingCallback, null, true); + this._editingLine = WebInspector.startEditing(lineRow.lastChild, { + context: null, + commitHandler: commitEditingCallback, + cancelHandler: cancelEditingCallback, + multiline: true + }); }, _commitEditingLine: function(lineNumber, element, cancelEditingCallback) diff --git a/WebCore/inspector/front-end/TimelineAgent.js b/WebCore/inspector/front-end/TimelineAgent.js index d44c2d0..97b8e42 100644 --- a/WebCore/inspector/front-end/TimelineAgent.js +++ b/WebCore/inspector/front-end/TimelineAgent.js @@ -56,18 +56,3 @@ WebInspector.TimelineAgent.RecordType = { MarkLoadEventType : 19, ScheduleResourceRequest : 20 }; - -WebInspector.addRecordToTimeline = function(record) { - if (WebInspector.panels.timeline) - WebInspector.panels.timeline.addRecordToTimeline(record); -} - -WebInspector.timelineProfilerWasStarted = function() { - if (WebInspector.panels.timeline) - WebInspector.panels.timeline.timelineWasStarted(); -} - -WebInspector.timelineProfilerWasStopped = function() { - if (WebInspector.panels.timeline) - WebInspector.panels.timeline.timelineWasStopped(); -} diff --git a/WebCore/inspector/front-end/TimelinePanel.js b/WebCore/inspector/front-end/TimelinePanel.js index 8900d8d..a661b75 100644 --- a/WebCore/inspector/front-end/TimelinePanel.js +++ b/WebCore/inspector/front-end/TimelinePanel.js @@ -98,6 +98,8 @@ WebInspector.TimelinePanel = function() this._calculator._showShortEvents = this.toggleFilterButton.toggled; this._markTimelineRecords = []; this._expandOffset = 15; + + InspectorBackend.registerDomainDispatcher("Timeline", this); } // Define row height, should be in sync with styles for timeline graphs. @@ -283,12 +285,12 @@ WebInspector.TimelinePanel.prototype = { this._scheduleRefresh(true); }, - timelineWasStarted: function() + timelineProfilerWasStarted: function() { this.toggleTimelineButton.toggled = true; }, - timelineWasStopped: function() + timelineProfilerWasStopped: function() { this.toggleTimelineButton.toggled = false; }, @@ -961,7 +963,7 @@ WebInspector.TimelinePanel.FormattedRecord.prototype = { contentHelper._appendLinkRow(WebInspector.UIString("Script"), this.data.url, this.data.lineNumber); break; case recordTypes.Paint: - contentHelper._appendTextRow(WebInspector.UIString("Location"), WebInspector.UIString("%d × %d", this.data.x, this.data.y)); + contentHelper._appendTextRow(WebInspector.UIString("Location"), WebInspector.UIString("(%d, %d)", this.data.x, this.data.y)); contentHelper._appendTextRow(WebInspector.UIString("Dimensions"), WebInspector.UIString("%d × %d", this.data.width, this.data.height)); case recordTypes.RecalculateStyles: // We don't want to see default details. break; diff --git a/WebCore/inspector/front-end/WatchExpressionsSidebarPane.js b/WebCore/inspector/front-end/WatchExpressionsSidebarPane.js index 44063a3..a01046b 100644 --- a/WebCore/inspector/front-end/WatchExpressionsSidebarPane.js +++ b/WebCore/inspector/front-end/WatchExpressionsSidebarPane.js @@ -240,7 +240,11 @@ WebInspector.WatchExpressionTreeElement.prototype = { this.listItemElement.addStyleClass("editing-sub-part"); - WebInspector.startEditing(this.nameElement, this.editingCommitted.bind(this), this.editingCancelled.bind(this), context); + WebInspector.startEditing(this.nameElement, { + context: context, + commitHandler: this.editingCommitted.bind(this), + cancelHandler: this.editingCancelled.bind(this) + }); }, editingCancelled: function(element, context) diff --git a/WebCore/inspector/front-end/WebKit.qrc b/WebCore/inspector/front-end/WebKit.qrc index 2db0182..90c4317 100644 --- a/WebCore/inspector/front-end/WebKit.qrc +++ b/WebCore/inspector/front-end/WebKit.qrc @@ -9,9 +9,9 @@ <file>AuditRules.js</file> <file>AuditsPanel.js</file> <file>BottomUpProfileDataGridTree.js</file> + <file>Breakpoint.js</file> <file>BreakpointManager.js</file> <file>BreakpointsSidebarPane.js</file> - <file>Callback.js</file> <file>CallStackSidebarPane.js</file> <file>ChangesView.js</file> <file>Checkbox.js</file> @@ -28,6 +28,7 @@ <file>DatabaseQueryView.js</file> <file>DatabaseTableView.js</file> <file>DataGrid.js</file> + <file>DebuggerModel.js</file> <file>DOMAgent.js</file> <file>DOMStorage.js</file> <file>DOMStorageItemsView.js</file> diff --git a/WebCore/inspector/front-end/WorkersSidebarPane.js b/WebCore/inspector/front-end/WorkersSidebarPane.js index 658d57c..b254f3c 100644 --- a/WebCore/inspector/front-end/WorkersSidebarPane.js +++ b/WebCore/inspector/front-end/WorkersSidebarPane.js @@ -100,15 +100,3 @@ WebInspector.Worker = function(id, url, shared) this.url = url; this.shared = shared; } - -WebInspector.didCreateWorker = function() -{ - var workersPane = WebInspector.panels.scripts.sidebarPanes.workers; - workersPane.addWorker.apply(workersPane, arguments); -} - -WebInspector.didDestroyWorker = function() -{ - var workersPane = WebInspector.panels.scripts.sidebarPanes.workers; - workersPane.removeWorker.apply(workersPane, arguments); -} diff --git a/WebCore/inspector/front-end/inspector.css b/WebCore/inspector/front-end/inspector.css index 965689b..c908427 100644 --- a/WebCore/inspector/front-end/inspector.css +++ b/WebCore/inspector/front-end/inspector.css @@ -1424,6 +1424,12 @@ body.inactive .placard.selected { text-decoration: none !important; } +.child-editing { + color: black !important; + text-decoration: none !important; + overflow: visible !important; +} + .editing br { display: none; } diff --git a/WebCore/inspector/front-end/inspector.html b/WebCore/inspector/front-end/inspector.html index 67fd081..9ed5019 100644 --- a/WebCore/inspector/front-end/inspector.html +++ b/WebCore/inspector/front-end/inspector.html @@ -55,7 +55,6 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. <script type="text/javascript" src="TabbedPane.js"></script> <script type="text/javascript" src="Placard.js"></script> <script type="text/javascript" src="View.js"></script> - <script type="text/javascript" src="Callback.js"></script> <script type="text/javascript" src="Drawer.js"></script> <script type="text/javascript" src="ChangesView.js"></script> <script type="text/javascript" src="ConsoleView.js"></script> @@ -73,6 +72,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. <script type="text/javascript" src="ApplicationCacheItemsView.js"></script> <script type="text/javascript" src="FileSystemView.js"></script> <script type="text/javascript" src="Script.js"></script> + <script type="text/javascript" src="Breakpoint.js"></script> <script type="text/javascript" src="BreakpointManager.js"></script> <script type="text/javascript" src="SidebarPane.js"></script> <script type="text/javascript" src="ElementsTreeOutline.js"></script> @@ -139,6 +139,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. <script type="text/javascript" src="TopDownProfileDataGridTree.js"></script> <script type="text/javascript" src="ProfileView.js"></script> <script type="text/javascript" src="HeapSnapshotView.js"></script> + <script type="text/javascript" src="DebuggerModel.js"></script> <script type="text/javascript" src="DOMAgent.js"></script> <script type="text/javascript" src="InjectedScript.js"></script> <script type="text/javascript" src="InjectedScriptAccess.js"></script> diff --git a/WebCore/inspector/front-end/inspector.js b/WebCore/inspector/front-end/inspector.js index 212f41a..a57f0f4 100644 --- a/WebCore/inspector/front-end/inspector.js +++ b/WebCore/inspector/front-end/inspector.js @@ -192,7 +192,7 @@ var WebInspector = { { pane.addBreakpointItem(new WebInspector.BreakpointItem(event.data)); } - WebInspector.breakpointManager.addEventListener("breakpoint-added", breakpointAdded); + WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointAdded, breakpointAdded); return pane; }, @@ -203,7 +203,7 @@ var WebInspector = { { pane.addBreakpointItem(new WebInspector.BreakpointItem(event.data)); } - WebInspector.breakpointManager.addEventListener("dom-breakpoint-added", breakpointAdded); + WebInspector.breakpointManager.addEventListener(WebInspector.BreakpointManager.Events.DOMBreakpointAdded, breakpointAdded); return pane; }, @@ -214,7 +214,7 @@ var WebInspector = { { pane.addBreakpointItem(new WebInspector.BreakpointItem(event.data)); } - WebInspector.breakpointManager.addEventListener("xhr-breakpoint-added", breakpointAdded); + WebInspector.breakpointManager.addEventListener(WebInspector.BreakpointManager.Events.XHRBreakpointAdded, breakpointAdded); return pane; }, @@ -478,7 +478,7 @@ WebInspector.loaded = function() { if ("page" in WebInspector.queryParamsObject) { WebInspector.socket = new WebSocket("ws://" + window.location.host + "/devtools/page/" + WebInspector.queryParamsObject.page); - WebInspector.socket.onmessage = function(message) { WebInspector_syncDispatch(message.data); } + WebInspector.socket.onmessage = function(message) { InspectorBackend.dispatch(message.data); } WebInspector.socket.onerror = function(error) { console.error(error); } WebInspector.socket.onopen = function() { InspectorFrontendHost.sendMessageToBackend = WebInspector.socket.send.bind(WebInspector.socket); @@ -520,6 +520,8 @@ WebInspector.doLoadedDone = function() this.resourceManager = new WebInspector.ResourceManager(); this.domAgent = new WebInspector.DOMAgent(); + InspectorBackend.registerDomainDispatcher("Inspector", this); + this.resourceCategories = { documents: new WebInspector.ResourceCategory("documents", WebInspector.UIString("Documents"), "rgb(47,102,236)"), stylesheets: new WebInspector.ResourceCategory("stylesheets", WebInspector.UIString("Stylesheets"), "rgb(157,231,119)"), @@ -531,8 +533,10 @@ WebInspector.doLoadedDone = function() other: new WebInspector.ResourceCategory("other", WebInspector.UIString("Other"), "rgb(186,186,186)") }; - this.breakpointManager = new WebInspector.BreakpointManager(); this.cssModel = new WebInspector.CSSStyleModel(); + this.debuggerModel = new WebInspector.DebuggerModel(); + + this.breakpointManager = new WebInspector.BreakpointManager(); this.panels = {}; this._createPanels(); @@ -609,8 +613,13 @@ WebInspector.doLoadedDone = function() InspectorBackend.setConsoleMessagesEnabled(true); + function propertyNamesCallback(names) + { + WebInspector.cssNameCompletions = new WebInspector.CSSCompletions(names); + } + // As a DOMAgent method, this needs to happen after the frontend has loaded and the agent is available. - InspectorBackend.getSupportedCSSProperties(WebInspector.CSSCompletions._load); + InspectorBackend.getSupportedCSSProperties(propertyNamesCallback); } WebInspector.addPanelToolbarIcon = function(toolbarElement, panel, previousToolbarItem) @@ -648,58 +657,18 @@ WebInspector.dispatch = function(message) { // This is important to LayoutTests. function delayDispatch() { - WebInspector_syncDispatch(message); + InspectorBackend.dispatch(message); WebInspector.pendingDispatches--; } WebInspector.pendingDispatches++; setTimeout(delayDispatch, 0); } -// This function is purposely put into the global scope for easy access. -WebInspector_syncDispatch = function(message) -{ - if (window.dumpInspectorProtocolMessages) - console.log("backend: " + ((typeof message === "string") ? message : JSON.stringify(message))); - - var messageObject = (typeof message === "string") ? JSON.parse(message) : message; - - var arguments = []; - if (messageObject.data) - for (var key in messageObject.data) - arguments.push(messageObject.data[key]); - - if ("seq" in messageObject) { // just a response for some request - if (messageObject.success) - WebInspector.processResponse(messageObject.seq, arguments); - else { - WebInspector.removeResponseCallbackEntry(messageObject.seq) - WebInspector.reportProtocolError(messageObject); - } - return; - } - - if (messageObject.type === "event") { - if (!(messageObject.event in WebInspector)) { - console.error("Protocol Error: Attempted to dispatch an unimplemented WebInspector method '%s'", messageObject.event); - return; - } - WebInspector[messageObject.event].apply(WebInspector, arguments); - } -} - WebInspector.dispatchMessageFromBackend = function(messageObject) { WebInspector.dispatch(messageObject); } -WebInspector.reportProtocolError = function(messageObject) -{ - console.error("Protocol Error: InspectorBackend request with seq = %d failed.", messageObject.seq); - for (var i = 0; i < messageObject.errors.length; ++i) - console.error(" " + messageObject.errors[i]); - WebInspector.removeResponseCallbackEntry(messageObject.seq); -} - WebInspector.windowResize = function(event) { if (this.currentPanel) @@ -1205,23 +1174,11 @@ WebInspector.showPanel = function(panel) this.currentPanel = this.panels[panel]; } -WebInspector.selectDatabase = function(o) -{ - WebInspector.showPanel("resources"); - WebInspector.panels.resources.selectDatabase(o); -} - WebInspector.consoleMessagesCleared = function() { WebInspector.console.clearMessages(); } -WebInspector.selectDOMStorage = function(o) -{ - WebInspector.showPanel("resources"); - WebInspector.panels.resources.selectDOMStorage(o); -} - WebInspector.domContentEventFired = function(time) { this.panels.audits.mainResourceDOMContentTime = time; @@ -1240,59 +1197,6 @@ WebInspector.loadEventFired = function(time) this.mainResourceLoadTime = time; } -WebInspector.addDatabase = function(payload) -{ - if (!this.panels.resources) - return; - var database = new WebInspector.Database( - payload.id, - payload.domain, - payload.name, - payload.version); - this.panels.resources.addDatabase(database); -} - -WebInspector.addDOMStorage = function(payload) -{ - if (!this.panels.resources) - return; - var domStorage = new WebInspector.DOMStorage( - payload.id, - payload.host, - payload.isLocalStorage); - this.panels.resources.addDOMStorage(domStorage); -} - -WebInspector.updateDOMStorage = function(storageId) -{ - this.panels.resources.updateDOMStorage(storageId); -} - -WebInspector.updateApplicationCacheStatus = function(status) -{ - this.panels.resources.updateApplicationCacheStatus(status); -} - -WebInspector.didGetFileSystemPath = function(root, type, origin) -{ - this.panels.resources.updateFileSystemPath(root, type, origin); -} - -WebInspector.didGetFileSystemError = function(type, origin) -{ - this.panels.resources.updateFileSystemError(type, origin); -} - -WebInspector.didGetFileSystemDisabled = function() -{ - this.panels.resources.setFileSystemDisabled(); -} - -WebInspector.updateNetworkState = function(isNowOnline) -{ - this.panels.resources.updateNetworkState(isNowOnline); -} - WebInspector.searchingForNodeWasEnabled = function() { this.panels.elements.searchingForNodeWasEnabled(); @@ -1303,62 +1207,9 @@ WebInspector.searchingForNodeWasDisabled = function() this.panels.elements.searchingForNodeWasDisabled(); } -WebInspector.attachDebuggerWhenShown = function() -{ - this.panels.scripts.attachDebuggerWhenShown(); -} - -WebInspector.debuggerWasEnabled = function() -{ - this.panels.scripts.debuggerWasEnabled(); -} - -WebInspector.debuggerWasDisabled = function() -{ - this.panels.scripts.debuggerWasDisabled(); -} - -WebInspector.profilerWasEnabled = function() -{ - this.panels.profiles.profilerWasEnabled(); -} - -WebInspector.profilerWasDisabled = function() -{ - this.panels.profiles.profilerWasDisabled(); -} - -WebInspector.parsedScriptSource = function(sourceID, sourceURL, source, startingLine, scriptWorldType) -{ - this.panels.scripts.addScript(sourceID, sourceURL, source, startingLine, undefined, undefined, scriptWorldType); -} - -WebInspector.restoredBreakpoint = function(sourceID, sourceURL, line, enabled, condition) -{ - this.breakpointManager.restoredBreakpoint(sourceID, sourceURL, line, enabled, condition); -} - -WebInspector.failedToParseScriptSource = function(sourceURL, source, startingLine, errorLine, errorMessage) -{ - this.panels.scripts.addScript(null, sourceURL, source, startingLine, errorLine, errorMessage); -} - -WebInspector.pausedScript = function(details) -{ - this.panels.scripts.debuggerPaused(details.callFrames); - this.breakpointManager.debuggerPaused(details); - InspectorFrontendHost.bringToFront(); -} - -WebInspector.resumedScript = function() -{ - this.breakpointManager.debuggerResumed(); - this.panels.scripts.debuggerResumed(); -} - WebInspector.reset = function() { - this.breakpointManager.reset(); + this.debuggerModel.reset(); for (var panelName in this.panels) { var panel = this.panels[panelName]; @@ -1371,14 +1222,6 @@ WebInspector.reset = function() this.console.clearMessages(); this.extensionServer.notifyInspectorReset(); - - this.breakpointManager.restoreBreakpoints(); -} - -WebInspector.resetProfilesPanel = function() -{ - if (WebInspector.panels.profiles) - WebInspector.panels.profiles.resetProfiles(); } WebInspector.bringToFront = function() @@ -1391,16 +1234,6 @@ WebInspector.inspectedURLChanged = function(url) InspectorFrontendHost.inspectedURLChanged(url); this.settings.inspectedURLChanged(url); this.extensionServer.notifyInspectedURLChanged(); - if (!this._breakpointsRestored) { - this.breakpointManager.restoreBreakpoints(); - this._breakpointsRestored = true; - } -} - -WebInspector.didCommitLoad = function() -{ - // Cleanup elements panel early on inspected page refresh. - WebInspector.setDocument(null); } WebInspector.updateConsoleMessageExpiredCount = function(count) @@ -1417,11 +1250,11 @@ WebInspector.addConsoleMessage = function(payload) payload.level, payload.line, payload.url, - payload.groupLevel, payload.repeatCount, payload.message, payload.parameters, - payload.stackTrace); + payload.stackTrace, + payload.requestId); this.console.addMessage(consoleMessage); } @@ -1487,7 +1320,6 @@ WebInspector.log = function(message, messageLevel) messageLevel || WebInspector.ConsoleMessage.MessageLevel.Debug, -1, null, - null, repeatCount, null, [message], @@ -1516,31 +1348,6 @@ WebInspector.log = function(message, messageLevel) logMessage(message); } -WebInspector.addProfileHeader = function(profile) -{ - this.panels.profiles.addProfileHeader(profile); -} - -WebInspector.setRecordingProfile = function(isProfiling) -{ - this.panels.profiles.getProfileType(WebInspector.CPUProfileType.TypeId).setRecordingProfile(isProfiling); - if (this.panels.profiles.hasTemporaryProfile(WebInspector.CPUProfileType.TypeId) !== isProfiling) { - if (!this._temporaryRecordingProfile) { - this._temporaryRecordingProfile = { - typeId: WebInspector.CPUProfileType.TypeId, - title: WebInspector.UIString("Recording…"), - uid: -1, - isTemporary: true - }; - } - if (isProfiling) - this.panels.profiles.addProfileHeader(this._temporaryRecordingProfile); - else - this.panels.profiles.removeProfileHeader(this._temporaryRecordingProfile); - } - this.panels.profiles.updateProfileTypeButtons(); -} - WebInspector.drawLoadingPieChart = function(canvas, percent) { var g = canvas.getContext("2d"); var darkColor = "rgb(122, 168, 218)"; @@ -1940,13 +1747,23 @@ WebInspector.isEditingAnyField = function() return this.__editing; } -WebInspector.startEditing = function(element, committedCallback, cancelledCallback, context, multiline) +// Available config fields (all optional): +// context: Object - an arbitrary context object to be passed to the commit and cancel handlers +// commitHandler: Function - handles editing "commit" outcome +// cancelHandler: Function - handles editing "cancel" outcome +// customFinishHandler: Function - custom finish handler for the editing session (invoked on keydown) +// multiline: Boolean - whether the edited element is multiline +WebInspector.startEditing = function(element, config) { if (element.__editing) return; element.__editing = true; WebInspector.__editing = true; + config = config || {}; + var committedCallback = config.commitHandler; + var cancelledCallback = config.cancelHandler; + var context = config.context; var oldText = getContent(element); var moveDirection = ""; @@ -2002,20 +1819,36 @@ WebInspector.startEditing = function(element, committedCallback, cancelledCallba committedCallback(this, getContent(this), oldText, context, moveDirection); } - function keyDownEventListener(event) { + function defaultFinishHandler(event) + { var isMetaOrCtrl = WebInspector.isMac() ? event.metaKey && !event.shiftKey && !event.ctrlKey && !event.altKey : event.ctrlKey && !event.shiftKey && !event.metaKey && !event.altKey; - if (isEnterKey(event) && (!multiline || isMetaOrCtrl)) { + if (isEnterKey(event) && (!config.multiline || isMetaOrCtrl)) + return "commit"; + else if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code) + return "cancel"; + else if (event.keyIdentifier === "U+0009") // Tab key + return "move-" + (event.shiftKey ? "backward" : "forward"); + } + + function keyDownEventListener(event) + { + var handler = config.customFinishHandler || defaultFinishHandler; + var result = handler(event); + if (result === "commit") { editingCommitted.call(element); event.preventDefault(); event.stopPropagation(); - } else if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code) { + } else if (result === "cancel") { editingCancelled.call(element); event.preventDefault(); event.stopPropagation(); - } else if (event.keyIdentifier === "U+0009") // Tab key - moveDirection = (event.shiftKey ? "backward" : "forward"); + } else if (result && result.indexOf("move-") === 0) { + moveDirection = result.substring(5); + if (event.keyIdentifier !== "U+0009") + blurEventListener(); + } } element.addEventListener("blur", blurEventListener, false); diff --git a/WebCore/inspector/front-end/networkPanel.css b/WebCore/inspector/front-end/networkPanel.css index 70ebe56..95ed1bf 100644 --- a/WebCore/inspector/front-end/networkPanel.css +++ b/WebCore/inspector/front-end/networkPanel.css @@ -159,13 +159,6 @@ content: ""; } -.network-sidebar .network-category-images .icon { - position: relative; - background-image: url(Images/resourcePlainIcon.png); - background-repeat: no-repeat; - content: ""; -} - .network-sidebar .data-grid.small .network-category-images .icon { background-image: url(Images/resourcePlainIconSmall.png); content: ""; @@ -473,21 +466,19 @@ margin-top: 1px; } -.data-grid table.data tr.revealed.network-category-documents, .data-grid table.data tr.revealed.network-category-stylesheets, -.data-grid table.data tr.revealed.network-category-images, .data-grid table.data tr.revealed.network-category-scripts, -.data-grid table.data tr.revealed.network-category-xhr, .data-grid table.data tr.revealed.network-category-fonts, -.data-grid table.data tr.revealed.network-category-websockets, .data-grid table.data tr.revealed.network-category-other { +.data-grid table.data tr.revealed.network-item { display: none; } -.data-grid.filter-all table.data tr.revealed.network-category-documents, .data-grid.filter-documents table.data tr.revealed.network-category-documents, -.data-grid.filter-all table.data tr.revealed.network-category-stylesheets, .data-grid.filter-stylesheets table.data tr.revealed.network-category-stylesheets, -.data-grid.filter-all table.data tr.revealed.network-category-images, .data-grid.filter-images table.data tr.revealed.network-category-images, -.data-grid.filter-all table.data tr.revealed.network-category-scripts, .data-grid.filter-scripts table.data tr.revealed.network-category-scripts, -.data-grid.filter-all table.data tr.revealed.network-category-xhr, .data-grid.filter-xhr table.data tr.revealed.network-category-xhr, -.data-grid.filter-all table.data tr.revealed.network-category-fonts, .data-grid.filter-fonts table.data tr.revealed.network-category-fonts, -.data-grid.filter-all table.data tr.revealed.network-category-websockets, .data-grid.filter-websockets table.data tr.revealed.network-category-websockets, -.data-grid.filter-all table.data tr.revealed.network-category-other, .data-grid.filter-other table.data tr.revealed.network-category-other { +.data-grid.filter-all table.data tr.revealed.network-item, +.data-grid.filter-documents table.data tr.revealed.network-category-documents, +.data-grid.filter-stylesheets table.data tr.revealed.network-category-stylesheets, +.data-grid.filter-images table.data tr.revealed.network-category-images, +.data-grid.filter-scripts table.data tr.revealed.network-category-scripts, +.data-grid.filter-xhr table.data tr.revealed.network-category-xhr, +.data-grid.filter-fonts table.data tr.revealed.network-category-fonts, +.data-grid.filter-websockets table.data tr.revealed.network-category-websockets, +.data-grid.filter-other table.data tr.revealed.network-category-other { display: table-row; } diff --git a/WebCore/inspector/front-end/treeoutline.js b/WebCore/inspector/front-end/treeoutline.js index a1e052f..27bc839 100644 --- a/WebCore/inspector/front-end/treeoutline.js +++ b/WebCore/inspector/front-end/treeoutline.js @@ -821,6 +821,10 @@ TreeElement.prototype.select = function(supressOnSelect, selectedByUser) this.selected = true; this.treeOutline._childrenListNode.focus(); + + // Focusing on another node may detach "this" from tree. + if (!this.treeOutline) + return; this.treeOutline.selectedTreeElement = this; if (this._listItemNode) this._listItemNode.addStyleClass("selected"); diff --git a/WebCore/inspector/front-end/utilities.js b/WebCore/inspector/front-end/utilities.js index f978c6f..688e080 100644 --- a/WebCore/inspector/front-end/utilities.js +++ b/WebCore/inspector/front-end/utilities.js @@ -216,6 +216,11 @@ Element.prototype.pruneEmptyTextNodes = function() } } +Element.prototype.isScrolledToBottom = function() +{ + return this.scrollTop === this.scrollHeight - this.offsetHeight; +} + Node.prototype.enclosingNodeOrSelfWithNodeNameInArray = function(nameArray) { for (var node = this; node && node !== this.ownerDocument; node = node.parentNode) |