2 * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14 * its contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 var showUserAgentStyles = true;
32 // Property values to omit in the computed style list.
33 // If a property has this value, it will be omitted.
34 // Note we do not provide a value for "display", "height", or "width", for example,
35 // since we always want to display those.
36 var typicalStylePropertyValue = {
37 "-webkit-background-clip": "border",
38 "-webkit-background-composite": "source-over",
39 "-webkit-background-origin": "padding",
40 "-webkit-background-size": "auto auto",
41 "-webkit-border-horizontal-spacing": "0px",
42 "-webkit-border-vertical-spacing": "0px",
43 "-webkit-box-align": "stretch",
44 "-webkit-box-direction": "normal",
45 "-webkit-box-flex": "0",
46 "-webkit-box-flex-group": "1",
47 "-webkit-box-lines": "single",
48 "-webkit-box-ordinal-group": "1",
49 "-webkit-box-orient": "horizontal",
50 "-webkit-box-pack": "start",
51 "-webkit-highlight": "none",
52 "-webkit-line-break": "normal",
53 "-webkit-line-clamp": "none",
54 "-webkit-marquee-direction": "auto",
55 "-webkit-marquee-increment": "6px",
56 "-webkit-marquee-repetition": "infinite",
57 "-webkit-marquee-style": "scroll",
58 "-webkit-nbsp-mode": "normal",
59 "-webkit-text-decorations-in-effect": "none",
60 "-webkit-text-security": "none",
61 "-webkit-user-modify": "read-only",
62 "background-attachment": "scroll",
63 "background-color": "rgba(0, 0, 0, 0)",
64 "background-image": "none",
65 "background-position-x": "auto",
66 "background-position-y": "auto",
67 "background-repeat": "repeat",
68 "border-bottom-color": "rgba(0, 0, 0, 0)",
69 "border-bottom-style": "none",
70 "border-bottom-width": "0px",
71 "border-collapse": "separate",
72 "border-left-color": "rgba(0, 0, 0, 0)",
73 "border-left-style": "none",
74 "border-left-width": "0px",
75 "border-right-color": "rgba(0, 0, 0, 0)",
76 "border-right-style": "none",
77 "border-right-width": "0px",
78 "border-top-color": "rgba(0, 0, 0, 0)",
79 "border-top-style": "none",
80 "border-top-width": "0px",
82 "caption-side": "top",
84 "color": "rgb(0, 0, 0)",
87 "empty-cells": "show",
89 "font-style": "normal",
90 "font-variant": "normal",
91 "font-weight": "normal",
93 "letter-spacing": "normal",
94 "line-height": "normal",
95 "list-style-image": "none",
96 "list-style-position": "outside",
97 "list-style-type": "disc",
98 "margin-bottom": "0px",
100 "margin-right": "0px",
102 "max-height": "none",
108 "outline-style": "none",
109 "overflow": "visible",
110 "overflow-x": "visible",
111 "overflow-y": "visible",
112 "padding-bottom": "0px",
113 "padding-left": "0px",
114 "padding-right": "0px",
115 "padding-top": "0px",
116 "page-break-after": "auto",
117 "page-break-before": "auto",
118 "page-break-inside": "auto",
119 "position": "static",
122 "table-layout": "auto",
123 "text-align": "auto",
124 "text-decoration": "none",
125 "text-indent": "0px",
126 "text-shadow": "none",
127 "text-transform": "none",
129 "unicode-bidi": "normal",
130 "vertical-align": "baseline",
131 "visibility": "visible",
132 "white-space": "normal",
134 "word-spacing": "0px",
135 "word-wrap": "normal",
139 // "Nicknames" for some common values that are easier to read.
140 var valueNickname = {
141 "rgb(0, 0, 0)": "black",
142 "rgb(255, 255, 255)": "white",
143 "rgba(0, 0, 0, 0)": "transparent",
146 // Display types for which margin is ignored.
147 var noMarginDisplayType = {
149 "table-column": "no",
150 "table-column-group": "no",
151 "table-footer-group": "no",
152 "table-header-group": "no",
154 "table-row-group": "no",
157 // Display types for which padding is ignored.
158 var noPaddingDisplayType = {
159 "table-column": "no",
160 "table-column-group": "no",
161 "table-footer-group": "no",
162 "table-header-group": "no",
164 "table-row-group": "no",
167 function setUpScrollbar(id)
169 var bar = new AppleVerticalScrollbar(document.getElementById(id));
171 bar.setTrackStart("Images/scrollTrackTop.png", 18);
172 bar.setTrackMiddle("Images/scrollTrackMiddle.png");
173 bar.setTrackEnd("Images/scrollTrackBottom.png", 18);
174 bar.setThumbStart("Images/scrollThumbTop.png", 9);
175 bar.setThumbMiddle("Images/scrollThumbMiddle.png");
176 bar.setThumbEnd("Images/scrollThumbBottom.png", 9);
183 treeScrollbar = setUpScrollbar("treeScrollbar");
185 nodeContentsScrollArea = new AppleScrollArea(document.getElementById("nodeContentsScrollview"),
186 setUpScrollbar("nodeContentsScrollbar"));
187 elementAttributesScrollArea = new AppleScrollArea(document.getElementById("elementAttributesScrollview"),
188 setUpScrollbar("elementAttributesScrollbar"));
190 styleRulesScrollArea = new AppleScrollArea(document.getElementById("styleRulesScrollview"),
191 setUpScrollbar("styleRulesScrollbar"));
192 stylePropertiesScrollArea = new AppleScrollArea(document.getElementById("stylePropertiesScrollview"),
193 setUpScrollbar("stylePropertiesScrollbar"));
195 jsPropertiesScrollArea = new AppleScrollArea(document.getElementById("jsPropertiesScrollview"),
196 setUpScrollbar("jsPropertiesScrollbar"));
198 treeScrollbar._getViewToContentRatio = function() {
199 var contentHeight = Inspector.treeViewScrollHeight();
200 var height = document.getElementById("treeScrollArea").offsetHeight;
201 if (contentHeight > height)
202 return height / contentHeight;
206 treeScrollbar._computeTrackOffset = function() { return Inspector.treeViewOffsetTop(); }
207 treeScrollbar._getContentLength = function() { return Inspector.treeViewScrollHeight(); }
208 treeScrollbar._getViewLength = function() { return document.getElementById("treeScrollArea").offsetHeight; }
209 treeScrollbar._canScroll = function() { return true; }
211 treeScrollbar.scrollTo = function(pos) {
212 Inspector.treeViewScrollTo(pos);
213 this.verticalHasScrolled();
216 treeScrollbar.verticalHasScrolled = function() {
217 var new_thumb_pos = this._thumbPositionForContentPosition(Inspector.treeViewOffsetTop());
218 this._thumbStart = new_thumb_pos;
219 this._thumb.style.top = new_thumb_pos + "px";
222 // much better AppleScrollArea reveal
223 AppleScrollArea.prototype.reveal = function(node) {
227 offsetY += obj.offsetTop;
228 obj = obj.offsetParent;
229 } while (obj && obj != this.content);
234 offsetX += obj.offsetLeft;
235 obj = obj.offsetParent;
236 } while (obj && obj != this.content);
238 var top = this.content.scrollTop;
239 var height = this.viewHeight;
240 if ((top + height) < (offsetY + node.clientHeight))
241 this.verticalScrollTo(offsetY - height + node.clientHeight);
242 else if (top > offsetY)
243 this.verticalScrollTo(offsetY);
245 var left = this.content.scrollLeft;
246 var width = this.viewWidth;
247 if ((left + width) < (offsetX + node.clientWidth))
248 this.horizontalScrollTo(offsetX - width + node.clientWidth);
249 else if (left > offsetX)
250 this.horizontalScrollTo(offsetX);
253 // Change the standard show/hide to include the entire scrollbar.
254 // This lets the content reflow to use the additional space when the scrollbar is hidden.
255 AppleScrollbar.prototype.hide = function() {
256 this._track.style.display = "none";
257 this.scrollbar.style.display = "none";
260 AppleScrollbar.prototype.show = function() {
261 this._track.style.display = "block";
262 this.scrollbar.style.removeProperty("display");
269 window.addEventListener("resize", refreshScrollbars, false);
271 toggleNoSelection(false);
275 function refreshScrollbars()
277 elementAttributesScrollArea.refresh();
278 jsPropertiesScrollArea.refresh();
279 nodeContentsScrollArea.refresh();
280 stylePropertiesScrollArea.refresh();
281 styleRulesScrollArea.refresh();
284 var searchActive = false;
286 function performSearch(query)
288 var treePopup = document.getElementById("treePopup");
289 var searchField = document.getElementById("search");
290 var searchCount = document.getElementById("searchCount");
292 if (query.length && !searchActive) {
293 treePopup.style.display = "none";
294 searchCount.style.display = "block";
295 searchField.style.width = "150px";
297 } else if (!query.length && searchActive) {
298 treePopup.style.removeProperty("display");
299 searchCount.style.removeProperty("display");
300 searchField.style.removeProperty("width");
301 searchActive = false;
304 Inspector.searchPerformed(query);
307 function resultsWithXpathQuery(query)
311 var focusedNode = Inspector.focusedDOMNode();
312 nodeList = focusedNode.document.evaluate(query, focusedNode.document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE);
314 // ignore any exceptions. the query might be malformed, but we allow that
319 var tabNames = ["node","metrics","style","properties"];
320 var currentPane = "node";
321 var paneUpdateState = [];
322 var noSelection = false;
324 function toggleNoSelection(state)
328 for (var i = 0; i < tabNames.length; i++)
329 document.getElementById(tabNames[i] + "Pane").style.display = "none";
330 document.getElementById("noSelection").style.removeProperty("display");
332 document.getElementById("noSelection").style.display = "none";
333 switchPane(currentPane);
337 function switchPane(pane)
340 for (var i = 0; i < tabNames.length; i++) {
341 var paneElement = document.getElementById(tabNames[i] + "Pane");
342 var button = document.getElementById(tabNames[i] + "Button");
343 if (!button.originalClassName)
344 button.originalClassName = button.className;
345 if (pane == tabNames[i]) {
347 paneElement.style.removeProperty("display");
348 button.className = button.originalClassName + " selected";
350 paneElement.style.display = "none";
351 button.className = button.originalClassName;
358 if (!paneUpdateState[pane]) {
359 eval("update" + pane.charAt(0).toUpperCase() + pane.substr(1) + "Pane()");
360 paneUpdateState[pane] = true;
366 function nodeTypeName(node)
368 switch (node.nodeType) {
369 case Node.ELEMENT_NODE: return "Element";
370 case Node.ATTRIBUTE_NODE: return "Attribute";
371 case Node.TEXT_NODE: return "Text";
372 case Node.CDATA_SECTION_NODE: return "Character Data";
373 case Node.ENTITY_REFERENCE_NODE: return "Entity Reference";
374 case Node.ENTITY_NODE: return "Entity";
375 case Node.PROCESSING_INSTRUCTION_NODE: return "Processing Instruction";
376 case Node.COMMENT_NODE: return "Comment";
377 case Node.DOCUMENT_NODE: return "Document";
378 case Node.DOCUMENT_TYPE_NODE: return "Document Type";
379 case Node.DOCUMENT_FRAGMENT_NODE: return "Document Fragment";
380 case Node.NOTATION_NODE: return "Notation";
385 function updatePanes()
387 for (var i = 0; i < tabNames.length; i++)
388 paneUpdateState[tabNames[i]] = false;
391 eval("update" + currentPane.charAt(0).toUpperCase() + currentPane.substr(1) + "Pane()");
392 paneUpdateState[currentPane] = true;
395 function updateElementAttributes()
397 var focusedNode = Inspector.focusedDOMNode();
398 var attributesList = document.getElementById("elementAttributesList")
400 attributesList.innerHTML = "";
402 if (!focusedNode.attributes.length)
403 attributesList.innerHTML = "<span class=\"disabled\">(none)</span>";
405 for (i = 0; i < focusedNode.attributes.length; i++) {
406 var attr = focusedNode.attributes[i];
407 var li = document.createElement("li");
409 var span = document.createElement("span");
410 span.className = "property";
411 if (attr.namespaceURI)
412 span.title = attr.namespaceURI;
413 span.textContent = attr.name;
414 li.appendChild(span);
416 span = document.createElement("span");
417 span.className = "relation";
418 span.textContent = "=";
419 li.appendChild(span);
421 span = document.createElement("span");
422 span.className = "value";
423 span.textContent = "\"" + attr.value + "\"";
424 span.title = attr.value;
425 li.appendChild(span);
428 span = document.createElement("span");
429 span.className = "mapped";
430 span.innerHTML = "(<a href=\"javascript:selectMappedStyleRule('" + attr.name + "')\">mapped style</a>)";
431 li.appendChild(span);
434 attributesList.appendChild(li);
437 elementAttributesScrollArea.refresh();
440 function updateNodePane()
444 var focusedNode = Inspector.focusedDOMNode();
446 if (focusedNode.nodeType == Node.TEXT_NODE || focusedNode.nodeType == Node.COMMENT_NODE) {
447 document.getElementById("nodeNamespaceRow").style.display = "none";
448 document.getElementById("elementAttributes").style.display = "none";
449 document.getElementById("nodeContents").style.removeProperty("display");
451 document.getElementById("nodeContentsScrollview").textContent = focusedNode.nodeValue;
452 nodeContentsScrollArea.refresh();
453 } else if (focusedNode.nodeType == Node.ELEMENT_NODE) {
454 document.getElementById("elementAttributes").style.removeProperty("display");
455 document.getElementById("nodeContents").style.display = "none";
457 updateElementAttributes();
459 if (focusedNode.namespaceURI.length > 0) {
460 document.getElementById("nodeNamespace").textContent = focusedNode.namespaceURI;
461 document.getElementById("nodeNamespace").title = focusedNode.namespaceURI;
462 document.getElementById("nodeNamespaceRow").style.removeProperty("display");
464 document.getElementById("nodeNamespaceRow").style.display = "none";
466 } else if (focusedNode.nodeType == Node.DOCUMENT_NODE) {
467 document.getElementById("nodeNamespaceRow").style.display = "none";
468 document.getElementById("elementAttributes").style.display = "none";
469 document.getElementById("nodeContents").style.display = "none";
472 document.getElementById("nodeType").textContent = nodeTypeName(focusedNode);
473 document.getElementById("nodeName").textContent = focusedNode.nodeName;
478 var styleRules = null;
479 var selectedStyleRuleIndex = 0;
480 var styleProperties = null;
481 var expandedStyleShorthands = [];
483 function updateStylePane()
485 var focusedNode = Inspector.focusedDOMNode();
486 if (focusedNode.nodeType == Node.TEXT_NODE && focusedNode.parentNode && focusedNode.parentNode.nodeType == Node.ELEMENT_NODE)
487 focusedNode = focusedNode.parentNode;
488 var rulesArea = document.getElementById("styleRulesScrollview");
489 var propertiesArea = document.getElementById("stylePropertiesTree");
491 rulesArea.innerHTML = "";
492 propertiesArea.innerHTML = "";
494 styleProperties = [];
496 if (focusedNode.nodeType == Node.ELEMENT_NODE) {
497 document.getElementById("styleRules").style.removeProperty("display");
498 document.getElementById("styleProperties").style.removeProperty("display");
499 document.getElementById("noStyle").style.display = "none";
501 var propertyCount = [];
503 var computedStyle = focusedNode.ownerDocument.defaultView.getComputedStyle(focusedNode);
504 if (computedStyle && computedStyle.length) {
506 isComputedStyle: true,
507 selectorText: "Computed Style",
508 style: computedStyle,
511 styleRules.push(computedObj);
514 var focusedNodeName = focusedNode.nodeName.toLowerCase();
515 for (var i = 0; i < focusedNode.attributes.length; i++) {
516 var attr = focusedNode.attributes[i];
521 subtitle: "element\u2019s \u201C" + attr.name + "\u201D attribute",
523 attrStyle.selectorText = focusedNodeName + "[" + attr.name;
524 if (attr.value.length)
525 attrStyle.selectorText += "=" + attr.value;
526 attrStyle.selectorText += "]";
527 styleRules.push(attrStyle);
531 var matchedStyleRules = focusedNode.ownerDocument.defaultView.getMatchedCSSRules(focusedNode, "", !showUserAgentStyles);
532 if (matchedStyleRules) {
533 for (var i = 0; i < matchedStyleRules.length; i++) {
534 styleRules.push(matchedStyleRules[i]);
538 if (focusedNode.style.length) {
540 selectorText: "Inline Style Attribute",
541 style: focusedNode.style,
542 subtitle: "element\u2019s \u201Cstyle\u201D attribute",
544 styleRules.push(inlineStyle);
547 if (styleRules.length && selectedStyleRuleIndex >= styleRules.length)
548 selectedStyleRuleIndex = (styleRules.length - 1);
550 var priorityUsed = false;
551 for (var i = (styleRules.length - 1); i >= 0; --i) {
552 styleProperties[i] = [];
554 var row = document.createElement("div");
555 row.className = "row";
556 if (i == selectedStyleRuleIndex)
557 row.className += " focused";
558 if (styleRules[i].isComputedStyle)
559 row.className += " computedStyle";
561 var cell = document.createElement("div");
562 cell.className = "cell selector";
563 var text = styleRules[i].selectorText;
564 cell.textContent = text;
566 row.appendChild(cell);
568 cell = document.createElement("div");
569 cell.className = "cell stylesheet";
571 if (styleRules[i].subtitle != null)
572 sheet = styleRules[i].subtitle;
573 else if (styleRules[i].parentStyleSheet && styleRules[i].parentStyleSheet.href)
574 sheet = styleRules[i].parentStyleSheet.href;
575 else if (styleRules[i].parentStyleSheet && !styleRules[i].parentStyleSheet.ownerNode)
576 sheet = "user agent stylesheet";
578 sheet = "inline stylesheet";
579 cell.textContent = sheet;
581 row.appendChild(cell);
583 row.styleRuleIndex = i;
584 row.addEventListener("click", styleRuleSelect, true);
586 var style = styleRules[i].style;
587 var styleShorthandLookup = [];
588 for (var j = 0; j < style.length; j++) {
591 var shorthand = style.getPropertyShorthand(name);
593 prop = styleShorthandLookup[shorthand];
595 if (!priorityUsed && style.getPropertyPriority(name).length)
599 prop.subProperties.push(name);
603 subProperties: [name],
604 unusedProperties: [],
605 name: (shorthand ? shorthand : name),
607 styleProperties[i].push(prop);
609 styleShorthandLookup[shorthand] = prop;
610 if (!propertyCount[shorthand]) {
611 propertyCount[shorthand] = 1;
613 prop.unusedProperties[shorthand] = true;
614 propertyCount[shorthand]++;
619 if (styleRules[i].isComputedStyle)
622 if (!propertyCount[name]) {
623 propertyCount[name] = 1;
625 prop.unusedProperties[name] = true;
626 propertyCount[name]++;
630 if (styleRules[i].isComputedStyle && styleRules.length > 1) {
631 var divider = document.createElement("hr");
632 divider.className = "divider";
633 rulesArea.insertBefore(divider, rulesArea.firstChild);
636 if (rulesArea.firstChild)
637 rulesArea.insertBefore(row, rulesArea.firstChild);
639 rulesArea.appendChild(row);
643 // walk the properties again and account for !important
644 var priorityCount = [];
645 for (var i = 0; i < styleRules.length; i++) {
646 if (styleRules[i].isComputedStyle)
648 var style = styleRules[i].style;
649 for (var j = 0; j < styleProperties[i].length; j++) {
650 var prop = styleProperties[i][j];
651 for (var k = 0; k < prop.subProperties.length; k++) {
652 var name = prop.subProperties[k];
653 if (style.getPropertyPriority(name).length) {
654 if (!priorityCount[name]) {
655 if (prop.unusedProperties[name])
656 prop.unusedProperties[name] = false;
657 priorityCount[name] = 1;
659 priorityCount[name]++;
661 } else if (priorityCount[name]) {
662 prop.unusedProperties[name] = true;
669 updateStyleProperties();
671 var noStyle = document.getElementById("noStyle");
672 noStyle.textContent = "Can't style " + nodeTypeName(focusedNode) + " nodes.";
673 document.getElementById("styleRules").style.display = "none";
674 document.getElementById("styleProperties").style.display = "none";
675 noStyle.style.removeProperty("display");
678 styleRulesScrollArea.refresh();
681 function styleRuleSelect(event)
683 var row = document.getElementById("styleRulesScrollview").firstChild;
685 if (row.nodeName == "DIV")
686 row.className = "row";
687 row = row.nextSibling;
690 row = event.currentTarget;
691 row.className = "row focused";
693 selectedStyleRuleIndex = row.styleRuleIndex;
694 updateStyleProperties();
697 function populateStyleListItem(li, prop, name)
699 var span = document.createElement("span");
700 span.className = "property";
701 span.textContent = name + ": ";
702 li.appendChild(span);
704 var value = prop.style.getPropertyValue(name);
708 span = document.createElement("span");
709 span.className = "value";
710 var textValue = valueNickname[value] ? valueNickname[value] : value;
711 var priority = prop.style.getPropertyPriority(name);
713 textValue += " !" + priority;
714 span.textContent = textValue + ";";
715 span.title = textValue;
716 li.appendChild(span);
718 var colors = value.match(/(rgb\([0-9]+, [0-9]+, [0-9]+\))|(rgba\([0-9]+, [0-9]+, [0-9]+, [0-9]+\))/g);
720 for (var k = 0; k < colors.length; k++) {
721 var swatch = document.createElement("span");
722 swatch.className = "colorSwatch";
723 swatch.style.backgroundColor = colors[k];
724 li.appendChild(swatch);
729 function updateStyleProperties()
731 var focusedNode = Inspector.focusedDOMNode();
732 var propertiesTree = document.getElementById("stylePropertiesTree");
733 propertiesTree.innerHTML = "";
735 if (selectedStyleRuleIndex >= styleProperties.length) {
736 stylePropertiesScrollArea.refresh();
740 var properties = styleProperties[selectedStyleRuleIndex];
741 var omitTypicalValues = styleRules[selectedStyleRuleIndex].isComputedStyle;
742 for (var i = 0; i < properties.length; i++) {
743 var prop = properties[i];
744 var name = prop.name;
745 if (omitTypicalValues && typicalStylePropertyValue[name] == prop.style.getPropertyValue(name))
748 var mainli = document.createElement("li");
749 if (prop.subProperties.length > 1) {
750 mainli.className = "hasChildren";
751 if (expandedStyleShorthands[name])
752 mainli.className += " expanded";
753 mainli.shorthand = name;
754 var button = document.createElement("button");
755 button.addEventListener("click", toggleStyleShorthand, false);
756 mainli.appendChild(button);
759 populateStyleListItem(mainli, prop, name);
760 propertiesTree.appendChild(mainli);
762 var overloadCount = 0;
763 if (prop.subProperties && prop.subProperties.length > 1) {
764 var subTree = document.createElement("ul");
765 if (!expandedStyleShorthands[name])
766 subTree.style.display = "none";
768 for (var j = 0; j < prop.subProperties.length; j++) {
769 var name = prop.subProperties[j];
770 var li = document.createElement("li");
771 if (prop.style.isPropertyImplicit(name) || prop.style.getPropertyValue(name) == "initial")
772 li.className = "implicit";
774 if (prop.unusedProperties[name] || prop.unusedProperties[name]) {
775 li.className += " overloaded";
779 populateStyleListItem(li, prop, name);
780 subTree.appendChild(li);
783 propertiesTree.appendChild(subTree);
786 if (prop.unusedProperties[name] || overloadCount == prop.subProperties.length)
787 mainli.className += " overloaded";
790 stylePropertiesScrollArea.refresh();
793 function toggleStyleShorthand(event)
795 var li = event.currentTarget.parentNode;
796 if (li.className.indexOf("expanded") != -1) {
797 li.className = li.className.replace(/ expanded/, "");
798 li.nextSibling.style.display = "none";
799 expandedStyleShorthands[li.shorthand] = false;
801 li.className += " expanded";
802 li.nextSibling.style.removeProperty("display");
803 expandedStyleShorthands[li.shorthand] = true;
806 stylePropertiesScrollArea.refresh();
809 function toggleShowUserAgentStyles()
811 showUserAgentStyles = !showUserAgentStyles;
815 function selectMappedStyleRule(attrName)
817 if (!paneUpdateState["style"])
820 for (var i = 0; i < styleRules.length; i++)
821 if (styleRules[i].attrName == attrName)
824 selectedStyleRuleIndex = i;
826 var row = document.getElementById("styleRulesScrollview").firstChild;
828 if (row.nodeName == "DIV") {
829 if (row.styleRuleIndex == selectedStyleRuleIndex)
830 row.className = "row focused";
832 row.className = "row";
834 row = row.nextSibling;
837 styleRulesScrollArea.refresh();
839 updateStyleProperties();
843 function setMetric(style, name, suffix)
845 var value = style.getPropertyValue(name + suffix);
846 if (value == "" || value == "0px")
849 value = value.replace(/px$/, "");
850 document.getElementById(name).textContent = value;
853 function setBoxMetrics(style, box, suffix)
855 setMetric(style, box + "-left", suffix);
856 setMetric(style, box + "-right", suffix);
857 setMetric(style, box + "-top", suffix);
858 setMetric(style, box + "-bottom", suffix);
861 function updateMetricsPane()
864 var focusedNode = Inspector.focusedDOMNode();
865 if (focusedNode.nodeType == Node.ELEMENT_NODE)
866 style = focusedNode.ownerDocument.defaultView.getComputedStyle(focusedNode);
867 if (!style || style.length == 0) {
868 document.getElementById("noMetrics").style.removeProperty("display");
869 document.getElementById("marginBoxTable").style.display = "none";
873 document.getElementById("noMetrics").style.display = "none";
874 document.getElementById("marginBoxTable").style.removeProperty("display");
876 setBoxMetrics(style, "margin", "");
877 setBoxMetrics(style, "border", "-width");
878 setBoxMetrics(style, "padding", "");
880 var size = style.getPropertyValue("width").replace(/px$/, "")
882 + style.getPropertyValue("height").replace(/px$/, "");
883 document.getElementById("content").textContent = size;
885 if (noMarginDisplayType[style.display] == "no")
886 document.getElementById("marginBoxTable").setAttribute("hide", "yes");
888 document.getElementById("marginBoxTable").removeAttribute("hide");
890 if (noPaddingDisplayType[style.display] == "no")
891 document.getElementById("paddingBoxTable").setAttribute("hide", "yes");
893 document.getElementById("paddingBoxTable").removeAttribute("hide");
896 function updatePropertiesPane()
898 // FIXME: Like the style pane, this should have a top item that's "all properties"
899 // and separate items for each item in the prototype chain. For now, we implement
900 // only the "all properties" part, and only for enumerable properties.
902 var focusedNode = Inspector.focusedDOMNode();
903 var list = document.getElementById("jsPropertiesList");
906 for (var name in focusedNode) {
907 var li = document.createElement("li");
909 var span = document.createElement("span");
910 span.className = "property";
911 span.textContent = name + ": ";
912 li.appendChild(span);
914 var value = focusedNode[name];
916 span = document.createElement("span");
917 span.className = "value";
918 span.textContent = value;
920 li.appendChild(span);
922 list.appendChild(li);
925 jsPropertiesScrollArea.refresh();