mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Add flag for sync/async CE creation
This commit is contained in:
parent
2f36d3544f
commit
062b128688
9 changed files with 78 additions and 35 deletions
|
@ -6,8 +6,7 @@ use dom::bindings::error::{report_pending_exception, throw_dom_exception};
|
|||
use dom::bindings::js::Root;
|
||||
use dom::bindings::reflector::DomObject;
|
||||
use dom::document::Document;
|
||||
use dom::element::Element;
|
||||
use dom::element::ElementCreator;
|
||||
use dom::element::{CustomElementCreationMode, Element, ElementCreator};
|
||||
use dom::globalscope::GlobalScope;
|
||||
use dom::htmlanchorelement::HTMLAnchorElement;
|
||||
use dom::htmlappletelement::HTMLAppletElement;
|
||||
|
@ -116,7 +115,8 @@ fn create_html_element(name: QualName,
|
|||
prefix: Option<Prefix>,
|
||||
is: Option<LocalName>,
|
||||
document: &Document,
|
||||
creator: ElementCreator)
|
||||
creator: ElementCreator,
|
||||
mode: CustomElementCreationMode)
|
||||
-> Root<Element> {
|
||||
assert!(name.ns == ns!(html));
|
||||
|
||||
|
@ -125,24 +125,31 @@ fn create_html_element(name: QualName,
|
|||
|
||||
if let Some(definition) = definition {
|
||||
if definition.is_autonomous() {
|
||||
let local_name = name.local.clone();
|
||||
return match definition.create_element(document) {
|
||||
Ok(element) => element,
|
||||
Err(error) => {
|
||||
// Step 6. Recovering from exception.
|
||||
let global = GlobalScope::current().unwrap_or_else(|| document.global());
|
||||
match mode {
|
||||
// TODO: Handle asynchronous CE creation. Relies on CE upgrades.
|
||||
CustomElementCreationMode::Asynchronous => {},
|
||||
CustomElementCreationMode::Synchronous => {
|
||||
let local_name = name.local.clone();
|
||||
return match definition.create_element(document) {
|
||||
Ok(element) => element,
|
||||
Err(error) => {
|
||||
// Step 6. Recovering from exception.
|
||||
let global = GlobalScope::current().unwrap_or_else(|| document.global());
|
||||
let cx = global.get_cx();
|
||||
|
||||
// Step 6.1.1
|
||||
unsafe {
|
||||
let _ac = JSAutoCompartment::new(global.get_cx(), global.reflector().get_jsobject().get());
|
||||
throw_dom_exception(global.get_cx(), &global, error);
|
||||
report_pending_exception(global.get_cx(), true);
|
||||
}
|
||||
// Step 6.1.1
|
||||
unsafe {
|
||||
let _ac = JSAutoCompartment::new(cx, global.reflector().get_jsobject().get());
|
||||
throw_dom_exception(cx, &global, error);
|
||||
report_pending_exception(cx, true);
|
||||
}
|
||||
|
||||
// Step 6.1.2
|
||||
Root::upcast(HTMLUnknownElement::new(local_name, prefix, document))
|
||||
// Step 6.1.2
|
||||
Root::upcast(HTMLUnknownElement::new(local_name, prefix, document))
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
} else {
|
||||
let element = create_native_html_element(name, prefix, document, creator);
|
||||
element.set_is(definition.name.clone());
|
||||
|
@ -323,11 +330,12 @@ pub fn create_native_html_element(name: QualName,
|
|||
pub fn create_element(name: QualName,
|
||||
is: Option<LocalName>,
|
||||
document: &Document,
|
||||
creator: ElementCreator)
|
||||
creator: ElementCreator,
|
||||
mode: CustomElementCreationMode)
|
||||
-> Root<Element> {
|
||||
let prefix = name.prefix.clone();
|
||||
match name.ns {
|
||||
ns!(html) => create_html_element(name, prefix, is, document, creator),
|
||||
ns!(html) => create_html_element(name, prefix, is, document, creator, mode),
|
||||
ns!(svg) => create_svg_element(name, prefix, document),
|
||||
_ => Element::new(name.local, name.ns, prefix, document)
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@ use dom::documentfragment::DocumentFragment;
|
|||
use dom::documenttype::DocumentType;
|
||||
use dom::domimplementation::DOMImplementation;
|
||||
use dom::element::{Element, ElementCreator, ElementPerformFullscreenEnter, ElementPerformFullscreenExit};
|
||||
use dom::element::CustomElementCreationMode;
|
||||
use dom::errorevent::ErrorEvent;
|
||||
use dom::event::{Event, EventBubbles, EventCancelable, EventDefault, EventStatus};
|
||||
use dom::eventtarget::EventTarget;
|
||||
|
@ -2854,7 +2855,7 @@ impl DocumentMethods for Document {
|
|||
|
||||
let name = QualName::new(None, ns, LocalName::from(local_name));
|
||||
let is = options.is.as_ref().map(|is| LocalName::from(&**is));
|
||||
Ok(Element::create(name, is, self, ElementCreator::ScriptCreated))
|
||||
Ok(Element::create(name, is, self, ElementCreator::ScriptCreated, CustomElementCreationMode::Synchronous))
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-document-createelementns
|
||||
|
@ -2867,7 +2868,7 @@ impl DocumentMethods for Document {
|
|||
&qualified_name)?;
|
||||
let name = QualName::new(prefix, namespace, local_name);
|
||||
let is = options.is.as_ref().map(|is| LocalName::from(&**is));
|
||||
Ok(Element::create(name, is, self, ElementCreator::ScriptCreated))
|
||||
Ok(Element::create(name, is, self, ElementCreator::ScriptCreated, CustomElementCreationMode::Synchronous))
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-document-createattribute
|
||||
|
@ -3121,7 +3122,11 @@ impl DocumentMethods for Document {
|
|||
Some(elem) => Root::upcast::<Node>(elem),
|
||||
None => {
|
||||
let name = QualName::new(None, ns!(svg), local_name!("title"));
|
||||
let elem = Element::create(name, None, self, ElementCreator::ScriptCreated);
|
||||
let elem = Element::create(name,
|
||||
None,
|
||||
self,
|
||||
ElementCreator::ScriptCreated,
|
||||
CustomElementCreationMode::Synchronous);
|
||||
let parent = root.upcast::<Node>();
|
||||
let child = elem.upcast::<Node>();
|
||||
parent.InsertBefore(child, parent.GetFirstChild().r())
|
||||
|
@ -3141,7 +3146,8 @@ impl DocumentMethods for Document {
|
|||
let elem = Element::create(name,
|
||||
None,
|
||||
self,
|
||||
ElementCreator::ScriptCreated);
|
||||
ElementCreator::ScriptCreated,
|
||||
CustomElementCreationMode::Synchronous);
|
||||
head.upcast::<Node>()
|
||||
.AppendChild(elem.upcast())
|
||||
.unwrap()
|
||||
|
|
|
@ -165,6 +165,11 @@ pub enum ElementCreator {
|
|||
ScriptCreated,
|
||||
}
|
||||
|
||||
pub enum CustomElementCreationMode {
|
||||
Synchronous,
|
||||
Asynchronous,
|
||||
}
|
||||
|
||||
impl ElementCreator {
|
||||
pub fn is_parser_created(&self) -> bool {
|
||||
match *self {
|
||||
|
@ -208,9 +213,10 @@ impl Element {
|
|||
pub fn create(name: QualName,
|
||||
is: Option<LocalName>,
|
||||
document: &Document,
|
||||
creator: ElementCreator)
|
||||
creator: ElementCreator,
|
||||
mode: CustomElementCreationMode)
|
||||
-> Root<Element> {
|
||||
create_element(name, is, document, creator)
|
||||
create_element(name, is, document, creator, mode)
|
||||
}
|
||||
|
||||
pub fn new_inherited(local_name: LocalName,
|
||||
|
@ -1984,7 +1990,8 @@ impl ElementMethods for Element {
|
|||
let body_elem = Element::create(QualName::new(None, ns!(html), local_name!("body")),
|
||||
None,
|
||||
&context_document,
|
||||
ElementCreator::ScriptCreated);
|
||||
ElementCreator::ScriptCreated,
|
||||
CustomElementCreationMode::Synchronous);
|
||||
Root::upcast(body_elem)
|
||||
},
|
||||
_ => context_node.GetParentElement().unwrap()
|
||||
|
|
|
@ -33,7 +33,7 @@ use dom::cssstylesheet::CSSStyleSheet;
|
|||
use dom::document::{Document, DocumentSource, HasBrowsingContext, IsHTMLDocument};
|
||||
use dom::documentfragment::DocumentFragment;
|
||||
use dom::documenttype::DocumentType;
|
||||
use dom::element::{Element, ElementCreator};
|
||||
use dom::element::{CustomElementCreationMode, Element, ElementCreator};
|
||||
use dom::eventtarget::EventTarget;
|
||||
use dom::globalscope::GlobalScope;
|
||||
use dom::htmlbodyelement::HTMLBodyElement;
|
||||
|
@ -1827,8 +1827,11 @@ impl Node {
|
|||
ns: element.namespace().clone(),
|
||||
local: element.local_name().clone()
|
||||
};
|
||||
let element = Element::create(name, element.get_is(),
|
||||
&document, ElementCreator::ScriptCreated);
|
||||
let element = Element::create(name,
|
||||
element.get_is(),
|
||||
&document,
|
||||
ElementCreator::ScriptCreated,
|
||||
CustomElementCreationMode::Asynchronous);
|
||||
Root::upcast::<Node>(element)
|
||||
},
|
||||
};
|
||||
|
|
|
@ -13,7 +13,7 @@ use dom::bindings::trace::JSTraceable;
|
|||
use dom::comment::Comment;
|
||||
use dom::document::Document;
|
||||
use dom::documenttype::DocumentType;
|
||||
use dom::element::{Element, ElementCreator};
|
||||
use dom::element::{CustomElementCreationMode, Element, ElementCreator};
|
||||
use dom::htmlformelement::{FormControlElementHelpers, HTMLFormElement};
|
||||
use dom::htmlscriptelement::HTMLScriptElement;
|
||||
use dom::htmltemplateelement::HTMLTemplateElement;
|
||||
|
@ -252,7 +252,8 @@ impl Sink {
|
|||
let elem = Element::create(name,
|
||||
is,
|
||||
&*self.document,
|
||||
ElementCreator::ParserCreated(self.current_line));
|
||||
ElementCreator::ParserCreated(self.current_line),
|
||||
CustomElementCreationMode::Synchronous);
|
||||
for attr in attrs {
|
||||
elem.set_attribute_from_parser(attr.name, DOMString::from(String::from(attr.value)), None);
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ use dom::characterdata::CharacterData;
|
|||
use dom::comment::Comment;
|
||||
use dom::document::{Document, DocumentSource, HasBrowsingContext, IsHTMLDocument};
|
||||
use dom::documenttype::DocumentType;
|
||||
use dom::element::{Element, ElementCreator};
|
||||
use dom::element::{Element, ElementCreator, CustomElementCreationMode};
|
||||
use dom::globalscope::GlobalScope;
|
||||
use dom::htmlformelement::{FormControlElementHelpers, HTMLFormElement};
|
||||
use dom::htmlimageelement::HTMLImageElement;
|
||||
|
@ -786,8 +786,11 @@ impl TreeSink for Sink {
|
|||
.find(|attr| attr.name.local.eq_str_ignore_ascii_case("is"))
|
||||
.map(|attr| LocalName::from(&*attr.value));
|
||||
|
||||
let elem = Element::create(name, is, &*self.document,
|
||||
ElementCreator::ParserCreated(self.current_line));
|
||||
let elem = Element::create(name,
|
||||
is,
|
||||
&*self.document,
|
||||
ElementCreator::ParserCreated(self.current_line),
|
||||
CustomElementCreationMode::Synchronous);
|
||||
|
||||
for attr in attrs {
|
||||
elem.set_attribute_from_parser(attr.name, DOMString::from(String::from(attr.value)), None);
|
||||
|
|
|
@ -6,3 +6,6 @@
|
|||
[Custom Elements: Custom element reactions must be invoked before returning to author scripts]
|
||||
expected: FAIL
|
||||
|
||||
[Calling Node.prototype.cloneNode(false) must push a new element queue to the processing stack]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -30,3 +30,6 @@
|
|||
[writeln on Document must enqueue connectedCallback after constructing a custom element]
|
||||
expected: FAIL
|
||||
|
||||
[importNode on Document must construct a new custom element when importing a custom element from a template]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -15,3 +15,12 @@
|
|||
[Inserting an element must not try to upgrade a custom element when it had already failed to upgrade once]
|
||||
expected: FAIL
|
||||
|
||||
[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
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue