diff --git a/components/net/fetch/methods.rs b/components/net/fetch/methods.rs index b6b5d80231c..59da722fb03 100644 --- a/components/net/fetch/methods.rs +++ b/components/net/fetch/methods.rs @@ -21,6 +21,7 @@ use net_traits::request::{Referrer, Request, RequestMode, ResponseTainting}; use net_traits::request::{Type, Origin, Window}; use net_traits::response::{Response, ResponseBody, ResponseType}; use servo_url::ServoUrl; +use std::ascii::AsciiExt; use std::borrow::Cow; use std::fmt; use std::fs::File; @@ -514,9 +515,10 @@ pub fn should_be_blocked_due_to_nosniff(request_type: Type, response_headers: &H fn parse_header(raw: &[Vec]) -> HyperResult { raw.first() .and_then(|v| str::from_utf8(v).ok()) - .and_then(|s| match s.trim().to_lowercase().as_str() { - "nosniff" => Some(XContentTypeOptions), - _ => None + .and_then(|s| if s.trim().eq_ignore_ascii_case("nosniff") { + Some(XContentTypeOptions) + } else { + None }) .ok_or(Error::Header) } diff --git a/components/script/dom/blob.rs b/components/script/dom/blob.rs index ddf14fc8096..191ea6f84f7 100644 --- a/components/script/dom/blob.rs +++ b/components/script/dom/blob.rs @@ -16,6 +16,7 @@ use ipc_channel::ipc; use net_traits::{CoreResourceMsg, IpcSend}; use net_traits::blob_url_store::{BlobBuf, get_blob_origin}; use net_traits::filemanager_thread::{FileManagerThreadMsg, ReadFileProgress, RelativePos}; +use std::ascii::AsciiExt; use std::mem; use std::ops::Index; use std::path::PathBuf; @@ -381,7 +382,7 @@ impl BlobMethods for Blob { /// see https://github.com/w3c/FileAPI/issues/43 fn normalize_type_string(s: &str) -> String { if is_ascii_printable(s) { - let s_lower = s.to_lowercase(); + let s_lower = s.to_ascii_lowercase(); // match s_lower.parse() as Result { // Ok(_) => s_lower, // Err(_) => "".to_string() diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 90ea06fbe7b..c63295a0674 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -3875,8 +3875,7 @@ fn update_with_current_time_ms(marker: &Cell) { /// https://w3c.github.io/webappsec-referrer-policy/#determine-policy-for-token pub fn determine_policy_for_token(token: &str) -> Option { - let lower = token.to_lowercase(); - return match lower.as_ref() { + match_ignore_ascii_case! { token, "never" | "no-referrer" => Some(ReferrerPolicy::NoReferrer), "default" | "no-referrer-when-downgrade" => Some(ReferrerPolicy::NoReferrerWhenDowngrade), "origin" => Some(ReferrerPolicy::Origin), diff --git a/components/script/dom/htmlareaelement.rs b/components/script/dom/htmlareaelement.rs index 0e3c26155fe..4e227491d01 100644 --- a/components/script/dom/htmlareaelement.rs +++ b/components/script/dom/htmlareaelement.rs @@ -240,7 +240,7 @@ impl HTMLAreaElement { pub fn get_shape_from_coords(&self) -> Option { let elem = self.upcast::(); let shape = elem.get_string_attribute(&"shape".into()); - let shp: Shape = match shape.to_lowercase().as_ref() { + let shp: Shape = match_ignore_ascii_case! { &shape, "circle" => Shape::Circle, "circ" => Shape::Circle, "rectangle" => Shape::Rectangle, diff --git a/components/script/dom/htmlelement.rs b/components/script/dom/htmlelement.rs index 59846595166..05683653fa1 100644 --- a/components/script/dom/htmlelement.rs +++ b/components/script/dom/htmlelement.rs @@ -32,7 +32,6 @@ use dom::virtualmethods::VirtualMethods; use dom_struct::dom_struct; use html5ever::{LocalName, Prefix}; use std::ascii::AsciiExt; -use std::borrow::ToOwned; use std::default::Default; use std::rc::Rc; use style::attr::AttrValue; @@ -374,12 +373,16 @@ impl HTMLElementMethods for HTMLElement { // https://html.spec.whatwg.org/multipage/#attr-data-* +static DATA_PREFIX: &str = "data-"; +static DATA_HYPHEN_SEPARATOR: char = '\x2d'; + fn to_snake_case(name: DOMString) -> DOMString { - let mut attr_name = "data-".to_owned(); + let mut attr_name = String::with_capacity(name.len() + DATA_PREFIX.len()); + attr_name.push_str(DATA_PREFIX); for ch in name.chars() { - if ch.is_uppercase() { - attr_name.push('\x2d'); - attr_name.extend(ch.to_lowercase()); + if ch.is_ascii_uppercase() { + attr_name.push(DATA_HYPHEN_SEPARATOR); + attr_name.push(ch.to_ascii_lowercase()); } else { attr_name.push(ch); } @@ -394,23 +397,21 @@ fn to_snake_case(name: DOMString) -> DOMString { // without the data prefix. fn to_camel_case(name: &str) -> Option { - if !name.starts_with("data-") { + if !name.starts_with(DATA_PREFIX) { return None; } let name = &name[5..]; - let has_uppercase = name.chars().any(|curr_char| { - curr_char.is_ascii() && curr_char.is_uppercase() - }); + let has_uppercase = name.chars().any(|curr_char| curr_char.is_ascii_uppercase()); if has_uppercase { return None; } - let mut result = "".to_owned(); + let mut result = String::with_capacity(name.len().saturating_sub(DATA_PREFIX.len())); let mut name_chars = name.chars(); while let Some(curr_char) = name_chars.next() { //check for hyphen followed by character - if curr_char == '\x2d' { + if curr_char == DATA_HYPHEN_SEPARATOR { if let Some(next_char) = name_chars.next() { - if next_char.is_ascii() && next_char.is_lowercase() { + if next_char.is_ascii_lowercase() { result.push(next_char.to_ascii_uppercase()); } else { result.push(curr_char); diff --git a/components/script/dom/request.rs b/components/script/dom/request.rs index 82b7773fc3e..9abfb4b0eb4 100644 --- a/components/script/dom/request.rs +++ b/components/script/dom/request.rs @@ -38,7 +38,6 @@ use net_traits::request::Request as NetTraitsRequest; use net_traits::request::RequestMode as NetTraitsRequestMode; use net_traits::request::Type as NetTraitsRequestType; use servo_url::ServoUrl; -use std::ascii::AsciiExt; use std::cell::{Cell, Ref}; use std::rc::Rc; @@ -453,15 +452,16 @@ fn net_request_from_global(global: &GlobalScope, // https://fetch.spec.whatwg.org/#concept-method-normalize fn normalize_method(m: &str) -> HttpMethod { - match m { - m if m.eq_ignore_ascii_case("DELETE") => HttpMethod::Delete, - m if m.eq_ignore_ascii_case("GET") => HttpMethod::Get, - m if m.eq_ignore_ascii_case("HEAD") => HttpMethod::Head, - m if m.eq_ignore_ascii_case("OPTIONS") => HttpMethod::Options, - m if m.eq_ignore_ascii_case("POST") => HttpMethod::Post, - m if m.eq_ignore_ascii_case("PUT") => HttpMethod::Put, - m => HttpMethod::Extension(m.to_string()), + match_ignore_ascii_case! { m, + "delete" => return HttpMethod::Delete, + "get" => return HttpMethod::Get, + "head" => return HttpMethod::Head, + "options" => return HttpMethod::Options, + "post" => return HttpMethod::Post, + "put" => return HttpMethod::Put, + _ => (), } + HttpMethod::Extension(m.to_string()) } // https://fetch.spec.whatwg.org/#concept-method diff --git a/components/script/lib.rs b/components/script/lib.rs index e1a1ab592cb..cab84d54294 100644 --- a/components/script/lib.rs +++ b/components/script/lib.rs @@ -2,6 +2,7 @@ * 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/. */ +#![feature(ascii_ctype)] #![feature(box_syntax)] #![feature(conservative_impl_trait)] #![feature(const_fn)] diff --git a/components/selectors/parser.rs b/components/selectors/parser.rs index 490399ce38c..e9b59f7f831 100644 --- a/components/selectors/parser.rs +++ b/components/selectors/parser.rs @@ -1586,10 +1586,10 @@ where Impl: SelectorImpl, F: FnOnce(i32, i32) -> Component { /// double-colon syntax, which can be used for all pseudo-elements). pub fn is_css2_pseudo_element<'i>(name: &CowRcStr<'i>) -> bool { // ** Do not add to this list! ** - return name.eq_ignore_ascii_case("before") || - name.eq_ignore_ascii_case("after") || - name.eq_ignore_ascii_case("first-line") || - name.eq_ignore_ascii_case("first-letter"); + match_ignore_ascii_case! { name, + "before" | "after" | "first-line" | "first-letter" => true, + _ => false, + } } /// Parse a simple selector other than a type selector. diff --git a/components/style/media_queries.rs b/components/style/media_queries.rs index 5f71ddf974f..b6bde057b3c 100644 --- a/components/style/media_queries.rs +++ b/components/style/media_queries.rs @@ -12,7 +12,6 @@ use cssparser::{Delimiter, Parser, Token, ParserInput}; use parser::ParserContext; use selectors::parser::SelectorParseError; use serialize_comma_separated_list; -use std::ascii::AsciiExt; use std::fmt; use style_traits::{ToCss, ParseError, StyleParseError}; @@ -146,20 +145,15 @@ pub enum MediaQueryType { impl MediaQueryType { fn parse(ident: &str) -> Result { - if ident.eq_ignore_ascii_case("all") { - return Ok(MediaQueryType::All); - } - - // From https://drafts.csswg.org/mediaqueries/#mq-syntax: - // - // The production does not include the keywords only, - // not, and, and or. - if ident.eq_ignore_ascii_case("not") || - ident.eq_ignore_ascii_case("or") || - ident.eq_ignore_ascii_case("and") || - ident.eq_ignore_ascii_case("only") { - return Err(()) - } + match_ignore_ascii_case! { ident, + "all" => return Ok(MediaQueryType::All), + // From https://drafts.csswg.org/mediaqueries/#mq-syntax: + // + // The production does not include the keywords only, + // not, and, and or. + "not" | "or" | "and" | "only" => return Err(()), + _ => (), + }; Ok(match MediaType::parse(ident) { Some(media_type) => MediaQueryType::Known(media_type), diff --git a/components/style_derive/to_css.rs b/components/style_derive/to_css.rs index 9bc19dc0695..2dbf8731e45 100644 --- a/components/style_derive/to_css.rs +++ b/components/style_derive/to_css.rs @@ -151,7 +151,7 @@ fn where_predicate(ty: syn::Ty) -> syn::WherePredicate { /// Transforms "FooBar" to "foo-bar". /// -/// If the first Camel segment is "Moz"" or "Webkit", the result string +/// If the first Camel segment is "Moz" or "Webkit", the result string /// is prepended with "-". fn to_css_identifier(mut camel_case: &str) -> String { camel_case = camel_case.trim_right_matches('_');