Upstream version 10.39.225.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     var expandedSomething = false;
508     callback = InspectorTest.safeWrap(callback);
509
510     function expand(treeItem)
511     {
512         var children = treeItem.children;
513         for (var i = 0; children && i < children.length; ++i) {
514             var child = children[i];
515             if (child.hasChildren && !child.expanded) {
516                 child.expand();
517                 expandedSomething = true;
518             }
519             expand(child);
520         }
521     }
522
523     function onAllNodesAvailable()
524     {
525         InspectorTest.firstElementsTreeOutline()._updateModifiedNodes();
526         expand(InspectorTest.firstElementsTreeOutline());
527         callback(expandedSomething);
528     }
529     WebInspector.inspectorView.showPanel("elements");
530     InspectorTest.findNode(function() { return false; }, onAllNodesAvailable);
531 };
532
533 InspectorTest.dumpDOMAgentTree = function(node)
534 {
535     if (!WebInspector.domModel._document)
536         return;
537
538     function dump(node, prefix)
539     {
540         InspectorTest.addResult(prefix + node.nodeName());
541         prefix = prefix + "    ";
542
543         if (node.templateContent())
544             dump(node.templateContent(), prefix);
545         if (node.importedDocument())
546             dump(node.importedDocument(), prefix);
547         var shadowRoots = node.shadowRoots();
548         for (var i = 0; i < shadowRoots.length; ++i)
549             dump(shadowRoots[i], prefix);
550         var children = node.children();
551         for (var i = 0; children && i < children.length; ++i)
552             dump(children[i], prefix);
553     }
554
555     dump(node, "");
556 };
557
558 InspectorTest.rangeText = function(range)
559 {
560     if (!range)
561         return "[undefined-undefined]";
562     return "[" + range.startLine + ":" + range.startColumn + "-" + range.endLine + ":" + range.endColumn + "]";
563 }
564
565 InspectorTest.generateUndoTest = function(testBody)
566 {
567     function result(next)
568     {
569         var testNode = InspectorTest.expandedNodeWithId(/function\s([^(]*)/.exec(testBody)[1]);
570         InspectorTest.addResult("Initial:");
571         InspectorTest.dumpElementsTree(testNode);
572
573         testBody(undo);
574
575         function undo()
576         {
577             InspectorTest.addResult("Post-action:");
578             InspectorTest.dumpElementsTree(testNode);
579             InspectorTest.expandElementsTree(expandedCallback);
580
581             function expandedCallback(expandedSomething)
582             {
583                 if (expandedSomething) {
584                     InspectorTest.addResult("== Expanded: ==");
585                     InspectorTest.dumpElementsTree(testNode);
586                 }
587                 WebInspector.domModel.undo(redo);
588             }
589         }
590
591         function redo()
592         {
593             InspectorTest.addResult("Post-undo (initial):");
594             InspectorTest.dumpElementsTree(testNode);
595             InspectorTest.expandElementsTree(expandedCallback);
596
597             function expandedCallback(expandedSomething)
598             {
599                 if (expandedSomething) {
600                     InspectorTest.addResult("== Expanded: ==");
601                     InspectorTest.dumpElementsTree(testNode);
602                 }
603                 WebInspector.domModel.redo(done);
604             }
605         }
606
607         function done()
608         {
609             InspectorTest.addResult("Post-redo (action):");
610             InspectorTest.dumpElementsTree(testNode);
611             InspectorTest.expandElementsTree(expandedCallback);
612
613             function expandedCallback(expandedSomething)
614             {
615                 if (expandedSomething) {
616                     InspectorTest.addResult("== Expanded: ==");
617                     InspectorTest.dumpElementsTree(testNode);
618                 }
619                 next();
620             }
621         }
622     }
623     result.toString = function()
624     {
625         return testBody.toString();
626     }
627     return result;
628 }
629
630 const indent = "    ";
631
632 InspectorTest.dumpRulesArray = function(rules, currentIndent)
633 {
634     if (!rules)
635         return;
636     currentIndent = currentIndent || "";
637     for (var i = 0; i < rules.length; ++i)
638         InspectorTest.dumpRule(rules[i], currentIndent);
639 }
640
641 InspectorTest.dumpRuleMatchesArray = function(matches, currentIndent)
642 {
643     if (!matches)
644         return;
645     currentIndent = currentIndent || "";
646     for (var i = 0; i < matches.length; ++i)
647         InspectorTest.dumpRule(matches[i].rule, currentIndent);
648 }
649
650 InspectorTest.dumpRule = function(rule, currentIndent)
651 {
652     function selectorRange()
653     {
654         var selectors = rule.selectorList.selectors;
655         if (!selectors || !selectors[0].range)
656             return "";
657         var ranges = [];
658         for (var i = 0; i < selectors.length; ++i) {
659             var range = selectors[i].range;
660             ranges.push(range.startLine + ":" + range.startColumn + "-" + range.endLine + ":" + range.endColumn);
661         }
662         return ", " + ranges.join("; ");
663     }
664
665     currentIndent = currentIndent || "";
666
667     if (!rule.type || rule.type === "style") {
668         InspectorTest.addResult(currentIndent + rule.selectorList.text + ": [" + rule.origin + selectorRange() + "] {");
669         InspectorTest.dumpStyle(rule.style, currentIndent + indent);
670         InspectorTest.addResult(currentIndent + "}");
671         return;
672     }
673
674     if (rule.type === "media") {
675         InspectorTest.addResult(currentIndent + "@media " + rule.mediaText + " {");
676         InspectorTest.dumpRulesArray(rule.childRules, currentIndent + indent);
677         InspectorTest.addResult(currentIndent + "}");
678         return;
679     }
680
681     if (rule.type === "import") {
682         InspectorTest.addResult(currentIndent + "@import: header=" + InspectorTest.rangeText(rule.headerRange) + ", body=" + InspectorTest.rangeText(rule.bodyRange));
683         return;
684     }
685
686     if (rule.type === "page" || rule.type === "font-face") {
687         if (rule.type === "page")
688             InspectorTest.addResult(currentIndent + rule.selectorList.text + " {");
689         else
690             InspectorTest.addResult(currentIndent + "@" + rule.type + " " + (rule.selectorList.text ? rule.selectorList.text + " " : "")  + "{");
691         InspectorTest.dumpStyle(rule.style, currentIndent + indent);
692         InspectorTest.addResult(currentIndent + "}");
693         return;
694     }
695
696     if (rule.type === "charset") {
697         InspectorTest.addResult("@charset");
698         return;
699     }
700
701     InspectorTest.addResult(currentIndent + "[UNKNOWN RULE]: header=" + InspectorTest.rangeText(rule.headerRange) + ", body=" + InspectorTest.rangeText(rule.bodyRange));
702 }
703
704 InspectorTest.dumpStyle = function(style, currentIndent)
705 {
706     currentIndent = currentIndent || "";
707     if (!style) {
708         InspectorTest.addResult(currentIndent + "[NO STYLE]");
709         return;
710     }
711     for (var i = 0; i < style.cssProperties.length; ++i) {
712         var property = style.cssProperties[i];
713         if (!property.disabled)
714             InspectorTest.addResult(currentIndent + "['" + property.name + "':'" + property.value + "'" + (property.important ? " is-important" : "") + (("parsedOk" in property) ? " non-parsed" : "") +"] @" + InspectorTest.rangeText(property.range) + " ");
715         else
716             InspectorTest.addResult(currentIndent + "[text='" + property.text + "'] disabled");
717     }
718 }
719
720 InspectorTest.dumpCSSStyleDeclaration = function(style, currentIndent)
721 {
722     currentIndent = currentIndent || "";
723     if (!style) {
724         InspectorTest.addResult(currentIndent + "[NO STYLE]");
725         return;
726     }
727     var properties = style.allProperties;
728     for (var i = 0; i < properties.length; ++i) {
729         var property = properties[i];
730         if (!property.disabled)
731             InspectorTest.addResult(currentIndent + "['" + property.name + "':'" + property.value + "'" + (property.important ? " is-important" : "") + (!property["parsedOk"] ? " non-parsed" : "") +"] @" + InspectorTest.rangeText(property.range) + " ");
732         else
733             InspectorTest.addResult(currentIndent + "[text='" + property.text + "'] disabled");
734     }
735 }
736
737 InspectorTest.dumpBreadcrumb = function(message)
738 {
739     if (message)
740         InspectorTest.addResult(message + ":");
741     var result = [];
742     var crumbs = WebInspector.inspectorView.panel("elements").crumbsElement;
743     var crumb = crumbs.lastChild;
744     while (crumb) {
745         result.unshift(crumb.textContent);
746         crumb = crumb.previousSibling;
747     }
748     InspectorTest.addResult(result.join(" > "));
749 }
750
751 InspectorTest.matchingSelectors = function(rule)
752 {
753     var selectors = [];
754     for (var i = 0; i < rule.matchingSelectors.length; ++i)
755         selectors.push(rule.selectors[rule.matchingSelectors[i]].value);
756     return "[" + selectors.join(", ") + "]";
757 }
758
759 InspectorTest.addNewRuleInStyleSheet = function(styleSheetHeader, selector, callback)
760 {
761     InspectorTest.addSniffer(WebInspector.StylesSidebarPane.prototype, "_addBlankSection", onBlankSection.bind(null, selector, callback));
762     WebInspector.panels.elements.sidebarPanes.styles._createNewRuleInStyleSheet(styleSheetHeader);
763 }
764
765 InspectorTest.addNewRule = function(selector, callback)
766 {
767     // Click "Add new rule".
768     document.getElementById("add-style-button-test-id").click();
769     InspectorTest.addSniffer(WebInspector.StylesSidebarPane.prototype, "_addBlankSection", onBlankSection.bind(null, selector, callback));
770 }
771
772 function onBlankSection(selector, callback)
773 {
774     var section = WebInspector.panels.elements.sidebarPanes.styles.sections[0][2];
775     if (typeof selector === "string")
776         section._selectorElement.textContent = selector;
777     section._selectorElement.dispatchEvent(InspectorTest.createKeyEvent("Enter"));
778     InspectorTest.runAfterPendingDispatches(callback.bind(null, section));
779 }
780
781 InspectorTest.dumpInspectorHighlight = function(node, callback)
782 {
783     node.boxModel(function(boxModel) {
784         var rectNames = ["margin", "border", "padding", "content"];
785         for (var i = 0; i < rectNames.length; i++) {
786             var rect = boxModel[rectNames[i]];
787             InspectorTest.addResult(rectNames[i] + " rect is " + (rect[4] - rect[0]) + " x " + (rect[5] - rect[1]) + " at (" + rect[0] + ", " + rect[1] + ")");
788         }
789         callback();
790    });
791 }
792
793 InspectorTest.dumpInspectorHighlightShape = function(node, callback)
794 {
795     node.boxModel(function(shapes) {
796         InspectorTest.addResult(JSON.stringify(shapes.shapeOutside.shape));
797         callback();
798     });
799 }
800
801 };