aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/script/dom/bindings/interface.rs8
-rw-r--r--components/script/dom/create.rs22
-rw-r--r--components/script/dom/customelementregistry.rs17
-rw-r--r--components/script/dom/element.rs20
-rw-r--r--tests/unit/script/size_of.rs8
-rw-r--r--tests/wpt/metadata/custom-elements/upgrading/Node-cloneNode.html.ini5
6 files changed, 59 insertions, 21 deletions
diff --git a/components/script/dom/bindings/interface.rs b/components/script/dom/bindings/interface.rs
index 0df46f40241..63658b3f0f9 100644
--- a/components/script/dom/bindings/interface.rs
+++ b/components/script/dom/bindings/interface.rs
@@ -81,7 +81,7 @@ use dom::bindings::js::Root;
use dom::bindings::utils::{DOM_PROTOTYPE_SLOT, ProtoOrIfaceArray, get_proto_or_iface_array};
use dom::create::create_native_html_element;
use dom::customelementregistry::ConstructionStackEntry;
-use dom::element::{Element, ElementCreator};
+use dom::element::{CustomElementState, Element, ElementCreator};
use dom::htmlelement::HTMLElement;
use dom::window::Window;
use html5ever::LocalName;
@@ -296,8 +296,10 @@ pub unsafe fn html_constructor<T>(window: &Window, call_args: &CallArgs) -> Fall
// Step 8.2 is performed in the generated caller code.
- // TODO: Step 8.3 - 8.4
- // Set the element's custom element state and definition.
+ // Step 8.3
+ element.set_custom_element_state(CustomElementState::Custom);
+
+ // Step 8.4
element.set_custom_element_definition(definition.clone());
// Step 8.5
diff --git a/components/script/dom/create.rs b/components/script/dom/create.rs
index e70c547e3d3..922757593f3 100644
--- a/components/script/dom/create.rs
+++ b/components/script/dom/create.rs
@@ -7,7 +7,7 @@ use dom::bindings::js::Root;
use dom::bindings::reflector::DomObject;
use dom::customelementregistry::{is_valid_custom_element_name, upgrade_element};
use dom::document::Document;
-use dom::element::{CustomElementCreationMode, Element, ElementCreator};
+use dom::element::{CustomElementCreationMode, CustomElementState, Element, ElementCreator};
use dom::globalscope::GlobalScope;
use dom::htmlanchorelement::HTMLAnchorElement;
use dom::htmlappletelement::HTMLAppletElement;
@@ -129,7 +129,9 @@ fn create_html_element(name: QualName,
if definition.is_autonomous() {
match mode {
CustomElementCreationMode::Asynchronous => {
- let result = Root::upcast(HTMLElement::new(name.local.clone(), prefix.clone(), document));
+ let result = Root::upcast::<Element>(
+ HTMLElement::new(name.local.clone(), prefix.clone(), document));
+ result.set_custom_element_state(CustomElementState::Undefined);
ScriptThread::enqueue_upgrade_reaction(&*result, definition);
return result;
},
@@ -153,7 +155,10 @@ fn create_html_element(name: QualName,
}
// Step 6.1.2
- Root::upcast(HTMLUnknownElement::new(local_name, prefix, document))
+ let element = Root::upcast::<Element>(
+ HTMLUnknownElement::new(local_name, prefix, document));
+ element.set_custom_element_state(CustomElementState::Failed);
+ element
},
};
},
@@ -162,6 +167,7 @@ fn create_html_element(name: QualName,
// Steps 5.1-5.2
let element = create_native_html_element(name, prefix, document, creator);
element.set_is(definition.name.clone());
+ element.set_custom_element_state(CustomElementState::Undefined);
match mode {
// Step 5.3
CustomElementCreationMode::Synchronous =>
@@ -174,7 +180,15 @@ fn create_html_element(name: QualName,
}
}
- create_native_html_element(name, prefix, document, creator)
+ // Steps 7.1-7.2
+ let result = create_native_html_element(name.clone(), prefix, document, creator);
+
+ // Step 7.3
+ if is_valid_custom_element_name(&*name.local) || is.is_some() {
+ result.set_custom_element_state(CustomElementState::Undefined);
+ }
+
+ result
}
pub fn create_native_html_element(name: QualName,
diff --git a/components/script/dom/customelementregistry.rs b/components/script/dom/customelementregistry.rs
index 100aae7cae3..a625d464129 100644
--- a/components/script/dom/customelementregistry.rs
+++ b/components/script/dom/customelementregistry.rs
@@ -18,7 +18,7 @@ use dom::bindings::reflector::{DomObject, Reflector, reflect_dom_object};
use dom::bindings::str::DOMString;
use dom::document::Document;
use dom::domexception::{DOMErrorName, DOMException};
-use dom::element::Element;
+use dom::element::{CustomElementState, Element};
use dom::globalscope::GlobalScope;
use dom::htmlelement::HTMLElement;
use dom::node::{document_from_node, Node, window_from_node};
@@ -477,8 +477,11 @@ impl CustomElementDefinition {
/// https://html.spec.whatwg.org/multipage/#concept-upgrade-an-element
#[allow(unsafe_code)]
pub fn upgrade_element(definition: Rc<CustomElementDefinition>, element: &Element) {
- // TODO: Steps 1-2
- // Track custom element state
+ // Steps 1-2
+ let state = element.get_custom_element_state();
+ if state == CustomElementState::Custom || state == CustomElementState::Failed {
+ return;
+ }
// Step 3
for attr in element.attrs().iter() {
@@ -504,8 +507,8 @@ pub fn upgrade_element(definition: Rc<CustomElementDefinition>, element: &Elemen
// Step 7 exception handling
if let Err(error) = result {
- // TODO: Step 7.1
- // Track custom element state
+ // Step 7.1
+ element.set_custom_element_state(CustomElementState::Failed);
// Step 7.2
element.clear_reaction_queue();
@@ -520,6 +523,10 @@ pub fn upgrade_element(definition: Rc<CustomElementDefinition>, element: &Elemen
return;
}
+ // Step 8
+ element.set_custom_element_state(CustomElementState::Custom);
+
+ // Step 9
element.set_custom_element_definition(definition);
}
diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs
index 270d7d7e020..6aeef3ce986 100644
--- a/components/script/dom/element.rs
+++ b/components/script/dom/element.rs
@@ -150,6 +150,8 @@ pub struct Element {
/// https://dom.spec.whatwg.org/#concept-element-custom-element-definition
#[ignore_heap_size_of = "Rc"]
custom_element_definition: DOMRefCell<Option<Rc<CustomElementDefinition>>>,
+ /// https://dom.spec.whatwg.org/#concept-element-custom-element-state
+ custom_element_state: Cell<CustomElementState>,
}
impl fmt::Debug for Element {
@@ -179,6 +181,15 @@ pub enum CustomElementCreationMode {
Asynchronous,
}
+/// https://dom.spec.whatwg.org/#concept-element-custom-element-state
+#[derive(Clone, Copy, PartialEq, Eq, HeapSizeOf, JSTraceable)]
+pub enum CustomElementState {
+ Undefined,
+ Failed,
+ Uncustomized,
+ Custom,
+}
+
impl ElementCreator {
pub fn is_parser_created(&self) -> bool {
match *self {
@@ -255,6 +266,7 @@ impl Element {
selector_flags: Cell::new(ElementSelectorFlags::empty()),
custom_element_reaction_queue: Default::default(),
custom_element_definition: Default::default(),
+ custom_element_state: Cell::new(CustomElementState::Uncustomized),
}
}
@@ -289,6 +301,14 @@ impl Element {
self.is.borrow().clone()
}
+ pub fn set_custom_element_state(&self, state: CustomElementState) {
+ self.custom_element_state.set(state);
+ }
+
+ pub fn get_custom_element_state(&self) -> CustomElementState {
+ self.custom_element_state.get()
+ }
+
pub fn set_custom_element_definition(&self, definition: Rc<CustomElementDefinition>) {
*self.custom_element_definition.borrow_mut() = Some(definition);
}
diff --git a/tests/unit/script/size_of.rs b/tests/unit/script/size_of.rs
index d6c4a6ad7f8..903ffc5ddc3 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, 424);
-sizeof_checker!(size_htmlelement, HTMLElement, 440);
-sizeof_checker!(size_div, HTMLDivElement, 440);
-sizeof_checker!(size_span, HTMLSpanElement, 440);
+sizeof_checker!(size_element, Element, 432);
+sizeof_checker!(size_htmlelement, HTMLElement, 448);
+sizeof_checker!(size_div, HTMLDivElement, 448);
+sizeof_checker!(size_span, HTMLSpanElement, 448);
sizeof_checker!(size_text, Text, 216);
sizeof_checker!(size_characterdata, CharacterData, 216);
diff --git a/tests/wpt/metadata/custom-elements/upgrading/Node-cloneNode.html.ini b/tests/wpt/metadata/custom-elements/upgrading/Node-cloneNode.html.ini
deleted file mode 100644
index 10ac904ac52..00000000000
--- a/tests/wpt/metadata/custom-elements/upgrading/Node-cloneNode.html.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[Node-cloneNode.html]
- type: testharness
- [Inserting an element must not try to upgrade a custom element when it had already failed to upgrade once]
- expected: FAIL
-