From 3347c3ef80cf64684f36edfba675e0dd0e47f8af Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Mon, 7 Apr 2014 17:36:49 +0200 Subject: Split out a do_set_attribute method. --- src/components/script/dom/element.rs | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/components/script/dom/element.rs b/src/components/script/dom/element.rs index 7b0ab7bd54e..a9cee2c8650 100644 --- a/src/components/script/dom/element.rs +++ b/src/components/script/dom/element.rs @@ -195,6 +195,10 @@ pub trait AttributeHandlers { fn set_attr(&mut self, name: DOMString, value: DOMString) -> ErrorResult; fn set_attribute(&mut self, namespace: Namespace, name: DOMString, value: DOMString) -> ErrorResult; + fn do_set_attribute(&mut self, local_name: DOMString, value: DOMString, + name: DOMString, namespace: Namespace, + prefix: Option, cb: |&JS| -> bool); + 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); @@ -253,15 +257,20 @@ impl AttributeHandlers for JS { let node: JS = NodeCast::from(self); node.get().wait_until_safe_to_modify_dom(); - // FIXME: reduce the time of `value.clone()`. - let idx = self.get().attrs.iter().position(|attr| { + let position: |&JS| -> bool = if self.get().html_element_in_html_document() { - attr.get().local_name.eq_ignore_ascii_case(local_name) + |attr| attr.get().local_name.eq_ignore_ascii_case(local_name) } else { - attr.get().local_name == local_name - } - }); + |attr| attr.get().local_name == local_name + }; + self.do_set_attribute(name.clone(), value, name.clone(), namespace::Null, None, position); + Ok(()) + } + fn do_set_attribute(&mut self, local_name: DOMString, value: DOMString, + name: DOMString, namespace: Namespace, + prefix: Option, cb: |&JS| -> bool) { + let idx = self.get().attrs.iter().position(cb); match idx { Some(idx) => { if namespace == namespace::Null { @@ -270,12 +279,12 @@ impl AttributeHandlers for JS { } self.get_mut().attrs[idx].get_mut().set_value(value.clone()); } + None => { let node: JS = 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); + name, namespace.clone(), prefix); self.get_mut().attrs.push(new_attr); } } @@ -283,7 +292,6 @@ impl AttributeHandlers for JS { if namespace == namespace::Null { self.after_set_attr(local_name, value); } - Ok(()) } fn after_set_attr(&mut self, local_name: DOMString, value: DOMString) { -- cgit v1.2.3 From b19165e9e1b35254b0e85a5e9fdea6a08b2fefbe Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Mon, 7 Apr 2014 17:47:32 +0200 Subject: Move SetAttribute onto JS. --- src/components/script/dom/element.rs | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/components/script/dom/element.rs b/src/components/script/dom/element.rs index a9cee2c8650..c274deb96a6 100644 --- a/src/components/script/dom/element.rs +++ b/src/components/script/dom/element.rs @@ -198,6 +198,7 @@ pub trait AttributeHandlers { fn do_set_attribute(&mut self, local_name: DOMString, value: DOMString, name: DOMString, namespace: Namespace, prefix: Option, cb: |&JS| -> bool); + fn SetAttribute(&mut self, 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; @@ -294,6 +295,17 @@ impl AttributeHandlers for JS { } } + // http://dom.spec.whatwg.org/#dom-element-setattribute + fn SetAttribute(&mut self, name: DOMString, value: DOMString) -> ErrorResult { + // FIXME: If name does not match the Name production in XML, throw an "InvalidCharacterError" exception. + let name = if self.get().html_element_in_html_document() { + name.to_ascii_lower() + } else { + name + }; + self.set_attr(name, value) + } + fn after_set_attr(&mut self, local_name: DOMString, value: DOMString) { let node: JS = NodeCast::from(self); match local_name.as_slice() { @@ -515,16 +527,10 @@ impl Element { } // http://dom.spec.whatwg.org/#dom-element-setattribute - pub fn SetAttribute(&mut self, abstract_self: &mut JS, + pub fn SetAttribute(&self, abstract_self: &mut JS, 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 - }; - abstract_self.set_attr(name, value) + abstract_self.SetAttribute(name, value) } // http://dom.spec.whatwg.org/#dom-element-setattributens -- cgit v1.2.3 From 883d67882ad9066d9340974cd052c97c0412f1f3 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Mon, 7 Apr 2014 17:56:31 +0200 Subject: Move SetAttributeNS onto JS. --- src/components/script/dom/element.rs | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/components/script/dom/element.rs b/src/components/script/dom/element.rs index c274deb96a6..6468aca641c 100644 --- a/src/components/script/dom/element.rs +++ b/src/components/script/dom/element.rs @@ -199,6 +199,8 @@ pub trait AttributeHandlers { name: DOMString, namespace: Namespace, prefix: Option, cb: |&JS| -> bool); fn SetAttribute(&mut self, name: DOMString, value: DOMString) -> ErrorResult; + fn SetAttributeNS(&mut self, namespace_url: Option, + 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; @@ -306,6 +308,19 @@ impl AttributeHandlers for JS { self.set_attr(name, value) } + fn SetAttributeNS(&mut self, namespace_url: Option, + name: DOMString, value: DOMString) -> ErrorResult { + let name_type = xml_name_type(name); + match name_type { + InvalidXMLName => return Err(InvalidCharacter), + Name => return Err(NamespaceError), + QName => {} + } + + let namespace = Namespace::from_str(null_str_as_empty_ref(&namespace_url)); + self.set_attribute(namespace, name, value) + } + fn after_set_attr(&mut self, local_name: DOMString, value: DOMString) { let node: JS = NodeCast::from(self); match local_name.as_slice() { @@ -534,20 +549,12 @@ impl Element { } // http://dom.spec.whatwg.org/#dom-element-setattributens - pub fn SetAttributeNS(&mut self, + pub fn SetAttributeNS(&self, abstract_self: &mut JS, namespace_url: Option, name: DOMString, value: DOMString) -> ErrorResult { - let name_type = xml_name_type(name); - match name_type { - InvalidXMLName => return Err(InvalidCharacter), - Name => return Err(NamespaceError), - QName => {} - } - - let namespace = Namespace::from_str(null_str_as_empty_ref(&namespace_url)); - abstract_self.set_attribute(namespace, name, value) + abstract_self.SetAttributeNS(namespace_url, name, value) } // http://dom.spec.whatwg.org/#dom-element-removeattribute -- cgit v1.2.3 From bf73a47ce0216683f6e65dbf281975f26877aeea Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Mon, 7 Apr 2014 21:09:24 +0200 Subject: Reimplement SetAttribute. --- src/components/script/dom/element.rs | 18 ++++++++++++++++-- src/test/content/test_element_attribute.html | 9 +++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/components/script/dom/element.rs b/src/components/script/dom/element.rs index 6468aca641c..9ecb10641b4 100644 --- a/src/components/script/dom/element.rs +++ b/src/components/script/dom/element.rs @@ -299,13 +299,27 @@ impl AttributeHandlers for JS { // http://dom.spec.whatwg.org/#dom-element-setattribute fn SetAttribute(&mut self, name: DOMString, value: DOMString) -> ErrorResult { - // FIXME: If name does not match the Name production in XML, throw an "InvalidCharacterError" exception. + let node: JS = NodeCast::from(self); + node.get().wait_until_safe_to_modify_dom(); + + // Step 1. + match xml_name_type(name) { + InvalidXMLName => return Err(InvalidCharacter), + _ => {} + } + + // Step 2. let name = if self.get().html_element_in_html_document() { name.to_ascii_lower() } else { name }; - self.set_attr(name, value) + + // Step 3-5. + self.do_set_attribute(name.clone(), value, name.clone(), namespace::Null, None, |attr| { + attr.get().name == name + }); + Ok(()) } fn SetAttributeNS(&mut self, namespace_url: Option, diff --git a/src/test/content/test_element_attribute.html b/src/test/content/test_element_attribute.html index 8631138c767..7455f36bffb 100644 --- a/src/test/content/test_element_attribute.html +++ b/src/test/content/test_element_attribute.html @@ -41,6 +41,15 @@ is(r2, null, "test4-1, Element.removeAttribute()."); } + { + test.setAttribute("xml:lang", "en"); + + let r1 = test.hasAttribute("xml:lang"); + is(r1, true, "test5-0, Element.setAttribute('xml:lang')."); + let r2 = test.getAttribute("xml:lang"); + is_not(r2, null, "test5-1, Element.setAttribute('xml:lang')."); + } + finish(); -- cgit v1.2.3 From d665ad5a179ce5623d023a24be7fb86d78ba3072 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Mon, 7 Apr 2014 22:35:13 +0200 Subject: Reimplement SetAttributeNS. --- src/components/script/dom/element.rs | 48 ++++++++++++++++++++++++++-- src/test/content/test_element_attribute.html | 10 ++++++ 2 files changed, 56 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/components/script/dom/element.rs b/src/components/script/dom/element.rs index 9ecb10641b4..22a2c7a7771 100644 --- a/src/components/script/dom/element.rs +++ b/src/components/script/dom/element.rs @@ -324,15 +324,59 @@ impl AttributeHandlers for JS { fn SetAttributeNS(&mut self, namespace_url: Option, name: DOMString, value: DOMString) -> ErrorResult { + let node: JS = NodeCast::from(self); + node.get().wait_until_safe_to_modify_dom(); + + // Step 1. + let namespace = Namespace::from_str(null_str_as_empty_ref(&namespace_url)); + let name_type = xml_name_type(name); match name_type { + // Step 2. InvalidXMLName => return Err(InvalidCharacter), + // Step 3. Name => return Err(NamespaceError), QName => {} } - let namespace = Namespace::from_str(null_str_as_empty_ref(&namespace_url)); - self.set_attribute(namespace, name, value) + // Step 4. + let (prefix, local_name) = get_attribute_parts(name.clone()); + match prefix { + Some(ref prefix_str) => { + // Step 5. + if namespace == namespace::Null { + return Err(NamespaceError); + } + + // Step 6. + if "xml" == prefix_str.as_slice() && namespace != namespace::XML { + return Err(NamespaceError); + } + + // Step 7b. + if "xmlns" == prefix_str.as_slice() && namespace != namespace::XMLNS { + return Err(NamespaceError); + } + }, + None => {} + } + + // Step 7a. + if "xmlns" == name && namespace != namespace::XMLNS { + return Err(NamespaceError); + } + + // Step 8. + if namespace == namespace::XMLNS && "xmlns" != name && Some(~"xmlns") != prefix { + return Err(NamespaceError); + } + + // Step 9. + self.do_set_attribute(local_name.clone(), value, name, namespace.clone(), prefix, |attr| { + attr.get().local_name == local_name && + attr.get().namespace == namespace + }); + Ok(()) } fn after_set_attr(&mut self, local_name: DOMString, value: DOMString) { diff --git a/src/test/content/test_element_attribute.html b/src/test/content/test_element_attribute.html index 7455f36bffb..d7ee6a23640 100644 --- a/src/test/content/test_element_attribute.html +++ b/src/test/content/test_element_attribute.html @@ -50,6 +50,16 @@ is_not(r2, null, "test5-1, Element.setAttribute('xml:lang')."); } + should_throw(function () { + test.setAttributeNS("http://example.com", "xmlns", "foo"); + }); + should_throw(function () { + test.setAttributeNS("http://www.w3.org/2000/xmlns/", "attr", "value"); + }); + should_throw(function () { + test.setAttributeNS("http://www.w3.org/2000/xmlns/", "prefix:attr", "value"); + }); + finish(); -- cgit v1.2.3 From ed18e4c948958bc4799331fadabd00e068eb941f Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Mon, 7 Apr 2014 22:44:19 +0200 Subject: Merge Attr::new_ns and Attr::new. --- src/components/script/dom/attr.rs | 19 ++++--------------- src/components/script/dom/element.rs | 4 ++-- src/components/script/dom/node.rs | 8 ++++---- 3 files changed, 10 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/components/script/dom/attr.rs b/src/components/script/dom/attr.rs index 8357665b63d..40da74cfbd2 100644 --- a/src/components/script/dom/attr.rs +++ b/src/components/script/dom/attr.rs @@ -6,7 +6,7 @@ use dom::bindings::codegen::AttrBinding; use dom::bindings::js::JS; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::window::Window; -use servo_util::namespace::{Namespace, Null}; +use servo_util::namespace::Namespace; use servo_util::str::DOMString; #[deriving(Encodable)] @@ -43,20 +43,9 @@ impl Attr { } } - pub fn new(window: &JS, local_name: DOMString, value: DOMString) -> JS { - let name = local_name.clone(); - Attr::new_helper(window, local_name, value, name, Null, None) - } - - pub fn new_ns(window: &JS, local_name: DOMString, value: DOMString, - name: DOMString, namespace: Namespace, - prefix: Option) -> JS { - Attr::new_helper(window, local_name, value, name, namespace, prefix) - } - - fn new_helper(window: &JS, local_name: DOMString, value: DOMString, - name: DOMString, namespace: Namespace, - prefix: Option) -> JS { + pub fn new(window: &JS, local_name: DOMString, value: DOMString, + name: DOMString, namespace: Namespace, + prefix: Option) -> JS { let attr = Attr::new_inherited(local_name, value, name, namespace, prefix); reflect_dom_object(~attr, window, AttrBinding::Wrap) } diff --git a/src/components/script/dom/element.rs b/src/components/script/dom/element.rs index 22a2c7a7771..5be2466b80d 100644 --- a/src/components/script/dom/element.rs +++ b/src/components/script/dom/element.rs @@ -286,8 +286,8 @@ impl AttributeHandlers for JS { None => { let node: JS = NodeCast::from(self); let doc = node.get().owner_doc().get(); - let new_attr = Attr::new_ns(&doc.window, local_name.clone(), value.clone(), - name, namespace.clone(), prefix); + let new_attr = Attr::new(&doc.window, local_name.clone(), value.clone(), + name, namespace.clone(), prefix); self.get_mut().attrs.push(new_attr); } } diff --git a/src/components/script/dom/node.rs b/src/components/script/dom/node.rs index eb259c4641d..8207f778835 100644 --- a/src/components/script/dom/node.rs +++ b/src/components/script/dom/node.rs @@ -1372,10 +1372,10 @@ impl Node { copy_elem.namespace = node_elem.namespace.clone(); for attr in node_elem.attrs.iter() { let attr = attr.get(); - copy_elem.attrs.push(Attr::new_ns(&document.get().window, - attr.local_name.clone(), attr.value.clone(), - attr.name.clone(), attr.namespace.clone(), - attr.prefix.clone())); + copy_elem.attrs.push(Attr::new(&document.get().window, + attr.local_name.clone(), attr.value.clone(), + attr.name.clone(), attr.namespace.clone(), + attr.prefix.clone())); } }, _ => () -- cgit v1.2.3