mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00: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::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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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