Commit d9561178 authored by morrita@chromium.org's avatar morrita@chromium.org

Let unresolved custom element go through CustomElementCallbackQueue.

As a preparation for crbug.com/313384, this change
introduces CustomElementResolutionInvocation that
is created per unresolved element and goes through
CECallbackQueue, then it does retry the resolution
attempt at its own invocation.

By going through the queue, we can guarantee
the tree order of unresolved element in CEUpdagradeCandidateMap
even with HTMLImports, which currently throw
unresolved elements into the candidate map in unpredictable way.

In coming changes, we'll fix the invocation order of
import-provided elements. This change will work with
those changes and will provide well defined order of
element upgrade.

BUG=313384
TEST=document-register-on-create-callback.html
R=dominicc,dglazkov,falken

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

git-svn-id: svn://svn.chromium.org/blink/trunk@164309 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 086ceb10
...@@ -3,5 +3,6 @@ This is a testharness.js-based test. ...@@ -3,5 +3,6 @@ This is a testharness.js-based test.
PASS transfer created callback PASS transfer created callback
PASS __proto__, :unresolved and created callback timing PASS __proto__, :unresolved and created callback timing
PASS other callbacks for a given element are queued during the created callback and dispatched when the created callback completes PASS other callbacks for a given element are queued during the created callback and dispatched when the created callback completes
PASS callback is called even if the element is moved to foreign document
Harness: the test ran to completion. Harness: the test ran to completion.
...@@ -111,5 +111,34 @@ withFrame(t.step_func(function(frame) { ...@@ -111,5 +111,34 @@ withFrame(t.step_func(function(frame) {
t.done(); t.done();
})); }));
})();
(function() {
t = async_test('callback is called even if the element is moved to foreign document');
var callbackInvoked = false;
withFrame(t.step_func(function(originalFrame) {
withFrame(function(destinationFrame) {
var protoA = Object.create(originalFrame.contentWindow.HTMLElement.prototype);
protoA.createdCallback = function() {
var toBeMoved = originalFrame.contentDocument.getElementById('toBeMoved');
destinationFrame.contentDocument.body.appendChild(toBeMoved);
};
var protoB = Object.create(originalFrame.contentWindow.HTMLElement.prototype);
protoB.createdCallback = function() {
callbackInvoked = true;
};
originalFrame.contentDocument.registerElement('x-a', {prototype: protoA});
originalFrame.contentDocument.registerElement('x-b', {prototype: protoB});
originalFrame.contentDocument.body.innerHTML = '<x-a></x-a><x-b id="toBeMoved"></x-b>';
assert_true(callbackInvoked);
t.done();
});
}));
})(); })();
</script> </script>
document.registerElement() in a createdCallback should upgrade elements that are in the same processing queue.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
PASS createdElements is ["elemA0", "elemB0"]
PASS createdElements is ["elemA0", "elemB0", "elemB1"]
PASS successfullyParsed is true
TEST COMPLETE
<!DOCTYPE html>
<script src="../../../resources/js-test.js"></script>
<script>
description('document.registerElement() in a createdCallback should upgrade elements that are in the same processing queue.');
var createdElements = [];
var protoA = Object.create(HTMLElement.prototype);
protoA.createdCallback = function () {
createdElements.push(this.id);
var protoB = Object.create(HTMLElement.prototype);
protoB.createdCallback = function () {
createdElements.push(this.id);
};
document.registerElement('x-b', {prototype: protoB});
shouldBe('createdElements', '["elemA0", "elemB0"]');
};
document.registerElement('x-a', {prototype: protoA});
</script>
<x-b id='elemB0'></x-b>
<x-a id='elemA0'></x-a>
<x-b id='elemB1'></x-b>
<script>
shouldBe('createdElements', '["elemA0", "elemB0", "elemB1"]');
</script>
...@@ -2038,10 +2038,13 @@ ...@@ -2038,10 +2038,13 @@
'dom/custom/CustomElementLifecycleCallbacks.h', 'dom/custom/CustomElementLifecycleCallbacks.h',
'dom/custom/CustomElementObserver.cpp', 'dom/custom/CustomElementObserver.cpp',
'dom/custom/CustomElementObserver.h', 'dom/custom/CustomElementObserver.h',
'dom/custom/CustomElementProcessingStep.h',
'dom/custom/CustomElementRegistrationContext.cpp', 'dom/custom/CustomElementRegistrationContext.cpp',
'dom/custom/CustomElementRegistrationContext.h', 'dom/custom/CustomElementRegistrationContext.h',
'dom/custom/CustomElementRegistry.cpp', 'dom/custom/CustomElementRegistry.cpp',
'dom/custom/CustomElementRegistry.h', 'dom/custom/CustomElementRegistry.h',
'dom/custom/CustomElementResolutionStep.cpp',
'dom/custom/CustomElementResolutionStep.h',
'dom/custom/CustomElementUpgradeCandidateMap.cpp', 'dom/custom/CustomElementUpgradeCandidateMap.cpp',
'dom/custom/CustomElementUpgradeCandidateMap.h', 'dom/custom/CustomElementUpgradeCandidateMap.h',
'dom/shadow/ComposedTreeWalker.cpp', 'dom/shadow/ComposedTreeWalker.cpp',
......
...@@ -101,7 +101,9 @@ void CustomElement::define(Element* element, PassRefPtr<CustomElementDefinition> ...@@ -101,7 +101,9 @@ void CustomElement::define(Element* element, PassRefPtr<CustomElementDefinition>
case Element::WaitingForUpgrade: case Element::WaitingForUpgrade:
definitions().add(element, definition); definitions().add(element, definition);
CustomElementCallbackScheduler::scheduleCreatedCallback(definition->callbacks(), element); if (element->inDocument() && element->document().domWindow())
CustomElementCallbackScheduler::scheduleAttachedCallback(definition->callbacks(), element);
definition->callbacks()->created(element);
break; break;
} }
} }
......
...@@ -36,25 +36,6 @@ ...@@ -36,25 +36,6 @@
namespace WebCore { namespace WebCore {
class CreatedInvocation : public CustomElementCallbackInvocation {
public:
CreatedInvocation(PassRefPtr<CustomElementLifecycleCallbacks> callbacks)
: CustomElementCallbackInvocation(callbacks)
{
}
private:
virtual void dispatch(Element*) OVERRIDE;
virtual bool isCreated() const OVERRIDE { return true; }
};
void CreatedInvocation::dispatch(Element* element)
{
if (element->inDocument() && element->document().domWindow())
CustomElementCallbackScheduler::scheduleAttachedCallback(callbacks(), element);
callbacks()->created(element);
}
class AttachedDetachedInvocation : public CustomElementCallbackInvocation { class AttachedDetachedInvocation : public CustomElementCallbackInvocation {
public: public:
AttachedDetachedInvocation(PassRefPtr<CustomElementLifecycleCallbacks>, CustomElementLifecycleCallbacks::CallbackType which); AttachedDetachedInvocation(PassRefPtr<CustomElementLifecycleCallbacks>, CustomElementLifecycleCallbacks::CallbackType which);
...@@ -114,13 +95,9 @@ void AttributeChangedInvocation::dispatch(Element* element) ...@@ -114,13 +95,9 @@ void AttributeChangedInvocation::dispatch(Element* element)
PassOwnPtr<CustomElementCallbackInvocation> CustomElementCallbackInvocation::createInvocation(PassRefPtr<CustomElementLifecycleCallbacks> callbacks, CustomElementLifecycleCallbacks::CallbackType which) PassOwnPtr<CustomElementCallbackInvocation> CustomElementCallbackInvocation::createInvocation(PassRefPtr<CustomElementLifecycleCallbacks> callbacks, CustomElementLifecycleCallbacks::CallbackType which)
{ {
switch (which) { switch (which) {
case CustomElementLifecycleCallbacks::Created:
return adoptPtr(new CreatedInvocation(callbacks));
case CustomElementLifecycleCallbacks::Attached: case CustomElementLifecycleCallbacks::Attached:
case CustomElementLifecycleCallbacks::Detached: case CustomElementLifecycleCallbacks::Detached:
return adoptPtr(new AttachedDetachedInvocation(callbacks, which)); return adoptPtr(new AttachedDetachedInvocation(callbacks, which));
default: default:
ASSERT_NOT_REACHED(); ASSERT_NOT_REACHED();
return PassOwnPtr<CustomElementCallbackInvocation>(); return PassOwnPtr<CustomElementCallbackInvocation>();
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#define CustomElementCallbackInvocation_h #define CustomElementCallbackInvocation_h
#include "core/dom/custom/CustomElementLifecycleCallbacks.h" #include "core/dom/custom/CustomElementLifecycleCallbacks.h"
#include "core/dom/custom/CustomElementProcessingStep.h"
#include "wtf/PassOwnPtr.h" #include "wtf/PassOwnPtr.h"
#include "wtf/PassRefPtr.h" #include "wtf/PassRefPtr.h"
#include "wtf/RefPtr.h" #include "wtf/RefPtr.h"
...@@ -39,18 +40,13 @@ ...@@ -39,18 +40,13 @@
namespace WebCore { namespace WebCore {
class Element; // FIXME: Rename to CustomElementCallbackStep
class CustomElementCallbackInvocation : public CustomElementProcessingStep {
class CustomElementCallbackInvocation {
WTF_MAKE_NONCOPYABLE(CustomElementCallbackInvocation); WTF_MAKE_NONCOPYABLE(CustomElementCallbackInvocation);
public: public:
static PassOwnPtr<CustomElementCallbackInvocation> createInvocation(PassRefPtr<CustomElementLifecycleCallbacks>, CustomElementLifecycleCallbacks::CallbackType); static PassOwnPtr<CustomElementCallbackInvocation> createInvocation(PassRefPtr<CustomElementLifecycleCallbacks>, CustomElementLifecycleCallbacks::CallbackType);
static PassOwnPtr<CustomElementCallbackInvocation> createAttributeChangedInvocation(PassRefPtr<CustomElementLifecycleCallbacks>, const AtomicString& name, const AtomicString& oldValue, const AtomicString& newValue); static PassOwnPtr<CustomElementCallbackInvocation> createAttributeChangedInvocation(PassRefPtr<CustomElementLifecycleCallbacks>, const AtomicString& name, const AtomicString& oldValue, const AtomicString& newValue);
virtual ~CustomElementCallbackInvocation() { }
virtual void dispatch(Element*) = 0;
virtual bool isCreated() const { return false; }
protected: protected:
CustomElementCallbackInvocation(PassRefPtr<CustomElementLifecycleCallbacks> callbacks) CustomElementCallbackInvocation(PassRefPtr<CustomElementLifecycleCallbacks> callbacks)
: m_callbacks(callbacks) : m_callbacks(callbacks)
......
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
#define CustomElementCallbackQueue_h #define CustomElementCallbackQueue_h
#include "core/dom/Element.h" #include "core/dom/Element.h"
#include "core/dom/custom/CustomElementCallbackInvocation.h" #include "core/dom/custom/CustomElementProcessingStep.h"
#include "wtf/PassOwnPtr.h" #include "wtf/PassOwnPtr.h"
#include "wtf/PassRefPtr.h" #include "wtf/PassRefPtr.h"
#include "wtf/RefPtr.h" #include "wtf/RefPtr.h"
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
namespace WebCore { namespace WebCore {
// FIXME: Should be renamed to CustomElementProcessingQueue
class CustomElementCallbackQueue { class CustomElementCallbackQueue {
WTF_MAKE_NONCOPYABLE(CustomElementCallbackQueue); WTF_MAKE_NONCOPYABLE(CustomElementCallbackQueue);
public: public:
...@@ -55,7 +56,7 @@ public: ...@@ -55,7 +56,7 @@ public:
m_owner = newOwner; m_owner = newOwner;
} }
void append(PassOwnPtr<CustomElementCallbackInvocation> invocation) { m_queue.append(invocation); } void append(PassOwnPtr<CustomElementProcessingStep> invocation) { m_queue.append(invocation); }
void processInElementQueue(ElementQueue); void processInElementQueue(ElementQueue);
bool inCreatedCallback() const { return m_inCreatedCallback; } bool inCreatedCallback() const { return m_inCreatedCallback; }
...@@ -63,7 +64,7 @@ private: ...@@ -63,7 +64,7 @@ private:
CustomElementCallbackQueue(PassRefPtr<Element>); CustomElementCallbackQueue(PassRefPtr<Element>);
RefPtr<Element> m_element; RefPtr<Element> m_element;
Vector<OwnPtr<CustomElementCallbackInvocation> > m_queue; Vector<OwnPtr<CustomElementProcessingStep> > m_queue;
ElementQueue m_owner; ElementQueue m_owner;
size_t m_index; size_t m_index;
bool m_inCreatedCallback; bool m_inCreatedCallback;
......
...@@ -33,7 +33,10 @@ ...@@ -33,7 +33,10 @@
#include "core/dom/Element.h" #include "core/dom/Element.h"
#include "core/dom/custom/CustomElementCallbackDispatcher.h" #include "core/dom/custom/CustomElementCallbackDispatcher.h"
#include "core/dom/custom/CustomElementCallbackInvocation.h"
#include "core/dom/custom/CustomElementLifecycleCallbacks.h" #include "core/dom/custom/CustomElementLifecycleCallbacks.h"
#include "core/dom/custom/CustomElementRegistrationContext.h"
#include "core/dom/custom/CustomElementResolutionStep.h"
namespace WebCore { namespace WebCore {
...@@ -46,15 +49,6 @@ void CustomElementCallbackScheduler::scheduleAttributeChangedCallback(PassRefPtr ...@@ -46,15 +49,6 @@ void CustomElementCallbackScheduler::scheduleAttributeChangedCallback(PassRefPtr
queue->append(CustomElementCallbackInvocation::createAttributeChangedInvocation(callbacks, name, oldValue, newValue)); queue->append(CustomElementCallbackInvocation::createAttributeChangedInvocation(callbacks, name, oldValue, newValue));
} }
void CustomElementCallbackScheduler::scheduleCreatedCallback(PassRefPtr<CustomElementLifecycleCallbacks> callbacks, PassRefPtr<Element> element)
{
if (!callbacks->hasCreatedCallback())
return;
CustomElementCallbackQueue* queue = instance().scheduleInCurrentElementQueue(element);
queue->append(CustomElementCallbackInvocation::createInvocation(callbacks, CustomElementLifecycleCallbacks::Created));
}
void CustomElementCallbackScheduler::scheduleAttachedCallback(PassRefPtr<CustomElementLifecycleCallbacks> callbacks, PassRefPtr<Element> element) void CustomElementCallbackScheduler::scheduleAttachedCallback(PassRefPtr<CustomElementLifecycleCallbacks> callbacks, PassRefPtr<Element> element)
{ {
if (!callbacks->hasAttachedCallback()) if (!callbacks->hasAttachedCallback())
...@@ -73,6 +67,13 @@ void CustomElementCallbackScheduler::scheduleDetachedCallback(PassRefPtr<CustomE ...@@ -73,6 +67,13 @@ void CustomElementCallbackScheduler::scheduleDetachedCallback(PassRefPtr<CustomE
queue->append(CustomElementCallbackInvocation::createInvocation(callbacks, CustomElementLifecycleCallbacks::Detached)); queue->append(CustomElementCallbackInvocation::createInvocation(callbacks, CustomElementLifecycleCallbacks::Detached));
} }
void CustomElementCallbackScheduler::scheduleResolutionStep(const CustomElementDescriptor& descriptor, PassRefPtr<Element> element)
{
RefPtr<CustomElementRegistrationContext> context = element->document().registrationContext();
CustomElementCallbackQueue* queue = instance().schedule(element);
queue->append(CustomElementResolutionStep::create(context.release(), descriptor));
}
CustomElementCallbackScheduler& CustomElementCallbackScheduler::instance() CustomElementCallbackScheduler& CustomElementCallbackScheduler::instance()
{ {
DEFINE_STATIC_LOCAL(CustomElementCallbackScheduler, instance, ()); DEFINE_STATIC_LOCAL(CustomElementCallbackScheduler, instance, ());
......
...@@ -39,15 +39,17 @@ ...@@ -39,15 +39,17 @@
namespace WebCore { namespace WebCore {
class CustomElementDescriptor;
class CustomElementLifecycleCallbacks; class CustomElementLifecycleCallbacks;
class CustomElementPendingImport;
class Element; class Element;
class CustomElementCallbackScheduler { class CustomElementCallbackScheduler {
public: public:
static void scheduleAttributeChangedCallback(PassRefPtr<CustomElementLifecycleCallbacks>, PassRefPtr<Element>, const AtomicString& name, const AtomicString& oldValue, const AtomicString& newValue); static void scheduleAttributeChangedCallback(PassRefPtr<CustomElementLifecycleCallbacks>, PassRefPtr<Element>, const AtomicString& name, const AtomicString& oldValue, const AtomicString& newValue);
static void scheduleCreatedCallback(PassRefPtr<CustomElementLifecycleCallbacks>, PassRefPtr<Element>);
static void scheduleAttachedCallback(PassRefPtr<CustomElementLifecycleCallbacks>, PassRefPtr<Element>); static void scheduleAttachedCallback(PassRefPtr<CustomElementLifecycleCallbacks>, PassRefPtr<Element>);
static void scheduleDetachedCallback(PassRefPtr<CustomElementLifecycleCallbacks>, PassRefPtr<Element>); static void scheduleDetachedCallback(PassRefPtr<CustomElementLifecycleCallbacks>, PassRefPtr<Element>);
static void scheduleResolutionStep(const CustomElementDescriptor&, PassRefPtr<Element>);
protected: protected:
friend class CustomElementCallbackDispatcher; friend class CustomElementCallbackDispatcher;
......
/*
* Copyright (C) 2013 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name of Google Inc. nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CustomElementProcessingStep_h
#define CustomElementProcessingStep_h
#include "wtf/Noncopyable.h"
namespace WebCore {
class Element;
class CustomElementProcessingStep {
WTF_MAKE_NONCOPYABLE(CustomElementProcessingStep);
public:
CustomElementProcessingStep() { }
virtual ~CustomElementProcessingStep() { }
virtual void dispatch(Element*) = 0;
// FIXME: Should be isUpgradeStep()
virtual bool isCreated() const { return false; }
};
}
#endif // CustomElementProcessingStep_h
...@@ -55,7 +55,7 @@ void CustomElementRegistrationContext::registerElement(Document* document, Custo ...@@ -55,7 +55,7 @@ void CustomElementRegistrationContext::registerElement(Document* document, Custo
// Upgrade elements that were waiting for this definition. // Upgrade elements that were waiting for this definition.
const CustomElementUpgradeCandidateMap::ElementSet& upgradeCandidates = m_candidates.takeUpgradeCandidatesFor(definition->descriptor()); const CustomElementUpgradeCandidateMap::ElementSet& upgradeCandidates = m_candidates.takeUpgradeCandidatesFor(definition->descriptor());
for (CustomElementUpgradeCandidateMap::ElementSet::const_iterator it = upgradeCandidates.begin(); it != upgradeCandidates.end(); ++it) for (CustomElementUpgradeCandidateMap::ElementSet::const_iterator it = upgradeCandidates.begin(); it != upgradeCandidates.end(); ++it)
didResolveElement(definition, *it); CustomElement::define(*it, definition);
} }
PassRefPtr<Element> CustomElementRegistrationContext::createCustomTagElement(Document& document, const QualifiedName& tagName) PassRefPtr<Element> CustomElementRegistrationContext::createCustomTagElement(Document& document, const QualifiedName& tagName)
...@@ -74,16 +74,16 @@ PassRefPtr<Element> CustomElementRegistrationContext::createCustomTagElement(Doc ...@@ -74,16 +74,16 @@ PassRefPtr<Element> CustomElementRegistrationContext::createCustomTagElement(Doc
} }
element->setCustomElementState(Element::WaitingForUpgrade); element->setCustomElementState(Element::WaitingForUpgrade);
resolve(element.get(), nullAtom); scheduleResolution(element.get(), nullAtom);
return element.release(); return element.release();
} }
void CustomElementRegistrationContext::didGiveTypeExtension(Element* element, const AtomicString& type) void CustomElementRegistrationContext::didGiveTypeExtension(Element* element, const AtomicString& type)
{ {
resolve(element, type); scheduleResolution(element, type);
} }
void CustomElementRegistrationContext::resolve(Element* element, const AtomicString& typeExtension) void CustomElementRegistrationContext::scheduleResolution(Element* element, const AtomicString& typeExtension)
{ {
// If an element has a custom tag name it takes precedence over // If an element has a custom tag name it takes precedence over
// the "is" attribute (if any). // the "is" attribute (if any).
...@@ -93,22 +93,19 @@ void CustomElementRegistrationContext::resolve(Element* element, const AtomicStr ...@@ -93,22 +93,19 @@ void CustomElementRegistrationContext::resolve(Element* element, const AtomicStr
ASSERT(!type.isNull()); ASSERT(!type.isNull());
CustomElementDescriptor descriptor(type, element->namespaceURI(), element->localName()); CustomElementDescriptor descriptor(type, element->namespaceURI(), element->localName());
CustomElementDefinition* definition = m_registry.find(descriptor); ASSERT(element->customElementState() == Element::WaitingForUpgrade);
if (definition) CustomElementCallbackScheduler::scheduleResolutionStep(descriptor, element);
didResolveElement(definition, element);
else
didCreateUnresolvedElement(descriptor, element);
}
void CustomElementRegistrationContext::didResolveElement(CustomElementDefinition* definition, Element* element)
{
CustomElement::define(element, definition);
} }
void CustomElementRegistrationContext::didCreateUnresolvedElement(const CustomElementDescriptor& descriptor, Element* element) void CustomElementRegistrationContext::resolve(Element* element, const CustomElementDescriptor& descriptor)
{ {
ASSERT(element->customElementState() == Element::WaitingForUpgrade); CustomElementDefinition* definition = m_registry.find(descriptor);
m_candidates.add(descriptor, element); if (definition) {
CustomElement::define(element, definition);
} else {
ASSERT(element->customElementState() == Element::WaitingForUpgrade);
m_candidates.add(descriptor, element);
}
} }
PassRefPtr<CustomElementRegistrationContext> CustomElementRegistrationContext::create() PassRefPtr<CustomElementRegistrationContext> CustomElementRegistrationContext::create()
......
...@@ -60,6 +60,8 @@ public: ...@@ -60,6 +60,8 @@ public:
static void setIsAttributeAndTypeExtension(Element*, const AtomicString& type); static void setIsAttributeAndTypeExtension(Element*, const AtomicString& type);
static void setTypeExtension(Element*, const AtomicString& type); static void setTypeExtension(Element*, const AtomicString& type);
void resolve(Element*, const CustomElementDescriptor&);
protected: protected:
CustomElementRegistrationContext() { } CustomElementRegistrationContext() { }
...@@ -67,9 +69,7 @@ protected: ...@@ -67,9 +69,7 @@ protected:
void didGiveTypeExtension(Element*, const AtomicString& type); void didGiveTypeExtension(Element*, const AtomicString& type);
private: private:
void resolve(Element*, const AtomicString& typeExtension); void scheduleResolution(Element*, const AtomicString& typeExtension);
void didResolveElement(CustomElementDefinition*, Element*);
void didCreateUnresolvedElement(const CustomElementDescriptor&, Element*);
CustomElementRegistry m_registry; CustomElementRegistry m_registry;
......
/*
* Copyright (C) 2013 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name of Google Inc. nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "core/dom/custom/CustomElementResolutionStep.h"
#include "core/dom/Element.h"
#include "core/dom/custom/CustomElementRegistrationContext.h"
namespace WebCore {
PassOwnPtr<CustomElementResolutionStep> CustomElementResolutionStep::create(PassRefPtr<CustomElementRegistrationContext> context, const CustomElementDescriptor& descriptor)
{
return adoptPtr(new CustomElementResolutionStep(context, descriptor));
}
CustomElementResolutionStep::CustomElementResolutionStep(PassRefPtr<CustomElementRegistrationContext> context, const CustomElementDescriptor& descriptor)
: m_context(context)
, m_descriptor(descriptor)
{
}
CustomElementResolutionStep::~CustomElementResolutionStep()
{
}
void CustomElementResolutionStep::dispatch(Element* element)
{
m_context->resolve(element, m_descriptor);
}
} // namespace WebCore
/*
* Copyright (C) 2013 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name of Google Inc. nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CustomElementResolutionStep_h
#define CustomElementResolutionStep_h
#include "core/dom/custom/CustomElementDescriptor.h"
#include "core/dom/custom/CustomElementProcessingStep.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/text/AtomicString.h"
namespace WebCore {
class CustomElementRegistrationContext;
class CustomElementResolutionStep : public CustomElementProcessingStep {
WTF_MAKE_NONCOPYABLE(CustomElementResolutionStep);
public:
static PassOwnPtr<CustomElementResolutionStep> create(PassRefPtr<CustomElementRegistrationContext>, const CustomElementDescriptor&);
virtual ~CustomElementResolutionStep();
protected:
CustomElementResolutionStep(PassRefPtr<CustomElementRegistrationContext>, const CustomElementDescriptor&);
virtual void dispatch(Element*) OVERRIDE;
virtual bool isCreated() const OVERRIDE { return true; }
private:
RefPtr<CustomElementRegistrationContext> m_context;
CustomElementDescriptor m_descriptor;
};
}
#endif // CustomElementResolutionStep_h
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