| <!DOCTYPE html> |
| <!-- |
| Distributed under both the W3C Test Suite License [1] and the W3C |
| 3-clause BSD License [2]. To contribute to a W3C Test Suite, see the |
| policies and contribution forms [3]. |
| |
| [1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license |
| [2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license |
| [3] http://www.w3.org/2004/10/27-testcases |
| --> |
| <html> |
| <head> |
| <title>Shadow DOM Test: Upper-boundary encapsulation: document's DOM tree accessors</title> |
| <link rel="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru"> |
| <link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru"> |
| <link rel="author" title="Mikhail Fursov" href="mailto:mfursov@unipro.ru"> |
| <link rel="author" title="Yuta Kitamura" href="mailto:yutak@google.com"> |
| <link rel="help" href="http://www.w3.org/TR/2013/WD-shadow-dom-20130514/#upper-boundary-encapsulation"> |
| <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."> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <script src="../../testcommon.js"></script> |
| <link rel="stylesheet" href="/resources/testharness.css"> |
| </head> |
| <body> |
| <div id="log"></div> |
| <script> |
| // A document's "DOM tree accessors" include: |
| // (document.)head, title, body, images, embeds, plugins, links, forms, |
| // scripts, getElementsByName(), cssElementMap, and currentScript |
| // |
| // Of these, it is unclear how document.cssElementMap can be tested. |
| // Except for it, there is a test corresponding to each accessor. |
| // |
| // Additionally, there are obsolete accessors |
| // <http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#other-elements,-attributes-and-apis>: |
| // (document.)anchors, applets, and all. |
| // |
| // and some accessors defined in the DOM specification (formerly known as |
| // "DOM Core") <http://dom.spec.whatwg.org/#interface-document>: |
| // (document.)documentElement, getElementsByTagName(), |
| // getElementsByTagNameNS(), getElementsByClassName(), and getElementById(). |
| // |
| // As it seems reasonable to have tests for these accessors, this file also |
| // includes tests for them, except for document.documentElement which is |
| // unclear whether we can test; the distribution process of Shadow DOM does not |
| // alter the host element, so the document element (e.g. <html>) cannot be |
| // replaced with an element in a shadow tree. |
| |
| // ---------------------------------------------------------------------------- |
| // Constants and utility functions |
| |
| // Place the same HTML content into both the host document and the shadow root. |
| // To differentiate these two, a class name is assigned to every element by |
| // populateTestContentToHostDocument() and populateTestContentToShadowRoot(). |
| var HTML_CONTENT = [ |
| '<head>', |
| '<title></title>', |
| '<link rel="help" href="#">', |
| '</head>', |
| '<body>', |
| '<p></p>', |
| '<a name="test-name"></a>', |
| '<a href="#"></a>', |
| '<area href="#">', |
| '<img src="#" alt="">', |
| '<embed></embed>', |
| '<form></form>', |
| '<script><' + '/script>', |
| '<applet></applet>', |
| '</body>' |
| ].join('\n'); |
| |
| function addClassNameToAllElements(document, root, className) { |
| var nodeIterator = document.createNodeIterator( |
| root, NodeFilter.SHOW_ELEMENT, null); |
| var node; |
| while (node = nodeIterator.nextNode()) |
| node.className = className; |
| } |
| |
| function populateTestContentToHostDocument(document) { |
| document.documentElement.innerHTML = HTML_CONTENT; |
| addClassNameToAllElements(document, document.documentElement, 'host'); |
| } |
| |
| function populateTestContentToShadowRoot(shadowRoot) { |
| shadowRoot.innerHTML = HTML_CONTENT; |
| addClassNameToAllElements(shadowRoot.ownerDocument, shadowRoot, 'shadow'); |
| } |
| |
| function createDocumentForTesting() { |
| var doc = document.implementation.createHTMLDocument(''); |
| populateTestContentToHostDocument(doc); |
| var shadowRoot = doc.documentElement.createShadowRoot(); |
| populateTestContentToShadowRoot(shadowRoot); |
| return doc; |
| } |
| |
| // Make sure the given HTMLCollection contains at least one elements and |
| // all elements have the class named "host". This function works well with |
| // HTMLCollection, HTMLAllCollection, and NodeList consisting of elements. |
| function assert_collection(collection) { |
| assert_true(collection.length > 0); |
| Array.prototype.forEach.call(collection, function (element) { |
| assert_equals(element.className, 'host'); |
| }); |
| } |
| |
| // ---------------------------------------------------------------------------- |
| // Tests for DOM tree accessors defined in HTML specification |
| |
| test(function () { |
| var doc = createDocumentForTesting(); |
| assert_equals(doc.head.className, 'host'); |
| assert_equals(doc.body.className, 'host'); |
| }, |
| '<head> and <body> in a shadow tree should not be accessible from ' + |
| 'owner document\'s "head" and "body" properties, respectively.' |
| ); |
| |
| test(function () { |
| var doc = document.implementation.createHTMLDocument(''); |
| populateTestContentToHostDocument(doc); |
| var shadowRoot = doc.documentElement.createShadowRoot(); |
| populateTestContentToShadowRoot(shadowRoot); |
| |
| // Replace the content of <title> to distinguish elements in a host |
| // document and a shadow tree. |
| doc.getElementsByTagName('title')[0].textContent = 'Title of host document'; |
| shadowRoot.getElementsByTagName('title')[0].textContent = |
| 'Title of shadow tree'; |
| |
| assert_equals(doc.title, 'Title of host document'); |
| }, |
| 'The content of title element in a shadow tree should not be accessible ' + |
| 'from owner document\'s "title" attribute.' |
| ); |
| |
| function testHTMLCollection(accessor) { |
| var doc = createDocumentForTesting(); |
| assert_collection(doc[accessor]); |
| } |
| |
| generate_tests( |
| testHTMLCollection, |
| ['images', 'embeds', 'plugins', 'links', 'forms', 'scripts'].map( |
| function (accessor) { |
| return [ |
| 'Elements in a shadow tree should not be accessible from ' + |
| 'owner document\'s "' + accessor + '" attribute.', |
| accessor |
| ]; |
| })); |
| |
| test(function () { |
| var doc = createDocumentForTesting(); |
| assert_collection(doc.getElementsByName('test-name')); |
| }, |
| 'Elements in a shadow tree should not be accessible from owner ' + |
| 'document\'s getElementsByName() method.' |
| ); |
| |
| // ---------------------------------------------------------------------------- |
| // Tests for obsolete accessors |
| |
| generate_tests( |
| testHTMLCollection, |
| ['anchors', 'applets', 'all'].map( |
| function (accessor) { |
| return [ |
| 'Elements in a shadow tree should not be accessible from ' + |
| 'owner document\'s "' + accessor + '" attribute.', |
| accessor |
| ]; |
| })); |
| |
| // ---------------------------------------------------------------------------- |
| // Tests for accessors defined in DOM specification |
| |
| test(function () { |
| var doc = createDocumentForTesting(); |
| assert_collection(doc.getElementsByTagName('p')); |
| }, |
| 'Elements in a shadow tree should not be accessible from owner ' + |
| 'document\'s getElementsByTagName() method.' |
| ); |
| |
| test(function () { |
| // Create a XML document. |
| var namespace = 'http://www.w3.org/1999/xhtml'; |
| var doc = document.implementation.createDocument(namespace, 'html'); |
| doc.documentElement.appendChild(doc.createElementNS(namespace, 'head')); |
| var body = doc.createElementNS(namespace, 'body'); |
| var pHost = doc.createElementNS(namespace, 'p'); |
| pHost.className = "host"; |
| body.appendChild(pHost); |
| doc.documentElement.appendChild(body); |
| |
| var shadowRoot = body.createShadowRoot(); |
| var pShadow = doc.createElementNS(namespace, 'p'); |
| pShadow.className = "shadow"; |
| shadowRoot.appendChild(pShadow); |
| |
| assert_collection(doc.getElementsByTagNameNS(namespace, 'p')); |
| }, |
| 'Elements in a shadow tree should not be accessible from owner ' + |
| 'document\'s getElementsByTagNameNS() method.' |
| ); |
| |
| test(function () { |
| var doc = document.implementation.createHTMLDocument(''); |
| populateTestContentToHostDocument(doc); |
| var shadowRoot = doc.documentElement.createShadowRoot(); |
| populateTestContentToShadowRoot(shadowRoot); |
| |
| shadowRoot.getElementsByTagName('p')[0].id = 'test-id'; |
| assert_equals(doc.getElementById('test-id'), null); |
| }, |
| 'Elements in a shadow tree should not be accessible from owner ' + |
| 'document\'s getElementById() method.' |
| ); |
| </script> |
| </body> |
| </html> |