Skip to content

Commit

Permalink
Track custom element state
Browse files Browse the repository at this point in the history
  • Loading branch information
cbrewster committed Aug 1, 2017
1 parent 141b81a commit 6b065b2
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 21 deletions.
8 changes: 5 additions & 3 deletions components/script/dom/bindings/interface.rs
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down
22 changes: 18 additions & 4 deletions components/script/dom/create.rs
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
},
Expand All @@ -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
},
};
},
Expand All @@ -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 =>
Expand All @@ -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,
Expand Down
17 changes: 12 additions & 5 deletions components/script/dom/customelementregistry.rs
Expand Up @@ -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};
Expand Down Expand Up @@ -483,8 +483,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() {
Expand All @@ -510,8 +513,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();
Expand All @@ -526,6 +529,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);
}

Expand Down
18 changes: 18 additions & 0 deletions components/script/dom/element.rs
Expand Up @@ -150,6 +150,7 @@ 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>>>,
custom_element_state: Cell<CustomElementState>,
}

impl fmt::Debug for Element {
Expand Down Expand Up @@ -179,6 +180,14 @@ pub enum CustomElementCreationMode {
Asynchronous,
}

#[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 {
Expand Down Expand Up @@ -255,6 +264,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),
}
}

Expand Down Expand Up @@ -289,6 +299,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);
}
Expand Down
8 changes: 4 additions & 4 deletions tests/unit/script/size_of.rs
Expand Up @@ -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);

This file was deleted.

0 comments on commit 6b065b2

Please sign in to comment.