Merge pull request #3090 from brunoabinader/document-cached-live-htmlcollections

Implement cache for remaining Document live collections; r=Ms2ger
This commit is contained in:
Ms2ger 2014-08-23 13:28:17 +02:00
commit 782deca569

View file

@ -78,7 +78,13 @@ pub struct Document {
pub is_html_document: bool, pub is_html_document: bool,
url: Untraceable<Url>, url: Untraceable<Url>,
quirks_mode: Untraceable<Cell<QuirksMode>>, quirks_mode: Untraceable<Cell<QuirksMode>>,
images: Cell<Option<JS<HTMLCollection>>>,
embeds: Cell<Option<JS<HTMLCollection>>>,
links: Cell<Option<JS<HTMLCollection>>>, links: Cell<Option<JS<HTMLCollection>>>,
forms: Cell<Option<JS<HTMLCollection>>>,
scripts: Cell<Option<JS<HTMLCollection>>>,
anchors: Cell<Option<JS<HTMLCollection>>>,
applets: Cell<Option<JS<HTMLCollection>>>,
} }
impl DocumentDerived for EventTarget { impl DocumentDerived for EventTarget {
@ -87,6 +93,20 @@ impl DocumentDerived for EventTarget {
} }
} }
struct ImagesFilter;
impl CollectionFilter for ImagesFilter {
fn filter(&self, elem: &JSRef<Element>, _root: &JSRef<Node>) -> bool {
elem.is_htmlimageelement()
}
}
struct EmbedsFilter;
impl CollectionFilter for EmbedsFilter {
fn filter(&self, elem: &JSRef<Element>, _root: &JSRef<Node>) -> bool {
elem.is_htmlembedelement()
}
}
struct LinksFilter; struct LinksFilter;
impl CollectionFilter for LinksFilter { impl CollectionFilter for LinksFilter {
fn filter(&self, elem: &JSRef<Element>, _root: &JSRef<Node>) -> bool { fn filter(&self, elem: &JSRef<Element>, _root: &JSRef<Node>) -> bool {
@ -94,6 +114,34 @@ impl CollectionFilter for LinksFilter {
} }
} }
struct FormsFilter;
impl CollectionFilter for FormsFilter {
fn filter(&self, elem: &JSRef<Element>, _root: &JSRef<Node>) -> bool {
elem.is_htmlformelement()
}
}
struct ScriptsFilter;
impl CollectionFilter for ScriptsFilter {
fn filter(&self, elem: &JSRef<Element>, _root: &JSRef<Node>) -> bool {
elem.is_htmlscriptelement()
}
}
struct AnchorsFilter;
impl CollectionFilter for AnchorsFilter {
fn filter(&self, elem: &JSRef<Element>, _root: &JSRef<Node>) -> bool {
elem.is_htmlanchorelement() && elem.has_attribute("href")
}
}
struct AppletsFilter;
impl CollectionFilter for AppletsFilter {
fn filter(&self, elem: &JSRef<Element>, _root: &JSRef<Node>) -> bool {
elem.is_htmlappletelement()
}
}
pub trait DocumentHelpers { pub trait DocumentHelpers {
fn url<'a>(&'a self) -> &'a Url; fn url<'a>(&'a self) -> &'a Url;
fn quirks_mode(&self) -> QuirksMode; fn quirks_mode(&self) -> QuirksMode;
@ -236,7 +284,13 @@ impl Document {
// http://dom.spec.whatwg.org/#concept-document-encoding // http://dom.spec.whatwg.org/#concept-document-encoding
encoding_name: Traceable::new(RefCell::new("utf-8".to_string())), encoding_name: Traceable::new(RefCell::new("utf-8".to_string())),
is_html_document: is_html_document == HTMLDocument, is_html_document: is_html_document == HTMLDocument,
images: Cell::new(None),
embeds: Cell::new(None),
links: Cell::new(None), links: Cell::new(None),
forms: Cell::new(None),
scripts: Cell::new(None),
anchors: Cell::new(None),
applets: Cell::new(None),
} }
} }
@ -665,27 +719,23 @@ impl<'a> DocumentMethods for JSRef<'a, Document> {
} }
fn Images(&self) -> Temporary<HTMLCollection> { fn Images(&self) -> Temporary<HTMLCollection> {
let window = self.window.root(); if self.images.get().is_none() {
struct ImagesFilter; let window = self.window.root();
impl CollectionFilter for ImagesFilter { let root = NodeCast::from_ref(self);
fn filter(&self, elem: &JSRef<Element>, _root: &JSRef<Node>) -> bool { let filter = box ImagesFilter;
elem.is_htmlimageelement() self.images.assign(Some(HTMLCollection::create(&*window, root, filter)));
}
} }
let filter = box ImagesFilter; Temporary::new(self.images.get().get_ref().clone())
HTMLCollection::create(&*window, NodeCast::from_ref(self), filter)
} }
fn Embeds(&self) -> Temporary<HTMLCollection> { fn Embeds(&self) -> Temporary<HTMLCollection> {
let window = self.window.root(); if self.embeds.get().is_none() {
struct EmbedsFilter; let window = self.window.root();
impl CollectionFilter for EmbedsFilter { let root = NodeCast::from_ref(self);
fn filter(&self, elem: &JSRef<Element>, _root: &JSRef<Node>) -> bool { let filter = box EmbedsFilter;
elem.is_htmlembedelement() self.embeds.assign(Some(HTMLCollection::create(&*window, root, filter)));
}
} }
let filter = box EmbedsFilter; Temporary::new(self.embeds.get().get_ref().clone())
HTMLCollection::create(&*window, NodeCast::from_ref(self), filter)
} }
fn Plugins(&self) -> Temporary<HTMLCollection> { fn Plugins(&self) -> Temporary<HTMLCollection> {
@ -703,53 +753,44 @@ impl<'a> DocumentMethods for JSRef<'a, Document> {
} }
fn Forms(&self) -> Temporary<HTMLCollection> { fn Forms(&self) -> Temporary<HTMLCollection> {
let window = self.window.root(); if self.forms.get().is_none() {
struct FormsFilter; let window = self.window.root();
impl CollectionFilter for FormsFilter { let root = NodeCast::from_ref(self);
fn filter(&self, elem: &JSRef<Element>, _root: &JSRef<Node>) -> bool { let filter = box FormsFilter;
elem.is_htmlformelement() self.forms.assign(Some(HTMLCollection::create(&*window, root, filter)));
}
} }
let filter = box FormsFilter; Temporary::new(self.forms.get().get_ref().clone())
HTMLCollection::create(&*window, NodeCast::from_ref(self), filter)
} }
fn Scripts(&self) -> Temporary<HTMLCollection> { fn Scripts(&self) -> Temporary<HTMLCollection> {
let window = self.window.root(); if self.scripts.get().is_none() {
struct ScriptsFilter; let window = self.window.root();
impl CollectionFilter for ScriptsFilter { let root = NodeCast::from_ref(self);
fn filter(&self, elem: &JSRef<Element>, _root: &JSRef<Node>) -> bool { let filter = box ScriptsFilter;
elem.is_htmlscriptelement() self.scripts.assign(Some(HTMLCollection::create(&*window, root, filter)));
}
} }
let filter = box ScriptsFilter; Temporary::new(self.scripts.get().get_ref().clone())
HTMLCollection::create(&*window, NodeCast::from_ref(self), filter)
} }
fn Anchors(&self) -> Temporary<HTMLCollection> { fn Anchors(&self) -> Temporary<HTMLCollection> {
let window = self.window.root(); if self.anchors.get().is_none() {
struct AnchorsFilter; let window = self.window.root();
impl CollectionFilter for AnchorsFilter { let root = NodeCast::from_ref(self);
fn filter(&self, elem: &JSRef<Element>, _root: &JSRef<Node>) -> bool { let filter = box AnchorsFilter;
elem.is_htmlanchorelement() && elem.get_attribute(Null, "name").is_some() self.anchors.assign(Some(HTMLCollection::create(&*window, root, filter)));
}
} }
let filter = box AnchorsFilter; Temporary::new(self.anchors.get().get_ref().clone())
HTMLCollection::create(&*window, NodeCast::from_ref(self), filter)
} }
fn Applets(&self) -> Temporary<HTMLCollection> { fn Applets(&self) -> Temporary<HTMLCollection> {
let window = self.window.root();
// FIXME: This should be return OBJECT elements containing applets. // FIXME: This should be return OBJECT elements containing applets.
struct AppletsFilter; if self.applets.get().is_none() {
impl CollectionFilter for AppletsFilter { let window = self.window.root();
fn filter(&self, elem: &JSRef<Element>, _root: &JSRef<Node>) -> bool { let root = NodeCast::from_ref(self);
elem.is_htmlappletelement() let filter = box AppletsFilter;
} self.applets.assign(Some(HTMLCollection::create(&*window, root, filter)));
} }
let filter = box AppletsFilter; Temporary::new(self.applets.get().get_ref().clone())
HTMLCollection::create(&*window, NodeCast::from_ref(self), filter)
} }
fn Location(&self) -> Temporary<Location> { fn Location(&self) -> Temporary<Location> {