diff options
-rw-r--r-- | components/script/dom/bindings/interface.rs | 8 | ||||
-rw-r--r-- | components/script/dom/create.rs | 22 | ||||
-rw-r--r-- | components/script/dom/customelementregistry.rs | 17 | ||||
-rw-r--r-- | components/script/dom/element.rs | 20 | ||||
-rw-r--r-- | tests/unit/script/size_of.rs | 8 | ||||
-rw-r--r-- | tests/wpt/metadata/custom-elements/upgrading/Node-cloneNode.html.ini | 5 |
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 - |