mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
Auto merge of #7611 - nox:cache-element-id, r=frewsxcv
Cache the `id` attribute on Element Thanks to @asabil for the original work, I only rebased it. Fixes #6359 and #7040. <!-- Reviewable:start --> [<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/7611) <!-- Reviewable:end -->
This commit is contained in:
commit
d1269294e6
6 changed files with 43 additions and 536 deletions
|
@ -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;
|
||||
|
@ -528,6 +531,13 @@ impl LayoutElementHelpers for LayoutJS<Element> {
|
|||
get_attr_for_layout(&*self.unsafe_get(), namespace, name).is_some()
|
||||
}
|
||||
|
||||
#[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 {
|
||||
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue