Expose the source map URL on a style sheet

This changes Servo to track the source map URL of a style sheet.  This
parallels a change going in to Gecko:
https://bugzilla.mozilla.org/show_bug.cgi?id=1388855
This commit is contained in:
Tom Tromey 2017-08-11 14:40:20 -06:00
parent fbabcaf614
commit 7224a5617f
7 changed files with 61 additions and 17 deletions

26
Cargo.lock generated
View file

@ -326,7 +326,7 @@ dependencies = [
"azure 0.20.1 (git+https://github.com/servo/rust-azure)",
"canvas_traits 0.0.1",
"compositing 0.0.1",
"cssparser 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cssparser 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gleam 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
"ipc-channel 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -341,7 +341,7 @@ dependencies = [
name = "canvas_traits"
version = "0.0.1"
dependencies = [
"cssparser 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cssparser 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_derive 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
@ -589,7 +589,7 @@ dependencies = [
[[package]]
name = "cssparser"
version = "0.19.0"
version = "0.19.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cssparser-macros 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1029,7 +1029,7 @@ name = "geckoservo"
version = "0.0.1"
dependencies = [
"atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cssparser 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cssparser 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1097,7 +1097,7 @@ dependencies = [
name = "gfx_tests"
version = "0.0.1"
dependencies = [
"cssparser 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cssparser 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gfx 0.0.1",
"ipc-channel 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"style 0.0.1",
@ -2470,7 +2470,7 @@ dependencies = [
"caseless 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"cmake 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)",
"cookie 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"cssparser 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cssparser 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)",
"deny_public_fields 0.0.1",
"devtools_traits 0.0.1",
"dom_struct 0.0.1",
@ -2543,7 +2543,7 @@ dependencies = [
"app_units 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"canvas_traits 0.0.1",
"cssparser 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cssparser 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gfx_traits 0.0.1",
"heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2616,7 +2616,7 @@ name = "selectors"
version = "0.19.0"
dependencies = [
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cssparser 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cssparser 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)",
"fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
@ -3015,7 +3015,7 @@ dependencies = [
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"cssparser 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cssparser 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)",
"encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
"fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
@ -3070,7 +3070,7 @@ version = "0.0.1"
dependencies = [
"app_units 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cssparser 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cssparser 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
"html5ever 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
@ -3092,7 +3092,7 @@ version = "0.0.1"
dependencies = [
"app_units 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cssparser 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cssparser 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_derive 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
@ -3107,7 +3107,7 @@ name = "stylo_tests"
version = "0.0.1"
dependencies = [
"atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cssparser 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cssparser 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
"geckoservo 0.0.1",
@ -3698,7 +3698,7 @@ dependencies = [
"checksum core-foundation-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "41115a6aa5d3e1e5ef98148373f25971d1fad53818553f216495f9e67e90a624"
"checksum core-graphics 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a9f841e9637adec70838c537cae52cb4c751cc6514ad05669b51d107c2021c79"
"checksum core-text 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "16ce16d9ed00181016c11ff48e561314bec92bfbce9fe48f319366618d4e5de6"
"checksum cssparser 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f3a5464ebae36626f28254b60d1abbba951417383192bcea65578b40fbec1a47"
"checksum cssparser 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1ce5f581b2fea3c097574b99ba16ca79607c4fc0d5e685b74b4ea05f2b18fe6c"
"checksum cssparser-macros 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "079adec4af52bb5275eadd004292028c79eb3c5f5b4ee8086a36d4197032f6df"
"checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850"
"checksum dbus 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4aee01fb76ada3e5e7ca642ea6664ebf7308a810739ca2aca44909a1191ac254"

View file

@ -113,6 +113,7 @@ impl HTMLMetaElement {
// resize; they don't need to force all styles to be
// recomputed.
dirty_on_viewport_size_change: AtomicBool::new(false),
source_map_url: RwLock::new(None),
},
media: Arc::new(shared_lock.wrap(MediaList::empty())),
shared_lock: shared_lock.clone(),

View file

@ -292,6 +292,7 @@ impl<'a> StyleStylesheetLoader for StylesheetLoader<'a> {
dirty_on_viewport_size_change: AtomicBool::new(false),
quirks_mode: context.quirks_mode,
namespaces: RwLock::new(Namespaces::default()),
source_map_url: RwLock::new(None),
},
media: media,
shared_lock: lock.clone(),

View file

@ -1960,6 +1960,10 @@ extern "C" {
RawServoStyleSheetContentsBorrowed)
-> OriginFlags;
}
extern "C" {
pub fn Servo_StyleSheet_GetSourceMapURL(sheet: RawServoStyleSheetContentsBorrowed,
result: *mut nsAString);
}
extern "C" {
pub fn Servo_StyleSet_Init(pres_context: RawGeckoPresContextOwned)
-> *mut RawServoStyleSet;

View file

@ -59,6 +59,8 @@ pub struct StylesheetContents {
pub quirks_mode: QuirksMode,
/// Whether this stylesheet would be dirty when the viewport size changes.
pub dirty_on_viewport_size_change: AtomicBool,
/// This stylesheet's source map URL.
pub source_map_url: RwLock<Option<String>>,
}
impl StylesheetContents {
@ -75,7 +77,7 @@ impl StylesheetContents {
line_number_offset: u64
) -> Self {
let namespaces = RwLock::new(Namespaces::default());
let (rules, dirty_on_viewport_size_change) = Stylesheet::parse_rules(
let (rules, dirty_on_viewport_size_change, source_map_url) = Stylesheet::parse_rules(
css,
&url_data,
origin,
@ -94,6 +96,7 @@ impl StylesheetContents {
namespaces: namespaces,
dirty_on_viewport_size_change: AtomicBool::new(dirty_on_viewport_size_change),
quirks_mode: quirks_mode,
source_map_url: RwLock::new(source_map_url),
}
}
@ -138,6 +141,7 @@ impl DeepCloneWithLock for StylesheetContents {
origin: self.origin,
url_data: RwLock::new((*self.url_data.read()).clone()),
namespaces: RwLock::new((*self.namespaces.read()).clone()),
source_map_url: RwLock::new((*self.source_map_url.read()).clone()),
}
}
}
@ -280,7 +284,7 @@ impl Stylesheet {
error_reporter: &ParseErrorReporter,
line_number_offset: u64) {
let namespaces = RwLock::new(Namespaces::default());
let (rules, dirty_on_viewport_size_change) =
let (rules, dirty_on_viewport_size_change, source_map_url) =
Stylesheet::parse_rules(
css,
&url_data,
@ -304,6 +308,7 @@ impl Stylesheet {
// Acquire the lock *after* parsing, to minimize the exclusive section.
let mut guard = existing.shared_lock.write();
*existing.contents.rules.write_with(&mut guard) = CssRules(rules);
*existing.contents.source_map_url.write() = source_map_url;
}
fn parse_rules(
@ -316,7 +321,7 @@ impl Stylesheet {
error_reporter: &ParseErrorReporter,
quirks_mode: QuirksMode,
line_number_offset: u64
) -> (Vec<CssRule>, bool) {
) -> (Vec<CssRule>, bool, Option<String>) {
let mut rules = Vec::new();
let mut input = ParserInput::new(css);
let mut input = Parser::new(&mut input);
@ -358,7 +363,8 @@ impl Stylesheet {
}
}
(rules, input.seen_viewport_percentages())
let source_map_url = input.current_source_map_url().map(String::from);
(rules, input.seen_viewport_percentages(), source_map_url)
}
/// Creates an empty stylesheet and parses it with a given base url, origin

View file

@ -1056,6 +1056,18 @@ pub extern "C" fn Servo_StyleSheet_GetOrigin(
}
}
#[no_mangle]
pub extern "C" fn Servo_StyleSheet_GetSourceMapURL(
sheet: RawServoStyleSheetContentsBorrowed,
result: *mut nsAString
) {
let contents = StylesheetContents::as_arc(&sheet);
let url_opt = contents.source_map_url.read();
if let Some(ref url) = *url_opt {
write!(unsafe { &mut *result }, "{}", url).unwrap();
}
}
fn read_locked_arc<T, R, F>(raw: &<Locked<T> as HasFFI>::FFIType, func: F) -> R
where Locked<T>: HasArcFFI, F: FnOnce(&T) -> R
{

View file

@ -241,6 +241,7 @@ fn test_parse_stylesheet() {
},
})))
], &stylesheet.shared_lock),
source_map_url: RwLock::new(None),
},
media: Arc::new(stylesheet.shared_lock.wrap(MediaList::empty())),
shared_lock: stylesheet.shared_lock.clone(),
@ -350,3 +351,22 @@ fn test_no_report_unrecognized_vendor_properties() {
error.message);
assert!(errors.is_empty());
}
#[test]
fn test_source_map_url() {
let tests = vec![
("", None),
("/*# sourceMappingURL=something */", Some("something".to_string())),
];
for test in tests {
let url = ServoUrl::parse("about::test").unwrap();
let lock = SharedRwLock::new();
let media = Arc::new(lock.wrap(MediaList::empty()));
let stylesheet = Stylesheet::from_str(test.0, url.clone(), Origin::UserAgent, media, lock,
None, &CSSErrorReporterTest, QuirksMode::NoQuirks,
0u64);
let url_opt = stylesheet.contents.source_map_url.read();
assert_eq!(*url_opt, test.1);
}
}