WebInspector.ResourcePanel = function(resource)
{
this.resource = resource;
this.messages = [];
WebInspector.Panel.call(this);
}
WebInspector.ResourcePanel.prototype = {
show: function()
{
this.resource.listItem.select(true);
this.resource.listItem.reveal();
if (this.currentView && "onshow" in this.currentView)
this.currentView.onshow();
WebInspector.Panel.prototype.show.call(this);
},
hide: function()
{
this.resource.listItem.deselect(true);
if (this.currentView && "onhide" in this.currentView)
this.currentView.onhide();
WebInspector.Panel.prototype.hide.call(this);
},
sourceRow: function(lineNumber)
{
this.refreshIfNeeded();
var doc = this.sourceFrame.contentDocument;
var rows = doc.getElementsByTagName("table")[0].rows;
--lineNumber;
if (lineNumber >= rows.length)
lineNumber = rows.length - 1;
return rows[lineNumber];
},
showSourceLine: function(lineNumber)
{
var row = this.sourceRow(lineNumber);
if (!row)
return;
this.navigateToView("source");
row.scrollIntoView(true);
},
addMessageToSource: function(msg)
{
this.messages.push(msg);
if (this.sourceFrame)
this._addMessageToSource(msg);
},
_addMessageToSource: function(msg)
{
var row = this.sourceRow(msg.line);
if (!row)
return;
var cell = row.getElementsByTagName("td")[1];
var errorDiv = cell.lastChild;
if (!errorDiv || errorDiv.nodeName.toLowerCase() !== "div" || !errorDiv.hasStyleClass("webkit-html-message-bubble")) {
errorDiv = document.createElement("div");
errorDiv.className = "webkit-html-message-bubble";
cell.appendChild(errorDiv);
}
var imageURL;
switch (msg.level) {
case WebInspector.ConsoleMessage.MessageLevel.Error:
errorDiv.addStyleClass("webkit-html-error-message");
imageURL = "Images/errorIcon.png";
break;
case WebInspector.ConsoleMessage.MessageLevel.Warning:
errorDiv.addStyleClass("webkit-html-warning-message");
imageURL = "Images/warningIcon.png";
break;
}
var lineDiv = document.createElement("div");
lineDiv.className = "webkit-html-message-line";
errorDiv.appendChild(lineDiv);
var image = document.createElement("img");
image.src = imageURL;
image.className = "webkit-html-message-icon";
lineDiv.appendChild(image);
lineDiv.appendChild(document.createTextNode(msg.message));
},
_addMessagesToSource: function()
{
for (var i = 0; i < this.messages.length; ++i)
this._addMessageToSource(this.messages[i]);
},
navigateToView: function(view)
{
if (typeof view === "string" || view instanceof String) {
if (this.needsRefresh)
this.refresh();
view = this.views[view];
}
WebInspector.navigateToView(view);
},
createViews: function()
{
this.currentView = null;
var selectViewFunction = function(event)
{
WebInspector.navigateToView(event.currentTarget.view);
}
var views = [
{name: "source", title: "Source", selected: true},
];
if (this.resource.category === WebInspector.resourceCategories.documents) {
var domView = {name: "dom", title: "DOM", selected: false};
var panel = this;
domView.onshow = function() { InspectorController.highlightDOMNode(panel.focusedDOMNode) };
domView.onhide = function() { InspectorController.hideDOMNodeHighlight() };
views.push(domView);
}
var oldViews = this.views || {};
this.views = {};
this.viewButtons = [];
for (var i = 0; i < views.length; ++i) {
var buttonElement = document.createElement("button");
buttonElement.setAttribute("title", views[i].title);
buttonElement.addEventListener("click", selectViewFunction, "true");
buttonElement.appendChild(document.createElement("img"));
var contentElement = document.createElement("div");
contentElement.className = "content " + views[i].name;
var view = oldViews[views[i].name] || {};
view.buttonElement = buttonElement;
view.contentElement = contentElement;
view.panel = this;
view.buttonElement.view = view;
if ("onshow" in views[i])
view.onshow = views[i].onshow;
if ("onhide" in views[i])
view.onhide = views[i].onhide;
this.views[views[i].name] = view;
this.viewButtons.push(buttonElement);
this.element.appendChild(contentElement);
}
this.currentView = this.views.source;
if (WebInspector.currentPanel == this)
WebInspector.updateViewButtons();
},
_createSourceFrame: function()
{
this.sourceFrame = document.createElement("iframe");
this.sourceFrame.setAttribute("viewsource", "true");
this.sourceFrame.name = "sourceFrame" + WebInspector.ResourcePanel.sourceFrameCounter++;
this.views.source.contentElement.appendChild(this.sourceFrame);
InspectorController.addSourceToFrame(this.resource.identifier, this.sourceFrame);
WebInspector.addMainEventListeners(this.sourceFrame.contentDocument);
this._addMessagesToSource();
},
updateTreeSelection: function()
{
if (!this.domTreeOutline || !this.domTreeOutline.selectedTreeElement)
return;
var element = this.domTreeOutline.selectedTreeElement;
element.updateSelection(element);
},
refresh: function()
{
this.needsRefresh = false;
this.element.removeChildren();
this.createViews();
if (!this.resource.finished)
this.views.source.contentElement.addStyleClass("loading");
else if (this.resource.failed)
this.views.source.contentElement.removeStyleClass("failed");
else if (this.resource.category === WebInspector.resourceCategories.documents) {
this._createSourceFrame();
this.views.dom.contentElement.sideContentElement = document.createElement("div");
this.views.dom.contentElement.sideContentElement.className = "content side";
this.views.dom.contentElement.treeContentElement = document.createElement("div");
this.views.dom.contentElement.treeContentElement.className = "content tree outline-disclosure";
this.views.dom.contentElement.treeListElement = document.createElement("ol");
this.domTreeOutline = new TreeOutline(this.views.dom.contentElement.treeListElement);
this.domTreeOutline.panel = this;
var panel = this;
window.addEventListener("resize", function() { panel.updateTreeSelection() }, false);
this.views.dom.contentElement.crumbsElement = document.createElement("div");
this.views.dom.contentElement.crumbsElement.className = "crumbs";
this.views.dom.contentElement.innerCrumbsElement = document.createElement("div");
this.views.dom.contentElement.crumbsElement.appendChild(this.views.dom.contentElement.innerCrumbsElement);
this.views.dom.contentElement.sidebarPanes = {};
this.views.dom.contentElement.sidebarPanes.styles = new WebInspector.SidebarPane("Styles");
this.views.dom.contentElement.sidebarPanes.metrics = new WebInspector.SidebarPane("Metrics");
this.views.dom.contentElement.sidebarPanes.properties = new WebInspector.SidebarPane("Properties");
var panel = this;
this.views.dom.contentElement.sidebarPanes.styles.onexpand = function() { panel.updateStyles() };
this.views.dom.contentElement.sidebarPanes.metrics.onexpand = function() { panel.updateMetrics() };
this.views.dom.contentElement.sidebarPanes.properties.onexpand = function() { panel.updateProperties() };
this.views.dom.contentElement.sidebarPanes.styles.expanded = true;
this.views.dom.contentElement.sidebarElement = document.createElement("div");
this.views.dom.contentElement.sidebarElement.className = "sidebar";
this.views.dom.contentElement.sidebarElement.appendChild(this.views.dom.contentElement.sidebarPanes.styles.element);
this.views.dom.contentElement.sidebarElement.appendChild(this.views.dom.contentElement.sidebarPanes.metrics.element);
this.views.dom.contentElement.sidebarElement.appendChild(this.views.dom.contentElement.sidebarPanes.properties.element);
this.views.dom.contentElement.sideContentElement.appendChild(this.views.dom.contentElement.treeContentElement);
this.views.dom.contentElement.sideContentElement.appendChild(this.views.dom.contentElement.crumbsElement);
this.views.dom.contentElement.treeContentElement.appendChild(this.views.dom.contentElement.treeListElement);
this.views.dom.contentElement.appendChild(this.views.dom.contentElement.sideContentElement);
this.views.dom.contentElement.appendChild(this.views.dom.contentElement.sidebarElement);
this.rootDOMNode = this.resource.documentNode;
} else if (this.resource.category === WebInspector.resourceCategories.images) {
this.views.source.contentElement.removeStyleClass("source");
this.views.source.contentElement.addStyleClass("image");
var container = document.createElement("div");
container.className = "image";
this.views.source.contentElement.appendChild(container);
this.imagePreviewElement = document.createElement("img");
this.imagePreviewElement.setAttribute("src", this.resource.url);
container.appendChild(this.imagePreviewElement);
container = document.createElement("div");
container.className = "info";
this.views.source.contentElement.appendChild(container);
var imageNameElement = document.createElement("h1");
imageNameElement.className = "title";
imageNameElement.textContent = this.resource.displayName;
container.appendChild(imageNameElement);
var infoListElement = document.createElement("dl");
infoListElement.className = "infoList";
var imageProperties = [
{name: "Dimensions", value: this.imagePreviewElement.naturalWidth + " \u00D7 " + this.imagePreviewElement.height},
{name: "File size", value: (this.resource.contentLength / 1024).toPrecision(2) + "KB"},
{name: "MIME type", value: this.resource.mimeType}
];
var listHTML = '';
for (var i = 0; i < imageProperties.length; ++i)
listHTML += "<dt>" + imageProperties[i].name + "</dt><dd>" + imageProperties[i].value + "</dd>";
infoListElement.innerHTML = listHTML;
container.appendChild(infoListElement);
} else if (this.resource.category === WebInspector.resourceCategories.stylesheets
|| this.resource.category === WebInspector.resourceCategories.scripts) {
this.views.source.contentElement.addStyleClass(this.resource.category.title.toLowerCase());
this._createSourceFrame();
} else {
if (this.resource.category)
this.views.source.contentElement.addStyleClass(this.resource.category.title.toLowerCase());
}
},
get currentView()
{
return this._currentView;
},
set currentView(x)
{
if (this._currentView === x)
return;
if (this._currentView) {
this._currentView.buttonElement.removeStyleClass("selected");
this._currentView.contentElement.removeStyleClass("selected");
if ("onhide" in this._currentView)
this._currentView.onhide();
}
this._currentView = x;
if (x) {
x.buttonElement.addStyleClass("selected");
x.contentElement.addStyleClass("selected");
if ("onshow" in x)
x.onshow();
if (x.contentElement.parentNode !== this.element)
InspectorController.log("Tried to set currentView to a view " + x.title + " whose contentElement is a non-child");
}
},
get rootDOMNode()
{
return this._rootDOMNode;
},
set rootDOMNode(x)
{
if (this._rootDOMNode === x)
return;
this._rootDOMNode = x;
this.updateBreadcrumb();
this.updateTreeOutline();
},
get focusedDOMNode()
{
return this._focusedDOMNode;
},
set focusedDOMNode(x)
{
if (this.resource.category !== WebInspector.resourceCategories.documents) {
InspectorController.log("Called set focusedDOMNode on a non-document resource " + this.resource.displayName + " which is not a document");
return;
}
if (this._focusedDOMNode === x) {
var nodeItem = this.revealNode(x);
if (nodeItem)
nodeItem.select();
return;
}
this._focusedDOMNode = x;
this.updateBreadcrumb();
for (var pane in this.views.dom.contentElement.sidebarPanes)
this.views.dom.contentElement.sidebarPanes[pane].needsUpdate = true;
this.updateStyles();
this.updateMetrics();
this.updateProperties();
InspectorController.highlightDOMNode(x);
var nodeItem = this.revealNode(x);
if (nodeItem)
nodeItem.select();
},
revealNode: function(node)
{
var nodeItem = this.domTreeOutline.findTreeElement(node, function(a, b) { return isAncestorNode.call(a, b); }, function(a) { return a.parentNode; });
if (!nodeItem)
return;
nodeItem.reveal();
return nodeItem;
},
updateTreeOutline: function()
{
this.domTreeOutline.removeChildrenRecursive();
if (!this.rootDOMNode)
return;
var node = (Preferences.ignoreWhitespace ? firstChildSkippingWhitespace.call(this.rootDOMNode) : this.rootDOMNode.firstChild);
while (node) {
var item = new WebInspector.DOMNodeTreeElement(node);
this.domTreeOutline.appendChild(item);
node = Preferences.ignoreWhitespace ? nextSiblingSkippingWhitespace.call(node) : node.nextSibling;
}
this.updateTreeSelection();
},
updateBreadcrumb: function()
{
if (!this.views || !this.views.dom.contentElement)
return;
var crumbs = this.views.dom.contentElement.innerCrumbsElement;
if (!crumbs)
return;
var handled = false;
var foundRoot = false;
var crumb = crumbs.firstChild;
while (crumb) {
if (crumb.representedObject === this.rootDOMNode)
foundRoot = true;
if (foundRoot)
crumb.addStyleClass("hidden");
else
crumb.removeStyleClass("hidden");
if (crumb.representedObject === this.focusedDOMNode) {
crumb.addStyleClass("selected");
handled = true;
} else {
crumb.removeStyleClass("selected");
}
crumb = crumb.nextSibling;
}
if (handled)
return;
crumbs.removeChildren();
var panel = this;
var selectCrumbFunction = function(event)
{
if (event.currentTarget.hasStyleClass("hidden"))
panel.rootDOMNode = event.currentTarget.representedObject.parentNode;
panel.focusedDOMNode = event.currentTarget.representedObject;
event.preventDefault();
event.stopPropagation();
}
var selectCrumbRootFunction = function(event)
{
panel.rootDOMNode = event.currentTarget.representedObject.parentNode;
panel.focusedDOMNode = event.currentTarget.representedObject;
event.preventDefault();
event.stopPropagation();
}
foundRoot = false;
var current = this.focusedDOMNode;
while (current) {
if (current.nodeType === Node.DOCUMENT_NODE)
break;
if (current === this.rootDOMNode)
foundRoot = true;
var crumb = document.createElement("span");
crumb.className = "crumb";
crumb.representedObject = current;
crumb.addEventListener("mousedown", selectCrumbFunction, false);
crumb.addEventListener("dblclick", selectCrumbRootFunction, false);
var crumbTitle;
switch (current.nodeType) {
case Node.ELEMENT_NODE:
crumbTitle = current.nodeName.toLowerCase();
var value = current.getAttribute("id");
if (value && value.length)
crumbTitle += "#" + value;
value = current.getAttribute("class");
if (value && value.length) {
var classes = value.split(/\s+/);
var classesLength = classes.length;
for (var i = 0; i < classesLength; ++i) {
value = classes[i];
if (value && value.length)
crumbTitle += "." + value;
}
}
break;
case Node.TEXT_NODE:
if (isNodeWhitespace.call(current))
crumbTitle = "(whitespace)";
else
crumbTitle = "(text)";
break
case Node.COMMENT_NODE:
crumbTitle = "<!-->";
break;
default:
crumbTitle = current.nodeName.toLowerCase();
}
crumb.textContent = crumbTitle;
if (foundRoot)
crumb.addStyleClass("hidden");
if (current === this.focusedDOMNode)
crumb.addStyleClass("selected");
if (!crumbs.childNodes.length)
crumb.addStyleClass("end");
if (current.parentNode.nodeType === Node.DOCUMENT_NODE)
crumb.addStyleClass("start");
crumbs.appendChild(crumb);
current = current.parentNode;
}
},
updateStyles: function()
{
if (!this.views.dom.contentElement.sidebarPanes.styles.expanded)
return;
if (!this.views.dom.contentElement.sidebarPanes.styles.needsUpdate)
return;
this.views.dom.contentElement.sidebarPanes.styles.needsUpdate = false;
var stylesBody = this.views.dom.contentElement.sidebarPanes.styles.bodyElement;
stylesBody.removeChildren();
this.views.dom.contentElement.sidebarPanes.styles.sections = [];
if (!this.focusedDOMNode)
return;
var styleNode = this.focusedDOMNode;
if (styleNode.nodeType === Node.TEXT_NODE && styleNode.parentNode)
styleNode = styleNode.parentNode;
var styleRules = [];
var styleProperties = [];
if (styleNode.nodeType === Node.ELEMENT_NODE) {
var propertyCount = [];
var computedStyle = styleNode.ownerDocument.defaultView.getComputedStyle(styleNode);
if (computedStyle && computedStyle.length)
styleRules.push({ isComputedStyle: true, selectorText: "Computed Style", style: computedStyle });
var styleNodeName = styleNode.nodeName.toLowerCase();
for (var i = 0; i < styleNode.attributes.length; ++i) {
var attr = styleNode.attributes[i];
if (attr.style) {
var attrStyle = { attrName: attr.name, style: attr.style };
attrStyle.subtitle = "element\u2019s \u201C" + attr.name + "\u201D attribute";
attrStyle.selectorText = styleNodeName + "[" + attr.name;
if (attr.value.length)
attrStyle.selectorText += "=" + attr.value;
attrStyle.selectorText += "]";
styleRules.push(attrStyle);
}
}
if (styleNode.style && styleNode.style.length) {
var inlineStyle = { selectorText: "Inline Style Attribute", style: styleNode.style };
inlineStyle.subtitle = "element\u2019s \u201Cstyle\u201D attribute";
styleRules.push(inlineStyle);
}
var matchedStyleRules = styleNode.ownerDocument.defaultView.getMatchedCSSRules(styleNode, "", !Preferences.showUserAgentStyles);
if (matchedStyleRules) {
for (var i = matchedStyleRules.length - 1; i >= 0; --i)
styleRules.push(matchedStyleRules[i]);
}
var priorityUsed = false;
var usedProperties = {};
var shorthandProperties = {};
for (var i = 0; i < styleRules.length; ++i) {
styleProperties[i] = [];
var style = styleRules[i].style;
var styleShorthandLookup = [];
for (var j = 0; j < style.length; ++j) {
var prop = null;
var name = style[j];
var shorthand = style.getPropertyShorthand(name);
if (!shorthand && styleRules[i].isComputedStyle)
shorthand = shorthandProperties[name];
if (shorthand) {
prop = styleShorthandLookup[shorthand];
shorthandProperties[name] = shorthand;
}
if (!priorityUsed && style.getPropertyPriority(name).length)
priorityUsed = true;
if (prop) {
prop.subProperties.push(name);
} else {
prop = { style: style, subProperties: [name], unusedProperties: [], name: (shorthand ? shorthand : name) };
styleProperties[i].push(prop);
if (shorthand) {
styleShorthandLookup[shorthand] = prop;
if (!styleRules[i].isComputedStyle) {
if (!propertyCount[shorthand]) {
propertyCount[shorthand] = 1;
} else {
prop.unusedProperties[shorthand] = true;
propertyCount[shorthand]++;
}
}
}
}
if (styleRules[i].isComputedStyle)
continue;
usedProperties[name] = true;
if (shorthand)
usedProperties[shorthand] = true;
if (!propertyCount[name]) {
propertyCount[name] = 1;
} else {
prop.unusedProperties[name] = true;
propertyCount[name]++;
}
}
}
if (priorityUsed) {
var priorityCount = [];
for (var i = 0; i < styleRules.length; ++i) {
if (styleRules[i].isComputedStyle)
continue;
var style = styleRules[i].style;
for (var j = 0; j < styleProperties[i].length; ++j) {
var prop = styleProperties[i][j];
for (var k = 0; k < prop.subProperties.length; ++k) {
var name = prop.subProperties[k];
if (style.getPropertyPriority(name).length) {
if (!priorityCount[name]) {
if (prop.unusedProperties[name])
prop.unusedProperties[name] = false;
priorityCount[name] = 1;
} else {
priorityCount[name]++;
}
} else if (priorityCount[name]) {
prop.unusedProperties[name] = true;
}
}
}
}
}
var styleRulesLength = styleRules.length;
for (var i = 0; i < styleRulesLength; ++i) {
var selectorText = styleRules[i].selectorText;
var section = new WebInspector.PropertiesSection(selectorText);
section.expanded = true;
if (styleRules[i].isComputedStyle) {
if (Preferences.showInheritedComputedStyleProperties)
section.element.addStyleClass("show-inherited");
var showInheritedLabel = document.createElement("label");
var showInheritedInput = document.createElement("input");
showInheritedInput.type = "checkbox";
showInheritedInput.checked = Preferences.showInheritedComputedStyleProperties;
var computedStyleSection = section;
var showInheritedToggleFunction = function(event) {
Preferences.showInheritedComputedStyleProperties = showInheritedInput.checked;
if (Preferences.showInheritedComputedStyleProperties)
computedStyleSection.element.addStyleClass("show-inherited");
else
computedStyleSection.element.removeStyleClass("show-inherited");
event.stopPropagation();
};
showInheritedLabel.addEventListener("click", showInheritedToggleFunction, false);
showInheritedLabel.appendChild(showInheritedInput);
showInheritedLabel.appendChild(document.createTextNode("Show implicit properties"));
section.subtitleElement.appendChild(showInheritedLabel);
} else {
var sheet;
var file = false;
if (styleRules[i].subtitle)
sheet = styleRules[i].subtitle;
else if (styleRules[i].parentStyleSheet && styleRules[i].parentStyleSheet.href) {
var url = styleRules[i].parentStyleSheet.href;
sheet = WebInspector.linkifyURL(url, url.trimURL(WebInspector.mainResource.domain).escapeHTML());
file = true;
} else if (styleRules[i].parentStyleSheet && !styleRules[i].parentStyleSheet.ownerNode)
sheet = "user agent stylesheet";
else
sheet = "inline stylesheet";
if (file)
section.subtitleElement.addStyleClass("file");
section.subtitle = sheet;
}
stylesBody.appendChild(section.element);
this.views.dom.contentElement.sidebarPanes.styles.sections.push(section);
var properties = styleProperties[i];
var isComputedStyle = styleRules[i].isComputedStyle;
for (var j = 0; j < properties.length; ++j) {
var prop = properties[j];
var propTreeElement = new WebInspector.StylePropertyTreeElement(prop, isComputedStyle, usedProperties);
section.propertiesTreeOutline.appendChild(propTreeElement);
}
}
} else {
}
},
updateMetrics: function()
{
if (!this.views.dom.contentElement.sidebarPanes.metrics.expanded)
return;
if (!this.views.dom.contentElement.sidebarPanes.metrics.needsUpdate)
return;
this.views.dom.contentElement.sidebarPanes.metrics.needsUpdate = false;
var metricsBody = this.views.dom.contentElement.sidebarPanes.metrics.bodyElement;
metricsBody.removeChildren();
if (!this.focusedDOMNode)
return;
var style;
if (this.focusedDOMNode.nodeType === Node.ELEMENT_NODE)
style = this.focusedDOMNode.ownerDocument.defaultView.getComputedStyle(this.focusedDOMNode);
if (!style)
return;
var metricsElement = document.createElement("div");
metricsElement.className = "metrics";
function boxPartValue(style, name, suffix)
{
var value = style.getPropertyValue(name + suffix);
if (value === "" || value === "0px")
value = "\u2012";
return value.replace(/px$/, "");
}
var noMarginDisplayType = {
"table-cell": true,
"table-column": true,
"table-column-group": true,
"table-footer-group": true,
"table-header-group": true,
"table-row": true,
"table-row-group": true
};
var noPaddingDisplayType = {
"table-column": true,
"table-column-group": true,
"table-footer-group": true,
"table-header-group": true,
"table-row": true,
"table-row-group": true
};
var boxes = ["content", "padding", "border", "margin"];
var previousBox;
for (var i = 0; i < boxes.length; ++i) {
var name = boxes[i];
if (name === "margin" && noMarginDisplayType[style.display])
continue;
if (name === "padding" && noPaddingDisplayType[style.display])
continue;
var boxElement = document.createElement("div");
boxElement.className = name;
if (boxes[i] === "content") {
var width = style.width.replace(/px$/, "");
var height = style.height.replace(/px$/, "");
boxElement.textContent = width + " \u00D7 " + height;
} else {
var suffix = boxes[i] === "border" ? "-width" : "";
var labelElement = document.createElement("div");
labelElement.className = "label";
labelElement.textContent = name;
boxElement.appendChild(labelElement);
var topElement = document.createElement("div");
topElement.className = "top";
topElement.textContent = boxPartValue(style, name + "-top", suffix);
boxElement.appendChild(topElement);
var leftElement = document.createElement("div");
leftElement.className = "left";
leftElement.textContent = boxPartValue(style, name + "-left", suffix);
boxElement.appendChild(leftElement);
if (previousBox)
boxElement.appendChild(previousBox);
var rightElement = document.createElement("div");
rightElement.className = "right";
rightElement.textContent = boxPartValue(style, name + "-right", suffix);
boxElement.appendChild(rightElement);
var bottomElement = document.createElement("div");
bottomElement.className = "bottom";
bottomElement.textContent = boxPartValue(style, name + "-bottom", suffix);
boxElement.appendChild(bottomElement);
}
previousBox = boxElement;
}
metricsElement.appendChild(previousBox);
metricsBody.appendChild(metricsElement);
},
updateProperties: function()
{
if (!this.views.dom.contentElement.sidebarPanes.properties.expanded)
return;
if (!this.views.dom.contentElement.sidebarPanes.properties.needsUpdate)
return;
this.views.dom.contentElement.sidebarPanes.properties.needsUpdate = false;
var propertiesBody = this.views.dom.contentElement.sidebarPanes.properties.bodyElement;
propertiesBody.removeChildren();
this.views.dom.contentElement.sidebarPanes.properties.sections = [];
if (!this.focusedDOMNode)
return;
for (var prototype = this.focusedDOMNode; prototype; prototype = prototype.__proto__) {
var hasChildren = false;
for (var prop in prototype) {
if (prop === "__treeElementIdentifier")
continue;
if (!prototype.hasOwnProperty(prop))
continue;
hasChildren = true;
break;
}
if (!hasChildren)
continue;
var title = Object.describe(prototype);
var subtitle;
if (title.match(/Prototype$/)) {
title = title.replace(/Prototype$/, "");
subtitle = "Prototype";
}
var section = new WebInspector.PropertiesSection(title, subtitle);
section.onpopulate = WebInspector.DOMPropertiesSection.onpopulate(prototype);
propertiesBody.appendChild(section.element);
this.views.dom.contentElement.sidebarPanes.properties.sections.push(section);
}
},
handleKeyEvent: function(event)
{
if (this.domTreeOutline && this.currentView && this.currentView === this.views.dom)
this.domTreeOutline.handleKeyEvent(event);
}
}
WebInspector.ResourcePanel.sourceFrameCounter = 0;
WebInspector.ResourcePanel.prototype.__proto__ = WebInspector.Panel.prototype;
WebInspector.SidebarPane = function(title)
{
this.element = document.createElement("div");
this.element.className = "pane";
this.titleElement = document.createElement("div");
this.titleElement.className = "title";
var pane = this;
this.titleElement.addEventListener("click", function() { pane.expanded = !pane.expanded; }, false);
this.bodyElement = document.createElement("div");
this.bodyElement.className = "body";
this.element.appendChild(this.titleElement);
this.element.appendChild(this.bodyElement);
this.title = title;
this.growbarVisible = false;
this.expanded = false;
this.onexpand = null;
this.oncollapse = null;
}
WebInspector.SidebarPane.prototype = {
get title()
{
return this._title;
},
set title(x)
{
if (this._title === x)
return;
this._title = x;
this.titleElement.textContent = x;
},
get growbarVisible()
{
return this._growbarVisible;
},
set growbarVisible(x)
{
if (this._growbarVisible === x)
return;
this._growbarVisible = x;
if (x && !this._growbarElement) {
this._growbarElement = document.createElement("div");
this._growbarElement.className = "growbar";
this.element.appendChild(this._growbarElement);
} else if (!x && this._growbarElement) {
if (this._growbarElement.parentNode)
this._growbarElement.parentNode(this._growbarElement);
delete this._growbarElement;
}
},
get expanded()
{
return this._expanded;
},
set expanded(x)
{
if (x)
this.expand();
else
this.collapse();
},
expand: function()
{
if (this._expanded)
return;
this._expanded = true;
this.element.addStyleClass("expanded");
if (this.onexpand)
this.onexpand(this);
},
collapse: function()
{
if (!this._expanded)
return;
this._expanded = false;
this.element.removeStyleClass("expanded");
if (this.oncollapse)
this.oncollapse(this);
}
}
WebInspector.PropertiesSection = function(title, subtitle)
{
this.element = document.createElement("div");
this.element.className = "section";
this.headerElement = document.createElement("div");
this.headerElement.className = "header";
this.titleElement = document.createElement("div");
this.titleElement.className = "title";
this.subtitleElement = document.createElement("div");
this.subtitleElement.className = "subtitle";
this.headerElement.appendChild(this.titleElement);
this.headerElement.appendChild(this.subtitleElement);
var section = this;
this.headerElement.addEventListener("click", function() { section.expanded = !section.expanded; }, false);
this.propertiesElement = document.createElement("ol");
this.propertiesElement.className = "properties";
this.propertiesTreeOutline = new TreeOutline(this.propertiesElement);
this.element.appendChild(this.headerElement);
this.element.appendChild(this.propertiesElement);
this.title = title;
this.subtitle = subtitle;
this.expanded = false;
}
WebInspector.PropertiesSection.prototype = {
get title()
{
return this._title;
},
set title(x)
{
if (this._title === x)
return;
this._title = x;
this.titleElement.textContent = x;
},
get subtitle()
{
return this._subtitle;
},
set subtitle(x)
{
if (this._subtitle === x)
return;
this._subtitle = x;
this.subtitleElement.innerHTML = x;
},
get expanded()
{
return this._expanded;
},
set expanded(x)
{
if (x)
this.expand();
else
this.collapse();
},
expand: function()
{
if (this._expanded)
return;
this._expanded = true;
if (!this._populated && this.onpopulate) {
this.onpopulate(this);
this._populated = true;
}
this.element.addStyleClass("expanded");
},
collapse: function()
{
if (!this._expanded)
return;
this._expanded = false;
this.element.removeStyleClass("expanded");
}
}
WebInspector.DOMPropertiesSection = function()
{
}
WebInspector.DOMPropertiesSection.onpopulate = function(prototype)
{
return function(section) {
var properties = Object.sortedProperties(prototype);
for (var i = 0; i < properties.length; ++i) {
var name = properties[i];
if (!prototype.hasOwnProperty(name))
continue;
if (name === "__treeElementIdentifier")
continue;
var item = new WebInspector.DOMPropertyTreeElement(name, prototype);
section.propertiesTreeOutline.appendChild(item);
}
}
}
WebInspector.DOMNodeTreeElement = function(node)
{
var hasChildren = (Preferences.ignoreWhitespace ? (firstChildSkippingWhitespace.call(node) ? true : false) : node.hasChildNodes());
var titleInfo = nodeTitleInfo.call(node, hasChildren, WebInspector.linkifyURL);
var title = titleInfo.title;
hasChildren = titleInfo.hasChildren;
var item = new TreeElement(title, node, hasChildren);
item.updateSelection = WebInspector.DOMNodeTreeElement.updateSelection;
item.onpopulate = WebInspector.DOMNodeTreeElement.populate;
item.onexpand = WebInspector.DOMNodeTreeElement.expanded;
item.oncollapse = WebInspector.DOMNodeTreeElement.collapsed;
item.onselect = WebInspector.DOMNodeTreeElement.selected;
item.onreveal = WebInspector.DOMNodeTreeElement.revealed;
item.ondblclick = WebInspector.DOMNodeTreeElement.doubleClicked;
if (hasChildren)
item.whitespaceIgnored = Preferences.ignoreWhitespace;
return item;
}
WebInspector.DOMNodeTreeElement.updateSelection = function(element)
{
if (!element || !element._listItemNode)
return;
if (!element.selectionElement) {
element.selectionElement = document.createElement("div");
element.selectionElement.className = "selection selected";
element._listItemNode.insertBefore(element.selectionElement, element._listItemNode.firstChild);
}
element.selectionElement.style.height = element._listItemNode.offsetHeight + "px";
}
WebInspector.DOMNodeTreeElement.populate = function(element)
{
if (element.children.length || element.whitespaceIgnored !== Preferences.ignoreWhitespace)
return;
element.removeChildren();
element.whitespaceIgnored = Preferences.ignoreWhitespace;
var node = (Preferences.ignoreWhitespace ? firstChildSkippingWhitespace.call(element.representedObject) : element.representedObject.firstChild);
while (node) {
var item = new WebInspector.DOMNodeTreeElement(node);
element.appendChild(item);
node = Preferences.ignoreWhitespace ? nextSiblingSkippingWhitespace.call(node) : node.nextSibling;
}
if (element.representedObject.nodeType == Node.ELEMENT_NODE) {
var title = "<span class=\"webkit-html-tag close\"></" + element.representedObject.nodeName.toLowerCase().escapeHTML() + "></span>";
var item = new TreeElement(title, element.representedObject, false);
item.selectable = false;
element.appendChild(item);
}
}
WebInspector.DOMNodeTreeElement.expanded = function(element)
{
element.treeOutline.panel.updateTreeSelection();
}
WebInspector.DOMNodeTreeElement.collapsed = function(element)
{
element.treeOutline.panel.updateTreeSelection();
}
WebInspector.DOMNodeTreeElement.revealed = function(element)
{
if (!element._listItemNode || !element.treeOutline || !element.treeOutline._childrenListNode)
return;
var parent = element.treeOutline.panel.views.dom.contentElement.treeContentElement;
parent.scrollToElement(element._listItemNode);
}
WebInspector.DOMNodeTreeElement.selected = function(element)
{
var panel = element.treeOutline.panel;
panel.focusedDOMNode = element.representedObject;
element.updateSelection(element);
setTimeout(function() { element.updateSelection(element) }, 0);
}
WebInspector.DOMNodeTreeElement.doubleClicked = function(element)
{
var panel = element.treeOutline.panel;
panel.rootDOMNode = element.representedObject.parentNode;
panel.focusedDOMNode = element.representedObject;
}
WebInspector.StylePropertyTreeElement = function(prop, computedStyle, usedProperties)
{
var overloadCount = 0;
var priority;
if (prop.subProperties && prop.subProperties.length > 1) {
for (var i = 0; i < prop.subProperties.length; ++i) {
var name = prop.subProperties[i];
if (!priority)
priority = prop.style.getPropertyPriority(name);
if (prop.unusedProperties[name])
overloadCount++;
}
}
if (!priority)
priority = prop.style.getPropertyPriority(prop.name);
var overloaded = (prop.unusedProperties[prop.name] || overloadCount === prop.subProperties.length);
var title = WebInspector.StylePropertyTreeElement.createTitle(prop.name, prop.style, overloaded, priority, computedStyle, usedProperties);
var item = new TreeElement(title, prop, (prop.subProperties && prop.subProperties.length > 1));
item.computedStyle = computedStyle;
item.onpopulate = WebInspector.StylePropertyTreeElement.populate;
return item;
}
WebInspector.StylePropertyTreeElement.createTitle = function(name, style, overloaded, priority, computed, usedProperties)
{
var valueNickname = {
"rgb(0, 0, 0)": "black",
"rgb(255, 255, 255)": "white",
"rgba(0, 0, 0, 0)": "transparent"
};
var alwaysShowComputedProperties = { "display": true, "height": true, "width": true };
var value = style.getPropertyValue(name);
var textValue = value;
if (value) {
var urls = value.match(/url\([^)]+\)/);
if (urls) {
for (var i = 0; i < urls.length; ++i) {
var url = urls[i].substring(4, urls[i].length - 1);
textValue = textValue.replace(urls[i], "url(" + WebInspector.linkifyURL(url) + ")");
}
} else {
if (value in valueNickname)
textValue = valueNickname[value];
textValue = textValue.escapeHTML();
}
}
var classes = [];
if (!computed && (style.isPropertyImplicit(name) || value == "initial"))
classes.push("implicit");
if (computed && !usedProperties[name] && !alwaysShowComputedProperties[name])
classes.push("inherited");
if (overloaded)
classes.push("overloaded");
var title = "";
if (classes.length)
title += "<span class=\"" + classes.join(" ") + "\">";
title += "<span class=\"name\">" + name.escapeHTML() + "</span>: ";
title += "<span class=\"value\">" + textValue;
if (priority && priority.length)
title += " !" + priority;
title += "</span>;";
if (value) {
var colors = value.match(/(rgb\([0-9]+,\s?[0-9]+,\s?[0-9]+\))|(rgba\([0-9]+,\s?[0-9]+,\s?[0-9]+,\s?[0-9]+\))/g);
if (colors) {
var colorsLength = colors.length;
for (var i = 0; i < colorsLength; ++i)
title += "<span class=\"swatch\" style=\"background-color: " + colors[i] + "\"></span>";
}
}
if (classes.length)
title += "</span>";
return title;
}
WebInspector.StylePropertyTreeElement.populate = function(element)
{
if (element.children.length)
return;
var prop = element.representedObject;
if (prop.subProperties && prop.subProperties.length > 1) {
for (var i = 0; i < prop.subProperties.length; ++i) {
var name = prop.subProperties[i];
var overloaded = (prop.unusedProperties[prop.name] || prop.unusedProperties[name]);
var priority = prop.style.getPropertyPriority(name);
var title = WebInspector.StylePropertyTreeElement.createTitle(name, prop.style, overloaded, priority, element.computedStyle);
var subitem = new TreeElement(title, {}, false);
element.appendChild(subitem);
}
}
}
WebInspector.RequestResponseTreeElement = function(name, object)
{
var title = "<span class=\"name\">" + name.escapeHTML() + "</span>";
var hasChildren = object instanceof Object;
if (!hasChildren) {
var objectAsString = object.toString();
title += ": <span class=\"value\">" + objectAsString.escapeHTML() + "</span>";
}
var item = new TreeElement(title, object, hasChildren);
item.onpopulate = WebInspector.RequestResponseTreeElement.onpopulate;
return item;
}
WebInspector.RequestResponseTreeElement.onpopulate = function(element)
{
if (element.children.length)
return;
for (var field in element.representedObject) {
var item = new WebInspector.RequestResponseTreeElement(field, element.representedObject[field]);
element.appendChild(item);
}
}
WebInspector.DOMPropertyTreeElement = function(name, object)
{
var title = "<span class=\"name\">" + name.escapeHTML() + "</span>: ";
title += "<span class=\"value\">" + Object.describe(object[name], true).escapeHTML() + "</span>";
var hasChildren = false;
var type = typeof object[name];
if (object[name] && (type === "object" || type === "function")) {
for (value in object[name]) {
hasChildren = true;
break;
}
}
var representedObj = { object: object, name: name };
var item = new TreeElement(title, representedObj, hasChildren);
item.onpopulate = WebInspector.DOMPropertyTreeElement.populate;
return item;
}
WebInspector.DOMPropertyTreeElement.populate = function(element)
{
if (element.children.length)
return;
var parent = element.representedObject.object[element.representedObject.name];
var properties = Object.sortedProperties(parent);
for (var i = 0; i < properties.length; ++i) {
if (properties[i] === "__treeElementIdentifier")
continue;
var item = new WebInspector.DOMPropertyTreeElement(properties[i], parent);
element.appendChild(item);
}
}