Diff
Modified: trunk/LayoutTests/ChangeLog (205084 => 205085)
--- trunk/LayoutTests/ChangeLog 2016-08-27 21:34:57 UTC (rev 205084)
+++ trunk/LayoutTests/ChangeLog 2016-08-27 22:13:44 UTC (rev 205085)
@@ -1,3 +1,17 @@
+2016-08-27 Ryosuke Niwa <[email protected]>
+
+ adoptcallback
+
+ Add adopted callback for custom elements
+ https://bugs.webkit.org/show_bug.cgi?id=161284
+
+ Reviewed by Antti Koivisto.
+
+ * fast/custom-elements/adopted-callback-expected.txt: Added.
+ * fast/custom-elements/adopted-callback.html: Added.
+ * fast/custom-elements/resources/document-types.js:
+ (const.DocumentTypes.create):
+
2016-08-27 Youenn Fablet <[email protected]>
html/dom/interfaces.html is flaky due to WebSocket test
Added: trunk/LayoutTests/fast/custom-elements/adopted-callback-expected.txt (0 => 205085)
--- trunk/LayoutTests/fast/custom-elements/adopted-callback-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/custom-elements/adopted-callback-expected.txt 2016-08-27 22:13:44 UTC (rev 205085)
@@ -0,0 +1,59 @@
+
+PASS Inserting a custom element into the owner document must not enqueue and invoke adoptedCallback
+PASS Inserting a custom element into a document of a template element must enqueue and invoke adoptedCallback
+PASS Moving a custom element from the owner document into a document of a template element must enqueue and invoke adoptedCallback
+PASS Inserting an ancestor of custom element into a document of a template element must enqueue and invoke adoptedCallback
+PASS Moving an ancestor of custom element from the owner document into a document of a template element must enqueue and invoke adoptedCallback
+PASS Inserting a custom element into a shadow tree in a document of a template element must enqueue and invoke adoptedCallback
+PASS Inserting the shadow host of a custom element into a document of a template element must enqueue and invoke adoptedCallback
+PASS Moving the shadow host of a custom element from the owner document into a document of a template element must enqueue and invoke adoptedCallback
+PASS Inserting a custom element into a detached shadow tree that belongs to a document of a template element must enqueue and invoke adoptedCallback
+PASS Inserting a custom element into a new document must enqueue and invoke adoptedCallback
+PASS Moving a custom element from the owner document into a new document must enqueue and invoke adoptedCallback
+PASS Inserting an ancestor of custom element into a new document must enqueue and invoke adoptedCallback
+PASS Moving an ancestor of custom element from the owner document into a new document must enqueue and invoke adoptedCallback
+PASS Inserting a custom element into a shadow tree in a new document must enqueue and invoke adoptedCallback
+PASS Inserting the shadow host of a custom element into a new document must enqueue and invoke adoptedCallback
+PASS Moving the shadow host of a custom element from the owner document into a new document must enqueue and invoke adoptedCallback
+PASS Inserting a custom element into a detached shadow tree that belongs to a new document must enqueue and invoke adoptedCallback
+PASS Inserting a custom element into a cloned document must enqueue and invoke adoptedCallback
+PASS Moving a custom element from the owner document into a cloned document must enqueue and invoke adoptedCallback
+PASS Inserting an ancestor of custom element into a cloned document must enqueue and invoke adoptedCallback
+PASS Moving an ancestor of custom element from the owner document into a cloned document must enqueue and invoke adoptedCallback
+PASS Inserting a custom element into a shadow tree in a cloned document must enqueue and invoke adoptedCallback
+PASS Inserting the shadow host of a custom element into a cloned document must enqueue and invoke adoptedCallback
+PASS Moving the shadow host of a custom element from the owner document into a cloned document must enqueue and invoke adoptedCallback
+PASS Inserting a custom element into a detached shadow tree that belongs to a cloned document must enqueue and invoke adoptedCallback
+PASS Inserting a custom element into a document created by createHTMLDocument must enqueue and invoke adoptedCallback
+PASS Moving a custom element from the owner document into a document created by createHTMLDocument must enqueue and invoke adoptedCallback
+PASS Inserting an ancestor of custom element into a document created by createHTMLDocument must enqueue and invoke adoptedCallback
+PASS Moving an ancestor of custom element from the owner document into a document created by createHTMLDocument must enqueue and invoke adoptedCallback
+PASS Inserting a custom element into a shadow tree in a document created by createHTMLDocument must enqueue and invoke adoptedCallback
+PASS Inserting the shadow host of a custom element into a document created by createHTMLDocument must enqueue and invoke adoptedCallback
+PASS Moving the shadow host of a custom element from the owner document into a document created by createHTMLDocument must enqueue and invoke adoptedCallback
+PASS Inserting a custom element into a detached shadow tree that belongs to a document created by createHTMLDocument must enqueue and invoke adoptedCallback
+PASS Inserting a custom element into a HTML document created by createDocument must enqueue and invoke adoptedCallback
+PASS Moving a custom element from the owner document into a HTML document created by createDocument must enqueue and invoke adoptedCallback
+PASS Inserting an ancestor of custom element into a HTML document created by createDocument must enqueue and invoke adoptedCallback
+PASS Moving an ancestor of custom element from the owner document into a HTML document created by createDocument must enqueue and invoke adoptedCallback
+PASS Inserting a custom element into a shadow tree in a HTML document created by createDocument must enqueue and invoke adoptedCallback
+PASS Inserting the shadow host of a custom element into a HTML document created by createDocument must enqueue and invoke adoptedCallback
+PASS Moving the shadow host of a custom element from the owner document into a HTML document created by createDocument must enqueue and invoke adoptedCallback
+PASS Inserting a custom element into a detached shadow tree that belongs to a HTML document created by createDocument must enqueue and invoke adoptedCallback
+PASS Inserting a custom element into a document in an iframe must enqueue and invoke adoptedCallback
+PASS Moving a custom element from the owner document into a document in an iframe must enqueue and invoke adoptedCallback
+PASS Inserting an ancestor of custom element into a document in an iframe must enqueue and invoke adoptedCallback
+PASS Moving an ancestor of custom element from the owner document into a document in an iframe must enqueue and invoke adoptedCallback
+PASS Inserting a custom element into a shadow tree in a document in an iframe must enqueue and invoke adoptedCallback
+PASS Inserting the shadow host of a custom element into a document in an iframe must enqueue and invoke adoptedCallback
+PASS Moving the shadow host of a custom element from the owner document into a document in an iframe must enqueue and invoke adoptedCallback
+PASS Inserting a custom element into a detached shadow tree that belongs to a document in an iframe must enqueue and invoke adoptedCallback
+PASS Inserting a custom element into a HTML document fetched by XHR must enqueue and invoke adoptedCallback
+PASS Moving a custom element from the owner document into a HTML document fetched by XHR must enqueue and invoke adoptedCallback
+PASS Inserting an ancestor of custom element into a HTML document fetched by XHR must enqueue and invoke adoptedCallback
+PASS Moving an ancestor of custom element from the owner document into a HTML document fetched by XHR must enqueue and invoke adoptedCallback
+PASS Inserting a custom element into a shadow tree in a HTML document fetched by XHR must enqueue and invoke adoptedCallback
+PASS Inserting the shadow host of a custom element into a HTML document fetched by XHR must enqueue and invoke adoptedCallback
+PASS Moving the shadow host of a custom element from the owner document into a HTML document fetched by XHR must enqueue and invoke adoptedCallback
+PASS Inserting a custom element into a detached shadow tree that belongs to a HTML document fetched by XHR must enqueue and invoke adoptedCallback
+
Added: trunk/LayoutTests/fast/custom-elements/adopted-callback.html (0 => 205085)
--- trunk/LayoutTests/fast/custom-elements/adopted-callback.html (rev 0)
+++ trunk/LayoutTests/fast/custom-elements/adopted-callback.html 2016-08-27 22:13:44 UTC (rev 205085)
@@ -0,0 +1,136 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>Custom Elements: adoptedCallback</title>
+<meta name="author" title="Ryosuke Niwa" href=""
+<meta name="assert" content="adoptedCallback must be enqueued whenever custom element is adopted into a new document">
+<link rel="help" href=""
+<script src=""
+<script src=""
+<script src=""
+<link rel='stylesheet' href=''>
+</head>
+<body>
+<div id="log"></div>
+<script>
+
+var calls = [];
+class MyCustomElement extends HTMLElement {
+ connectedCallback() { calls.push('connected'); }
+ adoptedCallback(oldDocument, newDocument) { calls.push('adopted'); calls.push(oldDocument); calls.push(newDocument); }
+ disconnectedCallback() { calls.push('disconnected'); }
+}
+customElements.define('my-custom-element', MyCustomElement);
+
+test(function () {
+ var instance = document.createElement('my-custom-element');
+ calls = [];
+ document.body.appendChild(instance);
+ assert_array_equals(calls, ['connected']);
+}, 'Inserting a custom element into the owner document must not enqueue and invoke adoptedCallback');
+
+DocumentTypes.forEach(function (entry) {
+ if (entry.isOwner)
+ return;
+
+ var documentName = entry.name;
+ var getDocument = entry.create;
+
+ promise_test(function () {
+ return getDocument().then(function (doc) {
+ var instance = document.createElement('my-custom-element');
+ calls = [];
+ doc.documentElement.appendChild(instance);
+ assert_array_equals(calls, ['adopted', document, doc, 'connected']);
+ });
+ }, 'Inserting a custom element into a ' + documentName + ' must enqueue and invoke adoptedCallback');
+
+ promise_test(function () {
+ return getDocument().then(function (doc) {
+ var instance = document.createElement('my-custom-element');
+ document.body.appendChild(instance);
+ calls = [];
+ doc.documentElement.appendChild(instance);
+ assert_array_equals(calls, ['disconnected', 'adopted', document, doc, 'connected']);
+ });
+ }, 'Moving a custom element from the owner document into a ' + documentName + ' must enqueue and invoke adoptedCallback');
+
+ promise_test(function () {
+ return getDocument().then(function (doc) {
+ var instance = document.createElement('my-custom-element');
+ var parent = document.createElement('div');
+ parent.appendChild(instance);
+ calls = [];
+ doc.documentElement.appendChild(parent);
+ assert_array_equals(calls, ['adopted', document, doc, 'connected']);
+ });
+ }, 'Inserting an ancestor of custom element into a ' + documentName + ' must enqueue and invoke adoptedCallback');
+
+ promise_test(function () {
+ return getDocument().then(function (doc) {
+ var instance = document.createElement('my-custom-element');
+ var parent = document.createElement('div');
+ parent.appendChild(instance);
+ document.body.appendChild(parent);
+ calls = [];
+ doc.documentElement.appendChild(parent);
+ assert_array_equals(calls, ['disconnected', 'adopted', document, doc, 'connected']);
+ });
+ }, 'Moving an ancestor of custom element from the owner document into a ' + documentName + ' must enqueue and invoke adoptedCallback');
+
+ promise_test(function () {
+ return getDocument().then(function (doc) {
+ var instance = document.createElement('my-custom-element');
+ var host = doc.createElementNS('http://www.w3.org/1999/xhtml', 'div');
+ var shadowRoot = host.attachShadow({mode: 'closed'});
+ doc.documentElement.appendChild(host);
+
+ calls = [];
+ shadowRoot.appendChild(instance);
+ assert_array_equals(calls, ['adopted', document, doc, 'connected']);
+ });
+ }, 'Inserting a custom element into a shadow tree in a ' + documentName + ' must enqueue and invoke adoptedCallback');
+
+ promise_test(function () {
+ return getDocument().then(function (doc) {
+ var instance = document.createElement('my-custom-element');
+ var host = document.createElement('div');
+ var shadowRoot = host.attachShadow({mode: 'closed'});
+ shadowRoot.appendChild(instance);
+
+ calls = [];
+ doc.documentElement.appendChild(host);
+ assert_array_equals(calls, ['adopted', document, doc, 'connected']);
+ });
+ }, 'Inserting the shadow host of a custom element into a ' + documentName + ' must enqueue and invoke adoptedCallback');
+
+ promise_test(function () {
+ return getDocument().then(function (doc) {
+ var instance = document.createElement('my-custom-element');
+ var host = document.createElement('div');
+ var shadowRoot = host.attachShadow({mode: 'closed'});
+ shadowRoot.appendChild(instance);
+ document.body.appendChild(host);
+
+ calls = [];
+ doc.documentElement.appendChild(host);
+ assert_array_equals(calls, ['disconnected', 'adopted', document, doc, 'connected']);
+ });
+ }, 'Moving the shadow host of a custom element from the owner document into a ' + documentName + ' must enqueue and invoke adoptedCallback');
+
+ promise_test(function () {
+ return getDocument().then(function (doc) {
+ var instance = document.createElement('my-custom-element');
+ var host = doc.createElementNS('http://www.w3.org/1999/xhtml', 'div');
+ var shadowRoot = host.attachShadow({mode: 'closed'});
+
+ calls = [];
+ shadowRoot.appendChild(instance);
+ assert_array_equals(calls, ['adopted', document, doc]);
+ });
+ }, 'Inserting a custom element into a detached shadow tree that belongs to a ' + documentName + ' must enqueue and invoke adoptedCallback');
+});
+
+</script>
+</body>
+</html>
Modified: trunk/LayoutTests/fast/custom-elements/resources/document-types.js (205084 => 205085)
--- trunk/LayoutTests/fast/custom-elements/resources/document-types.js 2016-08-27 21:34:57 UTC (rev 205084)
+++ trunk/LayoutTests/fast/custom-elements/resources/document-types.js 2016-08-27 22:13:44 UTC (rev 205085)
@@ -1,7 +1,8 @@
const DocumentTypes = [
{
name: 'document',
- create: function () { return Promise.resolve(document); }
+ create: function () { return Promise.resolve(document); },
+ isOwner: true,
},
{
name: 'document of a template element',
Modified: trunk/Source/WebCore/ChangeLog (205084 => 205085)
--- trunk/Source/WebCore/ChangeLog 2016-08-27 21:34:57 UTC (rev 205084)
+++ trunk/Source/WebCore/ChangeLog 2016-08-27 22:13:44 UTC (rev 205085)
@@ -1,3 +1,41 @@
+2016-08-27 Ryosuke Niwa <[email protected]>
+
+ Add adopted callback for custom elements
+ https://bugs.webkit.org/show_bug.cgi?id=161284
+
+ Reviewed by Antti Koivisto.
+
+ Added the support for adoptedCallback: https://dom.spec.whatwg.org/#concept-node-adopt
+ For now, we only support this callback on appendChild.
+
+ Test: fast/custom-elements/adopted-callback.html
+
+ * bindings/js/JSCustomElementInterface.cpp:
+ (WebCore::JSCustomElementInterface::invokeCallback): Added JSDOMGlobalObject* as an argument to the callback so that
+ we can invoke toJS on Document in invokeAdoptedCallback.
+ (WebCore::JSCustomElementInterface::setAdoptedCallback): Added.
+ (WebCore::JSCustomElementInterface::invokeAdoptedCallback): Added.
+ (WebCore::JSCustomElementInterface::setAttributeChangedCallback):
+ * bindings/js/JSCustomElementInterface.h:
+ (WebCore::JSCustomElementInterface::hasConnectedCallback): Added.
+ (WebCore::JSCustomElementInterface::hasDisconnectedCallback): Added.
+ (WebCore::JSCustomElementInterface::hasAdoptedCallback): Added.
+ * bindings/js/JSCustomElementRegistryCustom.cpp:
+ (WebCore::JSCustomElementRegistry::define):
+ * dom/CustomElementReactionQueue.cpp:
+ (WebCore::CustomElementReactionQueueItem::CustomElementReactionQueueItem): Added a variant that takes two documents.
+ (WebCore::CustomElementReactionQueueItem::invoke):
+ (WebCore::CustomElementReactionQueue::enqueueConnectedCallbackIfNeeded): Fixed a bug that this function was always
+ enqueuing a callback even when the interface didn't have connectedCallback. Also, there is no need to check
+ the nullity of the interface since it should never be null.
+ (WebCore::CustomElementReactionQueue::enqueueDisconnectedCallbackIfNeeded): Ditto.
+ (WebCore::CustomElementReactionQueue::enqueueAdoptedCallbackIfNeeded): Added.
+ (WebCore::CustomElementReactionQueue::enqueueAttributeChangedCallbackIfNeeded): Assert that the interface is never
+ null instead of exiting early.
+ * dom/CustomElementReactionQueue.h:
+ * dom/Element.cpp:
+ (WebCore::Element::didMoveToNewDocument): Added a call to enqueueAdoptedCallbackIfNeeded.
+
2016-08-27 Yoshiaki Jitsukawa <[email protected]>
Fix the !PLATFORM(WIN) && USE(CURL) build.
Modified: trunk/Source/WebCore/bindings/js/JSCustomElementInterface.cpp (205084 => 205085)
--- trunk/Source/WebCore/bindings/js/JSCustomElementInterface.cpp 2016-08-27 21:34:57 UTC (rev 205084)
+++ trunk/Source/WebCore/bindings/js/JSCustomElementInterface.cpp 2016-08-27 22:13:44 UTC (rev 205085)
@@ -150,7 +150,7 @@
wrappedElement->setCustomElementIsResolved(*this);
}
-void JSCustomElementInterface::invokeCallback(Element& element, JSObject* callback, const WTF::Function<void(ExecState*, MarkedArgumentBuffer&)>& addArguments)
+void JSCustomElementInterface::invokeCallback(Element& element, JSObject* callback, const WTF::Function<void(ExecState*, JSDOMGlobalObject*, MarkedArgumentBuffer&)>& addArguments)
{
if (!canInvokeCallback())
return;
@@ -174,7 +174,7 @@
ASSERT(callType != CallType::None);
MarkedArgumentBuffer args;
- addArguments(state, args);
+ addArguments(state, globalObject, args);
InspectorInstrumentationCookie cookie = JSMainThreadExecState::instrumentFunctionCall(context, callType, callData);
@@ -207,6 +207,19 @@
invokeCallback(element, m_disconnectedCallback.get());
}
+void JSCustomElementInterface::setAdoptedCallback(JSC::JSObject* callback)
+{
+ m_adoptedCallback = callback;
+}
+
+void JSCustomElementInterface::invokeAdoptedCallback(Element& element, Document& oldDocument, Document& newDocument)
+{
+ invokeCallback(element, m_adoptedCallback.get(), [&](ExecState* state, JSDOMGlobalObject* globalObject, MarkedArgumentBuffer& args) {
+ args.append(toJS(state, globalObject, oldDocument));
+ args.append(toJS(state, globalObject, newDocument));
+ });
+}
+
void JSCustomElementInterface::setAttributeChangedCallback(JSC::JSObject* callback, const Vector<String>& observedAttributes)
{
m_attributeChangedCallback = callback;
@@ -217,7 +230,7 @@
void JSCustomElementInterface::invokeAttributeChangedCallback(Element& element, const QualifiedName& attributeName, const AtomicString& oldValue, const AtomicString& newValue)
{
- invokeCallback(element, m_attributeChangedCallback.get(), [&](ExecState* state, MarkedArgumentBuffer& args) {
+ invokeCallback(element, m_attributeChangedCallback.get(), [&](ExecState* state, JSDOMGlobalObject*, MarkedArgumentBuffer& args) {
args.append(jsStringWithCache(state, attributeName.localName()));
args.append(jsStringOrNull(state, oldValue));
args.append(jsStringOrNull(state, newValue));
Modified: trunk/Source/WebCore/bindings/js/JSCustomElementInterface.h (205084 => 205085)
--- trunk/Source/WebCore/bindings/js/JSCustomElementInterface.h 2016-08-27 21:34:57 UTC (rev 205084)
+++ trunk/Source/WebCore/bindings/js/JSCustomElementInterface.h 2016-08-27 22:13:44 UTC (rev 205085)
@@ -50,6 +50,7 @@
namespace WebCore {
class DOMWrapperWorld;
+class Document;
class Element;
class JSDOMGlobalObject;
class MathMLElement;
@@ -68,11 +69,17 @@
void upgradeElement(Element&);
void setConnectedCallback(JSC::JSObject*);
+ bool hasConnectedCallback() const { return !!m_connectedCallback; }
void invokeConnectedCallback(Element&);
void setDisconnectedCallback(JSC::JSObject*);
+ bool hasDisconnectedCallback() const { return !!m_disconnectedCallback; }
void invokeDisconnectedCallback(Element&);
+ void setAdoptedCallback(JSC::JSObject*);
+ bool hasAdoptedCallback() const { return !!m_adoptedCallback; }
+ void invokeAdoptedCallback(Element&, Document& oldDocument, Document& newDocument);
+
void setAttributeChangedCallback(JSC::JSObject* callback, const Vector<String>& observedAttributes);
bool observesAttribute(const AtomicString& name) const { return m_observedAttributes.contains(name); }
void invokeAttributeChangedCallback(Element&, const QualifiedName&, const AtomicString& oldValue, const AtomicString& newValue);
@@ -91,12 +98,13 @@
private:
JSCustomElementInterface(const QualifiedName&, JSC::JSObject* callback, JSDOMGlobalObject*);
- void invokeCallback(Element&, JSC::JSObject* callback, const WTF::Function<void(JSC::ExecState*, JSC::MarkedArgumentBuffer&)>& addArguments = {});
+ void invokeCallback(Element&, JSC::JSObject* callback, const WTF::Function<void(JSC::ExecState*, JSDOMGlobalObject*, JSC::MarkedArgumentBuffer&)>& addArguments = { });
QualifiedName m_name;
JSC::Weak<JSC::JSObject> m_constructor;
JSC::Weak<JSC::JSObject> m_connectedCallback;
JSC::Weak<JSC::JSObject> m_disconnectedCallback;
+ JSC::Weak<JSC::JSObject> m_adoptedCallback;
JSC::Weak<JSC::JSObject> m_attributeChangedCallback;
RefPtr<DOMWrapperWorld> m_isolatedWorld;
Vector<RefPtr<Element>, 1> m_constructionStack;
Modified: trunk/Source/WebCore/bindings/js/JSCustomElementRegistryCustom.cpp (205084 => 205085)
--- trunk/Source/WebCore/bindings/js/JSCustomElementRegistryCustom.cpp 2016-08-27 21:34:57 UTC (rev 205084)
+++ trunk/Source/WebCore/bindings/js/JSCustomElementRegistryCustom.cpp 2016-08-27 22:13:44 UTC (rev 205085)
@@ -119,10 +119,11 @@
if (disconnectedCallback)
elementInterface->setDisconnectedCallback(disconnectedCallback);
- // FIXME: Add the support for adoptedCallback.
- getCustomElementCallback(state, prototypeObject, Identifier::fromString(&vm, "adoptedCallback"));
+ auto* adoptedCallback = getCustomElementCallback(state, prototypeObject, Identifier::fromString(&vm, "adoptedCallback"));
if (state.hadException())
return jsUndefined();
+ if (adoptedCallback)
+ elementInterface->setAdoptedCallback(adoptedCallback);
auto* attributeChangedCallback = getCustomElementCallback(state, prototypeObject, Identifier::fromString(&vm, "attributeChangedCallback"));
if (state.hadException())
Modified: trunk/Source/WebCore/dom/CustomElementReactionQueue.cpp (205084 => 205085)
--- trunk/Source/WebCore/dom/CustomElementReactionQueue.cpp 2016-08-27 21:34:57 UTC (rev 205084)
+++ trunk/Source/WebCore/dom/CustomElementReactionQueue.cpp 2016-08-27 22:13:44 UTC (rev 205085)
@@ -46,6 +46,7 @@
ElementUpgrade,
Connected,
Disconnected,
+ Adopted,
AttributeChanged,
};
@@ -55,6 +56,14 @@
, m_interface(elementInterface)
{ }
+ CustomElementReactionQueueItem(Element& element, JSCustomElementInterface& elementInterface, Document& oldDocument, Document& newDocument)
+ : m_type(Type::Adopted)
+ , m_element(element)
+ , m_interface(elementInterface)
+ , m_oldDocument(&oldDocument)
+ , m_newDocument(&newDocument)
+ { }
+
CustomElementReactionQueueItem(Element& element, JSCustomElementInterface& elementInterface, const QualifiedName& attributeName, const AtomicString& oldValue, const AtomicString& newValue)
: m_type(Type::AttributeChanged)
, m_element(element)
@@ -76,6 +85,9 @@
case Type::Disconnected:
m_interface->invokeDisconnectedCallback(m_element.get());
break;
+ case Type::Adopted:
+ m_interface->invokeAdoptedCallback(m_element.get(), *m_oldDocument, *m_newDocument);
+ break;
case Type::AttributeChanged:
ASSERT(m_attributeName);
m_interface->invokeAttributeChangedCallback(m_element.get(), m_attributeName.value(), m_oldValue, m_newValue);
@@ -87,6 +99,8 @@
Type m_type;
Ref<Element> m_element;
Ref<JSCustomElementInterface> m_interface;
+ RefPtr<Document> m_oldDocument;
+ RefPtr<Document> m_newDocument;
Optional<QualifiedName> m_attributeName;
AtomicString m_oldValue;
AtomicString m_newValue;
@@ -108,8 +122,10 @@
void CustomElementReactionQueue::enqueueConnectedCallbackIfNeeded(Element& element)
{
+ ASSERT(element.isCustomElement());
auto* elementInterface = element.customElementInterface();
- if (!elementInterface)
+ ASSERT(elementInterface);
+ if (!elementInterface->hasConnectedCallback())
return;
if (auto* queue = CustomElementReactionStack::ensureCurrentQueue())
@@ -118,8 +134,10 @@
void CustomElementReactionQueue::enqueueDisconnectedCallbackIfNeeded(Element& element)
{
+ ASSERT(element.isCustomElement());
auto* elementInterface = element.customElementInterface();
- if (!elementInterface)
+ ASSERT(elementInterface);
+ if (!elementInterface->hasDisconnectedCallback())
return;
if (auto* queue = CustomElementReactionStack::ensureCurrentQueue())
@@ -126,10 +144,24 @@
queue->m_items.append({CustomElementReactionQueueItem::Type::Disconnected, element, *elementInterface});
}
+void CustomElementReactionQueue::enqueueAdoptedCallbackIfNeeded(Element& element, Document& oldDocument, Document& newDocument)
+{
+ ASSERT(element.isCustomElement());
+ auto* elementInterface = element.customElementInterface();
+ ASSERT(elementInterface);
+ if (!elementInterface->hasAdoptedCallback())
+ return;
+
+ if (auto* queue = CustomElementReactionStack::ensureCurrentQueue())
+ queue->m_items.append({element, *elementInterface, oldDocument, newDocument});
+}
+
void CustomElementReactionQueue::enqueueAttributeChangedCallbackIfNeeded(Element& element, const QualifiedName& attributeName, const AtomicString& oldValue, const AtomicString& newValue)
{
+ ASSERT(element.isCustomElement());
auto* elementInterface = element.customElementInterface();
- if (!elementInterface || !elementInterface->observesAttribute(attributeName.localName()))
+ ASSERT(elementInterface);
+ if (!elementInterface->observesAttribute(attributeName.localName()))
return;
if (auto* queue = CustomElementReactionStack::ensureCurrentQueue())
Modified: trunk/Source/WebCore/dom/CustomElementReactionQueue.h (205084 => 205085)
--- trunk/Source/WebCore/dom/CustomElementReactionQueue.h 2016-08-27 21:34:57 UTC (rev 205084)
+++ trunk/Source/WebCore/dom/CustomElementReactionQueue.h 2016-08-27 22:13:44 UTC (rev 205085)
@@ -34,6 +34,7 @@
namespace WebCore {
class CustomElementReactionQueueItem;
+class Document;
class Element;
class JSCustomElementInterface;
class QualifiedName;
@@ -47,6 +48,7 @@
static void enqueueElementUpgrade(Element&, JSCustomElementInterface&);
static void enqueueConnectedCallbackIfNeeded(Element&);
static void enqueueDisconnectedCallbackIfNeeded(Element&);
+ static void enqueueAdoptedCallbackIfNeeded(Element&, Document& oldDocument, Document& newDocument);
static void enqueueAttributeChangedCallbackIfNeeded(Element&, const QualifiedName&, const AtomicString& oldValue, const AtomicString& newValue);
void invokeAll();
Modified: trunk/Source/WebCore/dom/Element.cpp (205084 => 205085)
--- trunk/Source/WebCore/dom/Element.cpp 2016-08-27 21:34:57 UTC (rev 205084)
+++ trunk/Source/WebCore/dom/Element.cpp 2016-08-27 22:13:44 UTC (rev 205085)
@@ -1493,6 +1493,11 @@
if (hasClass())
attributeChanged(classAttr, nullAtom, getAttribute(classAttr));
}
+
+#if ENABLE(CUSTOM_ELEMENTS)
+ if (UNLIKELY(isCustomElement()))
+ CustomElementReactionQueue::enqueueAdoptedCallbackIfNeeded(*this, *oldDocument, document());
+#endif
}
bool Element::hasAttributes() const