blob: 7883f09e6a9de6835a6febddcfe76fb831596278 [file] [log] [blame]
<!DOCTYPE html>
<html>
<head>
<script src="../../../resources/js-test-pre.js"></script>
<script src="resources/shadow-dom.js"></script>
</head>
<body>
<div id="console"></div>
<div id="sandbox"></div>
<script>
description("Tests for Composed Shadow DOM Tree Traversal APIs. Can only run within DRT");
if (window.testRunner)
testRunner.dumpAsText();
function dumpNode(node)
{
if (!node)
return '(null)'
var output = node.nodeName + "\t";
if (node.id)
output += ' id=' + node.id;
if (node.className)
output += ' class=' + node.className;
return output;
}
function dumpComposedShadowTree(node, indent)
{
indent = indent || "";
var output = indent + dumpNode(node) + "\n";
var child;
for (child = internals.firstChildByWalker(node); child; child = internals.nextSiblingByWalker(child))
output += dumpComposedShadowTree(child, indent + "\t");
return output;
}
function lastNodeByWalker(root)
{
var lastNode = root;
while (internals.lastChildByWalker(lastNode))
lastNode = internals.lastChildByWalker(lastNode);
return lastNode;
}
function showComposedShadowTreeByTraversingInForward(root)
{
var node = root;
var last = lastNodeByWalker(root);
while (node) {
debug(dumpNode(node));
if (node == last)
break;
node = internals.nextNodeByWalker(node);
}
}
function showComposedShadowTreeByTraversingInBackward(root)
{
var node = lastNodeByWalker(root);
while (node) {
debug(dumpNode(node));
if (node == root)
break;
node = internals.previousNodeByWalker(node);
}
}
function showComposedShadowTree(node)
{
debug('Composed Shadow Tree:');
debug(dumpComposedShadowTree(node));
debug('Traverse in forward.');
showComposedShadowTreeByTraversingInForward(node);
debug('Traverse in backward.');
showComposedShadowTreeByTraversingInBackward(node);
debug('');
}
function showNextNode(node) {
var next = internals.nextNodeByWalker(node);
debug('Next node of [' + dumpNode(node) + '] is [' + dumpNode(next) + ']');
}
function testComposedShadowTree(node)
{
var sandbox = document.getElementById('sandbox');
sandbox.innerHTML = '';
sandbox.appendChild(node);
document.body.offsetLeft;
showComposedShadowTree(node);
}
debug('ShadowRoot should be used.');
testComposedShadowTree(
createDOM('div', {'id': 'a'},
createShadowRoot(createDOM('div', {'id': 'b'})),
createDOM('div', {'id': 'c'})));
debug('A content element should select light children');
testComposedShadowTree(
createDOM('div', {'id': 'a'},
createShadowRoot(createDOM('div', {'id': 'b'}),
createDOM('content')),
createDOM('div', {'id': 'c'}),
createDOM('div', {'id': 'd'})));
debug('Test for content element selector.');
testComposedShadowTree(
createDOM('div', {'id': 'a'},
createShadowRoot(createDOM('div', {'id': 'b'}),
createDOM('content', {'select': '#d'})),
createDOM('div', {'id': 'c'}),
createDOM('div', {'id': 'd'}),
createDOM('div', {'id': 'e'})));
debug('Light children should be selected only at once.');
testComposedShadowTree(
createDOM('div', {'id': 'a'},
createShadowRoot(createDOM('div', {'id': 'b'}),
createDOM('content', {'select': '#d'}),
createDOM('content')),
createDOM('div', {'id': 'c'}),
createDOM('div', {'id': 'd'}),
createDOM('div', {'id': 'e'})));
debug('A content element can have fallback elements.');
testComposedShadowTree(
createDOM('div', {'id': 'a'},
createShadowRoot(createDOM('div', {'id': 'b'}),
createDOM('content', {'select': '#z'},
createDOM('div', {'id': 'f1'}),
createDOM('div', {'id': 'f2'}))),
createDOM('div', {'id': 'c'})));
debug('Fallback elements should not be used if a content element selects an element.');
testComposedShadowTree(
createDOM('div', {'id': 'a'},
createShadowRoot(createDOM('div', {'id': 'b'}),
createDOM('content', {'select': '#c'},
createDOM('div', {'id': 'f1'},
createDOM('div', {'id': 'f2'})))),
createDOM('div', {'id': 'c'})));
debug('Test for traversal, starting with a fallback element which is not used.');
showComposedShadowTree(getNodeInShadowTreeStack('a/f1'));
showNextNode(getNodeInShadowTreeStack('a/f1'));
showNextNode(getNodeInShadowTreeStack('a/f2'));
debug('');
debug('Test for Nested ShadowRoots.');
testComposedShadowTree(
createDOM('div', {'id': 'a'},
createShadowRoot(createDOM('div', {'id': 'b'},
createShadowRoot(createDOM('div', {'id': 'c'}),
createDOM('content'),
createDOM('div', {'id': 'd'})),
createDOM('div', {'id': 'e'})),
createDOM('div', {'id': 'f'}),
createDOM('content'),
createDOM('div', {'id': 'g'})),
createDOM('div', {'id': 'h'}),
createDOM('div', {'id': 'i'})));
debug('Test for Multiple ShadowRoots.');
testComposedShadowTree(
createDOM('div', {'id': 'a'},
createShadowRoot(createDOM('div', {'id': 'b'}),
createDOM('content'),
createDOM('div', {'id': 'c'})),
createShadowRoot(createDOM('div', {'id': 'd'}),
createDOM('shadow'),
createDOM('div', {'id': 'e'})),
createDOM('div', {'id': 'f'})));
debug('Test for inactive insertion points.');
testComposedShadowTree(
createDOM('div', {'id': 'a'},
createDOM('content', {'id': 'b'},
createDOM('content', {'id': 'c'}))));
debug('Test for an orphaned shadow subtree.');
testComposedShadowTree(
createDOM('div', {'id': 'a'},
createShadowRoot(
createDOM('div', {'id': 'b'},
createDOM('div', {'id': 'c'}))),
createShadowRoot(
createDOM('div', {'id': 'd'}))));
debug('Test for traversal, starting with a node in an orphaned shadow subtree.');
showComposedShadowTree(getNodeInShadowTreeStack('a/b'));
debug('Test for a content element which does not select any nodes nor have fallback elements.');
testComposedShadowTree(
createDOM('div', {'id': 'a'},
createShadowRoot(createDOM('content', {'select': '#none'}),
createDOM('div', {'id': 'b'}),
createDOM('content', {'select': '#none'}),
createDOM('div', {'id': 'c'}),
createDOM('content', {'select': '#none'}))));
debug('Test for a nested insertion point.');
testComposedShadowTree(
createDOM('div', {'id': 'a'},
createShadowRoot(createDOM('div', {'id': 'b'},
createShadowRoot(createDOM('content', {})),
createDOM('content', {}))),
createDOM('div', {'id': 'c'})));
debug('Test for nested insertion points. Some of them are either empty insertion points or inactive insertion points.');
testComposedShadowTree(
createDOM('div', {'id': 'a'},
createShadowRoot(createDOM('content', {'select': '#none'}),
createDOM('div', {'id': 'b'},
createShadowRoot(createDOM('content', {'select': '.select-1'}),
createDOM('div', {'id': 'c'}),
createDOM('content', {'select': '.select-2'})),
createDOM('content', {'class': 'select-1', 'select': '.select-4'}),
createDOM('content', {'class': 'select-2', 'select': '#none'}),
createDOM('div', {'id': 'd', 'class': 'select-2'}),
createDOM('content', {'class': 'select-2', 'select': '#none'}),
createDOM('div', {'id': 'e', 'class': 'select-2'}),
createDOM('content', {'class': 'select-2', 'select': '#none'}))),
createDOM('content', {'id': 'inactive-insertion-point', 'class': 'select-4'}),
createDOM('div', {'id': 'should-not-be-selected'}),
createDOM('div', {'id': 'f', 'class': 'select-4'})));
debug('Test for a re-projection.');
testComposedShadowTree(
createDOM('div', {'id': 'a'},
createShadowRoot(
createDOM('div', {'id': 'b'},
createShadowRoot(createDOM('content', {'select': '#c'})),
createDOM('content', {'select': '#c'}))),
createDOM('div', {'id': 'c'})));
debug('Test for a content element which is selected by another content element.');
testComposedShadowTree(
createDOM('div', {'id': 'a'},
createShadowRoot(
createDOM('div', {'id': 'b'},
createShadowRoot(createDOM('content', {'select': '#content'}),
createDOM('div', {'id': 'most-inner-child'}),
createDOM('content', {'select': '#host-child'})),
createDOM('content', {'id': 'content', 'select': '#host-child'},
createDOM('div', {'id': 'should-not-be-used'})),
createDOM('div', {'id': 'inner-child', 'class': 'foo'}))),
createDOM('div', {'id': 'host-child'})));
debug('Test for a reprojection. Content elements should be used in document order.');
testComposedShadowTree(
createDOM('div', {'id': 'a'},
createShadowRoot(
createDOM('content', {'select': '#host-child1'}),
createDOM('div', {'id': 'b'},
createShadowRoot(createDOM('content', {'select': '.child'})),
createDOM('content', {'select': '.child'}))),
createDOM('div', {'id': 'host-child1', 'class': 'child'}),
createDOM('div', {'id': 'host-child2', 'class': 'child'})));
debug('Test for complex re-projections.');
testComposedShadowTree(
createDOM('div', {'id': 'a'},
createShadowRoot(
createDOM('div', {'id': 'b'},
createShadowRoot(createDOM('content', {'select': '.foo'}),
createDOM('div', {'id': 'c'})),
// Select #child-1
createDOM('content', {'select': '#child-1'},
createDOM('div', {'class': 'should-not-be-used'}),
// Should not select any nodes since it's inactive.
createDOM('content', {'class': 'should-be-inactive', 'select': '.foo'})),
createDOM('div', {'id': 'd', 'class': 'foo'},
createShadowRoot(createDOM('div', {'id': 'e'}),
// Should select #child-2 and #g.
createDOM('content', {'select': '.foo'}),
createDOM('div', {'id': 'f'})),
// Select #child-2
createDOM('content', {'select': '#child-2'}),
createDOM('div', {'id': 'g', 'class': 'foo'})),
createDOM('div', {'class': 'should-not-be-selected'}),
createDOM('div', {'id': 'h', 'class': 'foo'}))),
createDOM('div', {'id': 'child-1', 'class': 'foo'}),
createDOM('div', {'id': 'not-selected', 'class': 'foo'}),
createDOM('div', {'id': 'child-2', 'class': 'foo'})));
</script>
<script src="../../../resources/js-test-post.js"></script>
</body>
</html>