Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / LayoutTests / http / tests / inspector / elements-test.js
1 var initialize_ElementTest = function() {
2
3 InspectorTest.findNode = function(matchFunction, callback)
4 {
5     callback = InspectorTest.safeWrap(callback);
6     var result = null;
7     var pendingRequests = 0;
8     function processChildren(node)
9     {
10         try {
11             if (result)
12                 return;
13
14             var children = (node.children() || []).concat(node.shadowRoots()).concat(Object.values(node.pseudoElements() || {}));
15             if (node.templateContent())
16                 children.push(node.templateContent());
17             else if (node.importedDocument())
18                 children.push(node.importedDocument());
19
20             for (var i = 0; i < children.length; ++i) {
21                 var childNode = children[i];
22                 if (matchFunction(childNode)) {
23                     result = childNode;
24                     callback(result);
25                     return;
26                 }
27                 pendingRequests++;
28                 childNode.getChildNodes(processChildren.bind(null, childNode));
29             }
30         } finally {
31             pendingRequests--;
32         }
33
34         if (!result && !pendingRequests)
35             callback(null);
36     }
37
38     WebInspector.domModel.requestDocument(documentRequested.bind(this));
39     function documentRequested(doc)
40     {
41         pendingRequests++;
42         doc.getChildNodes(processChildren.bind(null, doc));
43     }
44 };
45
46 InspectorTest.nodeWithId = function(idValue, callback)
47 {
48     function nodeIdMatches(node)
49     {
50         return node.getAttribute("id") === idValue;
51     }
52     InspectorTest.findNode(nodeIdMatches, callback);
53 }
54
55 InspectorTest.shadowRootByHostId = function(idValue, callback)
56 {
57     function shadowRootMatches(node)
58     {
59         return node.isShadowRoot() && node.parentNode.getAttribute("id") === idValue;
60     }
61     InspectorTest.findNode(shadowRootMatches, callback);
62 }
63
64 InspectorTest.nodeWithClass = function(classValue, callback)
65 {
66     function nodeClassMatches(node)
67     {
68         var classAttr = node.getAttribute("class");
69         return classAttr && classAttr.indexOf(classValue) > -1;
70     }
71     InspectorTest.findNode(nodeClassMatches, callback);
72 }
73
74 InspectorTest.expandedNodeWithId = function(idValue)
75 {
76     var result;
77     function callback(node)
78     {
79         result = node;
80     }
81     InspectorTest.nodeWithId(idValue, callback);
82     return result;
83 }
84
85 InspectorTest.selectNode = function(node)
86 {
87     WebInspector.Revealer.reveal(node);
88 }
89
90 InspectorTest.selectNodeWithId = function(idValue, callback)
91 {
92     callback = InspectorTest.safeWrap(callback);
93     function onNodeFound(node)
94     {
95         InspectorTest.selectNode(node);
96         callback(node);
97     }
98     InspectorTest.nodeWithId(idValue, onNodeFound);
99 }
100
101 function waitForStylesRebuild(matchFunction, callback, requireRebuild)
102 {
103     (function sniff(node, rebuild)
104     {
105         if ((rebuild || !requireRebuild) && node && matchFunction(node)) {
106             callback();
107             return;
108         }
109         InspectorTest.addSniffer(WebInspector.StylesSidebarPane.prototype, "_nodeStylesUpdatedForTest", sniff);
110     })(null);
111 }
112
113 InspectorTest.waitForStyles = function(idValue, callback, requireRebuild)
114 {
115     callback = InspectorTest.safeWrap(callback);
116
117     function nodeWithId(node)
118     {
119         return node.getAttribute("id") === idValue;
120     }
121
122     waitForStylesRebuild(nodeWithId, callback, requireRebuild);
123 }
124
125 InspectorTest.waitForStylesForClass = function(classValue, callback, requireRebuild)
126 {
127     callback = InspectorTest.safeWrap(callback);
128
129     function nodeWithClass(node)
130     {
131         var classAttr = node.getAttribute("class");
132         return classAttr && classAttr.indexOf(classValue) > -1;
133     }
134
135     waitForStylesRebuild(nodeWithClass, callback, requireRebuild);
136 }
137
138 InspectorTest.selectNodeAndWaitForStyles = function(idValue, callback)
139 {
140     WebInspector.inspectorView.showPanel("elements");
141
142     callback = InspectorTest.safeWrap(callback);
143
144     var targetNode;
145
146     InspectorTest.waitForStyles(idValue, stylesUpdated, true);
147     InspectorTest.selectNodeWithId(idValue, nodeSelected);
148
149     function nodeSelected(node)
150     {
151         targetNode = node;
152     }
153
154     function stylesUpdated()
155     {
156         callback(targetNode);
157     }
158 }
159
160 InspectorTest.selectNodeAndWaitForStylesWithComputed = function(idValue, callback)
161 {
162     callback = InspectorTest.safeWrap(callback);
163
164     function stylesCallback(targetNode)
165     {
166         InspectorTest.addSniffer(WebInspector.ComputedStyleSidebarPane.prototype, "onContentReady", callback);
167         WebInspector.panels.elements.sidebarPanes.computedStyle.expand();
168     }
169
170     InspectorTest.selectNodeAndWaitForStyles(idValue, stylesCallback);
171 }
172
173 InspectorTest.firstElementsTreeOutline = function()
174 {
175     return WebInspector.panels.elements._treeOutlines[0];
176 }
177
178 InspectorTest.dumpSelectedElementStyles = function(excludeComputed, excludeMatched, omitLonghands, includeSelectorGroupMarks)
179 {
180     function extractText(element)
181     {
182         var text = element.textContent;
183         if (text)
184             return text;
185         var anchor = element.querySelector("[data-uncopyable]");
186         if (!anchor)
187             return "";
188         var anchorText = anchor.getAttribute("data-uncopyable");
189         var uiLocation = anchor.__uiLocation;
190         var anchorTarget = uiLocation ? (uiLocation.uiSourceCode.name() + ":" + (uiLocation.lineNumber + 1) + ":" + (uiLocation.columnNumber + 1)) : "";
191         return anchorText + " -> " + anchorTarget;
192     }
193
194     function buildMarkedSelectors(element)
195     {
196         var result = "";
197         for (var node = element.firstChild; node; node = node.nextSibling) {
198             if (node.nodeType === Node.ELEMENT_NODE && node.classList.contains("selector-matches"))
199                 result += "[$" + node.textContent + "$]";
200             else
201                 result += node.textContent;
202         }
203         return result;
204     }
205
206     var styleSections = WebInspector.panels.elements.sidebarPanes.styles.sections;
207     for (var pseudoId in styleSections) {
208         var pseudoName = WebInspector.StylesSidebarPane.PseudoIdNames[pseudoId];
209         var sections = styleSections[pseudoId];
210         for (var i = 0; i < sections.length; ++i) {
211             var section = sections[i];
212             if (section.computedStyle && excludeComputed)
213                 continue;
214             if (section.rule && excludeMatched)
215                 continue;
216             if (section.element && section.element.classList.contains("user-rule") && !WebInspector.settings.showUserAgentStyles.get())
217                 continue;
218             if (section.element.previousSibling && section.element.previousSibling.className === "sidebar-separator")
219                 InspectorTest.addResult("======== " + section.element.previousSibling.textContent + " ========");
220             InspectorTest.addResult((section.expanded ? "[expanded] " : "[collapsed] ") + (section.noAffect ? "[no-affect] " : ""));
221             var chainEntries = section.titleElement.querySelectorAll(".media-list .media");
222             chainEntries = Array.prototype.slice.call(chainEntries);
223             if (section.titleElement.children[1])
224                 chainEntries.push(section.titleElement.children[1]);
225
226             for (var j = 0; j < chainEntries.length; ++j) {
227                 var chainEntry = chainEntries[j];
228                 var entryLine = includeSelectorGroupMarks ? buildMarkedSelectors(chainEntry.children[1]) : chainEntry.children[1].textContent;
229                 if (chainEntry.children[2])
230                     entryLine += " " + chainEntry.children[2].textContent;
231                 entryLine += " (" + extractText(chainEntry.children[0]) + ")";
232                 InspectorTest.addResult(entryLine);
233             }
234             section.expand();
235             InspectorTest.dumpStyleTreeOutline(section.propertiesTreeOutline, omitLonghands ? 1 : 2);
236             InspectorTest.addResult("");
237         }
238         InspectorTest.addResult("");
239     }
240 }
241
242 InspectorTest.toggleStyleProperty = function(propertyName, checked)
243 {
244     var treeItem = InspectorTest.getElementStylePropertyTreeItem(propertyName);
245     treeItem.toggleEnabled({ target: { checked: checked }, consume: function() { } });
246 }
247
248 InspectorTest.toggleMatchedStyleProperty = function(propertyName, checked)
249 {
250     var treeItem = InspectorTest.getMatchedStylePropertyTreeItem(propertyName);
251     treeItem.toggleEnabled({ target: { checked: checked }, consume: function() { } });
252 }
253
254 InspectorTest.expandAndDumpSelectedElementEventListeners = function(callback)
255 {
256     InspectorTest.expandSelectedElementEventListeners(function() {
257         InspectorTest.dumpSelectedElementEventListeners(callback);
258     });
259 }
260
261 InspectorTest.expandSelectedElementEventListeners = function(callback)
262 {
263     var sidebarPane = WebInspector.panels.elements.sidebarPanes.eventListeners;
264     sidebarPane.expand();
265
266     InspectorTest.runAfterPendingDispatches(function() {
267         InspectorTest.expandSelectedElementEventListenersSubsections(callback);
268     });
269 }
270
271 InspectorTest.expandSelectedElementEventListenersSubsections = function(callback)
272 {
273     var eventListenerSections = WebInspector.panels.elements.sidebarPanes.eventListeners.sections;
274     for (var i = 0; i < eventListenerSections.length; ++i)
275         eventListenerSections[i].expand();
276
277     // Multiple sections may expand.
278     InspectorTest.runAfterPendingDispatches(function() {
279         InspectorTest.expandSelectedElementEventListenersEventBars(callback);
280     });
281 }
282
283 InspectorTest.expandSelectedElementEventListenersEventBars = function(callback)
284 {
285     var eventListenerSections = WebInspector.panels.elements.sidebarPanes.eventListeners.sections;
286     for (var i = 0; i < eventListenerSections.length; ++i) {
287         var eventBarChildren = eventListenerSections[i]._eventBars.children;
288         for (var j = 0; j < eventBarChildren.length; ++j)
289             eventBarChildren[j]._section.expand();
290     }
291
292     // Multiple sections may expand.
293     InspectorTest.runAfterPendingDispatches(callback);
294 }
295
296 InspectorTest.dumpSelectedElementEventListeners = function(callback)
297 {
298     function formatSourceNameProperty(value)
299     {
300         return "[clipped-for-test]/" + value.replace(/(.*?\/)LayoutTests/, "LayoutTests");
301     }
302
303     var eventListenerSections = WebInspector.panels.elements.sidebarPanes.eventListeners.sections;
304     for (var i = 0; i < eventListenerSections.length; ++i) {
305         var section = eventListenerSections[i];
306         var eventType = section._title;
307         InspectorTest.addResult("");
308         InspectorTest.addResult("======== " + eventType + " ========");
309         var eventBarChildren = section._eventBars.children;
310         for (var j = 0; j < eventBarChildren.length; ++j) {
311             var objectPropertiesSection = eventBarChildren[j]._section;
312             InspectorTest.dumpObjectPropertySection(objectPropertiesSection, {
313                 sourceName: formatSourceNameProperty
314             });
315         }
316     }
317
318     callback();
319 }
320
321 InspectorTest.dumpObjectPropertySection = function(section, formatters)
322 {
323     var expandedSubstring = section.expanded ? "[expanded]" : "[collapsed]";
324     InspectorTest.addResult(expandedSubstring + " " + section.titleElement.textContent + " " + section.subtitleAsTextForTest);
325     if (!section.propertiesForTest)
326         return;
327
328     for (var i = 0; i < section.propertiesForTest.length; ++i) {
329         var property = section.propertiesForTest[i];
330         var key = property.name;
331         var value = property.value._description;
332         if (key in formatters)
333             value = formatters[key](value);
334         InspectorTest.addResult("    " + key + ": " + value);
335     }
336 }
337
338 InspectorTest.dumpObjectPropertySectionDeep = function(section)
339 {
340     function domNodeToString(node) {
341         if (node)
342             return "'" + node.textContent + "'";
343         else
344             return "null";
345     }
346     function dumpTreeElementRecursively(treeElement, prefix) {
347         if ("nameElement" in treeElement)
348             InspectorTest.addResult(prefix + domNodeToString(treeElement.nameElement) + " => " + domNodeToString(treeElement.valueElement));
349         else
350             InspectorTest.addResult(prefix + treeElement.title);
351         for (var i = 0; i < treeElement.children.length; i++)
352             dumpTreeElementRecursively(treeElement.children[i], prefix + "    ");
353     }
354
355     var childNodes = section.propertiesTreeOutline.children;
356     for (var i = 0; i < childNodes.length; i++) {
357         dumpTreeElementRecursively(childNodes[i], "");
358     }
359 }
360
361 // FIXME: this returns the first tree item found (may fail for same-named properties in a style).
362 InspectorTest.getElementStylePropertyTreeItem = function(propertyName)
363 {
364     var styleSections = WebInspector.panels.elements.sidebarPanes.styles.sections[0];
365     var elementStyleSection = styleSections[1];
366     return InspectorTest.getFirstPropertyTreeItemForSection(elementStyleSection, propertyName);
367 };
368
369 // FIXME: this returns the first tree item found (may fail for same-named properties in a style).
370 InspectorTest.getMatchedStylePropertyTreeItem = function(propertyName)
371 {
372     var styleSections = WebInspector.panels.elements.sidebarPanes.styles.sections[0];
373     for (var i = 1; i < styleSections.length; ++i) {
374         var treeItem = InspectorTest.getFirstPropertyTreeItemForSection(styleSections[i], propertyName);
375         if (treeItem)
376             return treeItem;
377     }
378     return null;
379 };
380
381 InspectorTest.getFirstPropertyTreeItemForSection = function(section, propertyName)
382 {
383     var outline = section.propertiesTreeOutline;
384     for (var i = 0; i < outline.children.length; ++i) {
385         var treeItem = outline.children[i];
386         if (treeItem.name === propertyName)
387             return treeItem;
388     }
389     return null;
390 };
391
392 InspectorTest.dumpStyleTreeOutline = function(treeItem, depth)
393 {
394     var children = treeItem.children;
395     for (var i = 0; i < children.length; ++i)
396         InspectorTest.dumpStyleTreeItem(children[i], "", depth || 2);
397 };
398
399 InspectorTest.dumpStyleTreeItem = function(treeItem, prefix, depth)
400 {
401     // Filter out width and height properties in order to minimize
402     // potential diffs.
403     if (!treeItem.listItemElement.textContent.indexOf("width") ||
404         !treeItem.listItemElement.textContent.indexOf("height"))
405         return;
406
407     if (treeItem.listItemElement.classList.contains("inherited"))
408         return;
409     var typePrefix = "";
410     if (treeItem.listItemElement.classList.contains("overloaded") || treeItem.listItemElement.classList.contains("inactive") || treeItem.listItemElement.classList.contains("not-parsed-ok"))
411         typePrefix += "/-- overloaded --/ ";
412     if (treeItem.listItemElement.classList.contains("disabled"))
413         typePrefix += "/-- disabled --/ ";
414     var textContent = treeItem.listItemElement.textContent;
415
416     // Add non-selectable url text.
417     var textData = treeItem.listItemElement.querySelector("[data-uncopyable]");
418     if (textData)
419         textContent += textData.getAttribute("data-uncopyable");
420     InspectorTest.addResult(prefix + typePrefix + textContent);
421     if (--depth) {
422         treeItem.expand();
423         var children = treeItem.children;
424         for (var i = 0; children && i < children.length; ++i)
425             InspectorTest.dumpStyleTreeItem(children[i], prefix + "    ", depth);
426     }
427 };
428
429 InspectorTest.dumpElementsTree = function(rootNode, depth, resultsArray)
430 {
431     function beautify(element)
432     {
433         return element.innerText.replace(/\u200b/g, "").replace(/\n/g, "\\n").trim();
434     }
435
436     function dumpMap(name, map)
437     {
438         var result = [];
439         for (var id in map)
440             result.push(id + "=" + map[id]);
441         if (!result.length)
442             return "";
443         return name + ":[" + result.join(",") + "]";
444     }
445
446     function userPropertyDataDump(treeItem)
447     {
448         if (treeItem._elementCloseTag)
449             return "";
450
451         var userProperties = "";
452         var node = treeItem.representedObject;
453         if (node) {
454             userProperties += dumpMap("userProperties", node._userProperties);
455             var dump = dumpMap("descendantUserAttributeCounters", node._descendantUserPropertyCounters);
456             if (dump) {
457                 if (userProperties)
458                     userProperties += ", ";
459                 userProperties += dump;
460             }
461             if (userProperties)
462                 userProperties = " [" + userProperties + "]";
463         }
464         return userProperties;
465     }
466
467     function print(treeItem, prefix, depth)
468     {
469         if (treeItem.listItemElement) {
470             var expander;
471             if (treeItem.hasChildren) {
472                 if (treeItem.expanded)
473                     expander = "- ";
474                 else
475                     expander = "+ ";
476             } else
477                 expander = "  ";
478
479             var userProperties = userPropertyDataDump(treeItem);
480             var value = prefix + expander + beautify(treeItem.listItemElement) + userProperties;
481             if (resultsArray)
482                 resultsArray.push(value);
483             else
484                 InspectorTest.addResult(value);
485         }
486
487         if (!treeItem.expanded)
488             return;
489
490         var children = treeItem.children;
491         var newPrefix = treeItem === treeItem.treeOutline ? "" : prefix + "    ";
492         for (var i = 0; depth && children && i < children.length; ++i) {
493             if (!children[i]._elementCloseTag)
494                 print(children[i], newPrefix, depth - 1);
495             else
496                 print(children[i], prefix, depth);
497         }
498     }
499
500     var treeOutline = InspectorTest.firstElementsTreeOutline();
501     treeOutline._updateModifiedNodes();
502     print(rootNode ? treeOutline.findTreeElement(rootNode) : treeOutline, "", depth || 10000);
503 };
504
505 InspectorTest.expandElementsTree = function(callback)
506 {
507     callback = InspectorTest.safeWrap(callback);
508
509     function expand(treeItem)
510     {
511         var children = treeItem.children;
512         for (var i = 0; children && i < children.length; ++i) {
513             children[i].expand();
514             expand(children[i]);
515         }
516     }
517
518     function onAllNodesAvailable()
519     {
520         InspectorTest.firstElementsTreeOutline()._updateModifiedNodes();
521         expand(InspectorTest.firstElementsTreeOutline());
522         callback();
523     }
524     WebInspector.inspectorView.showPanel("elements");
525     InspectorTest.findNode(function() { return false; }, onAllNodesAvailable);
526 };
527
528 InspectorTest.dumpDOMAgentTree = function(node)
529 {
530     if (!WebInspector.domModel._document)
531         return;
532
533     function dump(node, prefix)
534     {
535         InspectorTest.addResult(prefix + node.nodeName());
536         prefix = prefix + "    ";
537
538         if (node.templateContent())
539             dump(node.templateContent(), prefix);
540         if (node.importedDocument())
541             dump(node.importedDocument(), prefix);
542         var shadowRoots = node.shadowRoots();
543         for (var i = 0; i < shadowRoots.length; ++i)
544             dump(shadowRoots[i], prefix);
545         var children = node.children();
546         for (var i = 0; children && i < children.length; ++i)
547             dump(children[i], prefix);
548     }
549
550     dump(node, "");
551 };
552
553 InspectorTest.rangeText = function(range)
554 {
555     if (!range)
556         return "[undefined-undefined]";
557     return "[" + range.startLine + ":" + range.startColumn + "-" + range.endLine + ":" + range.endColumn + "]";
558 }
559
560 InspectorTest.generateUndoTest = function(testBody)
561 {
562     function result(next)
563     {
564         var testNode = InspectorTest.expandedNodeWithId(/function\s([^(]*)/.exec(testBody)[1]);
565         InspectorTest.addResult("Initial:");
566         InspectorTest.dumpElementsTree(testNode);
567
568         testBody(undo);
569
570         function undo()
571         {
572             InspectorTest.addResult("Post-action:");
573             InspectorTest.dumpElementsTree(testNode);
574             WebInspector.domModel.undo(redo);
575         }
576
577         function redo()
578         {
579             InspectorTest.addResult("Post-undo (initial):");
580             InspectorTest.dumpElementsTree(testNode);
581             WebInspector.domModel.redo(done);
582         }
583
584         function done()
585         {
586             InspectorTest.addResult("Post-redo (action):");
587             InspectorTest.dumpElementsTree(testNode);
588             next();
589         }
590     }
591     result.toString = function()
592     {
593         return testBody.toString();
594     }
595     return result;
596 }
597
598 const indent = "    ";
599
600 InspectorTest.dumpRulesArray = function(rules, currentIndent)
601 {
602     if (!rules)
603         return;
604     currentIndent = currentIndent || "";
605     for (var i = 0; i < rules.length; ++i)
606         InspectorTest.dumpRule(rules[i], currentIndent);
607 }
608
609 InspectorTest.dumpRuleMatchesArray = function(matches, currentIndent)
610 {
611     if (!matches)
612         return;
613     currentIndent = currentIndent || "";
614     for (var i = 0; i < matches.length; ++i)
615         InspectorTest.dumpRule(matches[i].rule, currentIndent);
616 }
617
618 InspectorTest.dumpRule = function(rule, currentIndent)
619 {
620     function selectorRange()
621     {
622         var selectors = rule.selectorList.selectors;
623         if (!selectors || !selectors[0].range)
624             return "";
625         var ranges = [];
626         for (var i = 0; i < selectors.length; ++i) {
627             var range = selectors[i].range;
628             ranges.push(range.startLine + ":" + range.startColumn + "-" + range.endLine + ":" + range.endColumn);
629         }
630         return ", " + ranges.join("; ");
631     }
632
633     currentIndent = currentIndent || "";
634
635     if (!rule.type || rule.type === "style") {
636         InspectorTest.addResult(currentIndent + rule.selectorList.text + ": [" + rule.origin + selectorRange() + "] {");
637         InspectorTest.dumpStyle(rule.style, currentIndent + indent);
638         InspectorTest.addResult(currentIndent + "}");
639         return;
640     }
641
642     if (rule.type === "media") {
643         InspectorTest.addResult(currentIndent + "@media " + rule.mediaText + " {");
644         InspectorTest.dumpRulesArray(rule.childRules, currentIndent + indent);
645         InspectorTest.addResult(currentIndent + "}");
646         return;
647     }
648
649     if (rule.type === "import") {
650         InspectorTest.addResult(currentIndent + "@import: header=" + InspectorTest.rangeText(rule.headerRange) + ", body=" + InspectorTest.rangeText(rule.bodyRange));
651         return;
652     }
653
654     if (rule.type === "page" || rule.type === "font-face") {
655         if (rule.type === "page")
656             InspectorTest.addResult(currentIndent + rule.selectorList.text + " {");
657         else
658             InspectorTest.addResult(currentIndent + "@" + rule.type + " " + (rule.selectorList.text ? rule.selectorList.text + " " : "")  + "{");
659         InspectorTest.dumpStyle(rule.style, currentIndent + indent);
660         InspectorTest.addResult(currentIndent + "}");
661         return;
662     }
663
664     if (rule.type === "charset") {
665         InspectorTest.addResult("@charset");
666         return;
667     }
668
669     InspectorTest.addResult(currentIndent + "[UNKNOWN RULE]: header=" + InspectorTest.rangeText(rule.headerRange) + ", body=" + InspectorTest.rangeText(rule.bodyRange));
670 }
671
672 InspectorTest.dumpStyle = function(style, currentIndent)
673 {
674     currentIndent = currentIndent || "";
675     if (!style) {
676         InspectorTest.addResult(currentIndent + "[NO STYLE]");
677         return;
678     }
679     for (var i = 0; i < style.cssProperties.length; ++i) {
680         var property = style.cssProperties[i];
681         if (!property.disabled)
682             InspectorTest.addResult(currentIndent + "['" + property.name + "':'" + property.value + "'" + (property.important ? " is-important" : "") + (("parsedOk" in property) ? " non-parsed" : "") +"] @" + InspectorTest.rangeText(property.range) + " ");
683         else
684             InspectorTest.addResult(currentIndent + "[text='" + property.text + "'] disabled");
685     }
686 }
687
688 InspectorTest.dumpCSSStyleDeclaration = function(style, currentIndent)
689 {
690     currentIndent = currentIndent || "";
691     if (!style) {
692         InspectorTest.addResult(currentIndent + "[NO STYLE]");
693         return;
694     }
695     var properties = style.allProperties;
696     for (var i = 0; i < properties.length; ++i) {
697         var property = properties[i];
698         if (!property.disabled)
699             InspectorTest.addResult(currentIndent + "['" + property.name + "':'" + property.value + "'" + (property.important ? " is-important" : "") + (!property["parsedOk"] ? " non-parsed" : "") +"] @" + InspectorTest.rangeText(property.range) + " ");
700         else
701             InspectorTest.addResult(currentIndent + "[text='" + property.text + "'] disabled");
702     }
703 }
704
705 InspectorTest.dumpBreadcrumb = function(message)
706 {
707     if (message)
708         InspectorTest.addResult(message + ":");
709     var result = [];
710     var crumbs = WebInspector.inspectorView.panel("elements").crumbsElement;
711     var crumb = crumbs.lastChild;
712     while (crumb) {
713         result.unshift(crumb.textContent);
714         crumb = crumb.previousSibling;
715     }
716     InspectorTest.addResult(result.join(" > "));
717 }
718
719 InspectorTest.matchingSelectors = function(rule)
720 {
721     var selectors = [];
722     for (var i = 0; i < rule.matchingSelectors.length; ++i)
723         selectors.push(rule.selectors[rule.matchingSelectors[i]].value);
724     return "[" + selectors.join(", ") + "]";
725 }
726
727 InspectorTest.addNewRule = function(selector, callback)
728 {
729     // Click "Add new rule".
730     document.getElementById("add-style-button-test-id").click();
731     var section = WebInspector.panels.elements.sidebarPanes.styles.sections[0][2];
732     if (typeof selector === "string")
733         section._selectorElement.textContent = selector;
734     section._selectorElement.dispatchEvent(InspectorTest.createKeyEvent("Enter"));
735     InspectorTest.addSniffer(WebInspector.BlankStylePropertiesSection.prototype, "makeNormal", callback);
736 }
737
738 InspectorTest.dumpInspectorHighlight = function(node, callback)
739 {
740     node.boxModel(function(boxModel) {
741         var rectNames = ["margin", "border", "padding", "content"];
742         for (var i = 0; i < rectNames.length; i++) {
743             var rect = boxModel[rectNames[i]];
744             InspectorTest.addResult(rectNames[i] + " rect is " + (rect[4] - rect[0]) + " x " + (rect[5] - rect[1]) + " at (" + rect[0] + ", " + rect[1] + ")");
745         }
746         callback();
747    });
748 }
749
750 InspectorTest.dumpInspectorHighlightShape = function(node, callback)
751 {
752     node.boxModel(function(shapes) {
753         InspectorTest.addResult(JSON.stringify(shapes.shapeOutside.shape));
754         callback();
755     });
756 }
757
758 };