diff options
author | Ms2ger <ms2ger@gmail.com> | 2014-03-14 12:00:42 +0100 |
---|---|---|
committer | Ms2ger <ms2ger@gmail.com> | 2014-03-20 19:42:42 +0100 |
commit | 038a195eade5476601a183f4b74e669f8619d6a4 (patch) | |
tree | 1f956099ff9997778b5d1992dd9e15a8ba325d91 /src/components/script/dom | |
parent | 0265fb9784baff3ea025198f3e5e73e6b81fe18e (diff) | |
download | servo-038a195eade5476601a183f4b74e669f8619d6a4.tar.gz servo-038a195eade5476601a183f4b74e669f8619d6a4.zip |
Move attributes-related functions onto JS<Element>.
Diffstat (limited to 'src/components/script/dom')
-rw-r--r-- | src/components/script/dom/bindings/codegen/Bindings.conf | 6 | ||||
-rw-r--r-- | src/components/script/dom/document.rs | 8 | ||||
-rw-r--r-- | src/components/script/dom/element.rs | 294 | ||||
-rw-r--r-- | src/components/script/dom/htmlcollection.rs | 5 | ||||
-rw-r--r-- | src/components/script/dom/htmliframeelement.rs | 71 | ||||
-rw-r--r-- | src/components/script/dom/htmlimageelement.rs | 48 | ||||
-rw-r--r-- | src/components/script/dom/htmlobjectelement.rs | 36 | ||||
-rw-r--r-- | src/components/script/dom/htmlscriptelement.rs | 10 |
8 files changed, 256 insertions, 222 deletions
diff --git a/src/components/script/dom/bindings/codegen/Bindings.conf b/src/components/script/dom/bindings/codegen/Bindings.conf index eac06e8454d..afcf4319ba3 100644 --- a/src/components/script/dom/bindings/codegen/Bindings.conf +++ b/src/components/script/dom/bindings/codegen/Bindings.conf @@ -53,11 +53,15 @@ DOMInterfaces = { 'needsAbstract': [ 'attributes', 'className', + 'getAttribute', + 'getAttributeNS', 'getBoundingClientRect', 'getClientRects', 'getElementsByClassName', 'getElementsByTagName', 'getElementsByTagNameNS', + 'hasAttribute', + 'hasAttributeNS', 'id', 'innerHTML', 'outerHTML', @@ -179,7 +183,7 @@ addHTMLElement('HTMLParamElement') addHTMLElement('HTMLPreElement') addHTMLElement('HTMLProgressElement') addHTMLElement('HTMLQuoteElement') -addHTMLElement('HTMLScriptElement') +addHTMLElement('HTMLScriptElement', needsAbstract=['src']) addHTMLElement('HTMLSelectElement') addHTMLElement('HTMLSourceElement') addHTMLElement('HTMLSpanElement') diff --git a/src/components/script/dom/document.rs b/src/components/script/dom/document.rs index 0a25b29aa2b..622263458d8 100644 --- a/src/components/script/dom/document.rs +++ b/src/components/script/dom/document.rs @@ -15,7 +15,7 @@ use dom::comment::Comment; use dom::documentfragment::DocumentFragment; use dom::documenttype::DocumentType; use dom::domimplementation::DOMImplementation; -use dom::element::{Element}; +use dom::element::{Element, AttributeHandlers}; use dom::element::{HTMLHtmlElementTypeId, HTMLHeadElementTypeId, HTMLTitleElementTypeId}; use dom::element::{HTMLBodyElementTypeId, HTMLFrameSetElementTypeId}; use dom::event::Event; @@ -435,7 +435,7 @@ impl Document { } let element: JS<Element> = ElementCast::to(node).unwrap(); - element.get().get_attribute(Null, "name").map_or(false, |attr| { + element.get_attribute(Null, "name").map_or(false, |attr| { attr.get().value_ref() == name }) }) @@ -460,7 +460,7 @@ impl Document { // FIXME: https://github.com/mozilla/servo/issues/1847 HTMLCollection::create(&self.window, &NodeCast::from(abstract_self), |elem| { ("a" == elem.get().tag_name || "area" == elem.get().tag_name) && - elem.get().get_attribute(Null, "href").is_some() + elem.get_attribute(Null, "href").is_some() }) } @@ -477,7 +477,7 @@ impl Document { pub fn Anchors(&self, abstract_self: &JS<Document>) -> JS<HTMLCollection> { // FIXME: https://github.com/mozilla/servo/issues/1847 HTMLCollection::create(&self.window, &NodeCast::from(abstract_self), |elem| { - "a" == elem.get().tag_name && elem.get().get_attribute(Null, "name").is_some() + "a" == elem.get().tag_name && elem.get_attribute(Null, "name").is_some() }) } diff --git a/src/components/script/dom/element.rs b/src/components/script/dom/element.rs index 166da8cc9d2..41336698143 100644 --- a/src/components/script/dom/element.rs +++ b/src/components/script/dom/element.rs @@ -155,7 +155,9 @@ impl Element { self.namespace == namespace::HTML && self.node.owner_doc().get().is_html_document } +} +impl Element { pub unsafe fn html_element_in_html_document_for_layout(&self) -> bool { if self.namespace != namespace::HTML { return false @@ -167,15 +169,6 @@ impl Element { (**owner_doc).is_html_document } - pub fn get_attribute(&self, - namespace: Namespace, - name: &str) -> Option<JS<Attr>> { - self.attrs.iter().find(|attr| { - let attr = attr.get(); - name == attr.local_name && attr.namespace == namespace - }).map(|x| x.clone()) - } - #[inline] pub unsafe fn get_attr_val_for_layout(&self, namespace: &Namespace, name: &str) -> Option<&'static str> { @@ -189,17 +182,48 @@ impl Element { cast::transmute((**attr).value.as_slice()) }) } +} + +pub trait AttributeHandlers { + fn get_attribute(&self, namespace: Namespace, name: &str) -> Option<JS<Attr>>; + fn set_attr(&mut self, name: DOMString, value: DOMString) -> ErrorResult; + fn set_attribute(&mut self, namespace: Namespace, name: DOMString, + value: DOMString) -> ErrorResult; + fn after_set_attr(&mut self, local_name: DOMString, value: DOMString); + fn remove_attribute(&mut self, namespace: Namespace, name: DOMString) -> ErrorResult; + fn before_remove_attr(&mut self, local_name: DOMString, old_value: DOMString); + fn notify_attribute_changed(&self, local_name: DOMString); + fn has_class(&self, name: &str) -> bool; + + // http://www.whatwg.org/html/#reflecting-content-attributes-in-idl-attributes + fn get_url_attribute(&self, name: &str) -> DOMString; + fn set_url_attribute(&mut self, name: &str, value: DOMString); + fn get_string_attribute(&self, name: &str) -> DOMString; + fn set_string_attribute(&mut self, name: &str, value: DOMString); +} + +pub trait AfterSetAttrListener { + fn AfterSetAttr(&mut self, name: DOMString, value: DOMString); +} + +pub trait BeforeRemoveAttrListener { + fn BeforeRemoveAttr(&mut self, name: DOMString); +} + +impl AttributeHandlers for JS<Element> { + fn get_attribute(&self, namespace: Namespace, name: &str) -> Option<JS<Attr>> { + self.get().attrs.iter().find(|attr| { + let attr = attr.get(); + name == attr.local_name && attr.namespace == namespace + }).map(|x| x.clone()) + } - pub fn set_attr(&mut self, abstract_self: &JS<Element>, name: DOMString, value: DOMString) - -> ErrorResult { - self.set_attribute(abstract_self, namespace::Null, name, value) + fn set_attr(&mut self, name: DOMString, value: DOMString) -> ErrorResult { + self.set_attribute(namespace::Null, name, value) } - pub fn set_attribute(&mut self, - abstract_self: &JS<Element>, - namespace: Namespace, - name: DOMString, - value: DOMString) -> ErrorResult { + fn set_attribute(&mut self, namespace: Namespace, name: DOMString, + value: DOMString) -> ErrorResult { let (prefix, local_name) = get_attribute_parts(name.clone()); match prefix { Some(ref prefix_str) => { @@ -212,92 +236,84 @@ impl Element { None => {} } - self.node.wait_until_safe_to_modify_dom(); + let node: JS<Node> = NodeCast::from(self); + node.get().wait_until_safe_to_modify_dom(); // FIXME: reduce the time of `value.clone()`. - let idx = self.attrs.iter().position(|attr| { + let idx = self.get().attrs.iter().position(|attr| { attr.get().local_name == local_name }); match idx { Some(idx) => { if namespace == namespace::Null { - let old_value = self.attrs[idx].get().Value(); - self.before_remove_attr(abstract_self, local_name.clone(), - old_value); + let old_value = self.get().attrs[idx].get().Value(); + self.before_remove_attr(local_name.clone(), old_value); } - self.attrs[idx].get_mut().set_value(value.clone()); + self.get_mut().attrs[idx].get_mut().set_value(value.clone()); } None => { - let doc = self.node.owner_doc(); - let doc = doc.get(); + let node: JS<Node> = NodeCast::from(self); + let doc = node.get().owner_doc().get(); let new_attr = Attr::new_ns(&doc.window, local_name.clone(), value.clone(), name.clone(), namespace.clone(), prefix); - self.attrs.push(new_attr); + self.get_mut().attrs.push(new_attr); } } if namespace == namespace::Null { - self.after_set_attr(abstract_self, local_name, value); + self.after_set_attr(local_name, value); } Ok(()) } - fn after_set_attr(&mut self, - abstract_self: &JS<Element>, - local_name: DOMString, - value: DOMString) { - + fn after_set_attr(&mut self, local_name: DOMString, value: DOMString) { + let node: JS<Node> = NodeCast::from(self); match local_name.as_slice() { "style" => { - let doc = self.node.owner_doc(); + let doc = node.get().owner_doc(); let base_url = doc.get().url().clone(); - self.style_attribute = Some(style::parse_style_attribute(value, &base_url)) + self.get_mut().style_attribute = Some(style::parse_style_attribute(value, &base_url)) } - "id" => { - let self_node: JS<Node> = NodeCast::from(abstract_self); - if self_node.is_in_doc() { - // XXX: this dual declaration are workaround to avoid the compile error: - // "borrowed value does not live long enough" - let mut doc = self.node.owner_doc().clone(); - let doc = doc.get_mut(); - doc.register_named_element(abstract_self, value.clone()); - } + "id" if node.is_in_doc() => { + // XXX: this dual declaration are workaround to avoid the compile error: + // "borrowed value does not live long enough" + let mut doc = node.get().owner_doc().clone(); + let doc = doc.get_mut(); + doc.register_named_element(self, value.clone()); } _ => () } //XXXjdm We really need something like a vtable so we can call AfterSetAttr. // This hardcoding is awful. - match abstract_self.get().node.type_id { + match node.type_id() { ElementNodeTypeId(HTMLImageElementTypeId) => { - let mut elem: JS<HTMLImageElement> = HTMLImageElementCast::to(abstract_self).unwrap(); - elem.get_mut().AfterSetAttr(local_name.clone(), value.clone()); + let mut elem: JS<HTMLImageElement> = HTMLImageElementCast::to(self).unwrap(); + elem.AfterSetAttr(local_name.clone(), value.clone()); } ElementNodeTypeId(HTMLIFrameElementTypeId) => { - let mut elem: JS<HTMLIFrameElement> = HTMLIFrameElementCast::to(abstract_self).unwrap(); - elem.get_mut().AfterSetAttr(local_name.clone(), value.clone()); + let mut elem: JS<HTMLIFrameElement> = HTMLIFrameElementCast::to(self).unwrap(); + elem.AfterSetAttr(local_name.clone(), value.clone()); } ElementNodeTypeId(HTMLObjectElementTypeId) => { - let mut elem: JS<HTMLObjectElement> = HTMLObjectElementCast::to(abstract_self).unwrap(); - elem.get_mut().AfterSetAttr(local_name.clone(), value.clone()); + let mut elem: JS<HTMLObjectElement> = HTMLObjectElementCast::to(self).unwrap(); + elem.AfterSetAttr(local_name.clone(), value.clone()); } _ => () } - self.notify_attribute_changed(abstract_self, local_name); + self.notify_attribute_changed(local_name); } - pub fn remove_attribute(&mut self, - abstract_self: &JS<Element>, - namespace: Namespace, - name: DOMString) -> ErrorResult { + fn remove_attribute(&mut self, namespace: Namespace, name: DOMString) -> ErrorResult { let (_, local_name) = get_attribute_parts(name.clone()); - self.node.wait_until_safe_to_modify_dom(); + let node: JS<Node> = NodeCast::from(self); + node.get().wait_until_safe_to_modify_dom(); - let idx = self.attrs.iter().position(|attr: &JS<Attr>| -> bool { + let idx = self.get().attrs.iter().position(|attr| { attr.get().local_name == local_name }); @@ -305,112 +321,102 @@ impl Element { None => (), Some(idx) => { if namespace == namespace::Null { - let removed_raw_value = self.attrs[idx].get().Value(); - self.before_remove_attr(abstract_self, local_name, removed_raw_value); + let removed_raw_value = self.get().attrs[idx].get().Value(); + self.before_remove_attr(local_name, removed_raw_value); } - self.attrs.remove(idx); + self.get_mut().attrs.remove(idx); } }; Ok(()) } - fn before_remove_attr(&mut self, - abstract_self: &JS<Element>, - local_name: DOMString, - old_value: DOMString) { + fn before_remove_attr(&mut self, local_name: DOMString, old_value: DOMString) { + let node: JS<Node> = NodeCast::from(self); match local_name.as_slice() { "style" => { - self.style_attribute = None + self.get_mut().style_attribute = None } - "id" => { - let self_node: JS<Node> = NodeCast::from(abstract_self); - if self_node.is_in_doc() { - // XXX: this dual declaration are workaround to avoid the compile error: - // "borrowed value does not live long enough" - let mut doc = self.node.owner_doc().clone(); - let doc = doc.get_mut(); - doc.unregister_named_element(old_value); - } + "id" if node.is_in_doc() => { + // XXX: this dual declaration are workaround to avoid the compile error: + // "borrowed value does not live long enough" + let mut doc = node.get().owner_doc().clone(); + let doc = doc.get_mut(); + doc.unregister_named_element(old_value); } _ => () } - //XXXjdm We really need something like a vtable so we can call AfterSetAttr. + //XXXjdm We really need something like a vtable so we can call BeforeRemoveAttr. // This hardcoding is awful. - match abstract_self.get().node.type_id { + match node.type_id() { ElementNodeTypeId(HTMLImageElementTypeId) => { - let mut elem: JS<HTMLImageElement> = HTMLImageElementCast::to(abstract_self).unwrap(); - elem.get_mut().BeforeRemoveAttr(local_name.clone()); + let mut elem: JS<HTMLImageElement> = HTMLImageElementCast::to(self).unwrap(); + elem.BeforeRemoveAttr(local_name.clone()); } ElementNodeTypeId(HTMLIFrameElementTypeId) => { - let mut elem: JS<HTMLIFrameElement> = HTMLIFrameElementCast::to(abstract_self).unwrap(); - elem.get_mut().BeforeRemoveAttr(local_name.clone()); + let mut elem: JS<HTMLIFrameElement> = HTMLIFrameElementCast::to(self).unwrap(); + elem.BeforeRemoveAttr(local_name.clone()); } _ => () } - self.notify_attribute_changed(abstract_self, local_name); + self.notify_attribute_changed(local_name); } - fn notify_attribute_changed(&self, - abstract_self: &JS<Element>, - local_name: DOMString) { - let node: JS<Node> = NodeCast::from(abstract_self); + fn notify_attribute_changed(&self, local_name: DOMString) { + let node: JS<Node> = NodeCast::from(self); if node.is_in_doc() { let damage = match local_name.as_slice() { "style" | "id" | "class" => MatchSelectorsDocumentDamage, _ => ContentChangedDocumentDamage }; - let document = self.node.owner_doc(); + let document = node.get().owner_doc(); document.get().damage_and_reflow(damage); } } - pub fn is_void(&self) -> bool { - if self.namespace != namespace::HTML { - return false - } - match self.tag_name.as_slice() { - /* List of void elements from - http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#html-fragment-serialization-algorithm */ - "area" | "base" | "basefont" | "bgsound" | "br" | "col" | "embed" | - "frame" | "hr" | "img" | "input" | "keygen" | "link" | "menuitem" | - "meta" | "param" | "source" | "track" | "wbr" => true, - _ => false - } - } - - pub fn has_class(&self, name: &str) -> bool { + fn has_class(&self, name: &str) -> bool { // FIXME: https://github.com/mozilla/servo/issues/1840 let class_names = self.get_string_attribute("class"); let mut classes = class_names.split(' '); classes.any(|class| name == class) } -} -// http://www.whatwg.org/html/#reflecting-content-attributes-in-idl-attributes -impl Element { - pub fn get_url_attribute(&self, name: &str) -> DOMString { + fn get_url_attribute(&self, name: &str) -> DOMString { // XXX Resolve URL. self.get_string_attribute(name) } - pub fn set_url_attribute(&mut self, abstract_self: &JS<Element>, - name: &str, value: DOMString) { - self.set_string_attribute(abstract_self, name, value); + fn set_url_attribute(&mut self, name: &str, value: DOMString) { + self.set_string_attribute(name, value); } - pub fn get_string_attribute(&self, name: &str) -> DOMString { + fn get_string_attribute(&self, name: &str) -> DOMString { match self.get_attribute(Null, name) { Some(x) => x.get().Value(), None => ~"" } } - pub fn set_string_attribute(&mut self, abstract_self: &JS<Element>, - name: &str, value: DOMString) { + fn set_string_attribute(&mut self, name: &str, value: DOMString) { assert!(name == name.to_ascii_lower()); - assert!(self.set_attribute(abstract_self, Null, name.to_owned(), value).is_ok()); + assert!(self.set_attribute(Null, name.to_owned(), value).is_ok()); + } +} + +impl Element { + pub fn is_void(&self) -> bool { + if self.namespace != namespace::HTML { + return false + } + match self.tag_name.as_slice() { + /* List of void elements from + http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#html-fragment-serialization-algorithm */ + "area" | "base" | "basefont" | "bgsound" | "br" | "col" | "embed" | + "frame" | "hr" | "img" | "input" | "keygen" | "link" | "menuitem" | + "meta" | "param" | "source" | "track" | "wbr" => true, + _ => false + } } } @@ -421,23 +427,23 @@ impl Element { } // http://dom.spec.whatwg.org/#dom-element-id - pub fn Id(&self, _abstract_self: &JS<Element>) -> DOMString { - self.get_string_attribute("id") + pub fn Id(&self, abstract_self: &JS<Element>) -> DOMString { + abstract_self.get_string_attribute("id") } // http://dom.spec.whatwg.org/#dom-element-id - pub fn SetId(&mut self, abstract_self: &JS<Element>, id: DOMString) { - self.set_string_attribute(abstract_self, "id", id); + pub fn SetId(&mut self, abstract_self: &mut JS<Element>, id: DOMString) { + abstract_self.set_string_attribute("id", id); } // http://dom.spec.whatwg.org/#dom-element-classname - pub fn ClassName(&self, _abstract_self: &JS<Element>) -> DOMString { - self.get_string_attribute("class") + pub fn ClassName(&self, abstract_self: &JS<Element>) -> DOMString { + abstract_self.get_string_attribute("class") } // http://dom.spec.whatwg.org/#dom-element-classname - pub fn SetClassName(&mut self, abstract_self: &JS<Element>, class: DOMString) { - self.set_string_attribute(abstract_self, "class", class); + pub fn SetClassName(&self, abstract_self: &mut JS<Element>, class: DOMString) { + abstract_self.set_string_attribute("class", class); } // http://dom.spec.whatwg.org/#dom-element-attributes @@ -455,37 +461,40 @@ impl Element { } // http://dom.spec.whatwg.org/#dom-element-getattribute - pub fn GetAttribute(&self, name: DOMString) -> Option<DOMString> { - let name = if self.html_element_in_html_document() { + pub fn GetAttribute(&self, abstract_self: &JS<Element>, name: DOMString) -> Option<DOMString> { + let name = if abstract_self.get().html_element_in_html_document() { name.to_ascii_lower() } else { name }; - self.get_attribute(Null, name).map(|s| s.get().Value()) + abstract_self.get_attribute(Null, name).map(|s| s.get().Value()) } // http://dom.spec.whatwg.org/#dom-element-getattributens - pub fn GetAttributeNS(&self, namespace: Option<DOMString>, local_name: DOMString) -> Option<DOMString> { + pub fn GetAttributeNS(&self, abstract_self: &JS<Element>, + namespace: Option<DOMString>, + local_name: DOMString) -> Option<DOMString> { let namespace = Namespace::from_str(null_str_as_empty_ref(&namespace)); - self.get_attribute(namespace, local_name) - .map(|attr| attr.get().value.clone()) + abstract_self.get_attribute(namespace, local_name) + .map(|attr| attr.get().value.clone()) } // http://dom.spec.whatwg.org/#dom-element-setattribute - pub fn SetAttribute(&mut self, abstract_self: &JS<Element>, name: DOMString, value: DOMString) - -> ErrorResult { + pub fn SetAttribute(&mut self, abstract_self: &mut JS<Element>, + name: DOMString, + value: DOMString) -> ErrorResult { // FIXME: If name does not match the Name production in XML, throw an "InvalidCharacterError" exception. let name = if self.html_element_in_html_document() { name.to_ascii_lower() } else { name }; - self.set_attr(abstract_self, name, value) + abstract_self.set_attr(name, value) } // http://dom.spec.whatwg.org/#dom-element-setattributens pub fn SetAttributeNS(&mut self, - abstract_self: &JS<Element>, + abstract_self: &mut JS<Element>, namespace_url: Option<DOMString>, name: DOMString, value: DOMString) -> ErrorResult { @@ -497,38 +506,41 @@ impl Element { } let namespace = Namespace::from_str(null_str_as_empty_ref(&namespace_url)); - self.set_attribute(abstract_self, namespace, name, value) + abstract_self.set_attribute(namespace, name, value) } // http://dom.spec.whatwg.org/#dom-element-removeattribute pub fn RemoveAttribute(&mut self, - abstract_self: &JS<Element>, + abstract_self: &mut JS<Element>, name: DOMString) -> ErrorResult { let name = if self.html_element_in_html_document() { name.to_ascii_lower() } else { name }; - self.remove_attribute(abstract_self, namespace::Null, name) + abstract_self.remove_attribute(namespace::Null, name) } // http://dom.spec.whatwg.org/#dom-element-removeattributens pub fn RemoveAttributeNS(&mut self, - abstract_self: &JS<Element>, + abstract_self: &mut JS<Element>, namespace: Option<DOMString>, localname: DOMString) -> ErrorResult { let namespace = Namespace::from_str(null_str_as_empty_ref(&namespace)); - self.remove_attribute(abstract_self, namespace, localname) + abstract_self.remove_attribute(namespace, localname) } // http://dom.spec.whatwg.org/#dom-element-hasattribute - pub fn HasAttribute(&self, name: DOMString) -> bool { - self.GetAttribute(name).is_some() + pub fn HasAttribute(&self, abstract_self: &JS<Element>, + name: DOMString) -> bool { + self.GetAttribute(abstract_self, name).is_some() } // http://dom.spec.whatwg.org/#dom-element-hasattributens - pub fn HasAttributeNS(&self, namespace: Option<DOMString>, local_name: DOMString) -> bool { - self.GetAttributeNS(namespace, local_name).is_some() + pub fn HasAttributeNS(&self, abstract_self: &JS<Element>, + namespace: Option<DOMString>, + local_name: DOMString) -> bool { + self.GetAttributeNS(abstract_self, namespace, local_name).is_some() } pub fn GetElementsByTagName(&self, abstract_self: &JS<Element>, localname: DOMString) -> JS<HTMLCollection> { @@ -614,7 +626,7 @@ pub trait IElement { impl IElement for JS<Element> { fn bind_to_tree_impl(&self) { - match self.get().get_attribute(Null, "id") { + match self.get_attribute(Null, "id") { Some(attr) => { let mut doc = document_from_node(self); doc.get_mut().register_named_element(self, attr.get().Value()); @@ -624,7 +636,7 @@ impl IElement for JS<Element> { } fn unbind_from_tree_impl(&self) { - match self.get().get_attribute(Null, "id") { + match self.get_attribute(Null, "id") { Some(attr) => { let mut doc = document_from_node(self); doc.get_mut().unregister_named_element(attr.get().Value()); diff --git a/src/components/script/dom/htmlcollection.rs b/src/components/script/dom/htmlcollection.rs index 221ec012bd4..77d36e07005 100644 --- a/src/components/script/dom/htmlcollection.rs +++ b/src/components/script/dom/htmlcollection.rs @@ -6,7 +6,7 @@ use dom::bindings::codegen::InheritTypes::{ElementCast}; use dom::bindings::codegen::HTMLCollectionBinding; use dom::bindings::js::JS; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; -use dom::element::Element; +use dom::element::{Element, AttributeHandlers}; use dom::node::{Node, NodeHelpers}; use dom::window::Window; use servo_util::namespace::Namespace; @@ -59,7 +59,7 @@ impl HTMLCollection { pub fn by_class_name(window: &JS<Window>, root: &JS<Node>, classes: DOMString) -> JS<HTMLCollection> { // FIXME: https://github.com/mozilla/servo/issues/1840 let classes: ~[&str] = classes.split(' ').collect(); - HTMLCollection::create(window, root, |elem| classes.iter().all(|class| elem.get().has_class(*class))) + HTMLCollection::create(window, root, |elem| classes.iter().all(|class| elem.has_class(*class))) } } @@ -87,7 +87,6 @@ impl HTMLCollection { // Step 2. self.elements.iter().find(|elem| { - let elem = elem.get(); elem.get_string_attribute("name") == key || elem.get_string_attribute("id") == key }).map(|maybe_elem| maybe_elem.clone()) } diff --git a/src/components/script/dom/htmliframeelement.rs b/src/components/script/dom/htmliframeelement.rs index 5098972ec15..a4999559cf5 100644 --- a/src/components/script/dom/htmliframeelement.rs +++ b/src/components/script/dom/htmliframeelement.rs @@ -7,7 +7,8 @@ use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLIFrameElementDerived use dom::bindings::js::JS; use dom::bindings::error::ErrorResult; use dom::document::Document; -use dom::element::HTMLIFrameElementTypeId; +use dom::element::{HTMLIFrameElementTypeId, Element}; +use dom::element::{AttributeHandlers, AfterSetAttrListener, BeforeRemoveAttrListener}; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; use dom::node::{Node, ElementNodeTypeId}; @@ -114,40 +115,14 @@ impl HTMLIFrameElement { Ok(()) } - pub fn Sandbox(&self, _abstract_self: &JS<HTMLIFrameElement>) -> DOMString { - self.htmlelement.element.get_string_attribute("sandbox") + pub fn Sandbox(&self, abstract_self: &JS<HTMLIFrameElement>) -> DOMString { + let element: JS<Element> = ElementCast::from(abstract_self); + element.get_string_attribute("sandbox") } - pub fn SetSandbox(&mut self, abstract_self: &JS<HTMLIFrameElement>, sandbox: DOMString) { - self.htmlelement.element.set_string_attribute(&ElementCast::from(abstract_self), - "sandbox", - sandbox); - } - - pub fn AfterSetAttr(&mut self, name: DOMString, value: DOMString) { - if "sandbox" == name { - let mut modes = AllowNothing as u8; - for word in value.split(' ') { - // FIXME: Workaround for https://github.com/mozilla/rust/issues/10683 - let word_lower = word.to_ascii_lower(); - modes |= match word_lower.as_slice() { - "allow-same-origin" => AllowSameOrigin, - "allow-forms" => AllowForms, - "allow-pointer-lock" => AllowPointerLock, - "allow-popups" => AllowPopups, - "allow-scripts" => AllowScripts, - "allow-top-navigation" => AllowTopNavigation, - _ => AllowNothing - } as u8; - } - self.sandbox = Some(modes); - } - } - - pub fn BeforeRemoveAttr(&mut self, name: DOMString) { - if "sandbox" == name { - self.sandbox = None; - } + pub fn SetSandbox(&mut self, abstract_self: &mut JS<HTMLIFrameElement>, sandbox: DOMString) { + let mut element: JS<Element> = ElementCast::from(abstract_self); + element.set_string_attribute("sandbox", sandbox); } pub fn AllowFullscreen(&self) -> bool { @@ -234,3 +209,33 @@ impl HTMLIFrameElement { None } } + +impl AfterSetAttrListener for JS<HTMLIFrameElement> { + fn AfterSetAttr(&mut self, name: DOMString, value: DOMString) { + if "sandbox" == name { + let mut modes = AllowNothing as u8; + for word in value.split(' ') { + // FIXME: Workaround for https://github.com/mozilla/rust/issues/10683 + let word_lower = word.to_ascii_lower(); + modes |= match word_lower.as_slice() { + "allow-same-origin" => AllowSameOrigin, + "allow-forms" => AllowForms, + "allow-pointer-lock" => AllowPointerLock, + "allow-popups" => AllowPopups, + "allow-scripts" => AllowScripts, + "allow-top-navigation" => AllowTopNavigation, + _ => AllowNothing + } as u8; + } + self.get_mut().sandbox = Some(modes); + } + } +} + +impl BeforeRemoveAttrListener for JS<HTMLIFrameElement> { + fn BeforeRemoveAttr(&mut self, name: DOMString) { + if "sandbox" == name { + self.get_mut().sandbox = None; + } + } +} diff --git a/src/components/script/dom/htmlimageelement.rs b/src/components/script/dom/htmlimageelement.rs index 861b8ca5633..af1d70444a2 100644 --- a/src/components/script/dom/htmlimageelement.rs +++ b/src/components/script/dom/htmlimageelement.rs @@ -9,6 +9,7 @@ use dom::bindings::js::JS; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::{Element, HTMLImageElementTypeId}; +use dom::element::{AttributeHandlers, AfterSetAttrListener, BeforeRemoveAttrListener}; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; use dom::node::{Node, ElementNodeTypeId, NodeHelpers, window_from_node}; @@ -91,21 +92,6 @@ impl HTMLImageElement { } } - pub fn AfterSetAttr(&mut self, name: DOMString, value: DOMString) { - if "src" == name { - let document = self.htmlelement.element.node.owner_doc().clone(); - let window = document.get().window.get(); - let url = Some(window.get_url()); - self.update_image(Some(value), url); - } - } - - pub fn BeforeRemoveAttr(&mut self, name: DOMString) { - if "src" == name { - self.update_image(None, None); - } - } - pub fn Alt(&self) -> DOMString { ~"" } @@ -118,9 +104,10 @@ impl HTMLImageElement { ~"" } - pub fn SetSrc(&mut self, abstract_self: &JS<HTMLImageElement>, src: DOMString) -> ErrorResult { - let node = &mut self.htmlelement.element; - node.set_attr(&ElementCast::from(abstract_self), ~"src", src.clone()) + pub fn SetSrc(&mut self, abstract_self: &mut JS<HTMLImageElement>, src: DOMString) -> ErrorResult { + let mut element: JS<Element> = ElementCast::from(abstract_self); + element.set_url_attribute("src", src); + Ok(()) } pub fn CrossOrigin(&self) -> DOMString { @@ -162,8 +149,7 @@ impl HTMLImageElement { pub fn SetWidth(&mut self, abstract_self: &JS<HTMLImageElement>, width: u32) -> ErrorResult { let mut elem: JS<Element> = ElementCast::from(abstract_self); - let mut elem_clone = elem.clone(); - elem.get_mut().set_attr(&mut elem_clone, ~"width", width.to_str()) + elem.set_attr(~"width", width.to_str()) } pub fn Height(&self, abstract_self: &JS<HTMLImageElement>) -> u32 { @@ -181,8 +167,8 @@ impl HTMLImageElement { } pub fn SetHeight(&mut self, abstract_self: &JS<HTMLImageElement>, height: u32) -> ErrorResult { - let node = &mut self.htmlelement.element; - node.set_attr(&ElementCast::from(abstract_self), ~"height", height.to_str()) + let mut elem: JS<Element> = ElementCast::from(abstract_self); + elem.set_attr(~"height", height.to_str()) } pub fn NaturalWidth(&self) -> u32 { @@ -245,3 +231,21 @@ impl HTMLImageElement { Ok(()) } } + +impl AfterSetAttrListener for JS<HTMLImageElement> { + fn AfterSetAttr(&mut self, name: DOMString, value: DOMString) { + if "src" == name { + let window = window_from_node(self); + let url = Some(window.get().get_url()); + self.get_mut().update_image(Some(value), url); + } + } +} + +impl BeforeRemoveAttrListener for JS<HTMLImageElement> { + fn BeforeRemoveAttr(&mut self, name: DOMString) { + if "src" == name { + self.get_mut().update_image(None, None); + } + } +} diff --git a/src/components/script/dom/htmlobjectelement.rs b/src/components/script/dom/htmlobjectelement.rs index 4c6e21012cf..d4e82a61da8 100644 --- a/src/components/script/dom/htmlobjectelement.rs +++ b/src/components/script/dom/htmlobjectelement.rs @@ -4,14 +4,16 @@ use dom::bindings::codegen::HTMLObjectElementBinding; use dom::bindings::codegen::InheritTypes::HTMLObjectElementDerived; +use dom::bindings::codegen::InheritTypes::ElementCast; use dom::bindings::js::JS; use dom::bindings::error::ErrorResult; use dom::document::Document; -use dom::element::HTMLObjectElementTypeId; +use dom::element::{Element, HTMLObjectElementTypeId}; +use dom::element::{AttributeHandlers, AfterSetAttrListener}; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; use dom::htmlformelement::HTMLFormElement; -use dom::node::{Node, ElementNodeTypeId}; +use dom::node::{Node, ElementNodeTypeId, NodeHelpers, window_from_node}; use dom::validitystate::ValidityState; use dom::windowproxy::WindowProxy; use servo_util::str::DOMString; @@ -50,12 +52,15 @@ impl HTMLObjectElement { } } -impl HTMLObjectElement { +trait ProcessDataURL { + fn process_data_url(&mut self, image_cache: ImageCacheTask, url: Option<Url>); +} +impl ProcessDataURL for JS<HTMLObjectElement> { // Makes the local `data` member match the status of the `data` attribute and starts /// prefetching the image. This method must be called after `data` is changed. - pub fn process_data_url(&mut self, image_cache: ImageCacheTask, url: Option<Url>) { - let elem = &mut self.htmlelement.element; + fn process_data_url(&mut self, image_cache: ImageCacheTask, url: Option<Url>) { + let elem: JS<Element> = ElementCast::from(self); // TODO: support other values match (elem.get_attribute(Null, "type").map(|x| x.get().Value()), @@ -70,16 +75,9 @@ impl HTMLObjectElement { _ => { } } } +} - pub fn AfterSetAttr(&mut self, name: DOMString, _value: DOMString) { - if "data" == name { - let document = self.htmlelement.element.node.owner_doc().clone(); - let window = document.get().window.clone(); - let url = Some(window.get().get_url()); - self.process_data_url(window.get().image_cache_task.clone(), url); - } - } - +impl HTMLObjectElement { pub fn Data(&self) -> DOMString { ~"" } @@ -245,3 +243,13 @@ impl HTMLObjectElement { None } } + +impl AfterSetAttrListener for JS<HTMLObjectElement> { + fn AfterSetAttr(&mut self, name: DOMString, _value: DOMString) { + if "data" == name { + let window = window_from_node(self); + let url = Some(window.get().get_url()); + self.process_data_url(window.get().image_cache_task.clone(), url); + } + } +} diff --git a/src/components/script/dom/htmlscriptelement.rs b/src/components/script/dom/htmlscriptelement.rs index 6cffaf288a6..18830c35bbd 100644 --- a/src/components/script/dom/htmlscriptelement.rs +++ b/src/components/script/dom/htmlscriptelement.rs @@ -4,10 +4,11 @@ use dom::bindings::codegen::HTMLScriptElementBinding; use dom::bindings::codegen::InheritTypes::HTMLScriptElementDerived; +use dom::bindings::codegen::InheritTypes::ElementCast; use dom::bindings::js::JS; use dom::bindings::error::ErrorResult; use dom::document::Document; -use dom::element::HTMLScriptElementTypeId; +use dom::element::{HTMLScriptElementTypeId, Element, AttributeHandlers}; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; use dom::node::{Node, ElementNodeTypeId}; @@ -41,11 +42,12 @@ impl HTMLScriptElement { } impl HTMLScriptElement { - pub fn Src(&self) -> DOMString { - self.htmlelement.element.get_url_attribute("src") + pub fn Src(&self, abstract_self: &JS<HTMLScriptElement>) -> DOMString { + let element: JS<Element> = ElementCast::from(abstract_self); + element.get_url_attribute("src") } - pub fn SetSrc(&mut self, _src: DOMString) -> ErrorResult { + pub fn SetSrc(&mut self, _abstract_self: &JS<HTMLScriptElement>, _src: DOMString) -> ErrorResult { Ok(()) } |