aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/script/dom/create.rs14
-rw-r--r--components/script/dom/document.rs19
-rw-r--r--components/script/dom/domimplementation.rs5
-rw-r--r--components/script/dom/element.rs17
-rw-r--r--components/script/dom/node.rs2
-rw-r--r--components/script/dom/servoparser/async_html.rs10
-rw-r--r--components/script/dom/servoparser/mod.rs8
-rw-r--r--components/script/dom/webidls/Document.webidl8
-rw-r--r--tests/unit/script/size_of.rs8
9 files changed, 66 insertions, 25 deletions
diff --git a/components/script/dom/create.rs b/components/script/dom/create.rs
index 52410a487b8..bcf7a551cf7 100644
--- a/components/script/dom/create.rs
+++ b/components/script/dom/create.rs
@@ -79,7 +79,7 @@ use dom::htmlulistelement::HTMLUListElement;
use dom::htmlunknownelement::HTMLUnknownElement;
use dom::htmlvideoelement::HTMLVideoElement;
use dom::svgsvgelement::SVGSVGElement;
-use html5ever::{QualName, Prefix};
+use html5ever::{LocalName, Prefix, QualName};
use js::jsapi::JSAutoCompartment;
use servo_config::prefs::PREFS;
@@ -114,16 +114,16 @@ fn create_svg_element(name: QualName,
#[allow(unsafe_code)]
fn create_html_element(name: QualName,
prefix: Option<Prefix>,
+ is: Option<LocalName>,
document: &Document,
creator: ElementCreator)
-> Root<Element> {
assert!(name.ns == ns!(html));
// Step 4
- let definition = document.lookup_custom_element_definition(name.local.clone(), None);
+ let definition = document.lookup_custom_element_definition(name.local.clone(), is);
if let Some(definition) = definition {
- // TODO: Handle customized built-in elements. Relies on CE upgrades.
if definition.is_autonomous() {
let local_name = name.local.clone();
return match definition.create_element(document) {
@@ -143,6 +143,11 @@ fn create_html_element(name: QualName,
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());
+ // TODO: Enqueue custom element upgrade
+ return element;
}
}
@@ -316,12 +321,13 @@ pub fn create_native_html_element(name: QualName,
}
pub fn create_element(name: QualName,
+ is: Option<LocalName>,
document: &Document,
creator: ElementCreator)
-> Root<Element> {
let prefix = name.prefix.clone();
match name.ns {
- ns!(html) => create_html_element(name, prefix, document, creator),
+ ns!(html) => create_html_element(name, prefix, is, document, creator),
ns!(svg) => create_svg_element(name, prefix, document),
_ => Element::new(name.local, name.ns, prefix, document)
}
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs
index a61421e7866..74189c13bbd 100644
--- a/components/script/dom/document.rs
+++ b/components/script/dom/document.rs
@@ -13,7 +13,7 @@ use dom::bindings::callback::ExceptionHandling;
use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::DOMRectBinding::DOMRectMethods;
use dom::bindings::codegen::Bindings::DocumentBinding;
-use dom::bindings::codegen::Bindings::DocumentBinding::{DocumentMethods, DocumentReadyState};
+use dom::bindings::codegen::Bindings::DocumentBinding::{DocumentMethods, DocumentReadyState, ElementCreationOptions};
use dom::bindings::codegen::Bindings::ElementBinding::ElementMethods;
use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
use dom::bindings::codegen::Bindings::EventHandlerBinding::OnErrorEventHandlerNonNull;
@@ -2834,7 +2834,10 @@ impl DocumentMethods for Document {
}
// https://dom.spec.whatwg.org/#dom-document-createelement
- fn CreateElement(&self, mut local_name: DOMString) -> Fallible<Root<Element>> {
+ fn CreateElement(&self,
+ mut local_name: DOMString,
+ options: &ElementCreationOptions)
+ -> Fallible<Root<Element>> {
if xml_name_type(&local_name) == InvalidXMLName {
debug!("Not a valid element name");
return Err(Error::InvalidCharacter);
@@ -2850,18 +2853,21 @@ impl DocumentMethods for Document {
};
let name = QualName::new(None, ns, LocalName::from(local_name));
- Ok(Element::create(name, self, ElementCreator::ScriptCreated))
+ let is = options.is.as_ref().map(|is| LocalName::from(&**is));
+ Ok(Element::create(name, is, self, ElementCreator::ScriptCreated))
}
// https://dom.spec.whatwg.org/#dom-document-createelementns
fn CreateElementNS(&self,
namespace: Option<DOMString>,
- qualified_name: DOMString)
+ qualified_name: DOMString,
+ options: &ElementCreationOptions)
-> Fallible<Root<Element>> {
let (namespace, prefix, local_name) = validate_and_extract(namespace,
&qualified_name)?;
let name = QualName::new(prefix, namespace, local_name);
- Ok(Element::create(name, self, ElementCreator::ScriptCreated))
+ let is = options.is.as_ref().map(|is| LocalName::from(&**is));
+ Ok(Element::create(name, is, self, ElementCreator::ScriptCreated))
}
// https://dom.spec.whatwg.org/#dom-document-createattribute
@@ -3115,7 +3121,7 @@ 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, self, ElementCreator::ScriptCreated);
+ let elem = Element::create(name, None, self, ElementCreator::ScriptCreated);
let parent = root.upcast::<Node>();
let child = elem.upcast::<Node>();
parent.InsertBefore(child, parent.GetFirstChild().r())
@@ -3133,6 +3139,7 @@ impl DocumentMethods for Document {
Some(head) => {
let name = QualName::new(None, ns!(html), local_name!("title"));
let elem = Element::create(name,
+ None,
self,
ElementCreator::ScriptCreated);
head.upcast::<Node>()
diff --git a/components/script/dom/domimplementation.rs b/components/script/dom/domimplementation.rs
index 8c1bee4f334..5b56242e14b 100644
--- a/components/script/dom/domimplementation.rs
+++ b/components/script/dom/domimplementation.rs
@@ -5,7 +5,7 @@
use document_loader::DocumentLoader;
use dom::bindings::codegen::Bindings::DOMImplementationBinding;
use dom::bindings::codegen::Bindings::DOMImplementationBinding::DOMImplementationMethods;
-use dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods;
+use dom::bindings::codegen::Bindings::DocumentBinding::{DocumentMethods, ElementCreationOptions};
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
use dom::bindings::error::Fallible;
use dom::bindings::inheritance::Castable;
@@ -92,7 +92,8 @@ impl DOMImplementationMethods for DOMImplementation {
let maybe_elem = if qname.is_empty() {
None
} else {
- match doc.upcast::<Document>().CreateElementNS(maybe_namespace, qname) {
+ let options = ElementCreationOptions { is: None };
+ match doc.upcast::<Document>().CreateElementNS(maybe_namespace, qname, &options) {
Err(error) => return Err(error),
Ok(elem) => Some(elem),
}
diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs
index 2c7372ebddf..858f17c002b 100644
--- a/components/script/dom/element.rs
+++ b/components/script/dom/element.rs
@@ -129,6 +129,7 @@ pub struct Element {
prefix: Option<Prefix>,
attrs: DOMRefCell<Vec<JS<Attr>>>,
id_attribute: DOMRefCell<Option<Atom>>,
+ is: DOMRefCell<Option<LocalName>>,
#[ignore_heap_size_of = "Arc"]
style_attribute: DOMRefCell<Option<Arc<Locked<PropertyDeclarationBlock>>>>,
attr_list: MutNullableJS<NamedNodeMap>,
@@ -205,9 +206,11 @@ impl<'a> TryFrom<&'a str> for AdjacentPosition {
//
impl Element {
pub fn create(name: QualName,
- document: &Document, creator: ElementCreator)
+ is: Option<LocalName>,
+ document: &Document,
+ creator: ElementCreator)
-> Root<Element> {
- create_element(name, document, creator)
+ create_element(name, is, document, creator)
}
pub fn new_inherited(local_name: LocalName,
@@ -229,6 +232,7 @@ impl Element {
prefix: prefix,
attrs: DOMRefCell::new(vec![]),
id_attribute: DOMRefCell::new(None),
+ is: DOMRefCell::new(None),
style_attribute: DOMRefCell::new(None),
attr_list: Default::default(),
class_list: Default::default(),
@@ -260,6 +264,14 @@ impl Element {
}
}
+ pub fn set_is(&self, is: LocalName) {
+ *self.is.borrow_mut() = Some(is);
+ }
+
+ pub fn get_is(&self) -> Option<LocalName> {
+ self.is.borrow().clone()
+ }
+
// https://drafts.csswg.org/cssom-view/#css-layout-box
// Elements that have a computed value of the display property
// that is table-column or table-column-group
@@ -1970,6 +1982,7 @@ impl ElementMethods for Element {
// Step 4.
NodeTypeId::DocumentFragment => {
let body_elem = Element::create(QualName::new(None, ns!(html), local_name!("body")),
+ None,
&context_document,
ElementCreator::ScriptCreated);
Root::upcast(body_elem)
diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs
index f09001625d0..ec4573f7960 100644
--- a/components/script/dom/node.rs
+++ b/components/script/dom/node.rs
@@ -1827,7 +1827,7 @@ impl Node {
ns: element.namespace().clone(),
local: element.local_name().clone()
};
- let element = Element::create(name,
+ let element = Element::create(name, element.get_is(),
&document, ElementCreator::ScriptCreated);
Root::upcast::<Node>(element)
},
diff --git a/components/script/dom/servoparser/async_html.rs b/components/script/dom/servoparser/async_html.rs
index e1632ffaf3c..899229be8f8 100644
--- a/components/script/dom/servoparser/async_html.rs
+++ b/components/script/dom/servoparser/async_html.rs
@@ -20,7 +20,7 @@ use dom::htmltemplateelement::HTMLTemplateElement;
use dom::node::Node;
use dom::processinginstruction::ProcessingInstruction;
use dom::virtualmethods::vtable_for;
-use html5ever::{Attribute, QualName, ExpandedName};
+use html5ever::{Attribute, LocalName, QualName, ExpandedName};
use html5ever::buffer_queue::BufferQueue;
use html5ever::tendril::StrTendril;
use html5ever::tokenizer::{Tokenizer as HtmlTokenizer, TokenizerOpts, TokenizerResult};
@@ -245,7 +245,13 @@ impl Sink {
self.insert_node(contents, JS::from_ref(template.Content().upcast()));
}
ParseOperation::CreateElement(id, name, attrs) => {
- let elem = Element::create(name, &*self.document,
+ let is = attrs.iter()
+ .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));
for attr in attrs {
elem.set_attribute_from_parser(attr.name, DOMString::from(String::from(attr.value)), None);
diff --git a/components/script/dom/servoparser/mod.rs b/components/script/dom/servoparser/mod.rs
index 6d6edb6d7a8..8e003e44040 100644
--- a/components/script/dom/servoparser/mod.rs
+++ b/components/script/dom/servoparser/mod.rs
@@ -29,7 +29,7 @@ use dom::processinginstruction::ProcessingInstruction;
use dom::text::Text;
use dom::virtualmethods::vtable_for;
use dom_struct::dom_struct;
-use html5ever::{Attribute, QualName, ExpandedName};
+use html5ever::{Attribute, ExpandedName, LocalName, QualName};
use html5ever::buffer_queue::BufferQueue;
use html5ever::tendril::{StrTendril, ByteTendril, IncompleteUtf8};
use html5ever::tree_builder::{NodeOrText, TreeSink, NextParserState, QuirksMode, ElementFlags};
@@ -782,7 +782,11 @@ impl TreeSink for Sink {
fn create_element(&mut self, name: QualName, attrs: Vec<Attribute>, _flags: ElementFlags)
-> JS<Node> {
- let elem = Element::create(name, &*self.document,
+ let is = attrs.iter()
+ .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));
for attr in attrs {
diff --git a/components/script/dom/webidls/Document.webidl b/components/script/dom/webidls/Document.webidl
index e3c67851011..457d92394d2 100644
--- a/components/script/dom/webidls/Document.webidl
+++ b/components/script/dom/webidls/Document.webidl
@@ -33,9 +33,9 @@ interface Document : Node {
HTMLCollection getElementsByClassName(DOMString classNames);
[NewObject, Throws]
- Element createElement(DOMString localName);
+ Element createElement(DOMString localName, optional ElementCreationOptions options);
[NewObject, Throws]
- Element createElementNS(DOMString? namespace, DOMString qualifiedName);
+ Element createElementNS(DOMString? namespace, DOMString qualifiedName, optional ElementCreationOptions options);
[NewObject]
DocumentFragment createDocumentFragment();
[NewObject]
@@ -75,6 +75,10 @@ Document implements ParentNode;
enum DocumentReadyState { "loading", "interactive", "complete" };
+dictionary ElementCreationOptions {
+ DOMString is;
+};
+
// https://html.spec.whatwg.org/multipage/#the-document-object
// [OverrideBuiltins]
partial /*sealed*/ interface Document {
diff --git a/tests/unit/script/size_of.rs b/tests/unit/script/size_of.rs
index c7c04b4aac1..b357f4605a3 100644
--- a/tests/unit/script/size_of.rs
+++ b/tests/unit/script/size_of.rs
@@ -31,10 +31,10 @@ 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, 344);
-sizeof_checker!(size_htmlelement, HTMLElement, 360);
-sizeof_checker!(size_div, HTMLDivElement, 360);
-sizeof_checker!(size_span, HTMLSpanElement, 360);
+sizeof_checker!(size_element, Element, 368);
+sizeof_checker!(size_htmlelement, HTMLElement, 384);
+sizeof_checker!(size_div, HTMLDivElement, 384);
+sizeof_checker!(size_span, HTMLSpanElement, 384);
sizeof_checker!(size_text, Text, 216);
sizeof_checker!(size_characterdata, CharacterData, 216);
sizeof_checker!(size_servothreadsafelayoutnode, ServoThreadSafeLayoutNode, 16);