aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/script/dom/attr.rs15
-rw-r--r--components/script/dom/create.rs5
-rw-r--r--components/script/dom/customelementregistry.rs350
-rw-r--r--components/script/dom/element.rs58
-rw-r--r--components/script/dom/node.rs29
-rw-r--r--components/script/microtask.rs5
-rw-r--r--components/script/script_thread.rs24
-rw-r--r--tests/unit/script/size_of.rs8
-rw-r--r--tests/wpt/metadata/custom-elements/CustomElementRegistry.html.ini24
-rw-r--r--tests/wpt/metadata/custom-elements/adopted-callback.html.ini90
-rw-r--r--tests/wpt/metadata/custom-elements/connected-callbacks.html.ini48
-rw-r--r--tests/wpt/metadata/custom-elements/custom-element-registry/define.html.ini48
-rw-r--r--tests/wpt/metadata/custom-elements/disconnected-callbacks.html.ini82
-rw-r--r--tests/wpt/metadata/custom-elements/reactions/Document.html.ini20
-rw-r--r--tests/wpt/metadata/custom-elements/reactions/Element.html.ini20
-rw-r--r--tests/wpt/metadata/custom-elements/reactions/HTMLOptionsCollection.html.ini8
-rw-r--r--tests/wpt/metadata/custom-elements/reactions/HTMLSelectElement.html.ini6
-rw-r--r--tests/wpt/metadata/custom-elements/reactions/Range.html.ini12
18 files changed, 603 insertions, 249 deletions
diff --git a/components/script/dom/attr.rs b/components/script/dom/attr.rs
index af5f0107ae4..bf2ecd6e910 100644
--- a/components/script/dom/attr.rs
+++ b/components/script/dom/attr.rs
@@ -9,6 +9,7 @@ use dom::bindings::inheritance::Castable;
use dom::bindings::js::{LayoutJS, MutNullableJS, Root, RootedReference};
use dom::bindings::reflector::{Reflector, reflect_dom_object};
use dom::bindings::str::DOMString;
+use dom::customelementregistry::CallbackReaction;
use dom::element::{AttributeMutation, Element};
use dom::mutationobserver::{Mutation, MutationObserver};
use dom::node::Node;
@@ -16,6 +17,7 @@ use dom::virtualmethods::vtable_for;
use dom::window::Window;
use dom_struct::dom_struct;
use html5ever::{Prefix, LocalName, Namespace};
+use script_thread::ScriptThread;
use servo_atoms::Atom;
use std::borrow::ToOwned;
use std::cell::Ref;
@@ -175,9 +177,20 @@ impl Attr {
let name = self.local_name().clone();
let namespace = self.namespace().clone();
let old_value = DOMString::from(&**self.value());
- let mutation = Mutation::Attribute { name, namespace, old_value };
+ let new_value = DOMString::from(&*value);
+ let mutation = Mutation::Attribute {
+ name: name.clone(),
+ namespace: namespace.clone(),
+ old_value: old_value.clone(),
+ };
+
MutationObserver::queue_a_mutation_record(owner.upcast::<Node>(), mutation);
+ if owner.get_custom_element_definition().is_some() {
+ let reaction = CallbackReaction::AttributeChanged(name, Some(old_value), Some(new_value), namespace);
+ ScriptThread::enqueue_callback_reaction(owner, reaction);
+ }
+
assert!(Some(owner) == self.owner().r());
owner.will_mutate_attr(self);
self.swap_value(&mut value);
diff --git a/components/script/dom/create.rs b/components/script/dom/create.rs
index e22e28a886e..5f03a3adb98 100644
--- a/components/script/dom/create.rs
+++ b/components/script/dom/create.rs
@@ -131,7 +131,10 @@ fn create_html_element(name: QualName,
CustomElementCreationMode::Synchronous => {
let local_name = name.local.clone();
return match definition.create_element(document, prefix.clone()) {
- Ok(element) => element,
+ Ok(element) => {
+ element.set_custom_element_definition(definition.clone());
+ element
+ },
Err(error) => {
// Step 6. Recovering from exception.
let global = GlobalScope::current().unwrap_or_else(|| document.global());
diff --git a/components/script/dom/customelementregistry.rs b/components/script/dom/customelementregistry.rs
index 94f580f7be9..0d151abb127 100644
--- a/components/script/dom/customelementregistry.rs
+++ b/components/script/dom/customelementregistry.rs
@@ -2,14 +2,14 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-use dom::bindings::callback::CallbackContainer;
+use dom::bindings::callback::{CallbackContainer, ExceptionHandling};
use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::CustomElementRegistryBinding;
use dom::bindings::codegen::Bindings::CustomElementRegistryBinding::CustomElementRegistryMethods;
use dom::bindings::codegen::Bindings::CustomElementRegistryBinding::ElementDefinitionOptions;
use dom::bindings::codegen::Bindings::ElementBinding::ElementMethods;
use dom::bindings::codegen::Bindings::FunctionBinding::Function;
-use dom::bindings::conversions::{ConversionResult, FromJSValConvertible};
+use dom::bindings::conversions::{ConversionResult, FromJSValConvertible, StringificationBehavior};
use dom::bindings::error::{Error, ErrorResult, Fallible};
use dom::bindings::inheritance::Castable;
use dom::bindings::js::{JS, Root};
@@ -24,13 +24,16 @@ use dom::node::Node;
use dom::promise::Promise;
use dom::window::Window;
use dom_struct::dom_struct;
-use html5ever::{LocalName, Prefix};
+use html5ever::{LocalName, Namespace, Prefix};
use js::conversions::ToJSValConvertible;
-use js::jsapi::{Construct1, IsConstructor, HandleValueArray, HandleObject};
-use js::jsapi::{JS_GetProperty, JSAutoCompartment, JSContext};
-use js::jsval::{JSVal, ObjectValue, UndefinedValue};
+use js::jsapi::{Construct1, IsCallable, IsConstructor, HandleValueArray, HandleObject, MutableHandleValue};
+use js::jsapi::{Heap, JS_GetProperty, JSAutoCompartment, JSContext};
+use js::jsval::{JSVal, NullValue, ObjectValue, UndefinedValue};
+use microtask::Microtask;
+use script_thread::ScriptThread;
use std::cell::Cell;
-use std::collections::HashMap;
+use std::collections::{HashMap, VecDeque};
+use std::ops::Deref;
use std::ptr;
use std::rc::Rc;
@@ -94,15 +97,14 @@ impl CustomElementRegistry {
/// https://html.spec.whatwg.org/multipage/#dom-customelementregistry-define
/// Steps 10.1, 10.2
#[allow(unsafe_code)]
- fn check_prototype(&self, constructor: HandleObject) -> ErrorResult {
+ fn check_prototype(&self, constructor: HandleObject, prototype: MutableHandleValue) -> ErrorResult {
let global_scope = self.window.upcast::<GlobalScope>();
- rooted!(in(global_scope.get_cx()) let mut prototype = UndefinedValue());
unsafe {
// Step 10.1
if !JS_GetProperty(global_scope.get_cx(),
constructor,
b"prototype\0".as_ptr() as *const _,
- prototype.handle_mut()) {
+ prototype) {
return Err(Error::JSFailed);
}
@@ -113,14 +115,80 @@ impl CustomElementRegistry {
}
Ok(())
}
+
+ /// https://html.spec.whatwg.org/multipage/#dom-customelementregistry-define
+ /// Steps 10.3, 10.4
+ fn get_callbacks(&self, prototype: HandleObject) -> Fallible<LifecycleCallbacks> {
+ let cx = self.window.get_cx();
+
+ // Step 4
+ Ok(LifecycleCallbacks {
+ connected_callback: get_callback(cx, prototype, b"connectedCallback\0")?,
+ disconnected_callback: get_callback(cx, prototype, b"disconnectedCallback\0")?,
+ adopted_callback: get_callback(cx, prototype, b"adoptedCallback\0")?,
+ attribute_changed_callback: get_callback(cx, prototype, b"attributeChangedCallback\0")?,
+ })
+ }
+
+ /// https://html.spec.whatwg.org/multipage/#dom-customelementregistry-define
+ /// Step 10.6
+ #[allow(unsafe_code)]
+ fn get_observed_attributes(&self, constructor: HandleObject) -> Fallible<Vec<DOMString>> {
+ let cx = self.window.get_cx();
+ rooted!(in(cx) let mut observed_attributes = UndefinedValue());
+ if unsafe { !JS_GetProperty(cx,
+ constructor,
+ b"observedAttributes\0".as_ptr() as *const _,
+ observed_attributes.handle_mut()) } {
+ return Err(Error::JSFailed);
+ }
+
+ if observed_attributes.is_undefined() {
+ return Ok(Vec::new());
+ }
+
+ let conversion = unsafe {
+ FromJSValConvertible::from_jsval(cx, observed_attributes.handle(), StringificationBehavior::Default)
+ };
+ match conversion {
+ Ok(ConversionResult::Success(attributes)) => Ok(attributes),
+ Ok(ConversionResult::Failure(error)) => Err(Error::Type(error.into())),
+ _ => Err(Error::JSFailed),
+ }
+ }
+}
+
+/// https://html.spec.whatwg.org/multipage/#dom-customelementregistry-define
+/// Step 10.4
+#[allow(unsafe_code)]
+fn get_callback(cx: *mut JSContext, prototype: HandleObject, name: &[u8]) -> Fallible<Option<Rc<Function>>> {
+ rooted!(in(cx) let mut callback = UndefinedValue());
+
+ // Step 10.4.1
+ if unsafe { !JS_GetProperty(cx,
+ prototype,
+ name.as_ptr() as *const _,
+ callback.handle_mut()) } {
+ return Err(Error::JSFailed);
+ }
+
+ // Step 10.4.2
+ if !callback.is_undefined() {
+ if !callback.is_object() || unsafe { !IsCallable(callback.to_object()) } {
+ return Err(Error::Type("Lifecycle callback is not callable".to_owned()));
+ }
+ Ok(Some(Function::new(cx, callback.to_object())))
+ } else {
+ Ok(None)
+ }
}
impl CustomElementRegistryMethods for CustomElementRegistry {
#[allow(unsafe_code, unrooted_must_root)]
/// https://html.spec.whatwg.org/multipage/#dom-customelementregistry-define
fn Define(&self, name: DOMString, constructor_: Rc<Function>, options: &ElementDefinitionOptions) -> ErrorResult {
- let global_scope = self.window.upcast::<GlobalScope>();
- rooted!(in(global_scope.get_cx()) let constructor = constructor_.callback());
+ let cx = self.window.get_cx();
+ rooted!(in(cx) let constructor = constructor_.callback());
let name = LocalName::from(&*name);
// Step 1
@@ -173,22 +241,50 @@ impl CustomElementRegistryMethods for CustomElementRegistry {
self.element_definition_is_running.set(true);
// Steps 10.1 - 10.2
- let result = {
- let _ac = JSAutoCompartment::new(global_scope.get_cx(), constructor.get());
- self.check_prototype(constructor.handle())
+ rooted!(in(cx) let mut prototype = UndefinedValue());
+ {
+ let _ac = JSAutoCompartment::new(cx, constructor.get());
+ if let Err(error) = self.check_prototype(constructor.handle(), prototype.handle_mut()) {
+ self.element_definition_is_running.set(false);
+ return Err(error);
+ }
+ };
+
+ // Steps 10.3 - 10.4
+ rooted!(in(cx) let proto_object = prototype.to_object());
+ let callbacks = {
+ let _ac = JSAutoCompartment::new(cx, proto_object.get());
+ match self.get_callbacks(proto_object.handle()) {
+ Ok(callbacks) => callbacks,
+ Err(error) => {
+ self.element_definition_is_running.set(false);
+ return Err(error);
+ },
+ }
};
- // TODO: Steps 10.3 - 10.6
- // 10.3 - 10.4 Handle lifecycle callbacks
- // 10.5 - 10.6 Get observed attributes from the constructor
+ // Step 10.5 - 10.6
+ let observed_attributes = if callbacks.attribute_changed_callback.is_some() {
+ let _ac = JSAutoCompartment::new(cx, constructor.get());
+ match self.get_observed_attributes(constructor.handle()) {
+ Ok(attributes) => attributes,
+ Err(error) => {
+ self.element_definition_is_running.set(false);
+ return Err(error);
+ },
+ }
+ } else {
+ Vec::new()
+ };
self.element_definition_is_running.set(false);
- result?;
// Step 11
let definition = CustomElementDefinition::new(name.clone(),
local_name,
- constructor_);
+ constructor_,
+ observed_attributes,
+ callbacks);
// Step 12
self.definitions.borrow_mut().insert(name.clone(), Rc::new(definition));
@@ -254,6 +350,21 @@ impl CustomElementRegistryMethods for CustomElementRegistry {
}
}
+#[derive(HeapSizeOf, JSTraceable, Clone)]
+pub struct LifecycleCallbacks {
+ #[ignore_heap_size_of = "Rc"]
+ connected_callback: Option<Rc<Function>>,
+
+ #[ignore_heap_size_of = "Rc"]
+ disconnected_callback: Option<Rc<Function>>,
+
+ #[ignore_heap_size_of = "Rc"]
+ adopted_callback: Option<Rc<Function>>,
+
+ #[ignore_heap_size_of = "Rc"]
+ attribute_changed_callback: Option<Rc<Function>>,
+}
+
/// https://html.spec.whatwg.org/multipage/#custom-element-definition
#[derive(HeapSizeOf, JSTraceable, Clone)]
pub struct CustomElementDefinition {
@@ -263,14 +374,25 @@ pub struct CustomElementDefinition {
#[ignore_heap_size_of = "Rc"]
pub constructor: Rc<Function>,
+
+ pub observed_attributes: Vec<DOMString>,
+
+ pub callbacks: LifecycleCallbacks,
}
impl CustomElementDefinition {
- fn new(name: LocalName, local_name: LocalName, constructor: Rc<Function>) -> CustomElementDefinition {
+ fn new(name: LocalName,
+ local_name: LocalName,
+ constructor: Rc<Function>,
+ observed_attributes: Vec<DOMString>,
+ callbacks: LifecycleCallbacks)
+ -> CustomElementDefinition {
CustomElementDefinition {
name: name,
local_name: local_name,
constructor: constructor,
+ observed_attributes: observed_attributes,
+ callbacks: callbacks,
}
}
@@ -330,6 +452,192 @@ impl CustomElementDefinition {
}
}
+#[derive(HeapSizeOf, JSTraceable)]
+#[must_root]
+pub enum CustomElementReaction {
+ // TODO: Support upgrade reactions
+ Callback(
+ #[ignore_heap_size_of = "Rc"]
+ Rc<Function>,
+ Box<[Heap<JSVal>]>
+ ),
+}
+
+impl CustomElementReaction {
+ /// https://html.spec.whatwg.org/multipage/#invoke-custom-element-reactions
+ #[allow(unsafe_code)]
+ pub fn invoke(&self, element: &Element) {
+ // Step 2.1
+ match *self {
+ CustomElementReaction::Callback(ref callback, ref arguments) => {
+ let arguments = arguments.iter().map(|arg| arg.handle()).collect();
+ let _ = callback.Call_(&*element, arguments, ExceptionHandling::Report);
+ }
+ }
+ }
+}
+
+pub enum CallbackReaction {
+ Connected,
+ Disconnected,
+ Adopted(Root<Document>, Root<Document>),
+ AttributeChanged(LocalName, Option<DOMString>, Option<DOMString>, Namespace),
+}
+
+/// https://html.spec.whatwg.org/multipage/#processing-the-backup-element-queue
+#[derive(HeapSizeOf, JSTraceable, Eq, PartialEq, Clone, Copy)]
+enum BackupElementQueueFlag {
+ Processing,
+ NotProcessing,
+}
+
+/// https://html.spec.whatwg.org/multipage/#custom-element-reactions-stack
+#[derive(HeapSizeOf, JSTraceable)]
+#[must_root]
+pub struct CustomElementReactionStack {
+ backup_queue: ElementQueue,
+ processing_backup_element_queue: Cell<BackupElementQueueFlag>,
+}
+
+impl CustomElementReactionStack {
+ pub fn new() -> CustomElementReactionStack {
+ CustomElementReactionStack {
+ backup_queue: ElementQueue::new(),
+ processing_backup_element_queue: Cell::new(BackupElementQueueFlag::NotProcessing),
+ }
+ }
+
+ /// https://html.spec.whatwg.org/multipage/#enqueue-an-element-on-the-appropriate-element-queue
+ /// Step 4
+ pub fn invoke_backup_element_queue(&self) {
+ // Step 4.1
+ self.backup_queue.invoke_reactions();
+
+ // Step 4.2
+ self.processing_backup_element_queue.set(BackupElementQueueFlag::NotProcessing);
+ }
+
+ /// https://html.spec.whatwg.org/multipage/#enqueue-an-element-on-the-appropriate-element-queue
+ pub fn enqueue_element(&self, element: &Element) {
+ // TODO: Steps 1 - 2
+ // Support multiple queues
+
+ // Step 1.1
+ self.backup_queue.append_element(element);
+
+ // Step 1.2
+ if self.processing_backup_element_queue.get() == BackupElementQueueFlag::Processing {
+ return;
+ }
+
+ // Step 1.3
+ self.processing_backup_element_queue.set(BackupElementQueueFlag::Processing);
+
+ // Step 4
+ ScriptThread::enqueue_microtask(Microtask::CustomElementReaction);
+ }
+
+ /// https://html.spec.whatwg.org/multipage/#enqueue-a-custom-element-callback-reaction
+ #[allow(unsafe_code)]
+ pub fn enqueue_callback_reaction(&self, element: &Element, reaction: CallbackReaction) {
+ // Step 1
+ let definition = match element.get_custom_element_definition() {
+ Some(definition) => definition,
+ None => return,
+ };
+
+ // Step 2
+ let (callback, args) = match reaction {
+ CallbackReaction::Connected => (definition.callbacks.connected_callback.clone(), Vec::new()),
+ CallbackReaction::Disconnected => (definition.callbacks.disconnected_callback.clone(), Vec::new()),
+ CallbackReaction::Adopted(ref old_doc, ref new_doc) => {
+ let args = vec![Heap::default(), Heap::default()];
+ args[0].set(ObjectValue(old_doc.reflector().get_jsobject().get()));
+ args[1].set(ObjectValue(new_doc.reflector().get_jsobject().get()));
+ (definition.callbacks.adopted_callback.clone(), args)
+ },
+ CallbackReaction::AttributeChanged(local_name, old_val, val, namespace) => {
+ // Step 4
+ if !definition.observed_attributes.iter().any(|attr| *attr == *local_name) {
+ return;
+ }
+
+ let cx = element.global().get_cx();
+
+ let local_name = DOMString::from(&*local_name);
+ rooted!(in(cx) let mut name_value = UndefinedValue());
+ unsafe { local_name.to_jsval(cx, name_value.handle_mut()); }
+
+ rooted!(in(cx) let mut old_value = NullValue());
+ if let Some(old_val) = old_val {
+ unsafe { old_val.to_jsval(cx, old_value.handle_mut()); }
+ }
+
+ rooted!(in(cx) let mut value = NullValue());
+ if let Some(val) = val {
+ unsafe { val.to_jsval(cx, value.handle_mut()); }
+ }
+
+ let namespace = DOMString::from(&*namespace);
+ rooted!(in(cx) let mut namespace_value = UndefinedValue());
+ unsafe { namespace.to_jsval(cx, namespace_value.handle_mut()); }
+
+ let args = vec![Heap::default(), Heap::default(), Heap::default(), Heap::default()];
+ args[0].set(name_value.get());
+ args[1].set(old_value.get());
+ args[2].set(value.get());
+ args[3].set(namespace_value.get());
+
+ (definition.callbacks.attribute_changed_callback.clone(), args)
+ },
+ };
+
+ // Step 3
+ let callback = match callback {
+ Some(callback) => callback,
+ None => return,
+ };
+
+ // Step 5
+ element.push_callback_reaction(callback, args.into_boxed_slice());
+
+ // Step 6
+ self.enqueue_element(element);
+ }
+}
+
+/// https://html.spec.whatwg.org/multipage/#element-queue
+#[derive(HeapSizeOf, JSTraceable)]
+#[must_root]
+struct ElementQueue {
+ queue: DOMRefCell<VecDeque<JS<Element>>>,
+}
+
+impl ElementQueue {
+ fn new() -> ElementQueue {
+ ElementQueue {
+ queue: Default::default(),
+ }
+ }
+
+ /// https://html.spec.whatwg.org/multipage/#invoke-custom-element-reactions
+ fn invoke_reactions(&self) {
+ // Steps 1-2
+ while let Some(element) = self.next_element() {
+ element.invoke_reactions()
+ }
+ self.queue.borrow_mut().clear();
+ }
+
+ fn next_element(&self) -> Option<Root<Element>> {
+ self.queue.borrow_mut().pop_front().as_ref().map(JS::deref).map(Root::from_ref)
+ }
+
+ fn append_element(&self, element: &Element) {
+ self.queue.borrow_mut().push_back(JS::from_ref(element));
+ }
+}
+
/// https://html.spec.whatwg.org/multipage/#valid-custom-element-name
fn is_valid_custom_element_name(name: &str) -> bool {
// Custom elment names must match:
diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs
index fcb08ba54c8..c43f7ffdd95 100644
--- a/components/script/dom/element.rs
+++ b/components/script/dom/element.rs
@@ -13,6 +13,7 @@ use dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods;
use dom::bindings::codegen::Bindings::ElementBinding;
use dom::bindings::codegen::Bindings::ElementBinding::ElementMethods;
use dom::bindings::codegen::Bindings::EventBinding::EventMethods;
+use dom::bindings::codegen::Bindings::FunctionBinding::Function;
use dom::bindings::codegen::Bindings::HTMLTemplateElementBinding::HTMLTemplateElementMethods;
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
use dom::bindings::codegen::Bindings::WindowBinding::{ScrollBehavior, ScrollToOptions};
@@ -30,6 +31,7 @@ use dom::bindings::xmlname::{namespace_from_domstring, validate_and_extract, xml
use dom::bindings::xmlname::XMLName::InvalidXMLName;
use dom::characterdata::CharacterData;
use dom::create::create_element;
+use dom::customelementregistry::{CallbackReaction, CustomElementDefinition, CustomElementReaction};
use dom::document::{Document, LayoutDocumentHelpers};
use dom::documentfragment::DocumentFragment;
use dom::domrect::DOMRect;
@@ -80,11 +82,12 @@ use html5ever::serialize;
use html5ever::serialize::SerializeOpts;
use html5ever::serialize::TraversalScope;
use html5ever::serialize::TraversalScope::{ChildrenOnly, IncludeNode};
-use js::jsapi::{HandleValue, JSAutoCompartment};
+use js::jsapi::{HandleValue, Heap, JSAutoCompartment};
+use js::jsval::JSVal;
use net_traits::request::CorsSettings;
use ref_filter_map::ref_filter_map;
use script_layout_interface::message::ReflowQueryType;
-use script_thread::Runnable;
+use script_thread::{Runnable, ScriptThread};
use selectors::attr::{AttrSelectorOperation, NamespaceConstraint, CaseSensitivity};
use selectors::matching::{ElementSelectorFlags, LocalMatchingContext, MatchingContext, MatchingMode};
use selectors::matching::{HAS_EDGE_CHILD_SELECTOR, HAS_SLOW_SELECTOR, HAS_SLOW_SELECTOR_LATER_SIBLINGS};
@@ -141,6 +144,11 @@ pub struct Element {
/// when it has exclusive access to the element.
#[ignore_heap_size_of = "bitflags defined in rust-selectors"]
selector_flags: Cell<ElementSelectorFlags>,
+ /// https://html.spec.whatwg.org/multipage/#custom-element-reaction-queue
+ custom_element_reaction_queue: DOMRefCell<Vec<CustomElementReaction>>,
+ /// https://dom.spec.whatwg.org/#concept-element-custom-element-definition
+ #[ignore_heap_size_of = "Rc"]
+ custom_element_definition: DOMRefCell<Option<Rc<CustomElementDefinition>>>,
}
impl fmt::Debug for Element {
@@ -244,6 +252,8 @@ impl Element {
class_list: Default::default(),
state: Cell::new(state),
selector_flags: Cell::new(ElementSelectorFlags::empty()),
+ custom_element_reaction_queue: Default::default(),
+ custom_element_definition: Default::default(),
}
}
@@ -278,6 +288,26 @@ impl Element {
self.is.borrow().clone()
}
+ pub fn set_custom_element_definition(&self, definition: Rc<CustomElementDefinition>) {
+ *self.custom_element_definition.borrow_mut() = Some(definition);
+ }
+
+ pub fn get_custom_element_definition(&self) -> Option<Rc<CustomElementDefinition>> {
+ (*self.custom_element_definition.borrow()).clone()
+ }
+
+ pub fn push_callback_reaction(&self, function: Rc<Function>, args: Box<[Heap<JSVal>]>) {
+ self.custom_element_reaction_queue.borrow_mut().push(CustomElementReaction::Callback(function, args));
+ }
+
+ pub fn invoke_reactions(&self) {
+ let mut reaction_queue = self.custom_element_reaction_queue.borrow_mut();
+ for reaction in reaction_queue.iter() {
+ reaction.invoke(self);
+ }
+ reaction_queue.clear();
+ }
+
// https://drafts.csswg.org/cssom-view/#css-layout-box
// Elements that have a computed value of the display property
// that is table-column or table-column-group
@@ -1036,10 +1066,20 @@ impl Element {
pub fn push_attribute(&self, attr: &Attr) {
let name = attr.local_name().clone();
let namespace = attr.namespace().clone();
- let old_value = DOMString::from(&**attr.value());
- let mutation = Mutation::Attribute { name, namespace, old_value };
+ let value = DOMString::from(&**attr.value());
+ let mutation = Mutation::Attribute {
+ name: name.clone(),
+ namespace: namespace.clone(),
+ old_value: value.clone(),
+ };
+
MutationObserver::queue_a_mutation_record(&self.node, mutation);
+ if self.get_custom_element_definition().is_some() {
+ let reaction = CallbackReaction::AttributeChanged(name, None, Some(value), namespace);
+ ScriptThread::enqueue_callback_reaction(self, reaction);
+ }
+
assert!(attr.GetOwnerElement().r() == Some(self));
self.will_mutate_attr(attr);
self.attrs.borrow_mut().push(JS::from_ref(attr));
@@ -1171,9 +1211,17 @@ impl Element {
let name = attr.local_name().clone();
let namespace = attr.namespace().clone();
let old_value = DOMString::from(&**attr.value());
- let mutation = Mutation::Attribute { name, namespace, old_value, };
+ let mutation = Mutation::Attribute {
+ name: name.clone(),
+ namespace: namespace.clone(),
+ old_value: old_value.clone(),
+ };
+
MutationObserver::queue_a_mutation_record(&self.node, mutation);
+ let reaction = CallbackReaction::AttributeChanged(name, Some(old_value), None, namespace);
+ ScriptThread::enqueue_callback_reaction(self, reaction);
+
self.attrs.borrow_mut().remove(idx);
attr.set_owner(None);
if attr.namespace() == &ns!() {
diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs
index 333b47c3a2c..1c25567cb2d 100644
--- a/components/script/dom/node.rs
+++ b/components/script/dom/node.rs
@@ -30,6 +30,7 @@ use dom::bindings::str::{DOMString, USVString};
use dom::bindings::xmlname::namespace_from_domstring;
use dom::characterdata::{CharacterData, LayoutCharacterDataHelpers};
use dom::cssstylesheet::CSSStyleSheet;
+use dom::customelementregistry::CallbackReaction;
use dom::document::{Document, DocumentSource, HasBrowsingContext, IsHTMLDocument};
use dom::documentfragment::DocumentFragment;
use dom::documenttype::DocumentType;
@@ -66,6 +67,7 @@ use ref_slice::ref_slice;
use script_layout_interface::{HTMLCanvasData, OpaqueStyleAndLayoutData, SVGSVGData};
use script_layout_interface::{LayoutElementType, LayoutNodeType, TrustedNodeAddress};
use script_layout_interface::message::Msg;
+use script_thread::ScriptThread;
use script_traits::DocumentActivity;
use script_traits::UntrustedNodeAddress;
use selectors::matching::{matches_selector_list, MatchingContext, MatchingMode};
@@ -313,6 +315,10 @@ impl Node {
// e.g. when removing a <form>.
vtable_for(&&*node).unbind_from_tree(&context);
node.style_and_layout_data.get().map(|d| node.dispose(d));
+ // https://dom.spec.whatwg.org/#concept-node-remove step 14
+ if let Some(element) = node.as_custom_element() {
+ ScriptThread::enqueue_callback_reaction(&*element, CallbackReaction::Disconnected);
+ }
}
self.owner_doc().content_and_heritage_changed(self, NodeDamage::OtherNodeDamage);
@@ -322,6 +328,15 @@ impl Node {
pub fn to_untrusted_node_address(&self) -> UntrustedNodeAddress {
UntrustedNodeAddress(self.reflector().get_jsobject().get() as *const c_void)
}
+
+ pub fn as_custom_element(&self) -> Option<Root<Element>> {
+ self.downcast::<Element>()
+ .and_then(|element| if element.get_custom_element_definition().is_some() {
+ Some(Root::from_ref(element))
+ } else {
+ None
+ })
+ }
}
pub struct QuerySelectorIterator {
@@ -1401,13 +1416,20 @@ impl Node {
let old_doc = node.owner_doc();
// Step 2.
node.remove_self();
+ // Step 3.
if &*old_doc != document {
- // Step 3.
+ // Step 3.1.
for descendant in node.traverse_preorder() {
descendant.set_owner_doc(document);
}
- // Step 4.
for descendant in node.traverse_preorder() {
+ // Step 3.2.
+ if let Some(element) = node.as_custom_element() {
+ ScriptThread::enqueue_callback_reaction(&*element,
+ CallbackReaction::Adopted(old_doc.clone(), Root::from_ref(document)));
+ }
+
+ // Step 3.3.
vtable_for(&descendant).adopting_steps(&old_doc);
}
}
@@ -1615,6 +1637,9 @@ impl Node {
// Step 7.1.
parent.add_child(*kid, child);
// Step 7.2: insertion steps.
+ if let Some(element) = kid.as_custom_element() {
+ ScriptThread::enqueue_callback_reaction(&*element, CallbackReaction::Connected);
+ }
}
if let SuppressObserver::Unsuppressed = suppress_observers {
vtable_for(&parent).children_changed(
diff --git a/components/script/microtask.rs b/components/script/microtask.rs
index 5028f2849da..a25b7ff3719 100644
--- a/components/script/microtask.rs
+++ b/components/script/microtask.rs
@@ -15,6 +15,7 @@ use dom::htmlimageelement::ImageElementMicrotask;
use dom::htmlmediaelement::MediaElementMicrotask;
use dom::mutationobserver::MutationObserver;
use msg::constellation_msg::PipelineId;
+use script_thread::ScriptThread;
use std::cell::Cell;
use std::mem;
use std::rc::Rc;
@@ -33,6 +34,7 @@ pub enum Microtask {
Promise(EnqueuedPromiseCallback),
MediaElement(MediaElementMicrotask),
ImageElement(ImageElementMicrotask),
+ CustomElementReaction,
NotifyMutationObservers,
}
@@ -87,6 +89,9 @@ impl MicrotaskQueue {
Microtask::ImageElement(ref task) => {
task.handler();
},
+ Microtask::CustomElementReaction => {
+ ScriptThread::invoke_backup_element_queue();
+ },
Microtask::NotifyMutationObservers => {
MutationObserver::notify_mutation_observers();
}
diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs
index 722bd2cda12..cb4603f805e 100644
--- a/components/script/script_thread.rs
+++ b/components/script/script_thread.rs
@@ -39,6 +39,7 @@ use dom::bindings::str::DOMString;
use dom::bindings::structuredclone::StructuredCloneData;
use dom::bindings::trace::JSTraceable;
use dom::bindings::utils::WRAP_CALLBACKS;
+use dom::customelementregistry::{CallbackReaction, CustomElementReactionStack};
use dom::document::{Document, DocumentSource, FocusType, HasBrowsingContext, IsHTMLDocument, TouchEventResult};
use dom::element::Element;
use dom::event::{Event, EventBubbles, EventCancelable};
@@ -510,6 +511,9 @@ pub struct ScriptThread {
/// A list of nodes with in-progress CSS transitions, which roots them for the duration
/// of the transition.
transitioning_nodes: DOMRefCell<Vec<JS<Node>>>,
+
+ /// https://html.spec.whatwg.org/multipage/#custom-element-reactions-stack
+ custom_element_reaction_stack: CustomElementReactionStack,
}
/// In the event of thread panic, all data on the stack runs its destructor. However, there
@@ -742,6 +746,24 @@ impl ScriptThread {
let _ = window.layout_chan().send(msg);
}
+ pub fn enqueue_callback_reaction(element:&Element, reaction: CallbackReaction) {
+ SCRIPT_THREAD_ROOT.with(|root| {
+ if let Some(script_thread) = root.get() {
+ let script_thread = unsafe { &*script_thread };
+ script_thread.custom_element_reaction_stack.enqueue_callback_reaction(element, reaction);
+ }
+ })
+ }
+
+ pub fn invoke_backup_element_queue() {
+ SCRIPT_THREAD_ROOT.with(|root| {
+ if let Some(script_thread) = root.get() {
+ let script_thread = unsafe { &*script_thread };
+ script_thread.custom_element_reaction_stack.invoke_backup_element_queue();
+ }
+ })
+ }
+
/// Creates a new script thread.
pub fn new(state: InitialScriptState,
port: Receiver<MainThreadScriptMsg>,
@@ -827,6 +849,8 @@ impl ScriptThread {
docs_with_no_blocking_loads: Default::default(),
transitioning_nodes: Default::default(),
+
+ custom_element_reaction_stack: CustomElementReactionStack::new(),
}
}
diff --git a/tests/unit/script/size_of.rs b/tests/unit/script/size_of.rs
index 3f935ffaf93..d6c4a6ad7f8 100644
--- a/tests/unit/script/size_of.rs
+++ b/tests/unit/script/size_of.rs
@@ -31,9 +31,9 @@ macro_rules! sizeof_checker (
// Update the sizes here
sizeof_checker!(size_event_target, EventTarget, 40);
sizeof_checker!(size_node, Node, 184);
-sizeof_checker!(size_element, Element, 376);
-sizeof_checker!(size_htmlelement, HTMLElement, 392);
-sizeof_checker!(size_div, HTMLDivElement, 392);
-sizeof_checker!(size_span, HTMLSpanElement, 392);
+sizeof_checker!(size_element, Element, 424);
+sizeof_checker!(size_htmlelement, HTMLElement, 440);
+sizeof_checker!(size_div, HTMLDivElement, 440);
+sizeof_checker!(size_span, HTMLSpanElement, 440);
sizeof_checker!(size_text, Text, 216);
sizeof_checker!(size_characterdata, CharacterData, 216);
diff --git a/tests/wpt/metadata/custom-elements/CustomElementRegistry.html.ini b/tests/wpt/metadata/custom-elements/CustomElementRegistry.html.ini
index 72117493595..7b1502e90f5 100644
--- a/tests/wpt/metadata/custom-elements/CustomElementRegistry.html.ini
+++ b/tests/wpt/metadata/custom-elements/CustomElementRegistry.html.ini
@@ -1,29 +1,5 @@
[CustomElementRegistry.html]
type: testharness
- [customElements.define must get callbacks of the constructor prototype]
- expected: FAIL
-
- [customElements.define must rethrow an exception thrown while getting callbacks on the constructor prototype]
- expected: FAIL
-
- [customElements.define must rethrow an exception thrown while converting a callback value to Function callback type]
- expected: FAIL
-
- [customElements.define must get "observedAttributes" property on the constructor prototype when "attributeChangedCallback" is present]
- expected: FAIL
-
- [customElements.define must rethrow an exception thrown while getting observedAttributes on the constructor prototype]
- expected: FAIL
-
- [customElements.define must rethrow an exception thrown while converting the value of observedAttributes to sequence<DOMString>]
- expected: FAIL
-
- [customElements.define must rethrow an exception thrown while iterating over observedAttributes to sequence<DOMString>]
- expected: FAIL
-
- [customElements.define must rethrow an exception thrown while retrieving Symbol.iterator on observedAttributes]
- expected: FAIL
-
[customElements.define must upgrade elements in the shadow-including tree order]
expected: FAIL
diff --git a/tests/wpt/metadata/custom-elements/adopted-callback.html.ini b/tests/wpt/metadata/custom-elements/adopted-callback.html.ini
index 6e0ecac11eb..7d4f4439a5b 100644
--- a/tests/wpt/metadata/custom-elements/adopted-callback.html.ini
+++ b/tests/wpt/metadata/custom-elements/adopted-callback.html.ini
@@ -1,14 +1,5 @@
[adopted-callback.html]
type: testharness
- [Inserting a custom element into the owner document must not enqueue and invoke adoptedCallback]
- expected: FAIL
-
- [Inserting a custom element into the document of the template elements must enqueue and invoke adoptedCallback]
- expected: FAIL
-
- [Moving a custom element from the owner document into the document of the template elements must enqueue and invoke adoptedCallback]
- expected: FAIL
-
[Inserting an ancestor of custom element into the document of the template elements must enqueue and invoke adoptedCallback]
expected: FAIL
@@ -27,12 +18,6 @@
[Inserting a custom element into a detached shadow tree that belongs to the document of the template elements must enqueue and invoke adoptedCallback]
expected: FAIL
- [Inserting a custom element into a new document must enqueue and invoke adoptedCallback]
- expected: FAIL
-
- [Moving a custom element from the owner document into a new document must enqueue and invoke adoptedCallback]
- expected: FAIL
-
[Inserting an ancestor of custom element into a new document must enqueue and invoke adoptedCallback]
expected: FAIL
@@ -51,12 +36,6 @@
[Inserting a custom element into a detached shadow tree that belongs to a new document must enqueue and invoke adoptedCallback]
expected: FAIL
- [Inserting a custom element into a cloned document must enqueue and invoke adoptedCallback]
- expected: FAIL
-
- [Moving a custom element from the owner document into a cloned document must enqueue and invoke adoptedCallback]
- expected: FAIL
-
[Inserting an ancestor of custom element into a cloned document must enqueue and invoke adoptedCallback]
expected: FAIL
@@ -75,12 +54,6 @@
[Inserting a custom element into a detached shadow tree that belongs to a cloned document must enqueue and invoke adoptedCallback]
expected: FAIL
- [Inserting a custom element into a document created by createHTMLDocument must enqueue and invoke adoptedCallback]
- expected: FAIL
-
- [Moving a custom element from the owner document into a document created by createHTMLDocument must enqueue and invoke adoptedCallback]
- expected: FAIL
-
[Inserting an ancestor of custom element into a document created by createHTMLDocument must enqueue and invoke adoptedCallback]
expected: FAIL
@@ -99,12 +72,6 @@
[Inserting a custom element into a detached shadow tree that belongs to a document created by createHTMLDocument must enqueue and invoke adoptedCallback]
expected: FAIL
- [Inserting a custom element into an HTML document created by createDocument must enqueue and invoke adoptedCallback]
- expected: FAIL
-
- [Moving a custom element from the owner document into an HTML document created by createDocument must enqueue and invoke adoptedCallback]
- expected: FAIL
-
[Inserting an ancestor of custom element into an HTML document created by createDocument must enqueue and invoke adoptedCallback]
expected: FAIL
@@ -123,12 +90,6 @@
[Inserting a custom element into a detached shadow tree that belongs to an HTML document created by createDocument must enqueue and invoke adoptedCallback]
expected: FAIL
- [Inserting a custom element into the document of an iframe must enqueue and invoke adoptedCallback]
- expected: FAIL
-
- [Moving a custom element from the owner document into the document of an iframe must enqueue and invoke adoptedCallback]
- expected: FAIL
-
[Inserting an ancestor of custom element into the document of an iframe must enqueue and invoke adoptedCallback]
expected: FAIL
@@ -147,12 +108,6 @@
[Inserting a custom element into a detached shadow tree that belongs to the document of an iframe must enqueue and invoke adoptedCallback]
expected: FAIL
- [Inserting a custom element into an HTML document fetched by XHR must enqueue and invoke adoptedCallback]
- expected: FAIL
-
- [Moving a custom element from the owner document into an HTML document fetched by XHR must enqueue and invoke adoptedCallback]
- expected: FAIL
-
[Inserting an ancestor of custom element into an HTML document fetched by XHR must enqueue and invoke adoptedCallback]
expected: FAIL
@@ -174,3 +129,48 @@
[Custom Elements: adoptedCallback]
expected: FAIL
+ [Inserting a custom element into the owner document must not enqueue and invoke adoptedCallback]
+ expected: FAIL
+
+ [Inserting a custom element into the document of the template elements must enqueue and invoke adoptedCallback]
+ expected: FAIL
+
+ [Moving a custom element from the owner document into the document of the template elements must enqueue and invoke adoptedCallback]
+ expected: FAIL
+
+ [Inserting a custom element into a new document must enqueue and invoke adoptedCallback]
+ expected: FAIL
+
+ [Moving a custom element from the owner document into a new document must enqueue and invoke adoptedCallback]
+ expected: FAIL
+
+ [Inserting a custom element into a cloned document must enqueue and invoke adoptedCallback]
+ expected: FAIL
+
+ [Moving a custom element from the owner document into a cloned document must enqueue and invoke adoptedCallback]
+ expected: FAIL
+
+ [Inserting a custom element into a document created by createHTMLDocument must enqueue and invoke adoptedCallback]
+ expected: FAIL
+
+ [Moving a custom element from the owner document into a document created by createHTMLDocument must enqueue and invoke adoptedCallback]
+ expected: FAIL
+
+ [Inserting a custom element into an HTML document created by createDocument must enqueue and invoke adoptedCallback]
+ expected: FAIL
+
+ [Moving a custom element from the owner document into an HTML document created by createDocument must enqueue and invoke adoptedCallback]
+ expected: FAIL
+
+ [Inserting a custom element into the document of an iframe must enqueue and invoke adoptedCallback]
+ expected: FAIL
+
+ [Moving a custom element from the owner document into the document of an iframe must enqueue and invoke adoptedCallback]
+ expected: FAIL
+
+ [Inserting a custom element into an HTML document fetched by XHR must enqueue and invoke adoptedCallback]
+ expected: FAIL
+
+ [Moving a custom element from the owner document into an HTML document fetched by XHR must enqueue and invoke adoptedCallback]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/custom-elements/connected-callbacks.html.ini b/tests/wpt/metadata/custom-elements/connected-callbacks.html.ini
index adb9b9c8072..457ec15b357 100644
--- a/tests/wpt/metadata/custom-elements/connected-callbacks.html.ini
+++ b/tests/wpt/metadata/custom-elements/connected-callbacks.html.ini
@@ -1,8 +1,5 @@
[connected-callbacks.html]
type: testharness
- [Inserting a custom element into the document must enqueue and invoke connectedCallback]
- expected: FAIL
-
[Inserting an ancestor of custom element into the document must enqueue and invoke connectedCallback]
expected: FAIL
@@ -15,9 +12,6 @@
[Inserting a custom element into a detached shadow tree that belongs to the document must not enqueue and invoke connectedCallback]
expected: FAIL
- [Inserting a custom element into the document of the template elements must enqueue and invoke connectedCallback]
- expected: FAIL
-
[Inserting an ancestor of custom element into the document of the template elements must enqueue and invoke connectedCallback]
expected: FAIL
@@ -30,9 +24,6 @@
[Inserting a custom element into a detached shadow tree that belongs to the document of the template elements must not enqueue and invoke connectedCallback]
expected: FAIL
- [Inserting a custom element into a new document must enqueue and invoke connectedCallback]
- expected: FAIL
-
[Inserting an ancestor of custom element into a new document must enqueue and invoke connectedCallback]
expected: FAIL
@@ -45,9 +36,6 @@
[Inserting a custom element into a detached shadow tree that belongs to a new document must not enqueue and invoke connectedCallback]
expected: FAIL
- [Inserting a custom element into a cloned document must enqueue and invoke connectedCallback]
- expected: FAIL
-
[Inserting an ancestor of custom element into a cloned document must enqueue and invoke connectedCallback]
expected: FAIL
@@ -60,9 +48,6 @@
[Inserting a custom element into a detached shadow tree that belongs to a cloned document must not enqueue and invoke connectedCallback]
expected: FAIL
- [Inserting a custom element into a document created by createHTMLDocument must enqueue and invoke connectedCallback]
- expected: FAIL
-
[Inserting an ancestor of custom element into a document created by createHTMLDocument must enqueue and invoke connectedCallback]
expected: FAIL
@@ -75,9 +60,6 @@
[Inserting a custom element into a detached shadow tree that belongs to a document created by createHTMLDocument must not enqueue and invoke connectedCallback]
expected: FAIL
- [Inserting a custom element into an HTML document created by createDocument must enqueue and invoke connectedCallback]
- expected: FAIL
-
[Inserting an ancestor of custom element into an HTML document created by createDocument must enqueue and invoke connectedCallback]
expected: FAIL
@@ -90,9 +72,6 @@
[Inserting a custom element into a detached shadow tree that belongs to an HTML document created by createDocument must not enqueue and invoke connectedCallback]
expected: FAIL
- [Inserting a custom element into the document of an iframe must enqueue and invoke connectedCallback]
- expected: FAIL
-
[Inserting an ancestor of custom element into the document of an iframe must enqueue and invoke connectedCallback]
expected: FAIL
@@ -105,9 +84,6 @@
[Inserting a custom element into a detached shadow tree that belongs to the document of an iframe must not enqueue and invoke connectedCallback]
expected: FAIL
- [Inserting a custom element into an HTML document fetched by XHR must enqueue and invoke connectedCallback]
- expected: FAIL
-
[Inserting an ancestor of custom element into an HTML document fetched by XHR must enqueue and invoke connectedCallback]
expected: FAIL
@@ -123,3 +99,27 @@
[Custom Elements: connectedCallback]
expected: FAIL
+ [Inserting a custom element into the document must enqueue and invoke connectedCallback]
+ expected: FAIL
+
+ [Inserting a custom element into the document of the template elements must enqueue and invoke connectedCallback]
+ expected: FAIL
+
+ [Inserting a custom element into a new document must enqueue and invoke connectedCallback]
+ expected: FAIL
+
+ [Inserting a custom element into a cloned document must enqueue and invoke connectedCallback]
+ expected: FAIL
+
+ [Inserting a custom element into a document created by createHTMLDocument must enqueue and invoke connectedCallback]
+ expected: FAIL
+
+ [Inserting a custom element into an HTML document created by createDocument must enqueue and invoke connectedCallback]
+ expected: FAIL
+
+ [Inserting a custom element into the document of an iframe must enqueue and invoke connectedCallback]
+ expected: FAIL
+
+ [Inserting a custom element into an HTML document fetched by XHR must enqueue and invoke connectedCallback]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/custom-elements/custom-element-registry/define.html.ini b/tests/wpt/metadata/custom-elements/custom-element-registry/define.html.ini
index a04a32d8f5e..14558fa24b2 100644
--- a/tests/wpt/metadata/custom-elements/custom-element-registry/define.html.ini
+++ b/tests/wpt/metadata/custom-elements/custom-element-registry/define.html.ini
@@ -3,51 +3,3 @@
[If constructor is arrow function, should throw a TypeError]
expected: FAIL
- [If constructor.prototype.connectedCallback throws, should rethrow]
- expected: FAIL
-
- [If constructor.prototype.connectedCallback is null, should throw a TypeError]
- expected: FAIL
-
- [If constructor.prototype.connectedCallback is object, should throw a TypeError]
- expected: FAIL
-
- [If constructor.prototype.connectedCallback is integer, should throw a TypeError]
- expected: FAIL
-
- [If constructor.prototype.disconnectedCallback throws, should rethrow]
- expected: FAIL
-
- [If constructor.prototype.disconnectedCallback is null, should throw a TypeError]
- expected: FAIL
-
- [If constructor.prototype.disconnectedCallback is object, should throw a TypeError]
- expected: FAIL
-
- [If constructor.prototype.disconnectedCallback is integer, should throw a TypeError]
- expected: FAIL
-
- [If constructor.prototype.adoptedCallback throws, should rethrow]
- expected: FAIL
-
- [If constructor.prototype.adoptedCallback is null, should throw a TypeError]
- expected: FAIL
-
- [If constructor.prototype.adoptedCallback is object, should throw a TypeError]
- expected: FAIL
-
- [If constructor.prototype.adoptedCallback is integer, should throw a TypeError]
- expected: FAIL
-
- [If constructor.prototype.attributeChangedCallback throws, should rethrow]
- expected: FAIL
-
- [If constructor.prototype.attributeChangedCallback is null, should throw a TypeError]
- expected: FAIL
-
- [If constructor.prototype.attributeChangedCallback is object, should throw a TypeError]
- expected: FAIL
-
- [If constructor.prototype.attributeChangedCallback is integer, should throw a TypeError]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/custom-elements/disconnected-callbacks.html.ini b/tests/wpt/metadata/custom-elements/disconnected-callbacks.html.ini
index 7b713889aa1..caa481be682 100644
--- a/tests/wpt/metadata/custom-elements/disconnected-callbacks.html.ini
+++ b/tests/wpt/metadata/custom-elements/disconnected-callbacks.html.ini
@@ -1,125 +1,125 @@
[disconnected-callbacks.html]
type: testharness
- [Removing a custom element from the document must enqueue and invoke disconnectedCallback]
+ [Removing a custom element from a shadow tree in the document must enqueue and invoke disconnectedCallback]
expected: FAIL
- [Removing an ancestor of custom element from the document must enqueue and invoke disconnectedCallback]
+ [Removing the shadow host of a custom element from athe document must enqueue and invoke disconnectedCallback]
expected: FAIL
- [Removing a custom element from a shadow tree in the document must enqueue and invoke disconnectedCallback]
+ [Removing a custom element from a detached shadow tree that belongs to the document must not enqueue and invoke disconnectedCallback]
expected: FAIL
- [Removing the shadow host of a custom element from athe document must enqueue and invoke disconnectedCallback]
+ [Removing a custom element from a shadow tree in the document of the template elements must enqueue and invoke disconnectedCallback]
expected: FAIL
- [Removing a custom element from a detached shadow tree that belongs to the document must not enqueue and invoke disconnectedCallback]
+ [Removing the shadow host of a custom element from athe document of the template elements must enqueue and invoke disconnectedCallback]
expected: FAIL
- [Removing a custom element from the document of the template elements must enqueue and invoke disconnectedCallback]
+ [Removing a custom element from a detached shadow tree that belongs to the document of the template elements must not enqueue and invoke disconnectedCallback]
expected: FAIL
- [Removing an ancestor of custom element from the document of the template elements must enqueue and invoke disconnectedCallback]
+ [Removing a custom element from a shadow tree in a new document must enqueue and invoke disconnectedCallback]
expected: FAIL
- [Removing a custom element from a shadow tree in the document of the template elements must enqueue and invoke disconnectedCallback]
+ [Removing the shadow host of a custom element from aa new document must enqueue and invoke disconnectedCallback]
expected: FAIL
- [Removing the shadow host of a custom element from athe document of the template elements must enqueue and invoke disconnectedCallback]
+ [Removing a custom element from a detached shadow tree that belongs to a new document must not enqueue and invoke disconnectedCallback]
expected: FAIL
- [Removing a custom element from a detached shadow tree that belongs to the document of the template elements must not enqueue and invoke disconnectedCallback]
+ [Removing a custom element from a shadow tree in a cloned document must enqueue and invoke disconnectedCallback]
expected: FAIL
- [Removing a custom element from a new document must enqueue and invoke disconnectedCallback]
+ [Removing the shadow host of a custom element from aa cloned document must enqueue and invoke disconnectedCallback]
expected: FAIL
- [Removing an ancestor of custom element from a new document must enqueue and invoke disconnectedCallback]
+ [Removing a custom element from a detached shadow tree that belongs to a cloned document must not enqueue and invoke disconnectedCallback]
expected: FAIL
- [Removing a custom element from a shadow tree in a new document must enqueue and invoke disconnectedCallback]
+ [Removing a custom element from a shadow tree in a document created by createHTMLDocument must enqueue and invoke disconnectedCallback]
expected: FAIL
- [Removing the shadow host of a custom element from aa new document must enqueue and invoke disconnectedCallback]
+ [Removing the shadow host of a custom element from aa document created by createHTMLDocument must enqueue and invoke disconnectedCallback]
expected: FAIL
- [Removing a custom element from a detached shadow tree that belongs to a new document must not enqueue and invoke disconnectedCallback]
+ [Removing a custom element from a detached shadow tree that belongs to a document created by createHTMLDocument must not enqueue and invoke disconnectedCallback]
expected: FAIL
- [Removing a custom element from a cloned document must enqueue and invoke disconnectedCallback]
+ [Removing a custom element from a shadow tree in an HTML document created by createDocument must enqueue and invoke disconnectedCallback]
expected: FAIL
- [Removing an ancestor of custom element from a cloned document must enqueue and invoke disconnectedCallback]
+ [Removing the shadow host of a custom element from aan HTML document created by createDocument must enqueue and invoke disconnectedCallback]
expected: FAIL
- [Removing a custom element from a shadow tree in a cloned document must enqueue and invoke disconnectedCallback]
+ [Removing a custom element from a detached shadow tree that belongs to an HTML document created by createDocument must not enqueue and invoke disconnectedCallback]
expected: FAIL
- [Removing the shadow host of a custom element from aa cloned document must enqueue and invoke disconnectedCallback]
+ [Removing a custom element from a shadow tree in the document of an iframe must enqueue and invoke disconnectedCallback]
expected: FAIL
- [Removing a custom element from a detached shadow tree that belongs to a cloned document must not enqueue and invoke disconnectedCallback]
+ [Removing the shadow host of a custom element from athe document of an iframe must enqueue and invoke disconnectedCallback]
expected: FAIL
- [Removing a custom element from a document created by createHTMLDocument must enqueue and invoke disconnectedCallback]
+ [Removing a custom element from a detached shadow tree that belongs to the document of an iframe must not enqueue and invoke disconnectedCallback]
expected: FAIL
- [Removing an ancestor of custom element from a document created by createHTMLDocument must enqueue and invoke disconnectedCallback]
+ [Removing a custom element from a shadow tree in an HTML document fetched by XHR must enqueue and invoke disconnectedCallback]
expected: FAIL
- [Removing a custom element from a shadow tree in a document created by createHTMLDocument must enqueue and invoke disconnectedCallback]
+ [Removing the shadow host of a custom element from aan HTML document fetched by XHR must enqueue and invoke disconnectedCallback]
expected: FAIL
- [Removing the shadow host of a custom element from aa document created by createHTMLDocument must enqueue and invoke disconnectedCallback]
+ [Removing a custom element from a detached shadow tree that belongs to an HTML document fetched by XHR must not enqueue and invoke disconnectedCallback]
expected: FAIL
- [Removing a custom element from a detached shadow tree that belongs to a document created by createHTMLDocument must not enqueue and invoke disconnectedCallback]
+ [Custom Elements: disconnectedCallback]
expected: FAIL
- [Removing a custom element from an HTML document created by createDocument must enqueue and invoke disconnectedCallback]
+ [Removing a custom element from the document must enqueue and invoke disconnectedCallback]
expected: FAIL
- [Removing an ancestor of custom element from an HTML document created by createDocument must enqueue and invoke disconnectedCallback]
+ [Removing an ancestor of custom element from the document must enqueue and invoke disconnectedCallback]
expected: FAIL
- [Removing a custom element from a shadow tree in an HTML document created by createDocument must enqueue and invoke disconnectedCallback]
+ [Removing a custom element from the document of the template elements must enqueue and invoke disconnectedCallback]
expected: FAIL
- [Removing the shadow host of a custom element from aan HTML document created by createDocument must enqueue and invoke disconnectedCallback]
+ [Removing an ancestor of custom element from the document of the template elements must enqueue and invoke disconnectedCallback]
expected: FAIL
- [Removing a custom element from a detached shadow tree that belongs to an HTML document created by createDocument must not enqueue and invoke disconnectedCallback]
+ [Removing a custom element from a new document must enqueue and invoke disconnectedCallback]
expected: FAIL
- [Removing a custom element from the document of an iframe must enqueue and invoke disconnectedCallback]
+ [Removing an ancestor of custom element from a new document must enqueue and invoke disconnectedCallback]
expected: FAIL
- [Removing an ancestor of custom element from the document of an iframe must enqueue and invoke disconnectedCallback]
+ [Removing a custom element from a cloned document must enqueue and invoke disconnectedCallback]
expected: FAIL
- [Removing a custom element from a shadow tree in the document of an iframe must enqueue and invoke disconnectedCallback]
+ [Removing an ancestor of custom element from a cloned document must enqueue and invoke disconnectedCallback]
expected: FAIL
- [Removing the shadow host of a custom element from athe document of an iframe must enqueue and invoke disconnectedCallback]
+ [Removing a custom element from a document created by createHTMLDocument must enqueue and invoke disconnectedCallback]
expected: FAIL
- [Removing a custom element from a detached shadow tree that belongs to the document of an iframe must not enqueue and invoke disconnectedCallback]
+ [Removing an ancestor of custom element from a document created by createHTMLDocument must enqueue and invoke disconnectedCallback]
expected: FAIL
- [Removing a custom element from an HTML document fetched by XHR must enqueue and invoke disconnectedCallback]
+ [Removing a custom element from an HTML document created by createDocument must enqueue and invoke disconnectedCallback]
expected: FAIL
- [Removing an ancestor of custom element from an HTML document fetched by XHR must enqueue and invoke disconnectedCallback]
+ [Removing an ancestor of custom element from an HTML document created by createDocument must enqueue and invoke disconnectedCallback]
expected: FAIL
- [Removing a custom element from a shadow tree in an HTML document fetched by XHR must enqueue and invoke disconnectedCallback]
+ [Removing a custom element from the document of an iframe must enqueue and invoke disconnectedCallback]
expected: FAIL
- [Removing the shadow host of a custom element from aan HTML document fetched by XHR must enqueue and invoke disconnectedCallback]
+ [Removing an ancestor of custom element from the document of an iframe must enqueue and invoke disconnectedCallback]
expected: FAIL
- [Removing a custom element from a detached shadow tree that belongs to an HTML document fetched by XHR must not enqueue and invoke disconnectedCallback]
+ [Removing a custom element from an HTML document fetched by XHR must enqueue and invoke disconnectedCallback]
expected: FAIL
- [Custom Elements: disconnectedCallback]
+ [Removing an ancestor of custom element from an HTML document fetched by XHR must enqueue and invoke disconnectedCallback]
expected: FAIL
diff --git a/tests/wpt/metadata/custom-elements/reactions/Document.html.ini b/tests/wpt/metadata/custom-elements/reactions/Document.html.ini
index 07e68da69b7..bf986fdbca0 100644
--- a/tests/wpt/metadata/custom-elements/reactions/Document.html.ini
+++ b/tests/wpt/metadata/custom-elements/reactions/Document.html.ini
@@ -1,14 +1,8 @@
[Document.html]
type: testharness
- [adoptNode on Document must enqueue an adopted reaction when importing a custom element]
- expected: FAIL
-
[execCommand on Document must enqueue a disconnected reaction when deleting a custom element from a contenteditable element]
expected: FAIL
- [title on Document must enqueue disconnectedCallback when removing a custom element]
- expected: FAIL
-
[body on Document must enqueue disconnectedCallback when removing a custom element]
expected: FAIL
@@ -21,15 +15,21 @@
[write on Document must enqueue disconnectedCallback when removing a custom element]
expected: FAIL
- [write on Document must enqueue connectedCallback after constructing a custom element]
+ [writeln on Document must enqueue disconnectedCallback when removing a custom element]
expected: FAIL
- [writeln on Document must enqueue disconnectedCallback when removing a custom element]
+ [importNode on Document must construct a new custom element when importing a custom element from a template]
expected: FAIL
- [writeln on Document must enqueue connectedCallback after constructing a custom element]
+ [adoptNode on Document must enqueue an adopted reaction when importing a custom element]
expected: FAIL
- [importNode on Document must construct a new custom element when importing a custom element from a template]
+ [title on Document must enqueue disconnectedCallback when removing a custom element]
+ expected: FAIL
+
+ [write on Document must enqueue connectedCallback after constructing a custom element]
+ expected: FAIL
+
+ [writeln on Document must enqueue connectedCallback after constructing a custom element]
expected: FAIL
diff --git a/tests/wpt/metadata/custom-elements/reactions/Element.html.ini b/tests/wpt/metadata/custom-elements/reactions/Element.html.ini
index fa721851548..d6e6402eece 100644
--- a/tests/wpt/metadata/custom-elements/reactions/Element.html.ini
+++ b/tests/wpt/metadata/custom-elements/reactions/Element.html.ini
@@ -51,33 +51,33 @@
[removeAttributeNode on Element must enqueue an attributeChanged reaction when removing an existing attribute]
expected: FAIL
- [insertAdjacentElement on Element must enqueue a connected reaction]
+ [innerHTML on Element must enqueue a connected reaction for a newly constructed custom element]
expected: FAIL
- [insertAdjacentElement on Element must enqueue a disconnected reaction, an adopted reaction, and a connected reaction when the custom element was in another document]
+ [innerHTML on Element must enqueue a attributeChanged reaction for a newly constructed custom element]
expected: FAIL
- [innerHTML on Element must enqueue a connected reaction for a newly constructed custom element]
+ [outerHTML on Element must enqueue a connected reaction for a newly constructed custom element]
expected: FAIL
- [innerHTML on Element must enqueue a attributeChanged reaction for a newly constructed custom element]
+ [outerHTML on Element must enqueue a attributeChanged reaction for a newly constructed custom element]
expected: FAIL
- [innerHTML on Element must enqueue a disconnected reaction]
+ [insertAdjacentHTML on Element must enqueue a connected reaction for a newly constructed custom element]
expected: FAIL
- [outerHTML on Element must enqueue a connected reaction for a newly constructed custom element]
+ [insertAdjacentHTML on Element must enqueue a attributeChanged reaction for a newly constructed custom element]
expected: FAIL
- [outerHTML on Element must enqueue a attributeChanged reaction for a newly constructed custom element]
+ [insertAdjacentElement on Element must enqueue a connected reaction]
expected: FAIL
- [outerHTML on Element must enqueue a disconnected reaction]
+ [insertAdjacentElement on Element must enqueue a disconnected reaction, an adopted reaction, and a connected reaction when the custom element was in another document]
expected: FAIL
- [insertAdjacentHTML on Element must enqueue a connected reaction for a newly constructed custom element]
+ [innerHTML on Element must enqueue a disconnected reaction]
expected: FAIL
- [insertAdjacentHTML on Element must enqueue a attributeChanged reaction for a newly constructed custom element]
+ [outerHTML on Element must enqueue a disconnected reaction]
expected: FAIL
diff --git a/tests/wpt/metadata/custom-elements/reactions/HTMLOptionsCollection.html.ini b/tests/wpt/metadata/custom-elements/reactions/HTMLOptionsCollection.html.ini
index bf68ae508ac..1a1f74719e6 100644
--- a/tests/wpt/metadata/custom-elements/reactions/HTMLOptionsCollection.html.ini
+++ b/tests/wpt/metadata/custom-elements/reactions/HTMLOptionsCollection.html.ini
@@ -1,15 +1,15 @@
[HTMLOptionsCollection.html]
type: testharness
- [length on HTMLOptionsCollection must enqueue disconnectedCallback when removing a custom element]
+ [The indexed setter on HTMLOptionsCollection must enqueue connectedCallback when inserting a custom element]
expected: FAIL
- [The indexed setter on HTMLOptionsCollection must enqueue connectedCallback when inserting a custom element]
+ [add on HTMLOptionsCollection must enqueue connectedCallback when inserting a custom element]
expected: FAIL
- [The indexed setter on HTMLOptionsCollection must enqueue disconnectedCallback when removing a custom element]
+ [length on HTMLOptionsCollection must enqueue disconnectedCallback when removing a custom element]
expected: FAIL
- [add on HTMLOptionsCollection must enqueue connectedCallback when inserting a custom element]
+ [The indexed setter on HTMLOptionsCollection must enqueue disconnectedCallback when removing a custom element]
expected: FAIL
[remove on HTMLOptionsCollection must enqueue disconnectedCallback when removing a custom element]
diff --git a/tests/wpt/metadata/custom-elements/reactions/HTMLSelectElement.html.ini b/tests/wpt/metadata/custom-elements/reactions/HTMLSelectElement.html.ini
index b2efcf5e449..517deb05807 100644
--- a/tests/wpt/metadata/custom-elements/reactions/HTMLSelectElement.html.ini
+++ b/tests/wpt/metadata/custom-elements/reactions/HTMLSelectElement.html.ini
@@ -1,8 +1,5 @@
[HTMLSelectElement.html]
type: testharness
- [length on HTMLSelectElement must enqueue disconnectedCallback when removing a custom element]
- expected: FAIL
-
[The indexed setter on HTMLSelectElement must enqueue connectedCallback when inserting a custom element]
expected: FAIL
@@ -12,6 +9,9 @@
[add on HTMLSelectElement must enqueue connectedCallback when inserting a custom element]
expected: FAIL
+ [length on HTMLSelectElement must enqueue disconnectedCallback when removing a custom element]
+ expected: FAIL
+
[remove on HTMLSelectElement must enqueue disconnectedCallback when removing a custom element]
expected: FAIL
diff --git a/tests/wpt/metadata/custom-elements/reactions/Range.html.ini b/tests/wpt/metadata/custom-elements/reactions/Range.html.ini
index 5a3c020f1bc..64c174992a5 100644
--- a/tests/wpt/metadata/custom-elements/reactions/Range.html.ini
+++ b/tests/wpt/metadata/custom-elements/reactions/Range.html.ini
@@ -1,8 +1,5 @@
[Range.html]
type: testharness
- [deleteContents on Range must enqueue a disconnected reaction]
- expected: FAIL
-
[extractContents on Range must enqueue a disconnected reaction]
expected: FAIL
@@ -15,6 +12,12 @@
[cloneContents on Range must enqueue an attributeChanged reaction when cloning an element only for observed attributes]
expected: FAIL
+ [createContextualFragment on Range must construct a custom element]
+ expected: FAIL
+
+ [deleteContents on Range must enqueue a disconnected reaction]
+ expected: FAIL
+
[insertNode on Range must enqueue a connected reaction]
expected: FAIL
@@ -27,6 +30,3 @@
[surroundContents on Range must enqueue a disconnected reaction, an adopted reaction, and a connected reaction when the custom element was in another document]
expected: FAIL
- [createContextualFragment on Range must construct a custom element]
- expected: FAIL
-