2017-03-17 06:07:37 +03:00
|
|
|
/* 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
|
2018-12-02 21:46:06 +03:00
|
|
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
2017-03-17 06:07:37 +03:00
|
|
|
|
|
|
|
//! Parsing stylesheets from bytes (not `&str`).
|
|
|
|
|
2018-11-01 16:09:54 +03:00
|
|
|
use crate::context::QuirksMode;
|
|
|
|
use crate::error_reporting::ParseErrorReporter;
|
|
|
|
use crate::media_queries::MediaList;
|
|
|
|
use crate::shared_lock::SharedRwLock;
|
2020-04-16 18:01:24 +03:00
|
|
|
use crate::stylesheets::{AllowImportRules, Origin, Stylesheet, StylesheetLoader, UrlExtraData};
|
2017-03-17 06:07:37 +03:00
|
|
|
use cssparser::{stylesheet_encoding, EncodingSupport};
|
2017-07-19 16:03:17 +03:00
|
|
|
use servo_arc::Arc;
|
2017-11-01 14:37:54 +03:00
|
|
|
use std::borrow::Cow;
|
2017-03-17 06:07:37 +03:00
|
|
|
use std::str;
|
|
|
|
|
2017-11-01 14:37:54 +03:00
|
|
|
struct EncodingRs;
|
2017-03-17 06:07:37 +03:00
|
|
|
|
2017-11-01 14:37:54 +03:00
|
|
|
impl EncodingSupport for EncodingRs {
|
|
|
|
type Encoding = &'static encoding_rs::Encoding;
|
2017-03-17 06:07:37 +03:00
|
|
|
|
|
|
|
fn utf8() -> Self::Encoding {
|
2017-11-01 14:37:54 +03:00
|
|
|
encoding_rs::UTF_8
|
2017-03-17 06:07:37 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
fn is_utf16_be_or_le(encoding: &Self::Encoding) -> bool {
|
2018-04-11 04:00:11 +03:00
|
|
|
*encoding == encoding_rs::UTF_16LE || *encoding == encoding_rs::UTF_16BE
|
2017-03-17 06:07:37 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
fn from_label(ascii_label: &[u8]) -> Option<Self::Encoding> {
|
2017-11-01 14:37:54 +03:00
|
|
|
encoding_rs::Encoding::for_label(ascii_label)
|
2017-03-17 06:07:37 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-11 04:00:11 +03:00
|
|
|
fn decode_stylesheet_bytes<'a>(
|
|
|
|
css: &'a [u8],
|
|
|
|
protocol_encoding_label: Option<&str>,
|
|
|
|
environment_encoding: Option<&'static encoding_rs::Encoding>,
|
|
|
|
) -> Cow<'a, str> {
|
2017-11-01 14:37:54 +03:00
|
|
|
let fallback_encoding = stylesheet_encoding::<EncodingRs>(
|
2018-04-11 04:00:11 +03:00
|
|
|
css,
|
|
|
|
protocol_encoding_label.map(str::as_bytes),
|
|
|
|
environment_encoding,
|
|
|
|
);
|
2017-11-01 14:37:54 +03:00
|
|
|
let (result, _used_encoding, _) = fallback_encoding.decode(&css);
|
|
|
|
// FIXME record used encoding for environment encoding of @import
|
|
|
|
result
|
2017-03-17 06:07:37 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
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`.
|
2018-06-23 20:57:44 +03:00
|
|
|
pub fn from_bytes(
|
2018-04-11 04:00:11 +03:00
|
|
|
bytes: &[u8],
|
|
|
|
url_data: UrlExtraData,
|
|
|
|
protocol_encoding_label: Option<&str>,
|
|
|
|
environment_encoding: Option<&'static encoding_rs::Encoding>,
|
|
|
|
origin: Origin,
|
|
|
|
media: MediaList,
|
|
|
|
shared_lock: SharedRwLock,
|
2019-06-23 13:54:27 +03:00
|
|
|
stylesheet_loader: Option<&dyn StylesheetLoader>,
|
|
|
|
error_reporter: Option<&dyn ParseErrorReporter>,
|
2018-04-11 04:00:11 +03:00
|
|
|
quirks_mode: QuirksMode,
|
2018-06-23 20:57:44 +03:00
|
|
|
) -> Stylesheet {
|
2017-11-01 14:37:54 +03:00
|
|
|
let string = decode_stylesheet_bytes(bytes, protocol_encoding_label, environment_encoding);
|
2018-04-11 04:00:11 +03:00
|
|
|
Stylesheet::from_str(
|
|
|
|
&string,
|
|
|
|
url_data,
|
|
|
|
origin,
|
|
|
|
Arc::new(shared_lock.wrap(media)),
|
|
|
|
shared_lock,
|
|
|
|
stylesheet_loader,
|
|
|
|
error_reporter,
|
|
|
|
quirks_mode,
|
|
|
|
0,
|
2020-04-16 18:01:24 +03:00
|
|
|
AllowImportRules::Yes,
|
2018-04-11 04:00:11 +03:00
|
|
|
)
|
2017-03-17 06:07:37 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Updates an empty stylesheet with a set of bytes that reached over the
|
|
|
|
/// network.
|
2018-06-23 20:57:44 +03:00
|
|
|
pub fn update_from_bytes(
|
2018-04-11 04:00:11 +03:00
|
|
|
existing: &Stylesheet,
|
|
|
|
bytes: &[u8],
|
|
|
|
protocol_encoding_label: Option<&str>,
|
|
|
|
environment_encoding: Option<&'static encoding_rs::Encoding>,
|
|
|
|
url_data: UrlExtraData,
|
2019-06-23 13:54:27 +03:00
|
|
|
stylesheet_loader: Option<&dyn StylesheetLoader>,
|
|
|
|
error_reporter: Option<&dyn ParseErrorReporter>,
|
2018-06-23 20:57:44 +03:00
|
|
|
) {
|
2017-11-01 14:37:54 +03:00
|
|
|
let string = decode_stylesheet_bytes(bytes, protocol_encoding_label, environment_encoding);
|
2018-04-11 04:00:11 +03:00
|
|
|
Self::update_from_str(
|
|
|
|
existing,
|
|
|
|
&string,
|
|
|
|
url_data,
|
|
|
|
stylesheet_loader,
|
|
|
|
error_reporter,
|
|
|
|
0,
|
2020-04-16 18:01:24 +03:00
|
|
|
AllowImportRules::Yes,
|
2018-04-11 04:00:11 +03:00
|
|
|
)
|
2017-03-17 06:07:37 +03:00
|
|
|
}
|
|
|
|
}
|