servo: Merge #2032 - Support for ASCII whitespace check (from brunoabinader:html-whitespace); r=Ms2ger
authorBruno de Oliveira Abinader <bruno.d@partner.samsung.com>
Sat, 05 Apr 2014 04:04:34 -0400
changeset 383183 787e1538dc7accb59349f9d29a9150e99fe0f43d
parent 383182 edda7537873b6994548f20850f6b0667496cdb65
child 383184 3629f830c84d32d1c8fadf3e9b8afb2145cef1bb
push id1468
push userasasaki@mozilla.com
push dateMon, 05 Jun 2017 19:31:07 +0000
treeherdermozilla-release@0641fc6ee9d1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersMs2ger
servo: Merge #2032 - Support for ASCII whitespace check (from brunoabinader:html-whitespace); r=Ms2ger Specs: http://dom.spec.whatwg.org/#concept-ordered-set-parser http://encoding.spec.whatwg.org/#ascii-whitespace This PR implements the HTMLSpaceCharSplits iterator, used to split a string in a subset of strings separated by valid HTML space characters. Its first usage is upon splitting ```class``` attribute values. Closes #1840. Source-Repo: https://github.com/servo/servo Source-Revision: 2a5f82a76453aebe1ce07f0e0c5b78bead93ed0c
servo/.gitignore
servo/src/components/script/dom/element.rs
servo/src/components/script/dom/htmlcollection.rs
servo/src/components/util/str.rs
servo/src/test/content/test_htmlspacechars.html
--- a/servo/.gitignore
+++ b/servo/.gitignore
@@ -5,16 +5,17 @@
 *.dylib
 *.dSYM
 *.dll
 *.dummy
 *.pkl
 *.pyc
 *.swp
 *.swo
+.DS_Store
 servo-test
 Makefile
 Servo.app
 build*
 objdir
 config.mk
 config.stamp
 config.tmp
--- a/servo/src/components/script/dom/element.rs
+++ b/servo/src/components/script/dom/element.rs
@@ -24,17 +24,17 @@ use dom::htmlobjectelement::HTMLObjectEl
 use dom::node::{ElementNodeTypeId, Node, NodeHelpers, NodeIterator, document_from_node};
 use dom::htmlserializer::serialize;
 use layout_interface::{ContentBoxQuery, ContentBoxResponse, ContentBoxesQuery};
 use layout_interface::{ContentBoxesResponse, ContentChangedDocumentDamage};
 use layout_interface::{MatchSelectorsDocumentDamage};
 use style;
 use servo_util::namespace;
 use servo_util::namespace::{Namespace, Null};
-use servo_util::str::{DOMString, null_str_as_empty_ref};
+use servo_util::str::{DOMString, null_str_as_empty_ref, split_html_space_chars};
 
 use std::ascii::StrAsciiExt;
 use std::cast;
 
 #[deriving(Encodable)]
 pub struct Element {
     node: Node,
     tag_name: DOMString,     // TODO: This should be an atom, not a DOMString.
@@ -371,19 +371,18 @@ impl AttributeHandlers for JS<Element> {
                 _ => ContentChangedDocumentDamage
             };
             let document = node.get().owner_doc();
             document.get().damage_and_reflow(damage);
         }
     }
 
     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(' ');
+        let mut classes = split_html_space_chars(class_names);
         classes.any(|class| name == class)
     }
 
     fn get_url_attribute(&self, name: &str) -> DOMString {
         // XXX Resolve URL.
         self.get_string_attribute(name)
     }
     fn set_url_attribute(&mut self, name: &str, value: DOMString) {
--- a/servo/src/components/script/dom/htmlcollection.rs
+++ b/servo/src/components/script/dom/htmlcollection.rs
@@ -5,17 +5,17 @@
 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, AttributeHandlers};
 use dom::node::{Node, NodeHelpers};
 use dom::window::Window;
 use servo_util::namespace::Namespace;
-use servo_util::str::DOMString;
+use servo_util::str::{DOMString, split_html_space_chars};
 
 use serialize::{Encoder, Encodable};
 
 pub trait CollectionFilter {
     fn filter(&self, elem: &JS<Element>, root: &JS<Node>) -> bool;
 }
 
 impl<S: Encoder> Encodable<S> for ~CollectionFilter {
@@ -95,17 +95,17 @@ impl HTMLCollection {
             classes: ~[DOMString]
         }
         impl CollectionFilter for ClassNameFilter {
             fn filter(&self, elem: &JS<Element>, _root: &JS<Node>) -> bool {
                 self.classes.iter().all(|class| elem.has_class(*class))
             }
         }
         let filter = ClassNameFilter {
-            classes: classes.split(' ').map(|class| class.into_owned()).to_owned_vec()
+            classes: split_html_space_chars(classes).map(|class| class.into_owned()).to_owned_vec()
         };
         HTMLCollection::create(window, root, ~filter)
     }
 }
 
 impl HTMLCollection {
     // http://dom.spec.whatwg.org/#dom-htmlcollection-length
     pub fn Length(&self) -> u32 {
--- a/servo/src/components/util/str.rs
+++ b/servo/src/components/util/str.rs
@@ -1,13 +1,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+use std::iter::Filter;
+use std::str::CharSplits;
+
 pub type DOMString = ~str;
+pub type StaticCharVec = &'static [char];
 pub type StaticStringVec = &'static [&'static str];
 
 pub fn null_str_as_empty(s: &Option<DOMString>) -> DOMString {
     // We don't use map_default because it would allocate ~"" even for Some.
     match *s {
         Some(ref s) => s.clone(),
         None => ~""
     }
@@ -26,16 +30,19 @@ pub fn is_whitespace(s: &str) -> bool {
         _ => false
     })
 }
 
 /// A "space character" according to:
 ///
 ///     http://www.whatwg.org/specs/web-apps/current-work/multipage/common-microsyntaxes.html#
 ///     space-character
-pub static HTML_SPACE_CHARACTERS: [char, ..5] = [
+pub static HTML_SPACE_CHARACTERS: StaticCharVec = &[
     '\u0020',
     '\u0009',
     '\u000a',
     '\u000c',
     '\u000d',
 ];
 
+pub fn split_html_space_chars<'a>(s: &'a str) -> Filter<'a, &'a str, CharSplits<'a, StaticCharVec>> {
+    s.split(HTML_SPACE_CHARACTERS).filter(|&split| !split.is_empty())
+}
new file mode 100644
--- /dev/null
+++ b/servo/src/test/content/test_htmlspacechars.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <script src="harness.js"></script>
+        <script>
+            is(document.getElementsByClassName("foo").length, 6);
+            is_not(document.getElementById("bar").className, "ggg foo");
+            finish();
+        </script>
+    </head>
+    <body>
+        <!-- \u0020 Space -->
+        <div id="foo-1" class="aaa&#32;foo"></div>
+        <!-- \u0009 Character tabulation -->
+        <div id="foo-2" class="bbb&#9;foo"></div>
+        <!-- \u000a Line feed -->
+        <div id="foo-3" class="ccc&#10;foo"></div>
+        <!-- \u000c Form feed -->
+        <div id="foo-4" class="ddd&#12;foo"></div>
+        <!-- \u000d Carriage return -->
+        <div id="foo-5" class="eee&#13;foo"></div>
+        <!-- Space -->
+        <div id="foo-6" class="fff foo"></div>
+        <!-- Non-HTML space character -->
+        <div id="bar" class="ggg&#11;foo"></div>
+    </body>
+</html>