blob: 40f6d57abe17cbacb385148fa39de053ae95127a [file] [log] [blame]
var initialize_ElementTest = function() {
InspectorTest.findNode = function(matchFunction, callback)
{
callback = InspectorTest.safeWrap(callback);
var result = null;
var topLevelChildrenRequested = false;
var pendingRequests = 0;
function processChildren(topLevel, children)
{
pendingRequests--;
if (result)
return;
for (var i = 0; children && i < children.length; ++i) {
var childNode = children[i];
if (matchFunction(childNode)) {
result = childNode;
callback(result);
return;
}
pendingRequests++;
childNode.getChildNodes(processChildren.bind(null, false));
}
if (topLevel)
topLevelChildrenRequested = true;
if (topLevelChildrenRequested && !result && !pendingRequests)
callback(null);
}
pendingRequests++;
WebInspector.domAgent.requestDocument(documentRequested.bind(this));
function documentRequested(doc)
{
doc.getChildNodes(processChildren.bind(this, true));
}
};
InspectorTest.nodeWithId = function(idValue, callback)
{
function nodeIdMatches(node)
{
return node.getAttribute("id") === idValue;
}
InspectorTest.findNode(nodeIdMatches, callback);
}
InspectorTest.expandedNodeWithId = function(idValue)
{
var result;
function callback(node)
{
result = node;
}
InspectorTest.nodeWithId(idValue, callback);
return result;
}
InspectorTest.selectNodeWithId = function(idValue, callback)
{
callback = InspectorTest.safeWrap(callback);
function onNodeFound(node)
{
if (node)
WebInspector._updateFocusedNode(node.id);
callback(node);
}
InspectorTest.nodeWithId(idValue, onNodeFound);
}
InspectorTest.waitForStyles = function(idValue, callback, requireRebuild)
{
callback = InspectorTest.safeWrap(callback);
(function sniff(node, rebuild)
{
if ((rebuild || !requireRebuild) && node && node.getAttribute("id") === idValue) {
callback();
return;
}
InspectorTest.addSniffer(WebInspector.StylesSidebarPane.prototype, "_nodeStylesUpdatedForTest", sniff);
})(null);
}
InspectorTest.selectNodeAndWaitForStyles = function(idValue, callback)
{
WebInspector.showPanel("elements");
callback = InspectorTest.safeWrap(callback);
var targetNode;
InspectorTest.waitForStyles(idValue, stylesUpdated, true);
InspectorTest.selectNodeWithId(idValue, nodeSelected);
function nodeSelected(node)
{
targetNode = node;
}
function stylesUpdated()
{
callback(targetNode);
}
}
InspectorTest.selectNodeAndWaitForStylesWithComputed = function(idValue, callback)
{
callback = InspectorTest.safeWrap(callback);
function stylesCallback(targetNode)
{
InspectorTest.addSniffer(WebInspector.SidebarPane.prototype, "onContentReady", callback);
WebInspector.panels.elements.sidebarPanes.computedStyle.expand();
}
InspectorTest.selectNodeAndWaitForStyles(idValue, stylesCallback);
}
InspectorTest.dumpSelectedElementStyles = function(excludeComputed, excludeMatched, omitLonghands, includeSelectorGroupMarks)
{
function extractText(element)
{
var text = element.textContent;
if (text)
return text;
element = element.querySelector("[data-uncopyable]");
return element ? element.getAttribute("data-uncopyable") : "";
}
function buildMarkedSelectors(element)
{
var result = "";
for (var node = element.firstChild; node; node = node.nextSibling) {
if (node.nodeType === Node.ELEMENT_NODE && node.className === "selector-matches")
result += "[$" + node.textContent + "$]";
else
result += node.textContent;
}
return result;
}
var styleSections = WebInspector.panels.elements.sidebarPanes.styles.sections;
for (var pseudoId in styleSections) {
var pseudoName = WebInspector.StylesSidebarPane.PseudoIdNames[pseudoId];
var sections = styleSections[pseudoId];
for (var i = 0; i < sections.length; ++i) {
var section = sections[i];
if (section.computedStyle && excludeComputed)
continue;
if (section.rule && excludeMatched)
continue;
if (section.element.previousSibling && section.element.previousSibling.className === "sidebar-separator")
InspectorTest.addResult("======== " + section.element.previousSibling.textContent + " ========");
InspectorTest.addResult((section.expanded ? "[expanded] " : "[collapsed] ") + (section.noAffect ? "[no-affect] " : ""));
var chainEntries = section.titleElement.children;
for (var j = 0; j < chainEntries.length; ++j) {
var chainEntry = chainEntries[j];
var entryLine = includeSelectorGroupMarks ? buildMarkedSelectors(chainEntry.children[1]) : chainEntry.children[1].textContent;
if (chainEntry.children[2])
entryLine += " " + chainEntry.children[2].textContent;
entryLine += " (" + extractText(chainEntry.children[0]) + ")";
InspectorTest.addResult(entryLine);
}
section.expand();
InspectorTest.dumpStyleTreeOutline(section.propertiesTreeOutline, omitLonghands ? 1 : 2);
InspectorTest.addResult("");
}
InspectorTest.addResult("");
}
}
InspectorTest.toggleStyleProperty = function(propertyName, checked)
{
var treeItem = InspectorTest.getElementStylePropertyTreeItem(propertyName);
treeItem.toggleEnabled({ target: { checked: checked }, consume: function() { } });
}
InspectorTest.toggleMatchedStyleProperty = function(propertyName, checked)
{
var treeItem = InspectorTest.getMatchedStylePropertyTreeItem(propertyName);
treeItem.toggleEnabled({ target: { checked: checked }, consume: function() { } });
}
InspectorTest.expandAndDumpSelectedElementEventListeners = function(callback)
{
InspectorTest.expandSelectedElementEventListeners(function() {
InspectorTest.dumpSelectedElementEventListeners(callback);
});
}
InspectorTest.expandSelectedElementEventListeners = function(callback)
{
var sidebarPane = WebInspector.panels.elements.sidebarPanes.eventListeners;
sidebarPane.expand();
InspectorTest.runAfterPendingDispatches(function() {
InspectorTest.expandSelectedElementEventListenersSubsections(callback);
});
}
InspectorTest.expandSelectedElementEventListenersSubsections = function(callback)
{
var eventListenerSections = WebInspector.panels.elements.sidebarPanes.eventListeners.sections;
for (var i = 0; i < eventListenerSections.length; ++i)
eventListenerSections[i].expand();
// Multiple sections may expand.
InspectorTest.runAfterPendingDispatches(function() {
InspectorTest.expandSelectedElementEventListenersEventBars(callback);
});
}
InspectorTest.expandSelectedElementEventListenersEventBars = function(callback)
{
var eventListenerSections = WebInspector.panels.elements.sidebarPanes.eventListeners.sections;
for (var i = 0; i < eventListenerSections.length; ++i) {
var eventBarChildren = eventListenerSections[i]._eventBars.children;
for (var j = 0; j < eventBarChildren.length; ++j)
eventBarChildren[j]._section.expand();
}
// Multiple sections may expand.
InspectorTest.runAfterPendingDispatches(callback);
}
InspectorTest.dumpSelectedElementEventListeners = function(callback)
{
function formatSourceNameProperty(value)
{
return "[clipped-for-test]/" + value.replace(/(.*?\/)LayoutTests/, "LayoutTests");
}
var eventListenerSections = WebInspector.panels.elements.sidebarPanes.eventListeners.sections;
for (var i = 0; i < eventListenerSections.length; ++i) {
var section = eventListenerSections[i];
var eventType = section._title;
InspectorTest.addResult("");
InspectorTest.addResult("======== " + eventType + " ========");
var eventBarChildren = section._eventBars.children;
for (var j = 0; j < eventBarChildren.length; ++j) {
var objectPropertiesSection = eventBarChildren[j]._section;
InspectorTest.dumpObjectPropertySection(objectPropertiesSection, {
sourceName: formatSourceNameProperty
});
}
}
callback();
}
InspectorTest.dumpObjectPropertySection = function(section, formatters)
{
var expandedSubstring = section.expanded ? "[expanded]" : "[collapsed]";
InspectorTest.addResult(expandedSubstring + " " + section.titleElement.textContent + " " + section.subtitleAsTextForTest);
if (!section.propertiesForTest)
return;
for (var i = 0; i < section.propertiesForTest.length; ++i) {
var property = section.propertiesForTest[i];
var key = property.name;
var value = property.value._description;
if (key in formatters)
value = formatters[key](value);
InspectorTest.addResult(" " + key + ": " + value);
}
}
InspectorTest.dumpObjectPropertySectionDeep = function(section)
{
function domNodeToString(node) {
if (node)
return "'" + node.textContent + "'";
else
return "null";
}
function dumpTreeElementRecursively(treeElement, prefix) {
if ("nameElement" in treeElement)
InspectorTest.addResult(prefix + domNodeToString(treeElement.nameElement) + " => " + domNodeToString(treeElement.valueElement));
else
InspectorTest.addResult(prefix + treeElement.title);
for (var i = 0; i < treeElement.children.length; i++)
dumpTreeElementRecursively(treeElement.children[i], prefix + " ");
}
var childNodes = section.propertiesTreeOutline.children;
for (var i = 0; i < childNodes.length; i++) {
dumpTreeElementRecursively(childNodes[i], "");
}
}
// FIXME: this returns the first tree item found (may fail for same-named properties in a style).
InspectorTest.getElementStylePropertyTreeItem = function(propertyName)
{
var styleSections = WebInspector.panels.elements.sidebarPanes.styles.sections[0];
var elementStyleSection = styleSections[1];
return InspectorTest.getFirstPropertyTreeItemForSection(elementStyleSection, propertyName);
};
// FIXME: this returns the first tree item found (may fail for same-named properties in a style).
InspectorTest.getMatchedStylePropertyTreeItem = function(propertyName)
{
var styleSections = WebInspector.panels.elements.sidebarPanes.styles.sections[0];
for (var i = 1; i < styleSections.length; ++i) {
var treeItem = InspectorTest.getFirstPropertyTreeItemForSection(styleSections[i], propertyName);
if (treeItem)
return treeItem;
}
return null;
};
InspectorTest.getFirstPropertyTreeItemForSection = function(section, propertyName)
{
var outline = section.propertiesTreeOutline;
for (var i = 0; i < outline.children.length; ++i) {
var treeItem = outline.children[i];
if (treeItem.name === propertyName)
return treeItem;
}
return null;
};
InspectorTest.dumpStyleTreeOutline = function(treeItem, depth)
{
var children = treeItem.children;
for (var i = 0; i < children.length; ++i)
InspectorTest.dumpStyleTreeItem(children[i], "", depth || 2);
};
InspectorTest.dumpStyleTreeItem = function(treeItem, prefix, depth)
{
// Filter out width and height properties in order to minimize
// potential diffs.
if (!treeItem.listItemElement.textContent.indexOf("width") ||
!treeItem.listItemElement.textContent.indexOf("height"))
return;
if (treeItem.listItemElement.hasStyleClass("inherited"))
return;
var typePrefix = "";
if (treeItem.listItemElement.hasStyleClass("overloaded") || treeItem.listItemElement.hasStyleClass("inactive") || treeItem.listItemElement.hasStyleClass("not-parsed-ok"))
typePrefix += "/-- overloaded --/ ";
if (treeItem.listItemElement.hasStyleClass("disabled"))
typePrefix += "/-- disabled --/ ";
var textContent = treeItem.listItemElement.textContent;
// Add non-selectable url text.
var textData = treeItem.listItemElement.querySelector("[data-uncopyable]");
if (textData)
textContent += textData.getAttribute("data-uncopyable");
InspectorTest.addResult(prefix + typePrefix + textContent);
if (--depth) {
treeItem.expand();
var children = treeItem.children;
for (var i = 0; children && i < children.length; ++i)
InspectorTest.dumpStyleTreeItem(children[i], prefix + " ", depth);
}
};
InspectorTest.dumpElementsTree = function(rootNode, depth)
{
function beautify(element)
{
return element.innerText.replace(/\u200b/g, "").replace(/\n/g, "\\n").trim();
}
function dumpMap(name, map)
{
var result = [];
for (var id in map)
result.push(id + "=" + map[id]);
if (!result.length)
return "";
return name + ":[" + result.join(",") + "]";
}
function userPropertyDataDump(treeItem)
{
if (treeItem._elementCloseTag)
return "";
var userProperties = "";
var node = treeItem.representedObject;
if (node) {
userProperties += dumpMap("userProperties", node._userProperties);
var dump = dumpMap("descendantUserAttributeCounters", node._descendantUserPropertyCounters);
if (dump) {
if (userProperties)
userProperties += ", ";
userProperties += dump;
}
if (userProperties)
userProperties = " [" + userProperties + "]";
}
return userProperties;
}
function print(treeItem, prefix, depth)
{
if (treeItem.listItemElement) {
var expander;
if (treeItem.hasChildren) {
if (treeItem.expanded)
expander = "- ";
else
expander = "+ ";
} else
expander = " ";
var userProperties = userPropertyDataDump(treeItem);
InspectorTest.addResult(prefix + expander + beautify(treeItem.listItemElement) + userProperties);
}
if (!treeItem.expanded)
return;
var children = treeItem.children;
for (var i = 0; depth && children && i < children.length - 1; ++i)
print(children[i], prefix + " ", depth - 1);
// Closing tag.
if (children && children.length)
print(children[children.length - 1], prefix, depth);
}
WebInspector.panels.elements.treeOutline._updateModifiedNodes();
var treeOutline = WebInspector.panels.elements.treeOutline;
print(rootNode ? treeOutline.findTreeElement(rootNode) : treeOutline, "", depth || 10000);
};
InspectorTest.expandElementsTree = function(callback)
{
callback = InspectorTest.safeWrap(callback);
function expand(treeItem)
{
var children = treeItem.children;
for (var i = 0; children && i < children.length; ++i) {
children[i].expand();
expand(children[i]);
}
}
function onAllNodesAvailable()
{
WebInspector.panels.elements.treeOutline._updateModifiedNodes();
expand(WebInspector.panels.elements.treeOutline);
callback();
}
WebInspector.showPanel("elements");
InspectorTest.findNode(function() { return false; }, onAllNodesAvailable);
};
InspectorTest.dumpDOMAgentTree = function()
{
if (!WebInspector.domAgent._document)
return;
function dump(node, prefix, startIndex)
{
InspectorTest.addResult(prefix + node.nodeName() + "[" + (node.id - startIndex)+ "]");
var children = node.children;
for (var i = 0; children && i < children.length; ++i)
dump(children[i], prefix + " ", startIndex);
}
dump(WebInspector.domAgent._document, "", WebInspector.domAgent._document.id - 1);
};
InspectorTest.rangeText = function(range)
{
if (!range)
return "[undefined-undefined]";
return "[" + range.startLine + ":" + range.startColumn + "-" + range.endLine + ":" + range.endColumn + "]";
}
InspectorTest.generateUndoTest = function(testBody)
{
function result(next)
{
var testNode = InspectorTest.expandedNodeWithId(/function\s([^(]*)/.exec(testBody)[1]);
InspectorTest.addResult("Initial:");
InspectorTest.dumpElementsTree(testNode);
testBody(undo);
function undo()
{
InspectorTest.addResult("Post-action:");
InspectorTest.dumpElementsTree(testNode);
WebInspector.domAgent.undo(redo);
}
function redo()
{
InspectorTest.addResult("Post-undo (initial):");
InspectorTest.dumpElementsTree(testNode);
WebInspector.domAgent.redo(done);
}
function done()
{
InspectorTest.addResult("Post-redo (action):");
InspectorTest.dumpElementsTree(testNode);
next();
}
}
result.toString = function()
{
return testBody.toString();
}
return result;
}
const indent = " ";
InspectorTest.dumpRulesArray = function(rules, currentIndent)
{
if (!rules)
return;
currentIndent = currentIndent || "";
for (var i = 0; i < rules.length; ++i)
InspectorTest.dumpRule(rules[i], currentIndent);
}
InspectorTest.dumpRuleMatchesArray = function(matches, currentIndent)
{
if (!matches)
return;
currentIndent = currentIndent || "";
for (var i = 0; i < matches.length; ++i)
InspectorTest.dumpRule(matches[i].rule, currentIndent);
}
InspectorTest.dumpRule = function(rule, currentIndent)
{
function selectorRange()
{
if (!rule.selectorList || !rule.selectorList.range)
return "";
var range = rule.selectorList.range;
return ", " + range.startLine + ":" + range.startColumn + "-" + range.endLine + ":" + range.endColumn;
}
currentIndent = currentIndent || "";
if (!rule.type || rule.type === "style") {
InspectorTest.addResult(currentIndent + rule.selectorList.text + ": [" + rule.origin + selectorRange() + "] {");
InspectorTest.dumpStyle(rule.style, currentIndent + indent);
InspectorTest.addResult(currentIndent + "}");
return;
}
if (rule.type === "media") {
InspectorTest.addResult(currentIndent + "@media " + rule.mediaText + " {");
InspectorTest.dumpRulesArray(rule.childRules, currentIndent + indent);
InspectorTest.addResult(currentIndent + "}");
return;
}
if (rule.type === "import") {
InspectorTest.addResult(currentIndent + "@import: header=" + InspectorTest.rangeText(rule.headerRange) + ", body=" + InspectorTest.rangeText(rule.bodyRange));
return;
}
if (rule.type === "page" || rule.type === "font-face") {
if (rule.type === "page")
InspectorTest.addResult(currentIndent + rule.selectorList.text + " {");
else
InspectorTest.addResult(currentIndent + "@" + rule.type + " " + (rule.selectorList.text ? rule.selectorList.text + " " : "") + "{");
InspectorTest.dumpStyle(rule.style, currentIndent + indent);
InspectorTest.addResult(currentIndent + "}");
return;
}
if (rule.type === "charset") {
InspectorTest.addResult("@charset");
return;
}
InspectorTest.addResult(currentIndent + "[UNKNOWN RULE]: header=" + InspectorTest.rangeText(rule.headerRange) + ", body=" + InspectorTest.rangeText(rule.bodyRange));
}
InspectorTest.dumpStyle = function(style, currentIndent)
{
currentIndent = currentIndent || "";
if (!style) {
InspectorTest.addResult(currentIndent + "[NO STYLE]");
return;
}
for (var i = 0; i < style.cssProperties.length; ++i) {
var property = style.cssProperties[i];
if (property.status !== "disabled")
InspectorTest.addResult(currentIndent + "['" + property.name + "':'" + property.value + "'" + (property.priority === "important" ? " is-important" : "") + (("parsedOk" in property) ? " non-parsed" : "") +"] @" + InspectorTest.rangeText(property.range) + " " + (property.status || "style"));
else
InspectorTest.addResult(currentIndent + "[text='" + property.text + "'] " + property.status);
}
}
};
function dumpInspectorHighlightRects()
{
var rectNames = ["margin", "border", "padding", "content"];
var rects = window.internals.inspectorHighlightRects();
for (var i = 0; i < rects.length; i++)
{
var rectName = (i < rectNames.length ? rectNames[i] : "untitled");
var rect = rects.item(i);
output(rectName + " rect is " + rect.width + " x " + rect.height + " at (" + rect.left + ", " + rect.top + ")");
}
}
function dumpInspectorHighlightedRegions()
{
var highlight = window.internals.inspectorHighlightObject();
if (!highlight.length) {
output("No highlighted node.");
return;
}
// Reformat the string using JSON.stringify.
var json = JSON.parse(highlight);
if (!json.elementInfo || !json.elementInfo.regionFlowInfo) {
output("No highlighted regions.");
return;
}
output(JSON.stringify(json.elementInfo.regionFlowInfo, null, 4));
}
function dumpInspectorHighlightedNode()
{
var highlight = window.internals.inspectorHighlightObject();
if (!highlight.length) {
output("No highlighted node.");
return;
}
// Reformat the string using JSON.stringify.
var json = JSON.parse(highlight);
if (!json) {
output("No highlighted node.");
return;
}
output(JSON.stringify(json, null, 4));
}