From 7224a5617f4ce1a5ff49be10781c40319c08c898 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Fri, 11 Aug 2017 14:40:20 -0600 Subject: [PATCH] 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 --- Cargo.lock | 26 ++++++++++---------- components/script/dom/htmlmetaelement.rs | 1 + components/script/stylesheet_loader.rs | 1 + components/style/gecko/generated/bindings.rs | 4 +++ components/style/stylesheets/stylesheet.rs | 14 ++++++++--- ports/geckolib/glue.rs | 12 +++++++++ tests/unit/style/stylesheets.rs | 20 +++++++++++++++ 7 files changed, 61 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4455b98c203..c3f25fc9531 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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" diff --git a/components/script/dom/htmlmetaelement.rs b/components/script/dom/htmlmetaelement.rs index 9370675eb6b..481da1c092f 100644 --- a/components/script/dom/htmlmetaelement.rs +++ b/components/script/dom/htmlmetaelement.rs @@ -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(), diff --git a/components/script/stylesheet_loader.rs b/components/script/stylesheet_loader.rs index 888cec43650..2271a8bba0a 100644 --- a/components/script/stylesheet_loader.rs +++ b/components/script/stylesheet_loader.rs @@ -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(), diff --git a/components/style/gecko/generated/bindings.rs b/components/style/gecko/generated/bindings.rs index f2798817eb4..d4b7e94326a 100644 --- a/components/style/gecko/generated/bindings.rs +++ b/components/style/gecko/generated/bindings.rs @@ -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; diff --git a/components/style/stylesheets/stylesheet.rs b/components/style/stylesheets/stylesheet.rs index 9c416dd9eab..2885c2c2468 100644 --- a/components/style/stylesheets/stylesheet.rs +++ b/components/style/stylesheets/stylesheet.rs @@ -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>, } 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, bool) { + ) -> (Vec, bool, Option) { 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 diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index efcea6f685d..4d6061206f2 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -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(raw: & as HasFFI>::FFIType, func: F) -> R where Locked: HasArcFFI, F: FnOnce(&T) -> R { diff --git a/tests/unit/style/stylesheets.rs b/tests/unit/style/stylesheets.rs index 7d58363c156..6683b26377a 100644 --- a/tests/unit/style/stylesheets.rs +++ b/tests/unit/style/stylesheets.rs @@ -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); + } +}