Commit 149b3006 authored by dominicc@chromium.org's avatar dominicc@chromium.org

Make Custom Element registration context creation explicit.

This brings the implementation into line with the spec, which
specifies when a document *does* get a new registration context, or
shares an existing one, instead of applying a heuristic based on
document type. See
<http://w3c.github.io/webcomponents/spec/custom/#creating-and-passing-registries>

BUG=339431

Review URL: https://codereview.chromium.org/132203012

git-svn-id: svn://svn.chromium.org/blink/trunk@166359 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 929faa31
This is a testharness.js-based test.
PASS registration context should not be shared with an iframe's document
PASS registration context should not be shared with the template document
PASS registration context should not be created by DOMImplementation-created documents
Harness: the test ran to completion.
......@@ -148,4 +148,41 @@ withFrame(t.step_func(function (frame) {
})();
(function () {
var t = async_test('registration context should not be created by ' +
'DOMImplementation-created documents');
withFrame(t.step_func(function (frame) {
// Test transitively sloughing off a registration context through
// multiple createDocument/createHTMLDocument steps.
var documentA = frame.contentDocument;
// This document is not HTML, XHTML; it will not process custom elements.
var documentB = documentA.implementation.createDocument(null, '');
assert_throws(
'NOT_SUPPORTED_ERR',
function() { documentB.registerElement('x-a'); });
// This document will not process custom elements because there is
// nothing to inherit from B.
var documentC = documentB.implementation.createHTMLDocument();
assert_throws(
'NOT_SUPPORTED_ERR',
function() { documentC.registerElement('x-b'); });
// Nor this one.
var documentD = documentC.implementation.createDocument(
'http://www.w3.org/1999/xhtml', 'html');
assert_throws(
'NOT_SUPPORTED_ERR',
function() { documentD.registerElement('x-c'); });
frame.remove();
t.done();
}));
})();
</script>
This is a testharness.js-based test.
PASS registration context is shared with DOMImplementation-created documents
PASS registration context is shared with some DOMImplementation-created documents
PASS registration context is shared with imported documents
Harness: the test ran to completion.
......@@ -66,8 +66,8 @@ testRegisterInAInstantiateInB_shouldActivateDefinition = function () {
(function () {
var t = async_test('registration context is shared with DOMImplementation-' +
'created documents');
var t = async_test('registration context is shared with some ' +
'DOMImplementation-created documents');
withFrame(t.step_func(function (frame) {
var documentA = frame.contentDocument;
......@@ -89,25 +89,12 @@ withFrame(t.step_func(function (frame) {
}));
withFrame(t.step_func(function (frame) {
// Test transitively sharing a registration context through multiple
// createDocument/createHTMLDocument steps.
var documentA = frame.contentDocument;
// This document is not HTML, XHTML; it will not process custom elements.
var documentB = documentA.implementation.createDocument(null, '');
// This document *will* process custom elements, in a new context.
var documentC = documentB.implementation.createHTMLDocument();
var documentD = documentC.implementation.createDocument(
'http://www.w3.org/1999/xhtml', 'html');
var documentE = documentD.implementation.createDocument(
var documentB = documentA.implementation.createDocument(
'http://www.w3.org/1999/xhtml', 'html');
var documentC = documentB.implementation.createHTMLDocument();
var tester = new TestRegistrationContextSharing(
frame.contentWindow, documentC, documentE);
frame.contentWindow, documentA, documentC);
tester.testRegistrationContextIsShared();
frame.remove();
t.done();
......@@ -121,10 +108,8 @@ var t = async_test('registration context is shared with imported documents');
var link;
var documentA;
t.step(function () {
// FIXME: When inserting a <link> within a frame triggers an import,
// run this part of the test in isolation within a frame.
documentA = document;
withFrame(t.step_func(function (frame) {
documentA = frame.contentDocument;
link = documentA.createElement('link');
link.rel = 'import';
......@@ -138,7 +123,7 @@ t.step(function () {
});
documentA.head.appendChild(link);
});
}));
})();
......
<!DOCTYPE html>
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<script>
(function() {
var t = async_test('an XHR response document must not have a registry');
var req = new XMLHttpRequest();
req.onreadystatechange = t.step_func(function() {
if (req.readyState == 4 && req.status == 200) {
assert_throws(
'NOT_SUPPORTED_ERR',
function () { req.response.registerElement('x-a'); });
t.done();
}
});
req.open('GET', 'resources/blank.html', true);
req.responseType = 'document';
req.send();
})();
</script>
......@@ -5311,7 +5311,7 @@ Document& Document::ensureTemplateDocument()
return *const_cast<Document*>(document);
if (isHTMLDocument()) {
DocumentInit init = DocumentInit::fromContext(contextDocument(), blankURL());
DocumentInit init = DocumentInit::fromContext(contextDocument(), blankURL()).withNewRegistrationContext();
m_templateDocument = HTMLDocument::create(init);
} else {
m_templateDocument = Document::create(DocumentInit(blankURL()));
......
......@@ -68,6 +68,7 @@ DocumentInit::DocumentInit(const KURL& url, Frame* frame, WeakPtr<Document> cont
, m_owner(ownerDocument(frame))
, m_contextDocument(contextDocument)
, m_import(import)
, m_createNewRegistrationContext(false)
{
}
......@@ -79,6 +80,7 @@ DocumentInit::DocumentInit(const DocumentInit& other)
, m_contextDocument(other.m_contextDocument)
, m_import(other.m_import)
, m_registrationContext(other.m_registrationContext)
, m_createNewRegistrationContext(other.m_createNewRegistrationContext)
{
}
......@@ -125,11 +127,18 @@ KURL DocumentInit::parentBaseURL() const
DocumentInit& DocumentInit::withRegistrationContext(CustomElementRegistrationContext* registrationContext)
{
ASSERT(!m_registrationContext);
ASSERT(!m_createNewRegistrationContext && !m_registrationContext);
m_registrationContext = registrationContext;
return *this;
}
DocumentInit& DocumentInit::withNewRegistrationContext()
{
ASSERT(!m_createNewRegistrationContext && !m_registrationContext);
m_createNewRegistrationContext = true;
return *this;
}
PassRefPtr<CustomElementRegistrationContext> DocumentInit::registrationContext(Document* document) const
{
if (!RuntimeEnabledFeatures::customElementsEnabled() && !RuntimeEnabledFeatures::embedderCustomElementsEnabled())
......@@ -138,10 +147,10 @@ PassRefPtr<CustomElementRegistrationContext> DocumentInit::registrationContext(D
if (!document->isHTMLDocument() && !document->isXHTMLDocument())
return 0;
if (m_registrationContext)
return m_registrationContext.get();
if (m_createNewRegistrationContext)
return CustomElementRegistrationContext::create();
return CustomElementRegistrationContext::create();
return m_registrationContext.get();
}
WeakPtr<Document> DocumentInit::contextDocument() const
......
......@@ -66,7 +66,7 @@ public:
Settings* settings() const;
DocumentInit& withRegistrationContext(CustomElementRegistrationContext*);
DocumentInit& withNewRegistrationContext();
PassRefPtr<CustomElementRegistrationContext> registrationContext(Document*) const;
WeakPtr<Document> contextDocument() const;
......@@ -82,6 +82,7 @@ private:
WeakPtr<Document> m_contextDocument;
HTMLImport* m_import;
RefPtr<CustomElementRegistrationContext> m_registrationContext;
bool m_createNewRegistrationContext;
};
} // namespace WebCore
......
......@@ -796,6 +796,7 @@ PassRefPtr<DocumentWriter> DocumentLoader::createWriterFor(Frame* frame, const D
// Create a new document before clearing the frame, because it may need to
// inherit an aliased security context.
DocumentInit init(url, frame);
init.withNewRegistrationContext();
// In some rare cases, we'll re-used a DOMWindow for a new Document. For example,
// when a script calls window.open("..."), the browser gives JavaScript a window
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment