servo: Merge #17086 - Add CSSOM support of @import rule for stylo (from upsuper:bug1352968); r=heycam
authorXidorn Quan <me@upsuper.org>
Mon, 29 May 2017 18:51:45 -0500
changeset 409269 c0a910347a2e3bed113447f3a151c8432b98d059
parent 409268 75eef8b3b1a55fda2faafba899062fc05e427bf6
child 409270 0ac37006d5ace7f389a23d1c5a5229c83b709115
push id7391
push usermtabara@mozilla.com
push dateMon, 12 Jun 2017 13:08:53 +0000
treeherdermozilla-beta@2191d7f87e2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersheycam
bugs17086, 1352968
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
servo: Merge #17086 - Add CSSOM support of @import rule for stylo (from upsuper:bug1352968); r=heycam This is the Servo side change of [bug 1352968](https://bugzilla.mozilla.org/show_bug.cgi?id=1352968). Source-Repo: https://github.com/servo/servo Source-Revision: 085743560caffc0d25c7225ac979a857efd82155
servo/components/style/gecko/generated/bindings.rs
servo/components/style/gecko/generated/structs_debug.rs
servo/components/style/gecko/generated/structs_release.rs
servo/components/style/stylesheets.rs
servo/ports/geckolib/glue.rs
--- a/servo/components/style/gecko/generated/bindings.rs
+++ b/servo/components/style/gecko/generated/bindings.rs
@@ -1735,20 +1735,16 @@ extern "C" {
                                               *const RawServoMediaList,
                                           extra_data:
                                               *mut RawGeckoURLExtraData,
                                           line_number_offset: u32,
                                           quirks_mode: nsCompatibility)
      -> RawServoStyleSheetStrong;
 }
 extern "C" {
-    pub fn Servo_ImportRule_GetSheet(import_rule: RawServoImportRuleBorrowed)
-     -> RawServoStyleSheetStrong;
-}
-extern "C" {
     pub fn Servo_StyleSheet_ClearAndUpdate(stylesheet:
                                                RawServoStyleSheetBorrowed,
                                            loader: *mut Loader,
                                            gecko_stylesheet:
                                                *mut ServoStyleSheet,
                                            data: *const nsACString,
                                            extra_data:
                                                *mut RawGeckoURLExtraData,
@@ -1869,16 +1865,30 @@ extern "C" {
     pub fn Servo_StyleRule_Debug(rule: RawServoStyleRuleBorrowed,
                                  result: *mut nsACString);
 }
 extern "C" {
     pub fn Servo_StyleRule_GetCssText(rule: RawServoStyleRuleBorrowed,
                                       result: *mut nsAString);
 }
 extern "C" {
+    pub fn Servo_CssRules_GetImportRuleAt(rules: ServoCssRulesBorrowed,
+                                          index: u32, line: *mut u32,
+                                          column: *mut u32)
+     -> RawServoImportRuleStrong;
+}
+extern "C" {
+    pub fn Servo_ImportRule_Debug(rule: RawServoImportRuleBorrowed,
+                                  result: *mut nsACString);
+}
+extern "C" {
+    pub fn Servo_ImportRule_GetCssText(rule: RawServoImportRuleBorrowed,
+                                       result: *mut nsAString);
+}
+extern "C" {
     pub fn Servo_Keyframe_Debug(rule: RawServoKeyframeBorrowed,
                                 result: *mut nsACString);
 }
 extern "C" {
     pub fn Servo_Keyframe_GetCssText(rule: RawServoKeyframeBorrowed,
                                      result: *mut nsAString);
 }
 extern "C" {
@@ -1996,16 +2006,24 @@ extern "C" {
                                     declarations:
                                         RawServoDeclarationBlockBorrowed);
 }
 extern "C" {
     pub fn Servo_StyleRule_GetSelectorText(rule: RawServoStyleRuleBorrowed,
                                            result: *mut nsAString);
 }
 extern "C" {
+    pub fn Servo_ImportRule_GetHref(rule: RawServoImportRuleBorrowed,
+                                    result: *mut nsAString);
+}
+extern "C" {
+    pub fn Servo_ImportRule_GetSheet(rule: RawServoImportRuleBorrowed)
+     -> *const RawServoStyleSheet;
+}
+extern "C" {
     pub fn Servo_Keyframe_GetKeyText(keyframe: RawServoKeyframeBorrowed,
                                      result: *mut nsAString);
 }
 extern "C" {
     pub fn Servo_Keyframe_SetKeyText(keyframe: RawServoKeyframeBorrowed,
                                      text: *const nsACString) -> bool;
 }
 extern "C" {
--- a/servo/components/style/gecko/generated/structs_debug.rs
+++ b/servo/components/style/gecko/generated/structs_debug.rs
@@ -1550,21 +1550,16 @@ pub mod root {
                 eSafeAgentSheetFeatures = 3,
             }
             #[repr(C)]
             #[derive(Debug, Copy, Clone)]
             pub struct GroupRule {
                 _unused: [u8; 0],
             }
             #[repr(C)]
-            #[derive(Debug, Copy, Clone)]
-            pub struct ImportRule {
-                _unused: [u8; 0],
-            }
-            #[repr(C)]
             #[derive(Debug)]
             pub struct Rule {
                 pub _base: root::nsIDOMCSSRule,
                 pub _base_1: root::nsWrapperCache,
                 pub mRefCnt: root::nsCycleCollectingAutoRefCnt,
                 pub _mOwningThread: root::nsAutoOwningThread,
                 pub mSheet: *mut root::mozilla::StyleSheet,
                 pub mParentRule: *mut root::mozilla::css::GroupRule,
@@ -3344,16 +3339,21 @@ pub mod root {
             }
             #[repr(C)]
             #[derive(Debug, Copy, Clone)]
             pub struct Promise {
                 _unused: [u8; 0],
             }
             #[repr(C)]
             #[derive(Debug, Copy, Clone)]
+            pub struct CSSImportRule {
+                _unused: [u8; 0],
+            }
+            #[repr(C)]
+            #[derive(Debug, Copy, Clone)]
             pub struct CSSRuleList {
                 _unused: [u8; 0],
             }
             #[repr(C)]
             #[derive(Debug)]
             pub struct MediaList {
                 pub _base: root::nsIDOMMediaList,
                 pub _base_1: root::nsWrapperCache,
@@ -6687,16 +6687,17 @@ pub mod root {
             pub _base_1: root::nsICSSLoaderObserver,
             pub _base_2: root::nsWrapperCache,
             pub mRefCnt: root::nsCycleCollectingAutoRefCnt,
             pub _mOwningThread: root::nsAutoOwningThread,
             pub mParent: *mut root::mozilla::StyleSheet,
             pub mTitle: ::nsstring::nsStringRepr,
             pub mDocument: *mut root::nsIDocument,
             pub mOwningNode: *mut root::nsINode,
+            pub mOwnerRule: *mut root::mozilla::dom::CSSImportRule,
             pub mMedia: root::RefPtr<root::mozilla::dom::MediaList>,
             pub mNext: root::RefPtr<root::mozilla::StyleSheet>,
             pub mParsingMode: root::mozilla::css::SheetParsingMode,
             pub mType: root::mozilla::StyleBackendType,
             pub mDisabled: bool,
             pub mDocumentAssociationMode: root::mozilla::StyleSheet_DocumentAssociationMode,
             pub mInner: *mut root::mozilla::StyleSheetInfo,
             pub mDirty: bool,
@@ -6781,17 +6782,17 @@ pub mod root {
         }
         extern "C" {
             #[link_name = "_ZN7mozilla10StyleSheet21_cycleCollectorGlobalE"]
             pub static mut StyleSheet__cycleCollectorGlobal:
                        root::mozilla::StyleSheet_cycleCollection;
         }
         #[test]
         fn bindgen_test_layout_StyleSheet() {
-            assert_eq!(::std::mem::size_of::<StyleSheet>() , 152usize , concat
+            assert_eq!(::std::mem::size_of::<StyleSheet>() , 160usize , concat
                        ! ( "Size of: " , stringify ! ( StyleSheet ) ));
             assert_eq! (::std::mem::align_of::<StyleSheet>() , 8usize , concat
                         ! ( "Alignment of " , stringify ! ( StyleSheet ) ));
         }
         #[repr(C)]
         #[derive(Debug)]
         pub struct OriginAttributes {
             pub _base: root::mozilla::dom::OriginAttributesDictionary,
--- a/servo/components/style/gecko/generated/structs_release.rs
+++ b/servo/components/style/gecko/generated/structs_release.rs
@@ -1474,21 +1474,16 @@ pub mod root {
                 eSafeAgentSheetFeatures = 3,
             }
             #[repr(C)]
             #[derive(Debug, Copy, Clone)]
             pub struct GroupRule {
                 _unused: [u8; 0],
             }
             #[repr(C)]
-            #[derive(Debug, Copy, Clone)]
-            pub struct ImportRule {
-                _unused: [u8; 0],
-            }
-            #[repr(C)]
             #[derive(Debug)]
             pub struct Rule {
                 pub _base: root::nsIDOMCSSRule,
                 pub _base_1: root::nsWrapperCache,
                 pub mRefCnt: root::nsCycleCollectingAutoRefCnt,
                 pub mSheet: *mut root::mozilla::StyleSheet,
                 pub mParentRule: *mut root::mozilla::css::GroupRule,
                 pub mLineNumber: u32,
@@ -3249,16 +3244,21 @@ pub mod root {
             }
             #[repr(C)]
             #[derive(Debug, Copy, Clone)]
             pub struct Promise {
                 _unused: [u8; 0],
             }
             #[repr(C)]
             #[derive(Debug, Copy, Clone)]
+            pub struct CSSImportRule {
+                _unused: [u8; 0],
+            }
+            #[repr(C)]
+            #[derive(Debug, Copy, Clone)]
             pub struct CSSRuleList {
                 _unused: [u8; 0],
             }
             #[repr(C)]
             #[derive(Debug)]
             pub struct MediaList {
                 pub _base: root::nsIDOMMediaList,
                 pub _base_1: root::nsWrapperCache,
@@ -6557,16 +6557,17 @@ pub mod root {
             pub _base: root::nsIDOMCSSStyleSheet,
             pub _base_1: root::nsICSSLoaderObserver,
             pub _base_2: root::nsWrapperCache,
             pub mRefCnt: root::nsCycleCollectingAutoRefCnt,
             pub mParent: *mut root::mozilla::StyleSheet,
             pub mTitle: ::nsstring::nsStringRepr,
             pub mDocument: *mut root::nsIDocument,
             pub mOwningNode: *mut root::nsINode,
+            pub mOwnerRule: *mut root::mozilla::dom::CSSImportRule,
             pub mMedia: root::RefPtr<root::mozilla::dom::MediaList>,
             pub mNext: root::RefPtr<root::mozilla::StyleSheet>,
             pub mParsingMode: root::mozilla::css::SheetParsingMode,
             pub mType: root::mozilla::StyleBackendType,
             pub mDisabled: bool,
             pub mDocumentAssociationMode: root::mozilla::StyleSheet_DocumentAssociationMode,
             pub mInner: *mut root::mozilla::StyleSheetInfo,
             pub mDirty: bool,
@@ -6651,17 +6652,17 @@ pub mod root {
         }
         extern "C" {
             #[link_name = "_ZN7mozilla10StyleSheet21_cycleCollectorGlobalE"]
             pub static mut StyleSheet__cycleCollectorGlobal:
                        root::mozilla::StyleSheet_cycleCollection;
         }
         #[test]
         fn bindgen_test_layout_StyleSheet() {
-            assert_eq!(::std::mem::size_of::<StyleSheet>() , 144usize , concat
+            assert_eq!(::std::mem::size_of::<StyleSheet>() , 152usize , concat
                        ! ( "Size of: " , stringify ! ( StyleSheet ) ));
             assert_eq! (::std::mem::align_of::<StyleSheet>() , 8usize , concat
                         ! ( "Alignment of " , stringify ! ( StyleSheet ) ));
         }
         #[repr(C)]
         #[derive(Debug)]
         pub struct OriginAttributes {
             pub _base: root::mozilla::dom::OriginAttributesDictionary,
--- a/servo/components/style/stylesheets.rs
+++ b/servo/components/style/stylesheets.rs
@@ -628,24 +628,28 @@ pub struct ImportRule {
     /// The `<url>` this `@import` rule is loading.
     pub url: SpecifiedUrl,
 
     /// The stylesheet is always present.
     ///
     /// It contains an empty list of rules and namespace set that is updated
     /// when it loads.
     pub stylesheet: Arc<Stylesheet>,
+
+    /// The line and column of the rule's source code.
+    pub source_location: SourceLocation,
 }
 
 impl Clone for ImportRule {
     fn clone(&self) -> ImportRule {
         let stylesheet: &Stylesheet = self.stylesheet.borrow();
         ImportRule {
             url: self.url.clone(),
             stylesheet: Arc::new(stylesheet.clone()),
+            source_location: self.source_location.clone(),
         }
     }
 }
 
 impl ToCssWithGuard for ImportRule {
     fn to_css<W>(&self, guard: &SharedRwLockReadGuard, dest: &mut W) -> fmt::Result
     where W: fmt::Write {
         try!(dest.write_str("@import "));
@@ -1525,16 +1529,18 @@ enum AtRulePrelude {
 
 
 impl<'a> AtRuleParser for TopLevelRuleParser<'a> {
     type Prelude = AtRulePrelude;
     type AtRule = CssRule;
 
     fn parse_prelude(&mut self, name: &str, input: &mut Parser)
                      -> Result<AtRuleType<AtRulePrelude, CssRule>, ()> {
+        let location = get_location_with_offset(input.current_source_location(),
+                                                self.context.line_number_offset);
         match_ignore_ascii_case! { name,
             "import" => {
                 if self.state.get() <= State::Imports {
                     self.state.set(State::Imports);
                     let url_string = input.expect_url_or_string()?;
                     let specified_url = SpecifiedUrl::parse_from_string(url_string, &self.context)?;
 
                     let media = parse_media_query_list(&self.context, input);
@@ -1556,34 +1562,32 @@ impl<'a> AtRuleParser for TopLevelRulePa
                                 media: media,
                                 shared_lock: self.shared_lock.clone(),
                                 origin: self.context.stylesheet_origin,
                                 url_data: self.context.url_data.clone(),
                                 namespaces: RwLock::new(Namespaces::default()),
                                 dirty_on_viewport_size_change: AtomicBool::new(false),
                                 disabled: AtomicBool::new(false),
                                 quirks_mode: self.context.quirks_mode,
-                            })
+                            }),
+                            source_location: location,
                         }
                     }, &mut |import_rule| {
                         Arc::new(self.shared_lock.wrap(import_rule))
                     });
                     return Ok(AtRuleType::WithoutBlock(CssRule::Import(arc)))
                 } else {
                     self.state.set(State::Invalid);
                     return Err(())  // "@import must be before any rule but @charset"
                 }
             },
             "namespace" => {
                 if self.state.get() <= State::Namespaces {
                     self.state.set(State::Namespaces);
 
-                    let location = get_location_with_offset(input.current_source_location(),
-                                                            self.context.line_number_offset);
-
                     let prefix_result = input.try(|input| input.expect_ident());
                     let url = Namespace::from(try!(input.expect_url_or_string()));
 
                     let opt_prefix = if let Ok(prefix) = prefix_result {
                         let prefix = Prefix::from(prefix);
                         self.namespaces.prefixes.insert(prefix.clone(), url.clone());
                         Some(prefix)
                     } else {
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -25,16 +25,17 @@ use style::gecko::restyle_damage::GeckoR
 use style::gecko::selector_parser::PseudoElement;
 use style::gecko::traversal::RecalcStyleOnly;
 use style::gecko::wrapper::GeckoElement;
 use style::gecko_bindings::bindings;
 use style::gecko_bindings::bindings::{RawGeckoElementBorrowed, RawGeckoElementBorrowedOrNull};
 use style::gecko_bindings::bindings::{RawGeckoKeyframeListBorrowed, RawGeckoKeyframeListBorrowedMut};
 use style::gecko_bindings::bindings::{RawServoDeclarationBlockBorrowed, RawServoDeclarationBlockStrong};
 use style::gecko_bindings::bindings::{RawServoDocumentRule, RawServoDocumentRuleBorrowed};
+use style::gecko_bindings::bindings::{RawServoImportRule, RawServoImportRuleBorrowed};
 use style::gecko_bindings::bindings::{RawServoKeyframe, RawServoKeyframeBorrowed, RawServoKeyframeStrong};
 use style::gecko_bindings::bindings::{RawServoKeyframesRule, RawServoKeyframesRuleBorrowed};
 use style::gecko_bindings::bindings::{RawServoMediaList, RawServoMediaListBorrowed, RawServoMediaListStrong};
 use style::gecko_bindings::bindings::{RawServoMediaRule, RawServoMediaRuleBorrowed};
 use style::gecko_bindings::bindings::{RawServoNamespaceRule, RawServoNamespaceRuleBorrowed};
 use style::gecko_bindings::bindings::{RawServoPageRule, RawServoPageRuleBorrowed};
 use style::gecko_bindings::bindings::{RawServoStyleSetBorrowed, RawServoStyleSetOwned};
 use style::gecko_bindings::bindings::{RawServoStyleSheetBorrowed, ServoComputedValuesBorrowed};
@@ -51,18 +52,18 @@ use style::gecko_bindings::bindings::Raw
 use style::gecko_bindings::bindings::RawGeckoCSSPropertyIDListBorrowed;
 use style::gecko_bindings::bindings::RawGeckoComputedKeyframeValuesListBorrowedMut;
 use style::gecko_bindings::bindings::RawGeckoComputedTimingBorrowed;
 use style::gecko_bindings::bindings::RawGeckoFontFaceRuleListBorrowedMut;
 use style::gecko_bindings::bindings::RawGeckoServoStyleRuleListBorrowedMut;
 use style::gecko_bindings::bindings::RawServoAnimationValueBorrowed;
 use style::gecko_bindings::bindings::RawServoAnimationValueMapBorrowedMut;
 use style::gecko_bindings::bindings::RawServoAnimationValueStrong;
-use style::gecko_bindings::bindings::RawServoImportRuleBorrowed;
 use style::gecko_bindings::bindings::RawServoStyleRuleBorrowed;
+use style::gecko_bindings::bindings::RawServoStyleSheet;
 use style::gecko_bindings::bindings::ServoComputedValuesBorrowedOrNull;
 use style::gecko_bindings::bindings::nsTArrayBorrowed_uintptr_t;
 use style::gecko_bindings::bindings::nsTimingFunctionBorrowed;
 use style::gecko_bindings::bindings::nsTimingFunctionBorrowedMut;
 use style::gecko_bindings::structs;
 use style::gecko_bindings::structs::{CSSPseudoElementType, CompositeOperation};
 use style::gecko_bindings::structs::{RawServoStyleRule, ServoStyleSheet};
 use style::gecko_bindings::structs::{SheetParsingMode, nsIAtom, nsCSSPropertyID};
@@ -983,16 +984,22 @@ macro_rules! impl_group_rule_funcs {
 }
 
 impl_basic_rule_funcs! { (Style, StyleRule, RawServoStyleRule),
     getter: Servo_CssRules_GetStyleRuleAt,
     debug: Servo_StyleRule_Debug,
     to_css: Servo_StyleRule_GetCssText,
 }
 
+impl_basic_rule_funcs! { (Import, ImportRule, RawServoImportRule),
+    getter: Servo_CssRules_GetImportRuleAt,
+    debug: Servo_ImportRule_Debug,
+    to_css: Servo_ImportRule_GetCssText,
+}
+
 impl_basic_rule_funcs_without_getter! { (Keyframe, RawServoKeyframe),
     debug: Servo_Keyframe_Debug,
     to_css: Servo_Keyframe_GetCssText,
 }
 
 impl_basic_rule_funcs! { (Keyframes, KeyframesRule, RawServoKeyframesRule),
     getter: Servo_CssRules_GetKeyframesRuleAt,
     debug: Servo_KeyframesRule_Debug,
@@ -1073,16 +1080,30 @@ pub extern "C" fn Servo_StyleRule_SetSty
 #[no_mangle]
 pub extern "C" fn Servo_StyleRule_GetSelectorText(rule: RawServoStyleRuleBorrowed, result: *mut nsAString) {
     read_locked_arc(rule, |rule: &StyleRule| {
         rule.selectors.to_css(unsafe { result.as_mut().unwrap() }).unwrap();
     })
 }
 
 #[no_mangle]
+pub extern "C" fn Servo_ImportRule_GetHref(rule: RawServoImportRuleBorrowed, result: *mut nsAString) {
+    read_locked_arc(rule, |rule: &ImportRule| {
+        write!(unsafe { &mut *result }, "{}", rule.url.as_str()).unwrap();
+    })
+}
+
+#[no_mangle]
+pub extern "C" fn Servo_ImportRule_GetSheet(rule: RawServoImportRuleBorrowed) -> *const RawServoStyleSheet {
+    read_locked_arc(rule, |rule: &ImportRule| {
+        rule.stylesheet.as_borrowed_opt().unwrap() as *const _
+    })
+}
+
+#[no_mangle]
 pub extern "C" fn Servo_Keyframe_GetKeyText(keyframe: RawServoKeyframeBorrowed, result: *mut nsAString) {
     read_locked_arc(keyframe, |keyframe: &Keyframe| {
         keyframe.selector.to_css(unsafe { result.as_mut().unwrap() }).unwrap()
     })
 }
 
 #[no_mangle]
 pub extern "C" fn Servo_Keyframe_SetKeyText(keyframe: RawServoKeyframeBorrowed, text: *const nsACString) -> bool {
@@ -2290,25 +2311,16 @@ pub extern "C" fn Servo_NoteExplicitHint
         restyle_data.hint.insert(restyle_hint.into());
         restyle_data.damage |= damage;
     } else {
         debug!("(Element not styled, discarding hints)");
     }
 }
 
 #[no_mangle]
-pub extern "C" fn Servo_ImportRule_GetSheet(import_rule:
-                                            RawServoImportRuleBorrowed)
-                                            -> RawServoStyleSheetStrong {
-    read_locked_arc(import_rule, |rule: &ImportRule| {
-        rule.stylesheet.clone().into_strong()
-    })
-}
-
-#[no_mangle]
 pub extern "C" fn Servo_TakeChangeHint(element: RawGeckoElementBorrowed) -> nsChangeHint
 {
     let element = GeckoElement(element);
     let damage = if let Some(mut data) = element.mutate_data() {
         let d = data.get_restyle().map_or(GeckoRestyleDamage::empty(), |r| r.damage);
         data.clear_restyle();
         d
     } else {