fune/servo/components/style/encoding_support.rs
mckaymatt 149e726153 servo: Merge #16394 - Support line number offsets for inline stylesheets (from mckaymatt:line_num_offset__issue_15693); r=SimonSapin
<!-- Please describe your changes on the following line: -->
This allows accurate line numbers when reporting stylesheet errors.

@jdm This is going to require some effort to merge my changes with other recent changes to `ParserContext`. Because of that I would appreciate a quick sanity check before I put the time into performing the merge.
For example, should I store the `offset` as a u64, or should it be an Option?

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [x] These changes fix #15693 (github issue number if applicable).

<!-- Either: -->
- [x] There are tests for these changes OR
- [ ] These changes do not require tests because _____

<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

Source-Repo: https://github.com/servo/servo
Source-Revision: 94397ff0b4fed138241760770ff2d230985bed8a

--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : 3ebb0c3b05f4529ae61351b2c9120f013d1d3339
2017-04-13 20:12:08 -05:00

90 lines
3.5 KiB
Rust

/* 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 self::encoding::{EncodingRef, DecoderTrap};
use shared_lock::SharedRwLock;
use std::str;
use std::sync::Arc;
use stylesheets::{Stylesheet, StylesheetLoader, Origin, UrlExtraData};
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<Self::Encoding> {
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<EncodingRef>)
-> (String, EncodingRef) {
let fallback_encoding = stylesheet_encoding::<RustEncoding>(
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],
url_data: UrlExtraData,
protocol_encoding_label: Option<&str>,
environment_encoding: Option<EncodingRef>,
origin: Origin,
media: MediaList,
shared_lock: SharedRwLock,
stylesheet_loader: Option<&StylesheetLoader>,
error_reporter: &ParseErrorReporter)
-> 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,
0u64)
}
/// 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<EncodingRef>,
url_data: &UrlExtraData,
stylesheet_loader: Option<&StylesheetLoader>,
error_reporter: &ParseErrorReporter) {
let (string, _) = decode_stylesheet_bytes(
bytes, protocol_encoding_label, environment_encoding);
Self::update_from_str(existing,
&string,
url_data,
stylesheet_loader,
error_reporter)
}
}