summaryrefslogtreecommitdiffstats
path: root/servo/components/style/encoding_support.rs
diff options
context:
space:
mode:
Diffstat (limited to 'servo/components/style/encoding_support.rs')
-rw-r--r--servo/components/style/encoding_support.rs105
1 files changed, 105 insertions, 0 deletions
diff --git a/servo/components/style/encoding_support.rs b/servo/components/style/encoding_support.rs
new file mode 100644
index 0000000000..c144ad0b3b
--- /dev/null
+++ b/servo/components/style/encoding_support.rs
@@ -0,0 +1,105 @@
+/* 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 https://mozilla.org/MPL/2.0/. */
+
+//! Parsing stylesheets from bytes (not `&str`).
+
+use crate::context::QuirksMode;
+use crate::error_reporting::ParseErrorReporter;
+use crate::media_queries::MediaList;
+use crate::shared_lock::SharedRwLock;
+use crate::stylesheets::{AllowImportRules, Origin, Stylesheet, StylesheetLoader, UrlExtraData};
+use cssparser::{stylesheet_encoding, EncodingSupport};
+use servo_arc::Arc;
+use std::borrow::Cow;
+use std::str;
+
+struct EncodingRs;
+
+impl EncodingSupport for EncodingRs {
+ type Encoding = &'static encoding_rs::Encoding;
+
+ fn utf8() -> Self::Encoding {
+ encoding_rs::UTF_8
+ }
+
+ fn is_utf16_be_or_le(encoding: &Self::Encoding) -> bool {
+ *encoding == encoding_rs::UTF_16LE || *encoding == encoding_rs::UTF_16BE
+ }
+
+ fn from_label(ascii_label: &[u8]) -> Option<Self::Encoding> {
+ encoding_rs::Encoding::for_label(ascii_label)
+ }
+}
+
+fn decode_stylesheet_bytes<'a>(
+ css: &'a [u8],
+ protocol_encoding_label: Option<&str>,
+ environment_encoding: Option<&'static encoding_rs::Encoding>,
+) -> Cow<'a, str> {
+ let fallback_encoding = stylesheet_encoding::<EncodingRs>(
+ css,
+ protocol_encoding_label.map(str::as_bytes),
+ environment_encoding,
+ );
+ let (result, _used_encoding, _) = fallback_encoding.decode(&css);
+ // FIXME record used encoding for environment encoding of @import
+ result
+}
+
+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],
+ url_data: UrlExtraData,
+ protocol_encoding_label: Option<&str>,
+ environment_encoding: Option<&'static encoding_rs::Encoding>,
+ origin: Origin,
+ media: MediaList,
+ shared_lock: SharedRwLock,
+ stylesheet_loader: Option<&dyn StylesheetLoader>,
+ error_reporter: Option<&dyn ParseErrorReporter>,
+ quirks_mode: QuirksMode,
+ ) -> Stylesheet {
+ let string = decode_stylesheet_bytes(bytes, protocol_encoding_label, environment_encoding);
+ Stylesheet::from_str(
+ &string,
+ url_data,
+ origin,
+ Arc::new(shared_lock.wrap(media)),
+ shared_lock,
+ stylesheet_loader,
+ error_reporter,
+ quirks_mode,
+ 0,
+ AllowImportRules::Yes,
+ )
+ }
+
+ /// 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<&'static encoding_rs::Encoding>,
+ url_data: UrlExtraData,
+ stylesheet_loader: Option<&dyn StylesheetLoader>,
+ error_reporter: Option<&dyn ParseErrorReporter>,
+ ) {
+ let string = decode_stylesheet_bytes(bytes, protocol_encoding_label, environment_encoding);
+ Self::update_from_str(
+ existing,
+ &string,
+ url_data,
+ stylesheet_loader,
+ error_reporter,
+ 0,
+ AllowImportRules::Yes,
+ )
+ }
+}