Skip to content

Commit

Permalink
Enqueue upgrades
Browse files Browse the repository at this point in the history
  • Loading branch information
cbrewster committed Aug 9, 2017
1 parent 4137120 commit 6d9d4ad
Show file tree
Hide file tree
Showing 12 changed files with 43 additions and 103 deletions.
20 changes: 16 additions & 4 deletions components/script/dom/create.rs
Expand Up @@ -5,7 +5,7 @@
use dom::bindings::error::{report_pending_exception, throw_dom_exception};
use dom::bindings::js::Root;
use dom::bindings::reflector::DomObject;
use dom::customelementregistry::is_valid_custom_element_name;
use dom::customelementregistry::{is_valid_custom_element_name, upgrade_element};
use dom::document::Document;
use dom::element::{CustomElementCreationMode, Element, ElementCreator};
use dom::globalscope::GlobalScope;
Expand Down Expand Up @@ -81,6 +81,7 @@ use dom::htmlvideoelement::HTMLVideoElement;
use dom::svgsvgelement::SVGSVGElement;
use html5ever::{LocalName, Prefix, QualName};
use js::jsapi::JSAutoCompartment;
use script_thread::ScriptThread;
use servo_config::prefs::PREFS;

fn create_svg_element(name: QualName,
Expand Down Expand Up @@ -127,8 +128,11 @@ fn create_html_element(name: QualName,
if let Some(definition) = definition {
if definition.is_autonomous() {
match mode {
// TODO: Handle asynchronous CE creation. Relies on CE upgrades.
CustomElementCreationMode::Asynchronous => {},
CustomElementCreationMode::Asynchronous => {
let result = Root::upcast(HTMLElement::new(name.local.clone(), prefix.clone(), document));
ScriptThread::enqueue_upgrade_reaction(&*result, definition);
return result;
},
CustomElementCreationMode::Synchronous => {
let local_name = name.local.clone();
return match definition.create_element(document, prefix.clone()) {
Expand All @@ -155,9 +159,17 @@ fn create_html_element(name: QualName,
},
}
} else {
// Steps 5.1-5.2
let element = create_native_html_element(name, prefix, document, creator);
element.set_is(definition.name.clone());
// TODO: Enqueue custom element upgrade
match mode {
// Step 5.3
CustomElementCreationMode::Synchronous =>
upgrade_element(definition, &*element),
// Step 5.4
CustomElementCreationMode::Asynchronous =>
ScriptThread::enqueue_upgrade_reaction(&*element, definition),
}
return element;
}
}
Expand Down
32 changes: 22 additions & 10 deletions components/script/dom/customelementregistry.rs
Expand Up @@ -9,6 +9,7 @@ use dom::bindings::codegen::Bindings::CustomElementRegistryBinding::CustomElemen
use dom::bindings::codegen::Bindings::CustomElementRegistryBinding::ElementDefinitionOptions;
use dom::bindings::codegen::Bindings::ElementBinding::ElementMethods;
use dom::bindings::codegen::Bindings::FunctionBinding::Function;
use dom::bindings::codegen::Bindings::WindowBinding::WindowBinding::WindowMethods;
use dom::bindings::conversions::{ConversionResult, FromJSValConvertible, StringificationBehavior};
use dom::bindings::error::{Error, ErrorResult, Fallible};
use dom::bindings::inheritance::Castable;
Expand Down Expand Up @@ -281,17 +282,28 @@ impl CustomElementRegistryMethods for CustomElementRegistry {
self.element_definition_is_running.set(false);

// Step 11
let definition = CustomElementDefinition::new(name.clone(),
local_name,
constructor_,
observed_attributes,
callbacks);
let definition = Rc::new(CustomElementDefinition::new(name.clone(),
local_name.clone(),
constructor_,
observed_attributes,
callbacks));

// Step 12
self.definitions.borrow_mut().insert(name.clone(), Rc::new(definition));

// TODO: Step 13, 14, 15
// Handle custom element upgrades
self.definitions.borrow_mut().insert(name.clone(), definition.clone());

// Step 13
let document = self.window.Document();

// Steps 14-15
for candidate in document.upcast::<Node>().traverse_preorder().filter_map(Root::downcast::<Element>) {
let is = candidate.get_is();
if *candidate.local_name() == local_name &&
*candidate.namespace() == ns!(html) &&
(extends.is_none() || is.as_ref() == Some(&name))
{
ScriptThread::enqueue_upgrade_reaction(&*candidate, definition.clone());
}
}

// Step 16, 16.3
if let Some(promise) = self.when_defined.borrow_mut().remove(&name) {
Expand Down Expand Up @@ -464,7 +476,7 @@ impl CustomElementDefinition {

/// https://html.spec.whatwg.org/multipage/#concept-upgrade-an-element
#[allow(unsafe_code)]
fn upgrade_element(definition: Rc<CustomElementDefinition>, element: &Element) {
pub fn upgrade_element(definition: Rc<CustomElementDefinition>, element: &Element) {
// TODO: Steps 1-2
// Track custom element state

Expand Down
9 changes: 5 additions & 4 deletions components/script/dom/node.rs
Expand Up @@ -30,7 +30,7 @@ use dom::bindings::str::{DOMString, USVString};
use dom::bindings::xmlname::namespace_from_domstring;
use dom::characterdata::{CharacterData, LayoutCharacterDataHelpers};
use dom::cssstylesheet::CSSStyleSheet;
use dom::customelementregistry::CallbackReaction;
use dom::customelementregistry::{CallbackReaction, try_upgrade_element};
use dom::document::{Document, DocumentSource, HasBrowsingContext, IsHTMLDocument};
use dom::documentfragment::DocumentFragment;
use dom::documenttype::DocumentType;
Expand Down Expand Up @@ -1639,12 +1639,13 @@ impl Node {
for descendant in kid.traverse_preorder().filter_map(Root::downcast::<Element>) {
// Step 7.7.2.
if descendant.is_connected() {
// Step 7.7.2.1.
if descendant.get_custom_element_definition().is_some() {
// Step 7.7.2.1.
ScriptThread::enqueue_callback_reaction(&*descendant, CallbackReaction::Connected);
} else {
// Step 7.7.2.2.
try_upgrade_element(&*descendant);
}
// TODO: Step 7.7.2.2.
// Try to upgrade descendant.
}
}
}
Expand Down
Expand Up @@ -3,9 +3,6 @@
[HTML parser must not instantiate custom elements inside template elements]
expected: FAIL

[HTML parser must use the registry of the content document inside an iframe]
expected: FAIL

[HTML parser must use the registry of window.document in a document created by document.implementation.createHTMLDocument()]
expected: FAIL

5 changes: 0 additions & 5 deletions tests/wpt/metadata/custom-elements/reaction-timing.html.ini

This file was deleted.

@@ -1,8 +1,5 @@
[Document.html]
type: testharness
[importNode on Document must construct a new custom element when importing a custom element from a template]
expected: FAIL

[execCommand on Document must enqueue a disconnected reaction when deleting a custom element from a contenteditable element]
expected: FAIL

Expand Down
3 changes: 0 additions & 3 deletions tests/wpt/metadata/custom-elements/reactions/Node.html.ini
Expand Up @@ -3,9 +3,6 @@
[cloneNode on Node must enqueue an attributeChanged reaction when cloning an element with an observed attribute]
expected: FAIL

[cloneNode on Node must not enqueue an attributeChanged reaction when cloning an element with an unobserved attribute]
expected: FAIL

[cloneNode on Node must enqueue an attributeChanged reaction when cloning an element only for observed attributes]
expected: FAIL

3 changes: 0 additions & 3 deletions tests/wpt/metadata/custom-elements/reactions/Range.html.ini
Expand Up @@ -3,9 +3,6 @@
[cloneContents on Range must enqueue an attributeChanged reaction when cloning an element with an observed attribute]
expected: FAIL

[cloneContents on Range must not enqueue an attributeChanged reaction when cloning an element with an unobserved attribute]
expected: FAIL

[cloneContents on Range must enqueue an attributeChanged reaction when cloning an element only for observed attributes]
expected: FAIL

Expand Down
50 changes: 0 additions & 50 deletions tests/wpt/metadata/custom-elements/upgrading.html.ini

This file was deleted.

@@ -1,17 +1,5 @@
[Node-cloneNode.html]
type: testharness
[Node.prototype.cloneNode(false) must be able to clone a custom element]
expected: FAIL

[Node.prototype.cloneNode(false) must be able to clone a custom element inside an iframe]
expected: FAIL

[Node.prototype.cloneNode(true) must be able to clone a descendent custom element]
expected: FAIL

[Node.prototype.cloneNode(true) must set parentNode, previousSibling, and nextSibling before upgrading custom elements]
expected: FAIL

[HTMLElement constructor must throw an InvalidStateError when the top of the construction stack is marked AlreadyConstructed due to a custom element constructor constructing itself after super() call]
expected: FAIL

Expand Down
Expand Up @@ -12,6 +12,3 @@
[Upgrading a custom element must enqueue attributeChangedCallback before connectedCallback]
expected: FAIL

[Upgrading a custom element must not invoke attributeChangedCallback and connectedCallback when the element failed to upgrade]
expected: FAIL

@@ -1,8 +1,5 @@
[upgrading-parser-created-element.html]
type: testharness
[Element.prototype.createElement must add an unresolved custom element to the upgrade candidates map]
expected: FAIL

[HTMLElement constructor must throw an InvalidStateError when the top of the construction stack is marked AlreadyConstructed due to a custom element constructor constructing itself after super() call]
expected: FAIL

Expand Down

0 comments on commit 6d9d4ad

Please sign in to comment.