diff --git a/components/style/Cargo.toml b/components/style/Cargo.toml index d6792900c2c..ac5d1922ea4 100644 --- a/components/style/Cargo.toml +++ b/components/style/Cargo.toml @@ -17,7 +17,7 @@ gecko = ["nsstring_vendor", "rayon/unstable"] use_bindgen = ["bindgen", "regex"] servo = ["serde/unstable", "serde", "serde_derive", "heapsize_derive", "style_traits/servo", "servo_atoms", "html5ever-atoms", - "cssparser/heapsize", "cssparser/serde", + "cssparser/heapsize", "cssparser/serde", "encoding", "rayon/unstable", "servo_url/servo"] testing = [] @@ -27,7 +27,7 @@ atomic_refcell = "0.1" bitflags = "0.7" cfg-if = "0.1.0" cssparser = "0.12" -encoding = "0.2" +encoding = {version = "0.2", optional = true} euclid = "0.11" fnv = "1.0" heapsize = "0.3.0" diff --git a/components/style/encoding_support.rs b/components/style/encoding_support.rs new file mode 100644 index 00000000000..62323ec2314 --- /dev/null +++ b/components/style/encoding_support.rs @@ -0,0 +1,89 @@ +/* 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/. */ + +//! Parsing stylesheets from bytes (not `&str`). + +extern crate encoding; + +use cssparser::{stylesheet_encoding, EncodingSupport}; +use error_reporting::ParseErrorReporter; +use media_queries::MediaList; +use parser::ParserContextExtraData; +use self::encoding::{EncodingRef, DecoderTrap}; +use servo_url::ServoUrl; +use std::str; +use stylesheets::{Stylesheet, StylesheetLoader, Origin}; + +struct RustEncoding; + +impl EncodingSupport for RustEncoding { + type Encoding = EncodingRef; + + fn utf8() -> Self::Encoding { + encoding::all::UTF_8 + } + + fn is_utf16_be_or_le(encoding: &Self::Encoding) -> bool { + matches!(encoding.name(), "utf-16be" | "utf-16le") + } + + fn from_label(ascii_label: &[u8]) -> Option { + str::from_utf8(ascii_label).ok().and_then(encoding::label::encoding_from_whatwg_label) + } +} + +fn decode_stylesheet_bytes(css: &[u8], protocol_encoding_label: Option<&str>, + environment_encoding: Option) + -> (String, EncodingRef) { + let fallback_encoding = stylesheet_encoding::( + css, protocol_encoding_label.map(str::as_bytes), environment_encoding); + let (result, used_encoding) = encoding::decode(css, DecoderTrap::Replace, fallback_encoding); + (result.unwrap(), used_encoding) +} + +impl Stylesheet { + /// Parse a stylesheet from a set of bytes, potentially received over the + /// network. + /// + /// Takes care of decoding the network bytes and forwards the resulting + /// string to `Stylesheet::from_str`. + pub fn from_bytes(bytes: &[u8], + base_url: ServoUrl, + protocol_encoding_label: Option<&str>, + environment_encoding: Option, + origin: Origin, + media: MediaList, + stylesheet_loader: Option<&StylesheetLoader>, + error_reporter: &ParseErrorReporter, + extra_data: ParserContextExtraData) + -> Stylesheet { + let (string, _) = decode_stylesheet_bytes( + bytes, protocol_encoding_label, environment_encoding); + Stylesheet::from_str(&string, + base_url, + origin, + media, + stylesheet_loader, + error_reporter, + extra_data) + } + + /// Updates an empty stylesheet with a set of bytes that reached over the + /// network. + pub fn update_from_bytes(existing: &Stylesheet, + bytes: &[u8], + protocol_encoding_label: Option<&str>, + environment_encoding: Option, + stylesheet_loader: Option<&StylesheetLoader>, + error_reporter: &ParseErrorReporter, + extra_data: ParserContextExtraData) { + let (string, _) = decode_stylesheet_bytes( + bytes, protocol_encoding_label, environment_encoding); + Self::update_from_str(existing, + &string, + stylesheet_loader, + error_reporter, + extra_data) + } +} diff --git a/components/style/lib.rs b/components/style/lib.rs index b681e5d1804..b5bc9f74440 100644 --- a/components/style/lib.rs +++ b/components/style/lib.rs @@ -43,7 +43,6 @@ extern crate atomic_refcell; extern crate bitflags; #[cfg(feature = "gecko")] #[macro_use] #[no_link] extern crate cfg_if; #[macro_use] extern crate cssparser; -extern crate encoding; extern crate euclid; extern crate fnv; #[cfg(feature = "gecko")] #[macro_use] pub mod gecko_string_cache; @@ -89,6 +88,7 @@ pub mod custom_properties; pub mod data; pub mod dom; pub mod element_state; +#[cfg(feature = "servo")] mod encoding_support; pub mod error_reporting; pub mod font_face; pub mod font_metrics; diff --git a/components/style/stylesheets.rs b/components/style/stylesheets.rs index 9145e761a4b..5b5c47e152f 100644 --- a/components/style/stylesheets.rs +++ b/components/style/stylesheets.rs @@ -7,10 +7,9 @@ #![deny(missing_docs)] use {Atom, Prefix, Namespace}; -use cssparser::{AtRuleParser, Parser, QualifiedRuleParser, stylesheet_encoding, EncodingSupport}; +use cssparser::{AtRuleParser, Parser, QualifiedRuleParser}; use cssparser::{AtRuleType, RuleListParser, SourcePosition, Token, parse_one_rule}; use cssparser::ToCss as ParserToCss; -use encoding::{self, EncodingRef, DecoderTrap}; use error_reporting::ParseErrorReporter; use font_face::{FontFaceRule, parse_font_face_block}; use keyframes::{Keyframe, parse_keyframe_list}; @@ -24,7 +23,6 @@ use servo_config::prefs::PREFS; use servo_url::ServoUrl; use std::cell::Cell; use std::fmt; -use std::str; use std::sync::Arc; use std::sync::atomic::{AtomicBool, Ordering}; use style_traits::ToCss; @@ -540,78 +538,7 @@ impl ToCss for StyleRule { } } -struct RustEncoding; - -impl EncodingSupport for RustEncoding { - type Encoding = EncodingRef; - - fn utf8() -> Self::Encoding { - encoding::all::UTF_8 - } - - fn is_utf16_be_or_le(encoding: &Self::Encoding) -> bool { - matches!(encoding.name(), "utf-16be" | "utf-16le") - } - - fn from_label(ascii_label: &[u8]) -> Option { - str::from_utf8(ascii_label).ok().and_then(encoding::label::encoding_from_whatwg_label) - } -} - -fn decode_stylesheet_bytes(css: &[u8], protocol_encoding_label: Option<&str>, - environment_encoding: Option) - -> (String, EncodingRef) { - let fallback_encoding = stylesheet_encoding::( - css, protocol_encoding_label.map(str::as_bytes), environment_encoding); - let (result, used_encoding) = encoding::decode(css, DecoderTrap::Replace, fallback_encoding); - (result.unwrap(), used_encoding) -} - impl Stylesheet { - /// Parse a stylesheet from a set of bytes, potentially received over the - /// network. - /// - /// Takes care of decoding the network bytes and forwards the resulting - /// string to `Stylesheet::from_str`. - pub fn from_bytes(bytes: &[u8], - base_url: ServoUrl, - protocol_encoding_label: Option<&str>, - environment_encoding: Option, - origin: Origin, - media: MediaList, - stylesheet_loader: Option<&StylesheetLoader>, - error_reporter: &ParseErrorReporter, - extra_data: ParserContextExtraData) - -> Stylesheet { - let (string, _) = decode_stylesheet_bytes( - bytes, protocol_encoding_label, environment_encoding); - Stylesheet::from_str(&string, - base_url, - origin, - media, - stylesheet_loader, - error_reporter, - extra_data) - } - - /// Updates an empty stylesheet with a set of bytes that reached over the - /// network. - pub fn update_from_bytes(existing: &Stylesheet, - bytes: &[u8], - protocol_encoding_label: Option<&str>, - environment_encoding: Option, - stylesheet_loader: Option<&StylesheetLoader>, - error_reporter: &ParseErrorReporter, - extra_data: ParserContextExtraData) { - let (string, _) = decode_stylesheet_bytes( - bytes, protocol_encoding_label, environment_encoding); - Self::update_from_str(existing, - &string, - stylesheet_loader, - error_reporter, - extra_data) - } - /// Updates an empty stylesheet from a given string of text. pub fn update_from_str(existing: &Stylesheet, css: &str,