dom-tree-accessors-001.html (8354B)
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title>Shadow DOM Test: Upper-boundary encapsulation: document's DOM tree accessors</title> 5 <link rel="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru"> 6 <link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru"> 7 <link rel="author" title="Mikhail Fursov" href="mailto:mfursov@unipro.ru"> 8 <link rel="author" title="Yuta Kitamura" href="mailto:yutak@google.com"> 9 <link rel="help" href="http://www.w3.org/TR/2013/WD-shadow-dom-20130514/#upper-boundary-encapsulation"> 10 <meta name="assert" content="Upper-boundary encapsulation: The shadow nodes and named shadow elements are not accessible using shadow host's document DOM tree accessors."> 11 <script src="/resources/testharness.js"></script> 12 <script src="/resources/testharnessreport.js"></script> 13 <script src="../../../../html/resources/common.js"></script> 14 </head> 15 <body> 16 <div id="log"></div> 17 <script> 18 // A document's "DOM tree accessors" include: 19 // (document.)head, title, body, images, embeds, plugins, links, forms, 20 // scripts, getElementsByName(), cssElementMap, and currentScript 21 // 22 // Of these, it is unclear how document.cssElementMap can be tested. 23 // Except for it, there is a test corresponding to each accessor. 24 // 25 // Additionally, there are obsolete accessors 26 // <http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#other-elements,-attributes-and-apis>: 27 // (document.)anchors, applets, and all. 28 // 29 // and some accessors defined in the DOM specification (formerly known as 30 // "DOM Core") <http://dom.spec.whatwg.org/#interface-document>: 31 // (document.)documentElement, getElementsByTagName(), 32 // getElementsByTagNameNS(), getElementsByClassName(), and getElementById(). 33 // 34 // As it seems reasonable to have tests for these accessors, this file also 35 // includes tests for them, except for document.documentElement which is 36 // unclear whether we can test; the distribution process of Shadow DOM does not 37 // alter the host element, so the document element (e.g. <html>) cannot be 38 // replaced with an element in a shadow tree. 39 40 // ---------------------------------------------------------------------------- 41 // Constants and utility functions 42 43 // Place the same HTML content into both the host document and the shadow root. 44 // To differentiate these two, a class name is assigned to every element by 45 // populateTestContentToHostDocument() and populateTestContentToShadowRoot(). 46 var HTML_CONTENT = [ 47 '<head>', 48 '<title></title>', 49 '<link rel="help" href="#">', 50 '</head>', 51 '<body>', 52 '<p></p>', 53 '<a name="test-name"></a>', 54 '<a href="#"></a>', 55 '<area href="#">', 56 '<img src="#" alt="">', 57 '<embed></embed>', 58 '<form></form>', 59 '<script><' + '/script>', 60 '</body>' 61 ].join('\n'); 62 63 function addClassNameToAllElements(document, root, className) { 64 var nodeIterator = document.createNodeIterator( 65 root, NodeFilter.SHOW_ELEMENT, null); 66 var node; 67 while (node = nodeIterator.nextNode()) 68 node.className = className; 69 } 70 71 function populateTestContentToHostDocument(document) { 72 document.documentElement.innerHTML = HTML_CONTENT; 73 addClassNameToAllElements(document, document.documentElement, 'host'); 74 } 75 76 function populateTestContentToShadowRoot(shadowRoot) { 77 shadowRoot.innerHTML = HTML_CONTENT; 78 addClassNameToAllElements(shadowRoot.ownerDocument, shadowRoot, 'shadow'); 79 } 80 81 function createDocumentForTesting() { 82 var doc = document.implementation.createHTMLDocument(''); 83 populateTestContentToHostDocument(doc); 84 var shadowRoot = doc.body.attachShadow({mode: 'open'}); 85 populateTestContentToShadowRoot(shadowRoot); 86 return doc; 87 } 88 89 // Make sure the given HTMLCollection contains at least one elements and 90 // all elements have the class named "host". This function works well with 91 // HTMLCollection, HTMLAllCollection, and NodeList consisting of elements. 92 function assert_collection(collection) { 93 assert_true(collection.length > 0); 94 Array.prototype.forEach.call(collection, function (element) { 95 assert_equals(element.className, 'host'); 96 }); 97 } 98 99 // ---------------------------------------------------------------------------- 100 // Tests for DOM tree accessors defined in HTML specification 101 102 test(function () { 103 var doc = createDocumentForTesting(); 104 assert_equals(doc.head.className, 'host'); 105 assert_equals(doc.body.className, 'host'); 106 }, 107 '<head> and <body> in a shadow tree should not be accessible from ' + 108 'owner document\'s "head" and "body" properties, respectively.' 109 ); 110 111 test(function () { 112 var doc = document.implementation.createHTMLDocument(''); 113 populateTestContentToHostDocument(doc); 114 115 // Note: this test is originally written to replace document.documentElement 116 // with shadow contents, but among Shadow DOM V1 allowed elements body is the 117 // most approximate to it, though some test may make lesser sense. 118 var shadowRoot = doc.body.attachShadow({mode: 'open'}); 119 populateTestContentToShadowRoot(shadowRoot); 120 121 // Replace the content of <title> to distinguish elements in a host 122 // document and a shadow tree. 123 doc.getElementsByTagName('title')[0].textContent = 'Title of host document'; 124 shadowRoot.querySelector('title').textContent = 125 'Title of shadow tree'; 126 127 assert_equals(doc.title, 'Title of host document'); 128 }, 129 'The content of title element in a shadow tree should not be accessible ' + 130 'from owner document\'s "title" attribute.' 131 ); 132 133 function testHTMLCollection(accessor) { 134 var doc = createDocumentForTesting(); 135 assert_collection(doc[accessor]); 136 } 137 138 generate_tests( 139 testHTMLCollection, 140 ['images', 'embeds', 'plugins', 'links', 'forms', 'scripts'].map( 141 function (accessor) { 142 return [ 143 'Elements in a shadow tree should not be accessible from ' + 144 'owner document\'s "' + accessor + '" attribute.', 145 accessor 146 ]; 147 })); 148 149 test(function () { 150 var doc = createDocumentForTesting(); 151 assert_collection(doc.getElementsByName('test-name')); 152 }, 153 'Elements in a shadow tree should not be accessible from owner ' + 154 'document\'s getElementsByName() method.' 155 ); 156 157 // ---------------------------------------------------------------------------- 158 // Tests for obsolete accessors 159 160 generate_tests( 161 testHTMLCollection, 162 ['anchors', 'all'].map( 163 function (accessor) { 164 return [ 165 'Elements in a shadow tree should not be accessible from ' + 166 'owner document\'s "' + accessor + '" attribute.', 167 accessor 168 ]; 169 })); 170 171 // ---------------------------------------------------------------------------- 172 // Tests for accessors defined in DOM specification 173 174 test(function () { 175 var doc = createDocumentForTesting(); 176 assert_collection(doc.getElementsByTagName('p')); 177 }, 178 'Elements in a shadow tree should not be accessible from owner ' + 179 'document\'s getElementsByTagName() method.' 180 ); 181 182 test(function () { 183 // Create a XML document. 184 var namespace = 'http://www.w3.org/1999/xhtml'; 185 var doc = document.implementation.createDocument(namespace, 'html'); 186 doc.documentElement.appendChild(doc.createElementNS(namespace, 'head')); 187 var body = doc.createElementNS(namespace, 'body'); 188 var pHost = doc.createElementNS(namespace, 'p'); 189 pHost.className = "host"; 190 body.appendChild(pHost); 191 doc.documentElement.appendChild(body); 192 193 var shadowRoot = body.attachShadow({mode: 'open'}); 194 var pShadow = doc.createElementNS(namespace, 'p'); 195 pShadow.className = "shadow"; 196 shadowRoot.appendChild(pShadow); 197 198 assert_collection(doc.getElementsByTagNameNS(namespace, 'p')); 199 }, 200 'Elements in a shadow tree should not be accessible from owner ' + 201 'document\'s getElementsByTagNameNS() method.' 202 ); 203 204 test(function () { 205 var doc = document.implementation.createHTMLDocument(''); 206 populateTestContentToHostDocument(doc); 207 var shadowRoot = doc.body.attachShadow({mode: 'open'}); 208 populateTestContentToShadowRoot(shadowRoot); 209 210 shadowRoot.querySelectorAll('p')[0].id = 'test-id'; 211 assert_equals(doc.getElementById('test-id'), null); 212 }, 213 'Elements in a shadow tree should not be accessible from owner ' + 214 'document\'s getElementById() method.' 215 ); 216 </script> 217 </body> 218 </html>