mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
Compute tag_name a maximum of once per document owner
This commit is contained in:
parent
939e0a5f89
commit
1ca4a3e32f
2 changed files with 63 additions and 15 deletions
|
@ -103,6 +103,7 @@ use style::values::specified::{self, CSSColor, CSSRGBA, LengthOrPercentage};
|
||||||
pub struct Element {
|
pub struct Element {
|
||||||
node: Node,
|
node: Node,
|
||||||
local_name: Atom,
|
local_name: Atom,
|
||||||
|
tag_name: TagName,
|
||||||
namespace: Namespace,
|
namespace: Namespace,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
attrs: DOMRefCell<Vec<JS<Attr>>>,
|
attrs: DOMRefCell<Vec<JS<Attr>>>,
|
||||||
|
@ -165,6 +166,7 @@ impl Element {
|
||||||
Element {
|
Element {
|
||||||
node: Node::new_inherited(document),
|
node: Node::new_inherited(document),
|
||||||
local_name: local_name,
|
local_name: local_name,
|
||||||
|
tag_name: TagName::new(),
|
||||||
namespace: namespace,
|
namespace: namespace,
|
||||||
prefix: prefix,
|
prefix: prefix,
|
||||||
attrs: DOMRefCell::new(vec![]),
|
attrs: DOMRefCell::new(vec![]),
|
||||||
|
@ -1367,17 +1369,20 @@ impl ElementMethods for Element {
|
||||||
|
|
||||||
// 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 qualified_name = match self.prefix {
|
let name = self.tag_name.or_init(|| {
|
||||||
Some(ref prefix) => {
|
let qualified_name = match self.prefix {
|
||||||
Cow::Owned(format!("{}:{}", &**prefix, &*self.local_name))
|
Some(ref prefix) => {
|
||||||
},
|
Cow::Owned(format!("{}:{}", &**prefix, &*self.local_name))
|
||||||
None => Cow::Borrowed(&*self.local_name)
|
},
|
||||||
};
|
None => Cow::Borrowed(&*self.local_name)
|
||||||
DOMString::from(if self.html_element_in_html_document() {
|
};
|
||||||
qualified_name.to_ascii_uppercase()
|
if self.html_element_in_html_document() {
|
||||||
} else {
|
Atom::from(qualified_name.to_ascii_uppercase())
|
||||||
qualified_name.into_owned()
|
} else {
|
||||||
})
|
Atom::from(qualified_name)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
DOMString::from(&*name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#dom-element-id
|
// https://dom.spec.whatwg.org/#dom-element-id
|
||||||
|
@ -2219,6 +2224,14 @@ impl VirtualMethods for Element {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn adopting_steps(&self, old_doc: &Document) {
|
||||||
|
self.super_type().unwrap().adopting_steps(old_doc);
|
||||||
|
|
||||||
|
if document_from_node(self).is_html_document() != old_doc.is_html_document() {
|
||||||
|
self.tag_name.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ::selectors::MatchAttrGeneric for Root<Element> {
|
impl<'a> ::selectors::MatchAttrGeneric for Root<Element> {
|
||||||
|
@ -2691,3 +2704,38 @@ impl AtomicElementFlags {
|
||||||
self.0.fetch_or(flags.bits() as usize, Ordering::Relaxed);
|
self.0.fetch_or(flags.bits() as usize, Ordering::Relaxed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A holder for an element's "tag name", which will be lazily
|
||||||
|
/// resolved and cached. Should be reset when the document
|
||||||
|
/// owner changes.
|
||||||
|
#[derive(JSTraceable, HeapSizeOf)]
|
||||||
|
struct TagName {
|
||||||
|
ptr: DOMRefCell<Option<Atom>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TagName {
|
||||||
|
fn new() -> TagName {
|
||||||
|
TagName { ptr: DOMRefCell::new(None) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Retrieve a copy of the current inner value. If it is `None`, it is
|
||||||
|
/// initialized with the result of `cb` first.
|
||||||
|
fn or_init<F>(&self, cb: F) -> Atom
|
||||||
|
where F: FnOnce() -> Atom
|
||||||
|
{
|
||||||
|
match &mut *self.ptr.borrow_mut() {
|
||||||
|
&mut Some(ref name) => name.clone(),
|
||||||
|
ptr => {
|
||||||
|
let name = cb();
|
||||||
|
*ptr = Some(name.clone());
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Clear the cached tag name, so that it will be re-calculated the
|
||||||
|
/// next time that `or_init()` is called.
|
||||||
|
fn clear(&self) {
|
||||||
|
*self.ptr.borrow_mut() = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -40,10 +40,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, 160);
|
sizeof_checker!(size_node, Node, 160);
|
||||||
sizeof_checker!(size_element, Element, 312);
|
sizeof_checker!(size_element, Element, 336);
|
||||||
sizeof_checker!(size_htmlelement, HTMLElement, 328);
|
sizeof_checker!(size_htmlelement, HTMLElement, 352);
|
||||||
sizeof_checker!(size_div, HTMLDivElement, 328);
|
sizeof_checker!(size_div, HTMLDivElement, 352);
|
||||||
sizeof_checker!(size_span, HTMLSpanElement, 328);
|
sizeof_checker!(size_span, HTMLSpanElement, 352);
|
||||||
sizeof_checker!(size_text, Text, 192);
|
sizeof_checker!(size_text, Text, 192);
|
||||||
sizeof_checker!(size_characterdata, CharacterData, 192);
|
sizeof_checker!(size_characterdata, CharacterData, 192);
|
||||||
sizeof_checker!(size_servothreadsafelayoutnode, ServoThreadSafeLayoutNode, 16);
|
sizeof_checker!(size_servothreadsafelayoutnode, ServoThreadSafeLayoutNode, 16);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue