1 function createShadowRoot()
3 var children = Array.prototype.slice.call(arguments);
4 if ((children[0] instanceof Object) && !(children[0] instanceof Node))
5 return {'isShadowRoot': true,
6 'attributes': children[0],
7 'children': children.slice(1)};
8 return {'isShadowRoot': true,
12 // This function can take optional child elements, which might be a result of createShadowRoot(), as arguments[2:].
13 function createDOM(tagName, attributes)
15 var element = document.createElement(tagName);
16 for (var name in attributes)
17 element.setAttribute(name, attributes[name]);
18 var childElements = Array.prototype.slice.call(arguments, 2);
19 for (var i = 0; i < childElements.length; ++i) {
20 var child = childElements[i];
21 if (child.isShadowRoot) {
22 var shadowRoot = element.createShadowRoot();
23 if (child.attributes) {
24 for (var attribute in child.attributes) {
25 // Shadow Root does not have setAttribute.
26 shadowRoot[attribute] = child.attributes[attribute];
29 for (var j = 0; j < child.children.length; ++j)
30 shadowRoot.appendChild(child.children[j]);
32 element.appendChild(child);
37 function isShadowHost(node)
39 return window.internals.oldestShadowRoot(node);
42 function isShadowRoot(node)
44 return node instanceof window.ShadowRoot;
47 function isIframeElement(element)
49 return element && element.nodeName == 'IFRAME';
52 // You can spefify youngerShadowRoot by consecutive slashes.
53 // See LayoutTests/fast/dom/shadow/get-element-by-id-in-shadow-root.html for actual usages.
54 function getNodeInTreeOfTrees(path)
56 var ids = path.split('/');
57 var node = document.getElementById(ids[0]);
58 for (var i = 1; node != null && i < ids.length; ++i) {
59 if (isIframeElement(node)) {
60 node = node.contentDocument.getElementById(ids[i]);
63 if (isShadowRoot(node))
64 node = internals.youngerShadowRoot(node);
65 else if (internals.oldestShadowRoot(node))
66 node = internals.oldestShadowRoot(node);
70 node = node.getElementById(ids[i]);
75 function dumpNode(node)
84 function dumpNodeList(nodeList) {
86 var length = nodeList.length;
87 for (var i = 0; i < length; i++)
88 result += dumpNode(nodeList[i]) + ", ";
89 result += "length: " + length;
93 function shouldBeEqualAsArray(nodeList, expectedNodes)
95 // FIXME: Avoid polluting the global namespace.
96 window.nodeList = nodeList;
97 window.expectedNodes = expectedNodes;
98 shouldBe("nodeList.length", "expectedNodes.length");
99 for (var i = 0; i < nodeList.length; ++i) {
100 shouldBe("nodeList.item(" + i + ")", "expectedNodes[" + i + "]");
104 function innermostActiveElement(element)
106 element = element || document.activeElement;
107 if (isIframeElement(element)) {
108 if (element.contentDocument.activeElement)
109 return innermostActiveElement(element.contentDocument.activeElement);
112 if (isShadowHost(element)) {
113 var shadowRoot = window.internals.oldestShadowRoot(element);
115 if (shadowRoot.activeElement)
116 return innermostActiveElement(shadowRoot.activeElement);
117 shadowRoot = window.internals.youngerShadowRoot(shadowRoot);
123 function isInnermostActiveElement(id)
125 var element = getNodeInTreeOfTrees(id);
127 debug('FAIL: There is no such element with id: '+ from);
130 if (element == innermostActiveElement())
132 debug('Expected innermost activeElement is ' + id + ', but actual innermost activeElement is ' + dumpNode(innermostActiveElement()));
136 function shouldNavigateFocus(from, to, direction)
138 debug('Should move from ' + from + ' to ' + to + ' in ' + direction);
139 var fromElement = getNodeInTreeOfTrees(from);
141 debug('FAIL: There is no such element with id: '+ from);
145 if (!isInnermostActiveElement(from)) {
146 debug('FAIL: Can not be focused: '+ from);
149 if (direction == 'forward')
150 navigateFocusForward();
152 navigateFocusBackward();
153 if (isInnermostActiveElement(to))
159 function navigateFocusForward()
161 eventSender.keyDown('\t');
164 function navigateFocusBackward()
166 eventSender.keyDown('\t', ['shiftKey']);
169 function testFocusNavigationFowrad(elements)
171 for (var i = 0; i + 1 < elements.length; ++i)
172 shouldNavigateFocus(elements[i], elements[i + 1], 'forward');
175 function testFocusNavigationBackward(elements)
177 for (var i = 0; i + 1 < elements.length; ++i)
178 shouldNavigateFocus(elements[i], elements[i + 1], 'backward');
181 function dumpComposedShadowTree(node, indent)
183 indent = indent || "";
184 var output = indent + dumpNode(node) + "\n";
186 for (child = internals.firstChildByWalker(node); child; child = internals.nextSiblingByWalker(child))
187 output += dumpComposedShadowTree(child, indent + "\t");
191 function lastNodeByWalker(root)
194 while (internals.lastChildByWalker(lastNode))
195 lastNode = internals.lastChildByWalker(lastNode);
199 function showComposedShadowTreeByTraversingInForward(root)
202 var last = lastNodeByWalker(root);
204 debug(dumpNode(node));
207 node = internals.nextNodeByWalker(node);
211 function showComposedShadowTreeByTraversingInBackward(root)
213 var node = lastNodeByWalker(root);
215 debug(dumpNode(node));
218 node = internals.previousNodeByWalker(node);
222 function showComposedShadowTree(node)
224 debug('Composed Shadow Tree:');
225 debug(dumpComposedShadowTree(node));
227 debug('Traverse in forward.');
228 showComposedShadowTreeByTraversingInForward(node);
230 debug('Traverse in backward.');
231 showComposedShadowTreeByTraversingInBackward(node);
236 function showNextNode(node) {
237 var next = internals.nextNodeByWalker(node);
238 debug('Next node of [' + dumpNode(node) + '] is [' + dumpNode(next) + ']');