summaryrefslogtreecommitdiffstats
path: root/WebCore/page/inspector/Resource.js
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/page/inspector/Resource.js')
-rw-r--r--WebCore/page/inspector/Resource.js689
1 files changed, 689 insertions, 0 deletions
diff --git a/WebCore/page/inspector/Resource.js b/WebCore/page/inspector/Resource.js
new file mode 100644
index 0000000..ed35970
--- /dev/null
+++ b/WebCore/page/inspector/Resource.js
@@ -0,0 +1,689 @@
+/*
+ * Copyright (C) 2007 Apple 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.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS 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 APPLE OR ITS 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.Resource = function(requestHeaders, url, domain, path, lastPathComponent, identifier, mainResource, cached)
+{
+ this.identifier = identifier;
+
+ this.startTime = -1;
+ this.endTime = -1;
+ this.mainResource = mainResource;
+ this.requestHeaders = requestHeaders;
+ this.url = url;
+ this.domain = domain;
+ this.path = path;
+ this.lastPathComponent = lastPathComponent;
+ this.cached = cached;
+
+ this.listItem = new WebInspector.ResourceTreeElement(this);
+ this.updateTitle();
+
+ this.category = WebInspector.resourceCategories.other;
+}
+
+// Keep these in sync with WebCore::InspectorResource::Type
+WebInspector.Resource.Type = {
+ Document: 0,
+ Stylesheet: 1,
+ Image: 2,
+ Font: 3,
+ Script: 4,
+ Other: 5,
+
+ isTextType: function(type)
+ {
+ return (type == this.Document) || (type == this.Stylesheet) || (type == this.Script);
+ },
+
+ toString: function(type)
+ {
+ switch (type) {
+ case this.Document:
+ return WebInspector.UIString("document");
+ case this.Stylesheet:
+ return WebInspector.UIString("stylesheet");
+ case this.Image:
+ return WebInspector.UIString("image");
+ case this.Font:
+ return WebInspector.UIString("font");
+ case this.Script:
+ return WebInspector.UIString("script");
+ case this.Other:
+ default:
+ return WebInspector.UIString("other");
+ }
+ }
+}
+
+WebInspector.Resource.prototype = {
+ get url()
+ {
+ return this._url;
+ },
+
+ set url(x)
+ {
+ if (this._url === x)
+ return;
+
+ var oldURL = this._url;
+ this._url = x;
+ WebInspector.resourceURLChanged(this, oldURL);
+ this.updateTitleSoon();
+ },
+
+ get domain()
+ {
+ return this._domain;
+ },
+
+ set domain(x)
+ {
+ if (this._domain === x)
+ return;
+ this._domain = x;
+ this.updateTitleSoon();
+ },
+
+ get lastPathComponent()
+ {
+ return this._lastPathComponent;
+ },
+
+ set lastPathComponent(x)
+ {
+ if (this._lastPathComponent === x)
+ return;
+ this._lastPathComponent = x;
+ this._lastPathComponentLowerCase = x ? x.toLowerCase() : null;
+ this.updateTitleSoon();
+ },
+
+ get displayName()
+ {
+ var title = this.lastPathComponent;
+ if (!title)
+ title = this.domain;
+ if (!title)
+ title = this.url;
+ return title;
+ },
+
+ get startTime()
+ {
+ return this._startTime;
+ },
+
+ set startTime(x)
+ {
+ if (this._startTime === x)
+ return;
+
+ this._startTime = x;
+
+ if (this.networkTimelineEntry)
+ this.networkTimelineEntry.refresh();
+ },
+
+ get responseReceivedTime()
+ {
+ return this._responseReceivedTime;
+ },
+
+ set responseReceivedTime(x)
+ {
+ if (this._responseReceivedTime === x)
+ return;
+
+ this._responseReceivedTime = x;
+
+ if (this.networkTimelineEntry)
+ this.networkTimelineEntry.refresh();
+ },
+
+ get endTime()
+ {
+ return this._endTime;
+ },
+
+ set endTime(x)
+ {
+ if (this._endTime === x)
+ return;
+
+ this._endTime = x;
+
+ if (this.networkTimelineEntry)
+ this.networkTimelineEntry.refresh();
+ },
+
+ get contentLength()
+ {
+ return this._contentLength;
+ },
+
+ set contentLength(x)
+ {
+ if (this._contentLength === x)
+ return;
+
+ this._contentLength = x;
+
+ if (this._expectedContentLength && this._expectedContentLength > x) {
+ this.updateTitle();
+ var canvas = document.getElementById("loadingIcon" + this.identifier);
+ if (canvas)
+ WebInspector.drawLoadingPieChart(canvas, (x / this._expectedContentLength));
+ }
+
+ WebInspector.networkPanel.updateSummaryGraphSoon();
+ },
+
+ get expectedContentLength()
+ {
+ return this._expectedContentLength;
+ },
+
+ set expectedContentLength(x)
+ {
+ if (this._expectedContentLength === x)
+ return;
+
+ this._expectedContentLength = x;
+
+ if (x && this._contentLength && this._contentLength <= x) {
+ var canvas = document.getElementById("loadingIcon" + this.identifier);
+ if (canvas)
+ WebInspector.drawLoadingPieChart(canvas, (this._contentLength / x));
+ }
+ },
+
+ get finished()
+ {
+ return this._finished;
+ },
+
+ set finished(x)
+ {
+ if (this._finished === x)
+ return;
+
+ this._finished = x;
+
+ if (x) {
+ var canvas = document.getElementById("loadingIcon" + this.identifier);
+ if (canvas)
+ canvas.parentNode.removeChild(canvas);
+
+ this._checkTips();
+ this._checkWarnings();
+ }
+
+ this.updateTitleSoon();
+ this.updatePanel();
+ },
+
+ get failed()
+ {
+ return this._failed;
+ },
+
+ set failed(x)
+ {
+ this._failed = x;
+
+ this.updateTitleSoon();
+ this.updatePanel();
+ },
+
+ get category()
+ {
+ return this._category;
+ },
+
+ set category(x)
+ {
+ if (this._category === x)
+ return;
+
+ var oldCategory = this._category;
+ if (oldCategory)
+ oldCategory.removeResource(this);
+
+ this._category = x;
+ this.updateTitle();
+
+ if (this._category)
+ this._category.addResource(this);
+
+ this.updatePanel();
+ },
+
+ get mimeType()
+ {
+ return this._mimeType;
+ },
+
+ set mimeType(x)
+ {
+ if (this._mimeType === x)
+ return;
+
+ this._mimeType = x;
+ },
+
+ get type()
+ {
+ return this._type;
+ },
+
+ set type(x)
+ {
+ if (this._type === x)
+ return;
+
+ this._type = x;
+
+ switch (x) {
+ case WebInspector.Resource.Type.Document:
+ this.category = WebInspector.resourceCategories.documents;
+ break;
+ case WebInspector.Resource.Type.Stylesheet:
+ this.category = WebInspector.resourceCategories.stylesheets;
+ break;
+ case WebInspector.Resource.Type.Script:
+ this.category = WebInspector.resourceCategories.scripts;
+ break;
+ case WebInspector.Resource.Type.Image:
+ this.category = WebInspector.resourceCategories.images;
+ break;
+ case WebInspector.Resource.Type.Font:
+ this.category = WebInspector.resourceCategories.fonts;
+ break;
+ case WebInspector.Resource.Type.Other:
+ default:
+ this.category = WebInspector.resourceCategories.other;
+ break;
+ }
+ },
+
+ get documentNode() {
+ if ("identifier" in this)
+ return InspectorController.getResourceDocumentNode(this.identifier);
+ return null;
+ },
+
+ get requestHeaders()
+ {
+ if (this._requestHeaders === undefined)
+ this._requestHeaders = {};
+ return this._requestHeaders;
+ },
+
+ set requestHeaders(x)
+ {
+ if (this._requestHeaders === x)
+ return;
+
+ this._requestHeaders = x;
+ delete this._sortedRequestHeaders;
+
+ if (this.networkTimelineEntry)
+ this.networkTimelineEntry.refreshInfo();
+ },
+
+ get sortedRequestHeaders()
+ {
+ if (this._sortedRequestHeaders !== undefined)
+ return this._sortedRequestHeaders;
+
+ this._sortedRequestHeaders = [];
+ for (var key in this.requestHeaders)
+ this._sortedRequestHeaders.push({header: key, value: this.requestHeaders[key]});
+ this._sortedRequestHeaders.sort(function(a,b) { return a.header.localeCompare(b.header) });
+
+ return this._sortedRequestHeaders;
+ },
+
+ get responseHeaders()
+ {
+ if (this._responseHeaders === undefined)
+ this._responseHeaders = {};
+ return this._responseHeaders;
+ },
+
+ set responseHeaders(x)
+ {
+ if (this._responseHeaders === x)
+ return;
+
+ this._responseHeaders = x;
+ delete this._sortedResponseHeaders;
+
+ if (this.networkTimelineEntry)
+ this.networkTimelineEntry.refreshInfo();
+ },
+
+ get sortedResponseHeaders()
+ {
+ if (this._sortedResponseHeaders !== undefined)
+ return this._sortedResponseHeaders;
+
+ this._sortedResponseHeaders = [];
+ for (var key in this.responseHeaders)
+ this._sortedResponseHeaders.push({header: key, value: this.responseHeaders[key]});
+ this._sortedResponseHeaders.sort(function(a,b) { return a.header.localeCompare(b.header) });
+
+ return this._sortedResponseHeaders;
+ },
+
+ get tips()
+ {
+ if (!("_tips" in this))
+ this._tips = {};
+ return this._tips;
+ },
+
+ _addTip: function(tip)
+ {
+ if (tip.id in this.tips)
+ return;
+
+ this.tips[tip.id] = tip;
+
+ // FIXME: Re-enable this code once we have a scope bar in the Console.
+ // Otherwise, we flood the Console with too many tips.
+ /*
+ var msg = new WebInspector.ConsoleMessage(WebInspector.ConsoleMessage.MessageSource.Other,
+ WebInspector.ConsoleMessage.MessageLevel.Tip, tip.message, -1, this.url);
+ WebInspector.consolePanel.addMessage(msg);
+ */
+
+ if (this.networkTimelineEntry)
+ this.networkTimelineEntry.showingTipButton = true;
+ },
+
+ _checkTips: function()
+ {
+ for (var tip in WebInspector.Tips)
+ this._checkTip(WebInspector.Tips[tip]);
+ },
+
+ _checkTip: function(tip)
+ {
+ var addTip = false;
+ switch (tip.id) {
+ case WebInspector.Tips.ResourceNotCompressed.id:
+ addTip = this._shouldCompress();
+ break;
+ }
+
+ if (addTip)
+ this._addTip(tip);
+ },
+
+ _shouldCompress: function()
+ {
+ return WebInspector.Resource.Type.isTextType(this.type)
+ && this.domain
+ && !("Content-Encoding" in this.responseHeaders)
+ && this.contentLength !== undefined
+ && this.contentLength >= 512;
+ },
+
+ _mimeTypeIsConsistentWithType: function()
+ {
+ if (this.type === undefined || this.type === WebInspector.Resource.Type.Other)
+ return true;
+
+ if (this.mimeType in WebInspector.MIMETypes)
+ return this.type in WebInspector.MIMETypes[this.mimeType];
+
+ return true;
+ },
+
+ _checkWarnings: function()
+ {
+ for (var warning in WebInspector.Warnings)
+ this._checkWarning(WebInspector.Warnings[warning]);
+ },
+
+ _checkWarning: function(warning)
+ {
+ var addWarning = false;
+ var msg;
+ switch (warning.id) {
+ case WebInspector.Warnings.IncorrectMIMEType.id:
+ if (!this._mimeTypeIsConsistentWithType())
+ msg = new WebInspector.ConsoleMessage(WebInspector.ConsoleMessage.MessageSource.Other,
+ WebInspector.ConsoleMessage.MessageLevel.Warning,
+ String.sprintf(WebInspector.Warnings.IncorrectMIMEType.message,
+ WebInspector.Resource.Type.toString(this.type), this.mimeType),
+ -1, this.url);
+ break;
+ }
+
+ if (msg)
+ WebInspector.consolePanel.addMessage(msg);
+ },
+
+ updateTitleSoon: function()
+ {
+ if (this.updateTitleTimeout)
+ return;
+ this.updateTitleTimeout = setTimeout(this.updateTitle.bind(this), 0);
+ },
+
+ updateTitle: function()
+ {
+ delete this.updateTitleTimeout;
+
+ var title = this.displayName;
+
+ var info = "";
+ if (this.domain && (!WebInspector.mainResource || (WebInspector.mainResource && this.domain !== WebInspector.mainResource.domain)))
+ info = this.domain;
+
+ if (this.path && this.lastPathComponent) {
+ var lastPathComponentIndex = this.path.lastIndexOf("/" + this.lastPathComponent);
+ if (lastPathComponentIndex != -1)
+ info += this.path.substring(0, lastPathComponentIndex);
+ }
+
+ var fullTitle = "";
+
+ if (this.errors)
+ fullTitle += "<span class=\"count errors\">" + (this.errors + this.warnings) + "</span>";
+ else if (this.warnings)
+ fullTitle += "<span class=\"count warnings\">" + this.warnings + "</span>";
+
+ fullTitle += "<span class=\"title" + (info && info.length ? "" : " only") + "\">" + title.escapeHTML() + "</span>";
+ if (info && info.length)
+ fullTitle += "<span class=\"info\">" + info.escapeHTML() + "</span>";
+
+ var iconClass = "icon";
+ switch (this.category) {
+ default:
+ break;
+ case WebInspector.resourceCategories.images:
+ case WebInspector.resourceCategories.other:
+ iconClass = "icon plain";
+ break;
+ case WebInspector.resourceCategories.fonts:
+ iconClass = "icon font";
+ }
+
+ if (!this.finished)
+ fullTitle += "<div class=\"" + iconClass + "\"><canvas id=\"loadingIcon" + this.identifier + "\" class=\"progress\" width=\"16\" height=\"16\"></canvas></div>";
+ else if (this.category === WebInspector.resourceCategories.images)
+ fullTitle += "<div class=\"" + iconClass + "\"><img class=\"preview\" src=\"" + this.url + "\"></div>";
+ else if (this.category === WebInspector.resourceCategories.fonts) {
+ var uniqueFontName = "WebInspectorFontPreview" + this.identifier;
+
+ this.fontStyleElement = document.createElement("style");
+ this.fontStyleElement.textContent = "@font-face { font-family: \"" + uniqueFontName + "\"; src: url(" + this.url + "); }";
+ document.getElementsByTagName("head").item(0).appendChild(this.fontStyleElement);
+
+ fullTitle += "<div class=\"" + iconClass + "\"><div class=\"preview\" style=\"font-family: " + uniqueFontName + "\">Ag</div></div>";
+ } else
+ fullTitle += "<div class=\"" + iconClass + "\"></div>";
+
+ this.listItem.title = fullTitle;
+ this.listItem.tooltip = this.url;
+ },
+
+ updatePanel: function()
+ {
+ if (this._panel) {
+ var current = (WebInspector.currentPanel === this._panel);
+
+ this._panel.detach();
+ delete this._panel;
+
+ if (current)
+ WebInspector.currentPanel = this.panel;
+ }
+ },
+
+ get panel()
+ {
+ if (!this._panel) {
+ if (this.finished && !this.failed) {
+ switch (this.category) {
+ case WebInspector.resourceCategories.documents:
+ this._panel = new WebInspector.DocumentPanel(this);
+ break;
+ case WebInspector.resourceCategories.stylesheets:
+ case WebInspector.resourceCategories.scripts:
+ this._panel = new WebInspector.SourcePanel(this);
+ break;
+ case WebInspector.resourceCategories.images:
+ this._panel = new WebInspector.ImagePanel(this);
+ break;
+ case WebInspector.resourceCategories.fonts:
+ this._panel = new WebInspector.FontPanel(this);
+ break;
+ }
+ }
+
+ if (!this._panel)
+ this._panel = new WebInspector.ResourcePanel(this);
+ }
+
+ return this._panel;
+ },
+
+ select: function()
+ {
+ WebInspector.navigateToResource(this);
+ },
+
+ deselect: function()
+ {
+ this.listItem.deselect(true);
+ if (WebInspector.currentPanel === this._panel)
+ WebInspector.currentPanel = null;
+ },
+
+ attach: function()
+ {
+ if (this._panel)
+ this._panel.attach();
+ },
+
+ detach: function()
+ {
+ if (this._panel)
+ this._panel.detach();
+ if (this.fontStyleElement && this.fontStyleElement.parentNode)
+ this.fontStyleElement.parentNode.removeChild(this.fontStyleElement);
+ },
+
+ get errors()
+ {
+ if (!("_errors" in this))
+ this._errors = 0;
+
+ return this._errors;
+ },
+
+ set errors(x)
+ {
+ if (this._errors === x)
+ return;
+
+ this._errors = x;
+ this.updateTitleSoon();
+ },
+
+ get warnings()
+ {
+ if (!("_warnings" in this))
+ this._warnings = 0;
+
+ return this._warnings;
+ },
+
+ set warnings(x)
+ {
+ if (this._warnings === x)
+ return;
+
+ this._warnings = x;
+ this.updateTitleSoon();
+ }
+}
+
+WebInspector.ResourceTreeElement = function(resource)
+{
+ TreeElement.call(this, "", resource, false);
+ this.resource = resource;
+}
+
+WebInspector.ResourceTreeElement.prototype = {
+ onselect: function()
+ {
+ var selectedElement = WebInspector.fileOutline.selectedTreeElement;
+ if (selectedElement)
+ selectedElement.deselect();
+ this.resource.select();
+ },
+
+ ondeselect: function()
+ {
+ this.resource.deselect();
+ },
+
+ onreveal: function()
+ {
+ if (this.listItemElement)
+ this.listItemElement.scrollIntoViewIfNeeded(false);
+ }
+}
+
+WebInspector.ResourceTreeElement.prototype.__proto__ = TreeElement.prototype;