Allow element prefix to be set

Implements step 6.1.10 of
https://dom.spec.whatwg.org/#concept-create-element
This commit is contained in:
Connor Brewster 2017-06-23 14:21:50 -06:00
parent dd9bb0550b
commit 37e8b89377
6 changed files with 26 additions and 17 deletions

View file

@ -130,7 +130,7 @@ fn create_html_element(name: QualName,
CustomElementCreationMode::Asynchronous => {}, CustomElementCreationMode::Asynchronous => {},
CustomElementCreationMode::Synchronous => { CustomElementCreationMode::Synchronous => {
let local_name = name.local.clone(); let local_name = name.local.clone();
return match definition.create_element(document) { return match definition.create_element(document, prefix.clone()) {
Ok(element) => element, Ok(element) => element,
Err(error) => { Err(error) => {
// Step 6. Recovering from exception. // Step 6. Recovering from exception.

View file

@ -24,7 +24,7 @@ use dom::node::Node;
use dom::promise::Promise; use dom::promise::Promise;
use dom::window::Window; use dom::window::Window;
use dom_struct::dom_struct; use dom_struct::dom_struct;
use html5ever::LocalName; use html5ever::{LocalName, Prefix};
use js::conversions::ToJSValConvertible; use js::conversions::ToJSValConvertible;
use js::jsapi::{Construct1, IsConstructor, HandleValueArray, HandleObject}; use js::jsapi::{Construct1, IsConstructor, HandleValueArray, HandleObject};
use js::jsapi::{JS_GetProperty, JSAutoCompartment, JSContext}; use js::jsapi::{JS_GetProperty, JSAutoCompartment, JSContext};
@ -281,7 +281,7 @@ impl CustomElementDefinition {
/// https://dom.spec.whatwg.org/#concept-create-element Step 6.1 /// https://dom.spec.whatwg.org/#concept-create-element Step 6.1
#[allow(unsafe_code)] #[allow(unsafe_code)]
pub fn create_element(&self, document: &Document) -> Fallible<Root<Element>> { pub fn create_element(&self, document: &Document, prefix: Option<Prefix>) -> Fallible<Root<Element>> {
let window = document.window(); let window = document.window();
let cx = window.get_cx(); let cx = window.get_cx();
// Step 2 // Step 2
@ -320,6 +320,9 @@ impl CustomElementDefinition {
return Err(Error::NotSupported); return Err(Error::NotSupported);
} }
// Step 10
element.set_prefix(prefix);
// Step 11 // Step 11
// Element's `is` is None by default // Element's `is` is None by default

View file

@ -126,7 +126,7 @@ pub struct Element {
local_name: LocalName, local_name: LocalName,
tag_name: TagName, tag_name: TagName,
namespace: Namespace, namespace: Namespace,
prefix: Option<Prefix>, prefix: DOMRefCell<Option<Prefix>>,
attrs: DOMRefCell<Vec<JS<Attr>>>, attrs: DOMRefCell<Vec<JS<Attr>>>,
id_attribute: DOMRefCell<Option<Atom>>, id_attribute: DOMRefCell<Option<Atom>>,
is: DOMRefCell<Option<LocalName>>, is: DOMRefCell<Option<LocalName>>,
@ -235,7 +235,7 @@ impl Element {
local_name: local_name, local_name: local_name,
tag_name: TagName::new(), tag_name: TagName::new(),
namespace: namespace, namespace: namespace,
prefix: prefix, prefix: DOMRefCell::new(prefix),
attrs: DOMRefCell::new(vec![]), attrs: DOMRefCell::new(vec![]),
id_attribute: DOMRefCell::new(None), id_attribute: DOMRefCell::new(None),
is: DOMRefCell::new(None), is: DOMRefCell::new(None),
@ -838,8 +838,12 @@ impl Element {
&self.namespace &self.namespace
} }
pub fn prefix(&self) -> Option<&Prefix> { pub fn prefix(&self) -> Ref<Option<Prefix>> {
self.prefix.as_ref() self.prefix.borrow()
}
pub fn set_prefix(&self, prefix: Option<Prefix>) {
*self.prefix.borrow_mut() = prefix;
} }
pub fn attrs(&self) -> Ref<[JS<Attr>]> { pub fn attrs(&self) -> Ref<[JS<Attr>]> {
@ -858,7 +862,9 @@ impl Element {
// Steps 3-4. // Steps 3-4.
for element in inclusive_ancestor_elements { for element in inclusive_ancestor_elements {
// Step 1. // Step 1.
if element.namespace() != &ns!() && element.prefix().map(|p| &**p) == prefix.as_ref().map(|p| &**p) { if element.namespace() != &ns!() &&
element.prefix().as_ref().map(|p| &**p) == prefix.as_ref().map(|p| &**p)
{
return element.namespace().clone(); return element.namespace().clone();
} }
@ -1436,13 +1442,13 @@ impl ElementMethods for Element {
// https://dom.spec.whatwg.org/#dom-element-prefix // https://dom.spec.whatwg.org/#dom-element-prefix
fn GetPrefix(&self) -> Option<DOMString> { fn GetPrefix(&self) -> Option<DOMString> {
self.prefix.as_ref().map(|p| DOMString::from(&**p)) self.prefix.borrow().as_ref().map(|p| DOMString::from(&**p))
} }
// https://dom.spec.whatwg.org/#dom-element-tagname // https://dom.spec.whatwg.org/#dom-element-tagname
fn TagName(&self) -> DOMString { fn TagName(&self) -> DOMString {
let name = self.tag_name.or_init(|| { let name = self.tag_name.or_init(|| {
let qualified_name = match self.prefix { let qualified_name = match *self.prefix.borrow() {
Some(ref prefix) => { Some(ref prefix) => {
Cow::Owned(format!("{}:{}", &**prefix, &*self.local_name)) Cow::Owned(format!("{}:{}", &**prefix, &*self.local_name))
}, },

View file

@ -152,7 +152,7 @@ impl HTMLCollection {
} }
fn match_element(elem: &Element, qualified_name: &LocalName) -> bool { fn match_element(elem: &Element, qualified_name: &LocalName) -> bool {
match elem.prefix() { match elem.prefix().as_ref() {
None => elem.local_name() == qualified_name, None => elem.local_name() == qualified_name,
Some(prefix) => qualified_name.starts_with(&**prefix) && Some(prefix) => qualified_name.starts_with(&**prefix) &&
qualified_name.find(":") == Some(prefix.len()) && qualified_name.find(":") == Some(prefix.len()) &&

View file

@ -1823,7 +1823,7 @@ impl Node {
NodeTypeId::Element(..) => { NodeTypeId::Element(..) => {
let element = node.downcast::<Element>().unwrap(); let element = node.downcast::<Element>().unwrap();
let name = QualName { let name = QualName {
prefix: element.prefix().map(|p| Prefix::from(&**p)), prefix: element.prefix().as_ref().map(|p| Prefix::from(&**p)),
ns: element.namespace().clone(), ns: element.namespace().clone(),
local: element.local_name().clone() local: element.local_name().clone()
}; };
@ -2292,7 +2292,7 @@ impl NodeMethods for Node {
let element = node.downcast::<Element>().unwrap(); let element = node.downcast::<Element>().unwrap();
let other_element = other.downcast::<Element>().unwrap(); let other_element = other.downcast::<Element>().unwrap();
(*element.namespace() == *other_element.namespace()) && (*element.namespace() == *other_element.namespace()) &&
(element.prefix() == other_element.prefix()) && (*element.prefix() == *other_element.prefix()) &&
(*element.local_name() == *other_element.local_name()) && (*element.local_name() == *other_element.local_name()) &&
(element.attrs().len() == other_element.attrs().len()) (element.attrs().len() == other_element.attrs().len())
} }

View file

@ -31,10 +31,10 @@ macro_rules! sizeof_checker (
// Update the sizes here // Update the sizes here
sizeof_checker!(size_event_target, EventTarget, 40); sizeof_checker!(size_event_target, EventTarget, 40);
sizeof_checker!(size_node, Node, 184); sizeof_checker!(size_node, Node, 184);
sizeof_checker!(size_element, Element, 368); sizeof_checker!(size_element, Element, 376);
sizeof_checker!(size_htmlelement, HTMLElement, 384); sizeof_checker!(size_htmlelement, HTMLElement, 392);
sizeof_checker!(size_div, HTMLDivElement, 384); sizeof_checker!(size_div, HTMLDivElement, 392);
sizeof_checker!(size_span, HTMLSpanElement, 384); sizeof_checker!(size_span, HTMLSpanElement, 392);
sizeof_checker!(size_text, Text, 216); sizeof_checker!(size_text, Text, 216);
sizeof_checker!(size_characterdata, CharacterData, 216); sizeof_checker!(size_characterdata, CharacterData, 216);
sizeof_checker!(size_servothreadsafelayoutnode, ServoThreadSafeLayoutNode, 16); sizeof_checker!(size_servothreadsafelayoutnode, ServoThreadSafeLayoutNode, 16);