Source code

Revision control

Other Tools

1
/* This Source Code Form is subject to the terms of the Mozilla Public
2
* License, v. 2.0. If a copy of the MPL was not distributed with this
3
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5
//! Parsing stylesheets from bytes (not `&str`).
6
7
extern crate encoding_rs;
8
9
use crate::context::QuirksMode;
10
use crate::error_reporting::ParseErrorReporter;
11
use crate::media_queries::MediaList;
12
use crate::shared_lock::SharedRwLock;
13
use crate::stylesheets::{Origin, Stylesheet, StylesheetLoader, UrlExtraData};
14
use cssparser::{stylesheet_encoding, EncodingSupport};
15
use servo_arc::Arc;
16
use std::borrow::Cow;
17
use std::str;
18
19
struct EncodingRs;
20
21
impl EncodingSupport for EncodingRs {
22
type Encoding = &'static encoding_rs::Encoding;
23
24
fn utf8() -> Self::Encoding {
25
encoding_rs::UTF_8
26
}
27
28
fn is_utf16_be_or_le(encoding: &Self::Encoding) -> bool {
29
*encoding == encoding_rs::UTF_16LE || *encoding == encoding_rs::UTF_16BE
30
}
31
32
fn from_label(ascii_label: &[u8]) -> Option<Self::Encoding> {
33
encoding_rs::Encoding::for_label(ascii_label)
34
}
35
}
36
37
fn decode_stylesheet_bytes<'a>(
38
css: &'a [u8],
39
protocol_encoding_label: Option<&str>,
40
environment_encoding: Option<&'static encoding_rs::Encoding>,
41
) -> Cow<'a, str> {
42
let fallback_encoding = stylesheet_encoding::<EncodingRs>(
43
css,
44
protocol_encoding_label.map(str::as_bytes),
45
environment_encoding,
46
);
47
let (result, _used_encoding, _) = fallback_encoding.decode(&css);
48
// FIXME record used encoding for environment encoding of @import
49
result
50
}
51
52
impl Stylesheet {
53
/// Parse a stylesheet from a set of bytes, potentially received over the
54
/// network.
55
///
56
/// Takes care of decoding the network bytes and forwards the resulting
57
/// string to `Stylesheet::from_str`.
58
pub fn from_bytes(
59
bytes: &[u8],
60
url_data: UrlExtraData,
61
protocol_encoding_label: Option<&str>,
62
environment_encoding: Option<&'static encoding_rs::Encoding>,
63
origin: Origin,
64
media: MediaList,
65
shared_lock: SharedRwLock,
66
stylesheet_loader: Option<&dyn StylesheetLoader>,
67
error_reporter: Option<&dyn ParseErrorReporter>,
68
quirks_mode: QuirksMode,
69
) -> Stylesheet {
70
let string = decode_stylesheet_bytes(bytes, protocol_encoding_label, environment_encoding);
71
Stylesheet::from_str(
72
&string,
73
url_data,
74
origin,
75
Arc::new(shared_lock.wrap(media)),
76
shared_lock,
77
stylesheet_loader,
78
error_reporter,
79
quirks_mode,
80
0,
81
)
82
}
83
84
/// Updates an empty stylesheet with a set of bytes that reached over the
85
/// network.
86
pub fn update_from_bytes(
87
existing: &Stylesheet,
88
bytes: &[u8],
89
protocol_encoding_label: Option<&str>,
90
environment_encoding: Option<&'static encoding_rs::Encoding>,
91
url_data: UrlExtraData,
92
stylesheet_loader: Option<&dyn StylesheetLoader>,
93
error_reporter: Option<&dyn ParseErrorReporter>,
94
) {
95
let string = decode_stylesheet_bytes(bytes, protocol_encoding_label, environment_encoding);
96
Self::update_from_str(
97
existing,
98
&string,
99
url_data,
100
stylesheet_loader,
101
error_reporter,
102
0,
103
)
104
}
105
}