diff options
Diffstat (limited to 'components/script/dom')
-rw-r--r-- | components/script/dom/element.rs | 52 | ||||
-rw-r--r-- | components/script/dom/node.rs | 28 |
2 files changed, 38 insertions, 42 deletions
diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index 8132011a0fe..1944d1d030e 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -70,7 +70,7 @@ use selectors::parser::{AttrSelector, NamespaceConstraint}; use smallvec::VecLike; use std::ascii::AsciiExt; use std::borrow::{Cow, ToOwned}; -use std::cell::{Ref, RefMut}; +use std::cell::Ref; use std::default::Default; use std::mem; use std::sync::Arc; @@ -92,6 +92,7 @@ pub struct Element { namespace: Namespace, prefix: Option<DOMString>, attrs: DOMRefCell<Vec<JS<Attr>>>, + id_attribute: DOMRefCell<Option<Atom>>, style_attribute: DOMRefCell<Option<PropertyDeclarationBlock>>, attr_list: MutNullableHeap<JS<NamedNodeMap>>, class_list: MutNullableHeap<JS<DOMTokenList>>, @@ -146,6 +147,7 @@ impl Element { attrs: DOMRefCell::new(vec!()), attr_list: Default::default(), class_list: Default::default(), + id_attribute: DOMRefCell::new(None), style_attribute: DOMRefCell::new(None), } } @@ -505,6 +507,7 @@ pub trait LayoutElementHelpers { unsafe fn html_element_in_html_document_for_layout(&self) -> bool; #[allow(unsafe_code)] unsafe fn has_attr_for_layout(&self, namespace: &Namespace, name: &Atom) -> bool; + fn id_attribute(&self) -> *const Option<Atom>; fn style_attribute(&self) -> *const Option<PropertyDeclarationBlock>; fn local_name(&self) -> &Atom; fn namespace(&self) -> &Namespace; @@ -529,6 +532,13 @@ impl LayoutElementHelpers for LayoutJS<Element> { } #[allow(unsafe_code)] + fn id_attribute(&self) -> *const Option<Atom> { + unsafe { + (*self.unsafe_get()).id_attribute.borrow_for_layout() + } + } + + #[allow(unsafe_code)] fn style_attribute(&self) -> *const Option<PropertyDeclarationBlock> { unsafe { (*self.unsafe_get()).style_attribute.borrow_for_layout() @@ -610,10 +620,6 @@ impl Element { self.attrs.borrow() } - pub fn attrs_mut(&self) -> RefMut<Vec<JS<Attr>>> { - self.attrs.borrow_mut() - } - pub fn style_attribute(&self) -> &DOMRefCell<Option<PropertyDeclarationBlock>> { &self.style_attribute } @@ -1484,6 +1490,15 @@ impl VirtualMethods for Element { NodeDamage::NodeStyleDamaged }, &atom!(id) => { + *self.id_attribute.borrow_mut() = + mutation.new_value(attr).and_then(|value| { + let value = value.as_atom(); + if value != &atom!("") { + Some(value.clone()) + } else { + None + } + }); if node.is_in_doc() { let value = attr.value().as_atom().clone(); match mutation { @@ -1530,13 +1545,9 @@ impl VirtualMethods for Element { if !tree_in_doc { return; } - if let Some(ref attr) = self.get_attribute(&ns!(""), &atom!("id")) { - let value = attr.value(); - if !value.is_empty() { - let doc = document_from_node(self); - let value = Atom::from_slice(&value); - doc.register_named_element(self, value.to_owned()); - } + if let Some(ref value) = *self.id_attribute.borrow() { + let doc = document_from_node(self); + doc.register_named_element(self, value.clone()); } } @@ -1547,13 +1558,9 @@ impl VirtualMethods for Element { if !tree_in_doc { return; } - if let Some(ref attr) = self.get_attribute(&ns!(""), &atom!("id")) { - let value = attr.value(); - if !value.is_empty() { - let doc = document_from_node(self); - let value = Atom::from_slice(&value); - doc.unregister_named_element(self, value.to_owned()); - } + if let Some(ref value) = *self.id_attribute.borrow() { + let doc = document_from_node(self); + doc.unregister_named_element(self, value.clone()); } } } @@ -1639,12 +1646,7 @@ impl<'a> ::selectors::Element for Root<Element> { node.get_focus_state() } fn get_id(&self) -> Option<Atom> { - self.get_attribute(&ns!(""), &atom!("id")).map(|attr| { - match *attr.r().value() { - AttrValue::Atom(ref val) => val.clone(), - _ => panic!("`id` attribute should be AttrValue::Atom"), - } - }) + self.id_attribute.borrow().clone() } fn get_disabled_state(&self) -> bool { let node = NodeCast::from_ref(&**self); diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index c93c5bbe65b..a63b0c2959e 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -811,18 +811,17 @@ impl Node { Err(()) => Err(Syntax), // Step 3. Ok(ref selectors) => { - let root = self.ancestors().last(); - let root = root.r().unwrap_or(self.clone()); - Ok(root.traverse_preorder().filter_map(ElementCast::to_root).find(|element| { + Ok(self.traverse_preorder().filter_map(ElementCast::to_root).find(|element| { matches(selectors, element, None) })) } } } + /// https://dom.spec.whatwg.org/#scope-match-a-selectors-string /// Get an iterator over all nodes which match a set of selectors - /// Be careful not to do anything which may manipulate the DOM tree whilst iterating, otherwise - /// the iterator may be invalidated + /// Be careful not to do anything which may manipulate the DOM tree + /// whilst iterating, otherwise the iterator may be invalidated. #[allow(unsafe_code)] pub unsafe fn query_selector_iter(&self, selectors: DOMString) -> Fallible<QuerySelectorIterator> { @@ -832,9 +831,7 @@ impl Node { Err(()) => Err(Syntax), // Step 3. Ok(selectors) => { - let root = self.ancestors().last(); - let root = root.r().unwrap_or(self); - Ok(QuerySelectorIterator::new(root.traverse_preorder(), selectors)) + Ok(QuerySelectorIterator::new(self.traverse_preorder(), selectors)) } } } @@ -1767,15 +1764,12 @@ impl Node { let node_elem = ElementCast::to_ref(node).unwrap(); let copy_elem = ElementCast::to_ref(copy.r()).unwrap(); - let window = document.r().window(); - for ref attr in &*node_elem.attrs() { - let attr = attr.root(); - let newattr = - Attr::new(window.r(), - attr.r().local_name().clone(), attr.r().value().clone(), - attr.r().name().clone(), attr.r().namespace().clone(), - attr.r().prefix().clone(), Some(copy_elem)); - copy_elem.attrs_mut().push(JS::from_rooted(&newattr)); + for attr in node_elem.attrs().iter().map(JS::root) { + copy_elem.push_new_attribute(attr.local_name().clone(), + attr.value().clone(), + attr.name().clone(), + attr.namespace().clone(), + attr.prefix().clone()); } }, _ => () |