mirror of
https://github.com/servo/servo.git
synced 2025-07-22 14:53:49 +01:00
Track custom element state
This commit is contained in:
parent
e700006fb2
commit
9f51c7df21
6 changed files with 59 additions and 21 deletions
|
@ -81,7 +81,7 @@ use dom::bindings::js::Root;
|
||||||
use dom::bindings::utils::{DOM_PROTOTYPE_SLOT, ProtoOrIfaceArray, get_proto_or_iface_array};
|
use dom::bindings::utils::{DOM_PROTOTYPE_SLOT, ProtoOrIfaceArray, get_proto_or_iface_array};
|
||||||
use dom::create::create_native_html_element;
|
use dom::create::create_native_html_element;
|
||||||
use dom::customelementregistry::ConstructionStackEntry;
|
use dom::customelementregistry::ConstructionStackEntry;
|
||||||
use dom::element::{Element, ElementCreator};
|
use dom::element::{CustomElementState, Element, ElementCreator};
|
||||||
use dom::htmlelement::HTMLElement;
|
use dom::htmlelement::HTMLElement;
|
||||||
use dom::window::Window;
|
use dom::window::Window;
|
||||||
use html5ever::LocalName;
|
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.
|
// Step 8.2 is performed in the generated caller code.
|
||||||
|
|
||||||
// TODO: Step 8.3 - 8.4
|
// Step 8.3
|
||||||
// Set the element's custom element state and definition.
|
element.set_custom_element_state(CustomElementState::Custom);
|
||||||
|
|
||||||
|
// Step 8.4
|
||||||
element.set_custom_element_definition(definition.clone());
|
element.set_custom_element_definition(definition.clone());
|
||||||
|
|
||||||
// Step 8.5
|
// Step 8.5
|
||||||
|
|
|
@ -7,7 +7,7 @@ use dom::bindings::js::Root;
|
||||||
use dom::bindings::reflector::DomObject;
|
use dom::bindings::reflector::DomObject;
|
||||||
use dom::customelementregistry::{is_valid_custom_element_name, upgrade_element};
|
use dom::customelementregistry::{is_valid_custom_element_name, upgrade_element};
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::element::{CustomElementCreationMode, Element, ElementCreator};
|
use dom::element::{CustomElementCreationMode, CustomElementState, Element, ElementCreator};
|
||||||
use dom::globalscope::GlobalScope;
|
use dom::globalscope::GlobalScope;
|
||||||
use dom::htmlanchorelement::HTMLAnchorElement;
|
use dom::htmlanchorelement::HTMLAnchorElement;
|
||||||
use dom::htmlappletelement::HTMLAppletElement;
|
use dom::htmlappletelement::HTMLAppletElement;
|
||||||
|
@ -129,7 +129,9 @@ fn create_html_element(name: QualName,
|
||||||
if definition.is_autonomous() {
|
if definition.is_autonomous() {
|
||||||
match mode {
|
match mode {
|
||||||
CustomElementCreationMode::Asynchronous => {
|
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);
|
ScriptThread::enqueue_upgrade_reaction(&*result, definition);
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
@ -153,7 +155,10 @@ fn create_html_element(name: QualName,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 6.1.2
|
// 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
|
// Steps 5.1-5.2
|
||||||
let element = create_native_html_element(name, prefix, document, creator);
|
let element = create_native_html_element(name, prefix, document, creator);
|
||||||
element.set_is(definition.name.clone());
|
element.set_is(definition.name.clone());
|
||||||
|
element.set_custom_element_state(CustomElementState::Undefined);
|
||||||
match mode {
|
match mode {
|
||||||
// Step 5.3
|
// Step 5.3
|
||||||
CustomElementCreationMode::Synchronous =>
|
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,
|
pub fn create_native_html_element(name: QualName,
|
||||||
|
|
|
@ -18,7 +18,7 @@ use dom::bindings::reflector::{DomObject, Reflector, reflect_dom_object};
|
||||||
use dom::bindings::str::DOMString;
|
use dom::bindings::str::DOMString;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::domexception::{DOMErrorName, DOMException};
|
use dom::domexception::{DOMErrorName, DOMException};
|
||||||
use dom::element::Element;
|
use dom::element::{CustomElementState, Element};
|
||||||
use dom::globalscope::GlobalScope;
|
use dom::globalscope::GlobalScope;
|
||||||
use dom::htmlelement::HTMLElement;
|
use dom::htmlelement::HTMLElement;
|
||||||
use dom::node::{document_from_node, Node, window_from_node};
|
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
|
/// https://html.spec.whatwg.org/multipage/#concept-upgrade-an-element
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
pub fn upgrade_element(definition: Rc<CustomElementDefinition>, element: &Element) {
|
pub fn upgrade_element(definition: Rc<CustomElementDefinition>, element: &Element) {
|
||||||
// TODO: Steps 1-2
|
// Steps 1-2
|
||||||
// Track custom element state
|
let state = element.get_custom_element_state();
|
||||||
|
if state == CustomElementState::Custom || state == CustomElementState::Failed {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Step 3
|
// Step 3
|
||||||
for attr in element.attrs().iter() {
|
for attr in element.attrs().iter() {
|
||||||
|
@ -504,8 +507,8 @@ pub fn upgrade_element(definition: Rc<CustomElementDefinition>, element: &Elemen
|
||||||
|
|
||||||
// Step 7 exception handling
|
// Step 7 exception handling
|
||||||
if let Err(error) = result {
|
if let Err(error) = result {
|
||||||
// TODO: Step 7.1
|
// Step 7.1
|
||||||
// Track custom element state
|
element.set_custom_element_state(CustomElementState::Failed);
|
||||||
|
|
||||||
// Step 7.2
|
// Step 7.2
|
||||||
element.clear_reaction_queue();
|
element.clear_reaction_queue();
|
||||||
|
@ -520,6 +523,10 @@ pub fn upgrade_element(definition: Rc<CustomElementDefinition>, element: &Elemen
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Step 8
|
||||||
|
element.set_custom_element_state(CustomElementState::Custom);
|
||||||
|
|
||||||
|
// Step 9
|
||||||
element.set_custom_element_definition(definition);
|
element.set_custom_element_definition(definition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -150,6 +150,8 @@ pub struct Element {
|
||||||
/// https://dom.spec.whatwg.org/#concept-element-custom-element-definition
|
/// https://dom.spec.whatwg.org/#concept-element-custom-element-definition
|
||||||
#[ignore_heap_size_of = "Rc"]
|
#[ignore_heap_size_of = "Rc"]
|
||||||
custom_element_definition: DOMRefCell<Option<Rc<CustomElementDefinition>>>,
|
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 {
|
impl fmt::Debug for Element {
|
||||||
|
@ -179,6 +181,15 @@ pub enum CustomElementCreationMode {
|
||||||
Asynchronous,
|
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 {
|
impl ElementCreator {
|
||||||
pub fn is_parser_created(&self) -> bool {
|
pub fn is_parser_created(&self) -> bool {
|
||||||
match *self {
|
match *self {
|
||||||
|
@ -255,6 +266,7 @@ impl Element {
|
||||||
selector_flags: Cell::new(ElementSelectorFlags::empty()),
|
selector_flags: Cell::new(ElementSelectorFlags::empty()),
|
||||||
custom_element_reaction_queue: Default::default(),
|
custom_element_reaction_queue: Default::default(),
|
||||||
custom_element_definition: Default::default(),
|
custom_element_definition: Default::default(),
|
||||||
|
custom_element_state: Cell::new(CustomElementState::Uncustomized),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,6 +301,14 @@ impl Element {
|
||||||
self.is.borrow().clone()
|
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>) {
|
pub fn set_custom_element_definition(&self, definition: Rc<CustomElementDefinition>) {
|
||||||
*self.custom_element_definition.borrow_mut() = Some(definition);
|
*self.custom_element_definition.borrow_mut() = Some(definition);
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,9 +31,9 @@ macro_rules! sizeof_checker (
|
||||||
// Update the sizes here
|
// Update the sizes here
|
||||||
sizeof_checker!(size_event_target, EventTarget, 40);
|
sizeof_checker!(size_event_target, EventTarget, 40);
|
||||||
sizeof_checker!(size_node, Node, 184);
|
sizeof_checker!(size_node, Node, 184);
|
||||||
sizeof_checker!(size_element, Element, 424);
|
sizeof_checker!(size_element, Element, 432);
|
||||||
sizeof_checker!(size_htmlelement, HTMLElement, 440);
|
sizeof_checker!(size_htmlelement, HTMLElement, 448);
|
||||||
sizeof_checker!(size_div, HTMLDivElement, 440);
|
sizeof_checker!(size_div, HTMLDivElement, 448);
|
||||||
sizeof_checker!(size_span, HTMLSpanElement, 440);
|
sizeof_checker!(size_span, HTMLSpanElement, 448);
|
||||||
sizeof_checker!(size_text, Text, 216);
|
sizeof_checker!(size_text, Text, 216);
|
||||||
sizeof_checker!(size_characterdata, CharacterData, 216);
|
sizeof_checker!(size_characterdata, CharacterData, 216);
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue