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