diff options
author | Steve Block <steveblock@google.com> | 2010-09-29 17:32:26 +0100 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2010-09-29 17:35:08 +0100 |
commit | 68513a70bcd92384395513322f1b801e7bf9c729 (patch) | |
tree | 161b50f75a5921d61731bb25e730005994fcec85 /WebCore/inspector/front-end | |
parent | fd5c6425ce58eb75211be7718d5dee960842a37e (diff) | |
download | external_webkit-68513a70bcd92384395513322f1b801e7bf9c729.zip external_webkit-68513a70bcd92384395513322f1b801e7bf9c729.tar.gz external_webkit-68513a70bcd92384395513322f1b801e7bf9c729.tar.bz2 |
Merge WebKit at r67908: Initial merge by Git
Change-Id: I43a553e7b3299b28cb6ee8aa035ed70fe342b972
Diffstat (limited to 'WebCore/inspector/front-end')
20 files changed, 396 insertions, 176 deletions
diff --git a/WebCore/inspector/front-end/AuditFormatters.js b/WebCore/inspector/front-end/AuditFormatters.js index de277ad..1bc1803 100755..100644 --- a/WebCore/inspector/front-end/AuditFormatters.js +++ b/WebCore/inspector/front-end/AuditFormatters.js @@ -79,8 +79,14 @@ WebInspector.AuditFormatters = { return parent; }, - url: function(url, displayText) + url: function(url, displayText, allowExternalNavigation) { - return WebInspector.linkifyURLAsNode(url, displayText || url, null, (url in WebInspector.resourceURLMap)); + var a = document.createElement("a"); + a.href = url; + a.title = url; + a.textContent = displayText || url; + if (allowExternalNavigation) + a.target = "_blank"; + return a; } }; diff --git a/WebCore/inspector/front-end/BreakpointsSidebarPane.js b/WebCore/inspector/front-end/BreakpointsSidebarPane.js index cda72fb..9688f3e 100644 --- a/WebCore/inspector/front-end/BreakpointsSidebarPane.js +++ b/WebCore/inspector/front-end/BreakpointsSidebarPane.js @@ -97,6 +97,7 @@ WebInspector.BreakpointItem = function(breakpoint) this._breakpoint = breakpoint; this._element = document.createElement("li"); + this._element.addEventListener("click", this._breakpointClicked.bind(this), false); var checkboxElement = document.createElement("input"); checkboxElement.className = "checkbox-elem"; @@ -141,8 +142,6 @@ WebInspector.JSBreakpointItem = function(breakpoint) { WebInspector.BreakpointItem.call(this, breakpoint); - this._element.addEventListener("click", this._breakpointClicked.bind(this), false); - var displayName = this._breakpoint.url ? WebInspector.displayNameForURL(this._breakpoint.url) : WebInspector.UIString("(program)"); var labelElement = document.createTextNode(displayName + ":" + this._breakpoint.line); this._element.appendChild(labelElement); @@ -183,8 +182,7 @@ WebInspector.DOMBreakpointItem = function(breakpoint) { WebInspector.BreakpointItem.call(this, breakpoint); - var node = WebInspector.domAgent.nodeForId(this._breakpoint.nodeId); - var link = WebInspector.panels.elements.linkifyNodeReference(node); + var link = WebInspector.panels.elements.linkifyNodeById(this._breakpoint.nodeId); this._element.appendChild(link); var type = WebInspector.DOMBreakpoint.labelForType(this._breakpoint.type); @@ -198,6 +196,11 @@ WebInspector.DOMBreakpointItem.prototype = { if (this._breakpoint.type != other._breakpoint.type) return this._breakpoint.type < other._breakpoint.type ? -1 : 1; return 0; + }, + + _breakpointClicked: function() + { + WebInspector.updateFocusedNode(this._breakpoint.nodeId); } } diff --git a/WebCore/inspector/front-end/CallStackSidebarPane.js b/WebCore/inspector/front-end/CallStackSidebarPane.js index 60eee34..91f35a6 100644 --- a/WebCore/inspector/front-end/CallStackSidebarPane.js +++ b/WebCore/inspector/front-end/CallStackSidebarPane.js @@ -26,7 +26,6 @@ WebInspector.CallStackSidebarPane = function() { WebInspector.SidebarPane.call(this, WebInspector.UIString("Call Stack")); - } WebInspector.CallStackSidebarPane.prototype = { @@ -83,6 +82,39 @@ WebInspector.CallStackSidebarPane.prototype = { } }, + updateStatus: function(status) + { + var statusElement = document.createElement("div"); + statusElement.className = "info"; + + var breakpointType = status.breakpoint.type; + var substitutions = [WebInspector.DOMBreakpoint.labelForType(breakpointType), WebInspector.panels.elements.linkifyNodeById(status.breakpoint.nodeId)]; + var formatters = { + s: function(substitution) + { + return substitution; + } + }; + function append(a, b) + { + if (typeof b === "string") + b = document.createTextNode(b); + statusElement.appendChild(b); + } + if (breakpointType === WebInspector.DOMBreakpoint.Types.SubtreeModified) { + var targetNode = WebInspector.panels.elements.linkifyNodeById(status.targetNodeId); + if (status.insertion) { + if (status.targetNodeId !== status.breakpoint.nodeId) + WebInspector.formatLocalized("Paused on a \"%s\" breakpoint set on %s, because a new child was added to its descendant %s.", substitutions.concat(targetNode), formatters, "", append); + else + WebInspector.formatLocalized("Paused on a \"%s\" breakpoint set on %s, because a new child was added to that node.", substitutions, formatters, "", append); + } else + WebInspector.formatLocalized("Paused on a \"%s\" breakpoint set on %s, because its descendant %s was removed.", substitutions.concat(targetNode), formatters, "", append); + } else + WebInspector.formatLocalized("Paused on a \"%s\" breakpoint set on %s.", substitutions, formatters, "", append); + this.bodyElement.appendChild(statusElement); + }, + get selectedCallFrame() { return this._selectedCallFrame; diff --git a/WebCore/inspector/front-end/ConsoleView.js b/WebCore/inspector/front-end/ConsoleView.js index 9785cd0..6f8bd8b 100644 --- a/WebCore/inspector/front-end/ConsoleView.js +++ b/WebCore/inspector/front-end/ConsoleView.js @@ -400,10 +400,13 @@ WebInspector.ConsoleView.prototype = { } var contextMenu = new WebInspector.ContextMenu(); - if (!WebInspector.monitoringXHREnabled) - contextMenu.appendCheckboxItem(WebInspector.UIString("XMLHttpRequest logging"), InspectorBackend.enableMonitoringXHR.bind(InspectorBackend), false); - else - contextMenu.appendCheckboxItem(WebInspector.UIString("XMLHttpRequest logging"), InspectorBackend.disableMonitoringXHR.bind(InspectorBackend), true); + + function monitoringXHRWasChanged(newState) + { + WebInspector.monitoringXHREnabled = newState; + } + var itemAction = InspectorBackend.setMonitoringXHREnabled.bind(InspectorBackend, !WebInspector.monitoringXHREnabled, monitoringXHRWasChanged); + contextMenu.appendCheckboxItem(WebInspector.UIString("XMLHttpRequest logging"), itemAction, WebInspector.monitoringXHREnabled); contextMenu.appendItem(WebInspector.UIString("Clear Console"), this.requestClearMessages.bind(this)); contextMenu.show(event); }, @@ -518,7 +521,7 @@ WebInspector.ConsoleView.prototype = { _enterKeyPressed: function(event) { - if (event.altKey) + if (event.altKey || event.ctrlKey) return; event.preventDefault(); @@ -1091,7 +1094,7 @@ WebInspector.ConsoleGroup.prototype = { if (msg.type === WebInspector.ConsoleMessage.MessageType.StartGroup || msg.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed) { this.messagesElement.parentNode.insertBefore(element, this.messagesElement); - element.addEventListener("click", this._titleClicked.bind(this), true); + element.addEventListener("click", this._titleClicked.bind(this), false); var groupElement = element.enclosingNodeOrSelfWithClass("console-group"); if (groupElement && msg.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed) groupElement.addStyleClass("collapsed"); diff --git a/WebCore/inspector/front-end/ElementsPanel.js b/WebCore/inspector/front-end/ElementsPanel.js index c60d4b1..72b23e1 100644 --- a/WebCore/inspector/front-end/ElementsPanel.js +++ b/WebCore/inspector/front-end/ElementsPanel.js @@ -147,7 +147,7 @@ WebInspector.ElementsPanel.prototype = { { WebInspector.Panel.prototype.hide.call(this); - WebInspector.hoveredDOMNode = null; + WebInspector.highlightDOMNode(0); InspectorBackend.disableSearchingForNode(); }, @@ -165,7 +165,7 @@ WebInspector.ElementsPanel.prototype = { this.rootDOMNode = null; this.focusedDOMNode = null; - WebInspector.hoveredDOMNode = null; + WebInspector.highlightDOMNode(0); this.recentlyModifiedNodes = []; @@ -187,9 +187,7 @@ WebInspector.ElementsPanel.prototype = { inspectedRootDocument.addEventListener("DOMNodeRemoved", this._nodeRemoved.bind(this)); inspectedRootDocument.addEventListener("DOMAttrModified", this._attributesUpdated.bind(this)); - this.treeOutline.suppressSelectHighlight = true; this.rootDOMNode = inspectedRootDocument; - this.treeOutline.suppressSelectHighlight = false; function selectNode(candidateFocusNode) { @@ -199,11 +197,9 @@ WebInspector.ElementsPanel.prototype = { if (!candidateFocusNode) return; - this.treeOutline.suppressSelectHighlight = true; this.focusedDOMNode = candidateFocusNode; if (this.treeOutline.selectedTreeElement) this.treeOutline.selectedTreeElement.expand(); - this.treeOutline.suppressSelectHighlight = false; } function selectLastSelectedNode(nodeId) @@ -261,6 +257,23 @@ WebInspector.ElementsPanel.prototype = { this._nodeSearchButton.toggled = false; }, + populateHrefContextMenu: function(contextMenu, event, anchorElement) + { + if (!anchorElement.href) + return false; + + var resourceURL = WebInspector.resourceURLForRelatedNode(this.focusedDOMNode, anchorElement.href); + if (!resourceURL) + return false; + + // Add resource-related actions. + // Keep these consistent with those added in WebInspector.StylesSidebarPane.prototype._populateHrefContextMenu(). + contextMenu.appendItem(WebInspector.UIString("Open Link in New Window"), WebInspector.openResource.bind(null, resourceURL, false)); + if (WebInspector.resourceForURL(resourceURL)) + contextMenu.appendItem(WebInspector.UIString("Open Link in Resources Panel"), WebInspector.openResource.bind(null, resourceURL, true)); + return true; + }, + _updateMatchesCount: function() { WebInspector.updateSearchMatchesCount(this._searchResults.length, this); @@ -561,7 +574,7 @@ WebInspector.ElementsPanel.prototype = { var nodeUnderMouse = document.elementFromPoint(event.pageX, event.pageY); var crumbElement = nodeUnderMouse.enclosingNodeOrSelfWithClass("crumb"); - WebInspector.hoveredDOMNode = (crumbElement ? crumbElement.representedObject : null); + WebInspector.highlightDOMNode(crumbElement ? crumbElement.representedObject.id : 0); if ("_mouseOutOfCrumbsTimeout" in this) { clearTimeout(this._mouseOutOfCrumbsTimeout); @@ -575,7 +588,7 @@ WebInspector.ElementsPanel.prototype = { if (nodeUnderMouse && nodeUnderMouse.isDescendant(this.crumbsElement)) return; - WebInspector.hoveredDOMNode = null; + WebInspector.highlightDOMNode(0); this._mouseOutOfCrumbsTimeout = setTimeout(this.updateBreadcrumbSizes.bind(this), 1000); }, @@ -761,11 +774,19 @@ WebInspector.ElementsPanel.prototype = { { var link = document.createElement("span"); link.className = "node-link"; - link.addEventListener("click", WebInspector.updateFocusedNode.bind(WebInspector, node.id), false); this.decorateNodeLabel(node, link); + WebInspector.wireElementWithDOMNode(link, node.id); return link; }, + linkifyNodeById: function(nodeId) + { + var node = WebInspector.domAgent.nodeForId(nodeId); + if (!node) + return document.createTextNode(WebInspector.UIString("<node>")); + return this.linkifyNodeReference(node); + }, + updateBreadcrumbSizes: function(focusedCrumb) { if (!this.visible) diff --git a/WebCore/inspector/front-end/ElementsTreeOutline.js b/WebCore/inspector/front-end/ElementsTreeOutline.js index 10131f4..e261234 100644 --- a/WebCore/inspector/front-end/ElementsTreeOutline.js +++ b/WebCore/inspector/front-end/ElementsTreeOutline.js @@ -93,27 +93,8 @@ WebInspector.ElementsTreeOutline.prototype = { // and the select() call would change the focusedDOMNode and reenter this setter. So to // avoid calling focusedNodeChanged() twice, first check if _focusedDOMNode is the same // node as the one passed in. - if (this._focusedDOMNode === x) { + if (this._focusedDOMNode === x) this.focusedNodeChanged(); - - if (x && !this.suppressSelectHighlight) { - InspectorBackend.highlightDOMNode(x.id); - - if ("_restorePreviousHighlightNodeTimeout" in this) - clearTimeout(this._restorePreviousHighlightNodeTimeout); - - function restoreHighlightToHoveredNode() - { - var hoveredNode = WebInspector.hoveredDOMNode; - if (hoveredNode) - InspectorBackend.highlightDOMNode(hoveredNode.id); - else - InspectorBackend.hideDOMNodeHighlight(); - } - - this._restorePreviousHighlightNodeTimeout = setTimeout(restoreHighlightToHoveredNode, 2000); - } - } }, get editing() @@ -260,7 +241,7 @@ WebInspector.ElementsTreeOutline.prototype = { element._createTooltipForNode(); } - WebInspector.hoveredDOMNode = (element ? element.representedObject : null); + WebInspector.highlightDOMNode(element ? element.representedObject.id : 0); }, _onmouseout: function(event) @@ -274,7 +255,7 @@ WebInspector.ElementsTreeOutline.prototype = { delete this._previousHoveredElement; } - WebInspector.hoveredDOMNode = null; + WebInspector.highlightDOMNode(0); }, _contextMenuEventFired: function(event) @@ -285,12 +266,21 @@ WebInspector.ElementsTreeOutline.prototype = { var contextMenu = new WebInspector.ContextMenu(); + var href = event.target.enclosingNodeOrSelfWithClass("webkit-html-resource-link") || event.target.enclosingNodeOrSelfWithClass("webkit-html-external-link"); var tag = event.target.enclosingNodeOrSelfWithClass("webkit-html-tag"); var textNode = event.target.enclosingNodeOrSelfWithClass("webkit-html-text-node"); - if (tag && listItem.treeElement._populateTagContextMenu) + var needSeparator; + if (href) + needSeparator = WebInspector.panels.elements.populateHrefContextMenu(contextMenu, event, href); + if (tag && listItem.treeElement._populateTagContextMenu) { + if (needSeparator) + contextMenu.appendSeparator(); listItem.treeElement._populateTagContextMenu(contextMenu, event); - else if (textNode && listItem.treeElement._populateTextContextMenu) + } else if (textNode && listItem.treeElement._populateTextContextMenu) { + if (needSeparator) + contextMenu.appendSeparator(); listItem.treeElement._populateTextContextMenu(contextMenu, textNode); + } contextMenu.show(event); } } @@ -1189,29 +1179,6 @@ WebInspector.ElementsTreeElement.prototype = { this._highlightSearchResults(); }, - _rewriteAttrHref: function(node, hrefValue) - { - if (!hrefValue || hrefValue.indexOf("://") > 0) - return hrefValue; - - for (var frameOwnerCandidate = node; frameOwnerCandidate; frameOwnerCandidate = frameOwnerCandidate.parentNode) { - if (frameOwnerCandidate.documentURL) { - var result = WebInspector.completeURL(frameOwnerCandidate.documentURL, hrefValue); - if (result) - return result; - break; - } - } - - // documentURL not found or has bad value - for (var url in WebInspector.resourceURLMap) { - var match = url.match(WebInspector.URLRegExp); - if (match && match[4] === hrefValue) - return url; - } - return hrefValue; - }, - _attributeHTML: function(name, value, node, linkify) { var hasText = (value.length > 0); @@ -1221,7 +1188,7 @@ WebInspector.ElementsTreeElement.prototype = { html += "=​\""; if (linkify && (name === "src" || name === "href")) { - var rewrittenHref = this._rewriteAttrHref(node, value); + var rewrittenHref = WebInspector.resourceURLForRelatedNode(node, value); value = value.replace(/([\/;:\)\]\}])/g, "$1\u200B"); html += linkify(rewrittenHref, value, "webkit-html-attribute-value", node.nodeName.toLowerCase() === "a"); } else { diff --git a/WebCore/inspector/front-end/HAREntry.js b/WebCore/inspector/front-end/HAREntry.js index 9f188ed..85e4f59 100644 --- a/WebCore/inspector/front-end/HAREntry.js +++ b/WebCore/inspector/front-end/HAREntry.js @@ -42,7 +42,7 @@ WebInspector.HAREntry.prototype = { return { pageref: this._resource.documentURL, startedDateTime: new Date(this._resource.startTime * 1000), - time: this._toMilliseconds(this._resource.duration), + time: WebInspector.HAREntry._toMilliseconds(this._resource.duration), request: this._buildRequest(), response: this._buildResponse(), // cache: {...}, -- Not supproted yet. @@ -95,14 +95,34 @@ WebInspector.HAREntry.prototype = { _buildTimings: function() { + var waitForConnection = this._interval("connectStart", "connectEnd"); + var blocked; + var connect; + var dns = this._interval("dnsStart", "dnsEnd"); + var send = this._interval("sendStart", "sendEnd"); + var ssl = this._interval("sslStart", "sslEnd"); + + if (ssl !== -1 && send !== -1) + send -= ssl; + + if (this._resource.connectionReused) { + connect = -1; + blocked = waitForConnection; + } else { + blocked = 0; + connect = waitForConnection; + if (dns !== -1) + connect -= dns; + } + return { - blocked: -1, // Not available. - dns: -1, // Not available. - connect: -1, // Not available. - send: -1, // Not available. - wait: this._toMilliseconds(this._resource.latency), - receive: this._toMilliseconds(this._resource.receiveDuration), - ssl: -1 // Not available. + blocked: blocked, + dns: dns, + connect: connect, + send: send, + wait: this._interval("sendEnd", "receiveHeadersEnd"), + receive: WebInspector.HAREntry._toMilliseconds(this._resource.receiveDuration), + ssl: ssl }; }, @@ -130,8 +150,65 @@ WebInspector.HAREntry.prototype = { return parameters.slice(); }, - _toMilliseconds: function(time) + _interval: function(start, end) + { + var timing = this._resource.timing; + if (!timing) + return -1; + var startTime = timing[start]; + return typeof startTime !== "number" || startTime === -1 ? -1 : Math.round(timing[end] - startTime); + } +}; + +WebInspector.HAREntry._toMilliseconds = function(time) +{ + return time === -1 ? -1 : Math.round(time * 1000); +} + +WebInspector.HARLog = function() +{ +} + +WebInspector.HARLog.prototype = { + build: function() + { + var webKitVersion = /AppleWebKit\/([^ ]+)/.exec(window.navigator.userAgent); + + return { + version: "1.2", + creator: { + name: "WebInspector", + version: webKitVersion ? webKitVersion[1] : "n/a" + }, + pages: this._buildPages(), + entries: Object.properties(WebInspector.resources).map(this._convertResource) + } + }, + + _buildPages: function() + { + return [ + { + startedDateTime: new Date(WebInspector.mainResource.startTime * 1000), + id: WebInspector.mainResource.documentURL, + title: "", + pageTimings: this._buildMainResourceTimings() + } + ]; + }, + + _buildMainResourceTimings: function() + { + var resourcesPanel = WebInspector.panels.resources; + var startTime = WebInspector.mainResource.startTime; + return { + onContentLoad: WebInspector.HAREntry._toMilliseconds(resourcesPanel.mainResourceDOMContentTime - startTime), + onLoad: WebInspector.HAREntry._toMilliseconds(resourcesPanel.mainResourceLoadTime - startTime), + } + }, + + _convertResource: function(id) { - return time === -1 ? -1 : Math.round(time * 1000); + return (new WebInspector.HAREntry(WebInspector.resources[id])).build(); } }; diff --git a/WebCore/inspector/front-end/InjectedScript.js b/WebCore/inspector/front-end/InjectedScript.js index d4e3d80..5544ed5 100644 --- a/WebCore/inspector/front-end/InjectedScript.js +++ b/WebCore/inspector/front-end/InjectedScript.js @@ -464,6 +464,10 @@ InjectedScript.prototype = { return str.replace(/^\[object (.*)\]$/i, "$1"); } else { // V8 + if (isFinite(obj.length) && typeof obj.callee === "function") { + // Arguments.constructor === Object in V8 + return "Arguments"; + } return obj.constructor && obj.constructor.name || "Object"; } }, diff --git a/WebCore/inspector/front-end/ProfileDataGridTree.js b/WebCore/inspector/front-end/ProfileDataGridTree.js index b10f392..adf34f1 100644 --- a/WebCore/inspector/front-end/ProfileDataGridTree.js +++ b/WebCore/inspector/front-end/ProfileDataGridTree.js @@ -96,19 +96,10 @@ WebInspector.ProfileDataGridNode.prototype = { cell.addStyleClass("highlight"); if (this.profileNode.url) { - var fileName = WebInspector.displayNameForURL(this.profileNode.url); - - var urlElement = document.createElement("a"); - urlElement.className = "profile-node-file webkit-html-resource-link"; - urlElement.href = this.profileNode.url; - urlElement.lineNumber = this.profileNode.lineNumber; - urlElement.preferredPanel = "scripts"; - + var lineNumber; if (this.profileNode.lineNumber > 0) - urlElement.textContent = fileName + ":" + this.profileNode.lineNumber; - else - urlElement.textContent = fileName; - + lineNumber = this.profileNode.lineNumber; + var urlElement = WebInspector.linkifyResourceAsNode(this.profileNode.url, "scripts", lineNumber, "profile-node-file"); cell.insertBefore(urlElement, cell.firstChild); } diff --git a/WebCore/inspector/front-end/Resource.js b/WebCore/inspector/front-end/Resource.js index de87047..ea9052d 100644 --- a/WebCore/inspector/front-end/Resource.js +++ b/WebCore/inspector/front-end/Resource.js @@ -45,7 +45,8 @@ WebInspector.Resource.Type = { Script: 4, XHR: 5, Media: 6, - Other: 7, + WebSocket: 7, + Other: 8, isTextType: function(type) { @@ -76,6 +77,8 @@ WebInspector.Resource.Type = { return "XHR"; case this.Media: return "media"; + case this.WebSocket: + return "WebSocket"; case this.Other: default: return "other"; @@ -372,6 +375,9 @@ WebInspector.Resource.prototype = { case WebInspector.Resource.Type.XHR: this.category = WebInspector.resourceCategories.xhr; break; + case WebInspector.Resource.Type.WebSocket: + this.category = WebInspector.resourceCategories.websocket; + break; case WebInspector.Resource.Type.Other: default: this.category = WebInspector.resourceCategories.other; @@ -584,7 +590,8 @@ WebInspector.Resource.prototype = { if (typeof this.type === "undefined" || this.type === WebInspector.Resource.Type.Other - || this.type === WebInspector.Resource.Type.XHR) + || this.type === WebInspector.Resource.Type.XHR + || this.type === WebInspector.Resource.Type.WebSocket) return true; if (this.mimeType in WebInspector.MIMETypes) diff --git a/WebCore/inspector/front-end/ResourceView.js b/WebCore/inspector/front-end/ResourceView.js index 7ce09b6..1c2574f 100644 --- a/WebCore/inspector/front-end/ResourceView.js +++ b/WebCore/inspector/front-end/ResourceView.js @@ -279,13 +279,19 @@ WebInspector.ResourceView.prototype = { _refreshRequestHeaders: function() { - this._refreshHeaders(WebInspector.UIString("Request Headers"), this.resource.sortedRequestHeaders, this.requestHeadersTreeElement); + var additionalRow = null; + if (typeof this.resource.webSocketRequestKey3 !== "undefined") + additionalRow = {header: "(Key3)", value: this.resource.webSocketRequestKey3}; + this._refreshHeaders(WebInspector.UIString("Request Headers"), this.resource.sortedRequestHeaders, additionalRow, this.requestHeadersTreeElement); this._refreshFormData(); }, _refreshResponseHeaders: function() { - this._refreshHeaders(WebInspector.UIString("Response Headers"), this.resource.sortedResponseHeaders, this.responseHeadersTreeElement); + var additionalRow = null; + if (typeof this.resource.webSocketChallengeResponse !== "undefined") + additionalRow = {header: "(Challenge Response)", value: this.resource.webSocketChallengeResponse}; + this._refreshHeaders(WebInspector.UIString("Response Headers"), this.resource.sortedResponseHeaders, additionalRow, this.responseHeadersTreeElement); }, _refreshHTTPInformation: function() @@ -316,7 +322,7 @@ WebInspector.ResourceView.prototype = { } }, - _refreshHeaders: function(title, headers, headersTreeElement) + _refreshHeaders: function(title, headers, additionalRow, headersTreeElement) { headersTreeElement.removeChildren(); @@ -333,6 +339,15 @@ WebInspector.ResourceView.prototype = { headerTreeElement.selectable = false; headersTreeElement.appendChild(headerTreeElement); } + + if (additionalRow) { + var title = "<div class=\"header-name\">" + additionalRow.header.escapeHTML() + ":</div>"; + title += "<div class=\"header-value source-code\">" + additionalRow.value.escapeHTML() + "</div>" + + var headerTreeElement = new TreeElement(title, null, false); + headerTreeElement.selectable = false; + headersTreeElement.appendChild(headerTreeElement); + } } } diff --git a/WebCore/inspector/front-end/ResourcesPanel.js b/WebCore/inspector/front-end/ResourcesPanel.js index 27df5cf..f329b1a 100644 --- a/WebCore/inspector/front-end/ResourcesPanel.js +++ b/WebCore/inspector/front-end/ResourcesPanel.js @@ -47,6 +47,8 @@ WebInspector.ResourcesPanel = function() this.filter(this.filterAllElement, false); this.graphsTreeElement.children[0].select(); this._resourceTrackingEnabled = false; + + this.sidebarElement.addEventListener("contextmenu", this._contextMenu.bind(this), true); } WebInspector.ResourcesPanel.prototype = { @@ -751,16 +753,23 @@ WebInspector.ResourcesPanel.prototype = { _toggleResourceTracking: function(optionalAlways) { + function callback(newState) { + if (newState) + WebInspector.panels.resources.resourceTrackingWasEnabled(); + else + WebInspector.panels.resources.resourceTrackingWasDisabled(); + } + if (this._resourceTrackingEnabled) { this.largerResourcesButton.visible = false; this.sortingSelectElement.visible = false; WebInspector.resources = {}; WebInspector.resourceURLMap = {}; - InspectorBackend.disableResourceTracking(true); + InspectorBackend.setResourceTrackingEnabled(false, true, callback); } else { this.largerResourcesButton.visible = true; this.sortingSelectElement.visible = true; - InspectorBackend.enableResourceTracking(!!optionalAlways); + InspectorBackend.setResourceTrackingEnabled(true, !!optionalAlways, callback); } }, @@ -857,7 +866,7 @@ WebInspector.ResourcesPanel.prototype = { var title = document.createElement("span"); title.className = "resource-timing-bar-title"; - if (i >= rows.length - 2) + if (total - rows[i].end < rows[i].start) title.style.right = (scale * (total - rows[i].end) + 3) + "px"; else title.style.left = (scale * rows[i].start + 3) + "px"; @@ -876,6 +885,36 @@ WebInspector.ResourcesPanel.prototype = { { WebInspector.Panel.prototype.hide.call(this); this._popoverHelper.hidePopup(); + }, + + _contextMenu: function(event) + { + // createBlobURL is enabled conditionally, do not expose resource export if it's not available. + if (typeof window.createBlobURL !== "function" || !Preferences.resourceExportEnabled) + return; + + var contextMenu = new WebInspector.ContextMenu(); + var resourceTreeItem = event.target.enclosingNodeOrSelfWithClass("resource-sidebar-tree-item"); + if (resourceTreeItem && resourceTreeItem.treeElement) { + var resource = resourceTreeItem.treeElement.representedObject; + 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)); } } diff --git a/WebCore/inspector/front-end/ScriptsPanel.js b/WebCore/inspector/front-end/ScriptsPanel.js index c5267f7..715339d 100644 --- a/WebCore/inspector/front-end/ScriptsPanel.js +++ b/WebCore/inspector/front-end/ScriptsPanel.js @@ -375,7 +375,7 @@ WebInspector.ScriptsPanel.prototype = { InjectedScriptAccess.get(callFrame.worldId).evaluateInCallFrame(callFrame.id, code, objectGroup, evalCallback); }, - debuggerPaused: function(callFrames) + debuggerPaused: function(details) { WebInspector.breakpointManager.removeOneTimeBreakpoint(); this._paused = true; @@ -384,8 +384,11 @@ WebInspector.ScriptsPanel.prototype = { this._updateDebuggerButtons(); - this.sidebarPanes.callstack.update(callFrames, this._sourceIDMap); - this.sidebarPanes.callstack.selectedCallFrame = callFrames[0]; + this.sidebarPanes.callstack.update(details.callFrames, this._sourceIDMap); + this.sidebarPanes.callstack.selectedCallFrame = details.callFrames[0]; + + if (details.status) + this.sidebarPanes.callstack.updateStatus(details.status); WebInspector.currentPanel = this; window.focus(); diff --git a/WebCore/inspector/front-end/Settings.js b/WebCore/inspector/front-end/Settings.js index 41d82f9..63f2641 100644 --- a/WebCore/inspector/front-end/Settings.js +++ b/WebCore/inspector/front-end/Settings.js @@ -44,7 +44,8 @@ var Preferences = { profilerAlwaysEnabled: false, auditsPanelEnabled: true, onlineDetectionEnabled: true, - domBreakpointsEnabled: false + domBreakpointsEnabled: false, + resourceExportEnabled: false } WebInspector.Settings = function(sessionScope) diff --git a/WebCore/inspector/front-end/StylesSidebarPane.js b/WebCore/inspector/front-end/StylesSidebarPane.js index 1dddde7..6aff37d 100644 --- a/WebCore/inspector/front-end/StylesSidebarPane.js +++ b/WebCore/inspector/front-end/StylesSidebarPane.js @@ -64,6 +64,7 @@ WebInspector.StylesSidebarPane = function(computedStylePane) this.titleElement.appendChild(this.settingsSelectElement); this._computedStylePane = computedStylePane; + this.element.addEventListener("contextmenu", this._contextMenuEventFired.bind(this), true); } // Taken from http://www.w3.org/TR/CSS21/propidx.html. @@ -105,6 +106,17 @@ WebInspector.StylesSidebarPane.prototype = { this.settingsSelectElement[2].selected = true; }, + _contextMenuEventFired: function(event) + { + var href = event.target.enclosingNodeOrSelfWithClass("webkit-html-resource-link") || event.target.enclosingNodeOrSelfWithClass("webkit-html-external-link"); + if (href) { + var contextMenu = new WebInspector.ContextMenu(); + var filled = WebInspector.panels.elements.populateHrefContextMenu(contextMenu, event, href); + if (filled) + contextMenu.show(event); + } + }, + update: function(node, editedSection, forceUpdate) { var refresh = false; diff --git a/WebCore/inspector/front-end/WebKit.qrc b/WebCore/inspector/front-end/WebKit.qrc index f90a9fe..c222f0e 100644 --- a/WebCore/inspector/front-end/WebKit.qrc +++ b/WebCore/inspector/front-end/WebKit.qrc @@ -266,5 +266,6 @@ <file>Images/warningOrangeDot.png</file> <file>Images/warningsErrors.png</file> <file>Images/whiteConnectorPoint.png</file> + <file alias="DebuggerScript.js">../../bindings/v8/DebuggerScript.js</file> </qresource> </RCC> diff --git a/WebCore/inspector/front-end/inspector.css b/WebCore/inspector/front-end/inspector.css index 4319816..6d8571c 100644 --- a/WebCore/inspector/front-end/inspector.css +++ b/WebCore/inspector/front-end/inspector.css @@ -1693,6 +1693,10 @@ li.editing .swatch, li.editing .enabled-button, li.editing-sub-part .delete-but color: gray; } +.pane > .body .placard + .info { + border-top: 1px solid gray +} + .pane.expanded > .body, .pane.expanded > .growbar { display: block; } @@ -2835,7 +2839,8 @@ button.enable-toggle-status-bar-item.toggled-on .glyph { } .resources-category-documents, .resources-category-stylesheets, .resources-category-images, -.resources-category-scripts, .resources-category-xhr, .resources-category-fonts, .resources-category-other { +.resources-category-scripts, .resources-category-xhr, .resources-category-fonts, +.resources-category-websockets, .resources-category-other { display: none; } @@ -2845,6 +2850,7 @@ button.enable-toggle-status-bar-item.toggled-on .glyph { .filter-all .resources-category-scripts, .filter-scripts .resources-category-scripts, .filter-all .resources-category-xhr, .filter-xhr .resources-category-xhr, .filter-all .resources-category-fonts, .filter-fonts .resources-category-fonts, +.filter-all .resources-category-websockets, .filter-websockets .resources-category-websockets, .filter-all .resources-category-other, .filter-other .resources-category-other, .resource-sidebar-tree-item.selected { display: list-item; @@ -2920,6 +2926,15 @@ button.enable-toggle-status-bar-item.toggled-on .glyph { -webkit-border-image: url(Images/timelineHollowPillYellow.png) 6 7 6 7; } +/* FIXME: Create bar images for WebSocket. */ +.resources-category-websockets .resources-graph-bar { + -webkit-border-image: url(Images/timelinePillGray.png) 6 7 6 7; +} + +.resources-category-websockets.resource-cached .resources-graph-bar { + -webkit-border-image: url(Images/timelineHollowPillGray.png) 6 7 6 7; +} + #resource-views { position: absolute; top: 23px; diff --git a/WebCore/inspector/front-end/inspector.js b/WebCore/inspector/front-end/inspector.js index 840745f..f6fa06b 100644 --- a/WebCore/inspector/front-end/inspector.js +++ b/WebCore/inspector/front-end/inspector.js @@ -403,45 +403,44 @@ var WebInspector = { } }, - get hoveredDOMNode() + highlightDOMNode: function(nodeId) { - return this._hoveredDOMNode; - }, + if ("_hideDOMNodeHighlightTimeout" in this) { + clearTimeout(this._hideDOMNodeHighlightTimeout); + delete this._hideDOMNodeHighlightTimeout; + } - set hoveredDOMNode(x) - { - if (this._hoveredDOMNode === x) + if (this._highlightedDOMNodeId === nodeId) return; - this._hoveredDOMNode = x; - - if (this._hoveredDOMNode) - this._updateHoverHighlightSoon(this.showingDOMNodeHighlight ? 50 : 500); + this._highlightedDOMNodeId = nodeId; + if (nodeId) + InspectorBackend.highlightDOMNode(nodeId); else - this._updateHoverHighlight(); + InspectorBackend.hideDOMNodeHighlight(); }, - _updateHoverHighlightSoon: function(delay) + highlightDOMNodeForTwoSeconds: function(nodeId) { - if ("_updateHoverHighlightTimeout" in this) - clearTimeout(this._updateHoverHighlightTimeout); - this._updateHoverHighlightTimeout = setTimeout(this._updateHoverHighlight.bind(this), delay); + this.highlightDOMNode(nodeId); + this._hideDOMNodeHighlightTimeout = setTimeout(this.highlightDOMNode.bind(this, 0), 2000); }, - _updateHoverHighlight: function() + wireElementWithDOMNode: function(element, nodeId) { - if ("_updateHoverHighlightTimeout" in this) { - clearTimeout(this._updateHoverHighlightTimeout); - delete this._updateHoverHighlightTimeout; - } + element.addEventListener("click", this._updateFocusedNode.bind(this, nodeId), false); + element.addEventListener("mouseover", this.highlightDOMNode.bind(this, nodeId), false); + element.addEventListener("mouseout", this.highlightDOMNode.bind(this, 0), false); + }, - if (this._hoveredDOMNode) { - InspectorBackend.highlightDOMNode(this._hoveredDOMNode.id); - this.showingDOMNodeHighlight = true; - } else { - InspectorBackend.hideDOMNodeHighlight(); - this.showingDOMNodeHighlight = false; - } + _updateFocusedNode: function(nodeId) + { + var node = WebInspector.domAgent.nodeForId(nodeId); + if (!node) + return; + + this.currentPanel = this.panels.elements; + this.panels.elements.focusedDOMNode = node; } } @@ -517,6 +516,7 @@ WebInspector.doLoadedDone = function() scripts: new WebInspector.ResourceCategory("scripts", WebInspector.UIString("Scripts"), "rgb(255,121,0)"), xhr: new WebInspector.ResourceCategory("xhr", WebInspector.UIString("XHR"), "rgb(231,231,10)"), fonts: new WebInspector.ResourceCategory("fonts", WebInspector.UIString("Fonts"), "rgb(255,82,62)"), + websocket: new WebInspector.ResourceCategory("websockets", WebInspector.UIString("WebSocket"), "rgb(186,186,186)"), // FIXME: Decide the color. other: new WebInspector.ResourceCategory("other", WebInspector.UIString("Other"), "rgb(186,186,186)") }; @@ -582,6 +582,16 @@ WebInspector.doLoadedDone = function() this.extensionServer.initExtensions(); + function populateInspectorState(inspectorState) + { + WebInspector.monitoringXHREnabled = inspectorState.monitoringXHREnabled; + if (inspectorState.resourceTrackingEnabled) + WebInspector.panels.resources.resourceTrackingWasEnabled(); + else + WebInspector.panels.resources.resourceTrackingWasDisabled(); + } + InspectorBackend.getInspectorState(populateInspectorState); + InspectorBackend.populateScriptObjects(); // As a DOMAgent method, this needs to happen after the frontend has loaded and the agent is available. @@ -720,22 +730,10 @@ WebInspector.disconnectFromBackend = function() InspectorFrontendHost.disconnectFromBackend(); } -WebInspector.documentMouseOver = function(event) -{ - if (event.target.tagName !== "A") - return; - - const anchor = event.target; - if (!anchor.hasStyleClass("webkit-html-resource-link")) - return; - if (anchor.href && anchor.href.indexOf("/data:") != -1) - return; -} - WebInspector.documentClick = function(event) { var anchor = event.target.enclosingNodeOrSelfWithNodeName("a"); - if (!anchor) + if (!anchor || anchor.target === "_blank") return; // Prevent the link from navigating, since we don't do any navigation by following links normally. @@ -788,6 +786,16 @@ WebInspector.documentClick = function(event) followLink(); } +WebInspector.openResource = function(resourceURL, inResourcesPanel) +{ + var resource = WebInspector.resourceForURL(resourceURL); + if (inResourcesPanel && resource) { + WebInspector.panels.resources.showResource(resource); + WebInspector.showPanel("resources"); + } else + InspectorBackend.openInInspectedWindow(resource ? resource.url : resourceURL); +} + WebInspector._registerShortcuts = function() { var shortcut = WebInspector.KeyboardShortcut; @@ -1223,6 +1231,8 @@ WebInspector.updateResource = function(payload) resource.requestMethod = payload.requestMethod; resource.requestFormData = payload.requestFormData; resource.documentURL = payload.documentURL; + if (typeof payload.webSocketRequestKey3 !== "undefined") + resource.webSocketRequestKey3 = payload.webSocketRequestKey3; if (resource.mainResource) this.mainResource = resource; @@ -1247,6 +1257,8 @@ WebInspector.updateResource = function(payload) resource.connectionReused = payload.connectionReused; resource.timing = payload.timing; resource.cached = payload.cached; + if (typeof payload.webSocketChallengeResponse !== "undefined") + resource.webSocketChallengeResponse = payload.webSocketChallengeResponse; } if (payload.didTypeChange) { @@ -1370,16 +1382,6 @@ WebInspector.updateNetworkState = function(isNowOnline) this.panels.storage.updateNetworkState(isNowOnline); } -WebInspector.resourceTrackingWasEnabled = function() -{ - this.panels.resources.resourceTrackingWasEnabled(); -} - -WebInspector.resourceTrackingWasDisabled = function() -{ - this.panels.resources.resourceTrackingWasDisabled(); -} - WebInspector.searchingForNodeWasEnabled = function() { this.panels.elements.searchingForNodeWasEnabled(); @@ -1390,16 +1392,6 @@ WebInspector.searchingForNodeWasDisabled = function() this.panels.elements.searchingForNodeWasDisabled(); } -WebInspector.monitoringXHRWasEnabled = function() -{ - this.monitoringXHREnabled = true; -} - -WebInspector.monitoringXHRWasDisabled = function() -{ - this.monitoringXHREnabled = false; -} - WebInspector.attachDebuggerWhenShown = function() { this.panels.scripts.attachDebuggerWhenShown(); @@ -1447,7 +1439,7 @@ WebInspector.failedToParseScriptSource = function(sourceURL, source, startingLin WebInspector.pausedScript = function(details) { - this.panels.scripts.debuggerPaused(details.callFrames); + this.panels.scripts.debuggerPaused(details); InspectorFrontendHost.bringToFront(); } @@ -1474,7 +1466,7 @@ WebInspector.reset = function() this.resourceURLMap = {}; this.cookieDomains = {}; this.applicationCacheDomains = {}; - this.hoveredDOMNode = null; + this.highlightDOMNode(0); delete this.mainResource; @@ -1683,13 +1675,8 @@ WebInspector.drawLoadingPieChart = function(canvas, percent) { WebInspector.updateFocusedNode = function(nodeId) { - var node = WebInspector.domAgent.nodeForId(nodeId); - if (!node) - // FIXME: Should we deselect if null is passed in? - return; - - this.currentPanel = this.panels.elements; - this.panels.elements.focusedDOMNode = node; + this._updateFocusedNode(nodeId); + this.highlightDOMNodeForTwoSeconds(nodeId); } WebInspector.displayNameForURL = function(url) @@ -1804,7 +1791,6 @@ WebInspector.linkifyURLAsNode = function(url, linkText, classes, isExternal, too a.title = url; else if (typeof tooltipText !== "string" || tooltipText.length) a.title = tooltipText; - a.target = "_blank"; a.textContent = linkText; return a; @@ -1828,6 +1814,29 @@ WebInspector.linkifyResourceAsNode = function(url, preferredPanel, lineNumber, c return node; } +WebInspector.resourceURLForRelatedNode = function(node, url) +{ + if (!url || url.indexOf("://") > 0) + return url; + + for (var frameOwnerCandidate = node; frameOwnerCandidate; frameOwnerCandidate = frameOwnerCandidate.parentNode) { + if (frameOwnerCandidate.documentURL) { + var result = WebInspector.completeURL(frameOwnerCandidate.documentURL, url); + if (result) + return result; + break; + } + } + + // documentURL not found or has bad value + for (var resourceURL in WebInspector.resourceURLMap) { + var match = resourceURL.match(WebInspector.URLRegExp); + if (match && match[4] === url) + return resourceURL; + } + return url; +}, + WebInspector.completeURL = function(baseURL, href) { var match = baseURL.match(WebInspector.URLRegExp); @@ -1850,7 +1859,6 @@ WebInspector.addMainEventListeners = function(doc) doc.defaultView.addEventListener("focus", this.windowFocused.bind(this), false); doc.defaultView.addEventListener("blur", this.windowBlurred.bind(this), false); doc.addEventListener("click", this.documentClick.bind(this), true); - doc.addEventListener("mouseover", this.documentMouseOver.bind(this), true); } WebInspector._searchFieldManualFocus = function(event) @@ -2008,6 +2016,11 @@ WebInspector.UIString = function(string) return String.vsprintf(string, Array.prototype.slice.call(arguments, 1)); } +WebInspector.formatLocalized = function(format, substitutions, formatters, initialValue, append) +{ + return String.format(WebInspector.UIString(format), substitutions, formatters, initialValue, append); +} + WebInspector.isMac = function() { if (!("_isMac" in this)) diff --git a/WebCore/inspector/front-end/treeoutline.js b/WebCore/inspector/front-end/treeoutline.js index 5891401..c2a3fe7 100644 --- a/WebCore/inspector/front-end/treeoutline.js +++ b/WebCore/inspector/front-end/treeoutline.js @@ -651,6 +651,7 @@ TreeElement.treeElementToggled = function(event) else element.treeElement.expand(); } + event.stopPropagation(); } TreeElement.treeElementDoubleClicked = function(event) diff --git a/WebCore/inspector/front-end/utilities.js b/WebCore/inspector/front-end/utilities.js index e8adff6..5e41da6 100644 --- a/WebCore/inspector/front-end/utilities.js +++ b/WebCore/inspector/front-end/utilities.js @@ -984,3 +984,12 @@ function createSearchRegex(query) } return new RegExp(regex, "i"); } + +function offerFileForDownload(contents) +{ + var builder = new BlobBuilder(); + builder.append(contents); + var blob = builder.getBlob("application/octet-stream"); + var url = window.createBlobURL(blob); + window.open(url); +} |