Bug 1339629 Part 1: Servo-side function to clone ServoStyleSheets. draft
authorBrad Werth <bwerth@mozilla.com>
Mon, 22 May 2017 12:55:43 -0700
changeset 584134 c84e209b6e7554f28e4b339d5a3eb270a5350d42
parent 584133 05621e30dc9ce60d697ba3c6474e852b392fb4f4
child 584135 c8d8be66c978cacdb3ba07e5f8415f1a9bd49d74
push id60643
push userbwerth@mozilla.com
push dateWed, 24 May 2017 23:47:41 +0000
bugs1339629
milestone55.0a1
Bug 1339629 Part 1: Servo-side function to clone ServoStyleSheets. MozReview-Commit-ID: 6hYIcOa86Y
servo/components/style/gecko/generated/bindings.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
@@ -1728,16 +1728,20 @@ extern "C" {
     pub fn Servo_StyleSheet_HasRules(sheet: RawServoStyleSheetBorrowed)
      -> bool;
 }
 extern "C" {
     pub fn Servo_StyleSheet_GetRules(sheet: RawServoStyleSheetBorrowed)
      -> ServoCssRulesStrong;
 }
 extern "C" {
+    pub fn Servo_StyleSheet_Clone(sheet: RawServoStyleSheetBorrowed)
+     -> RawServoStyleSheetStrong;
+}
+extern "C" {
     pub fn Servo_StyleSet_Init(pres_context: RawGeckoPresContextOwned)
      -> RawServoStyleSetOwned;
 }
 extern "C" {
     pub fn Servo_StyleSet_Clear(set: RawServoStyleSetBorrowed);
 }
 extern "C" {
     pub fn Servo_StyleSet_RebuildData(set: RawServoStyleSetBorrowed);
--- a/servo/components/style/stylesheets.rs
+++ b/servo/components/style/stylesheets.rs
@@ -86,17 +86,17 @@ pub enum Origin {
     /// http://dev.w3.org/csswg/css-cascade/#cascade-origin-author
     Author,
 
     /// http://dev.w3.org/csswg/css-cascade/#cascade-origin-user
     User,
 }
 
 /// A set of namespaces applying to a given stylesheet.
-#[derive(Default, Debug)]
+#[derive(Clone, Default, Debug)]
 #[allow(missing_docs)]
 pub struct Namespaces {
     pub default: Option<Namespace>,
     pub prefixes: FnvHashMap<Prefix , Namespace>,
 }
 
 /// A list of CSS rules.
 #[derive(Debug)]
@@ -896,16 +896,33 @@ impl Stylesheet {
     ///
     /// Disabled stylesheets remain in the document, but their rules are not
     /// added to the Stylist.
     pub fn set_disabled(&self, disabled: bool) -> bool {
         self.disabled.swap(disabled, Ordering::SeqCst) != disabled
     }
 }
 
+impl Clone for Stylesheet {
+    fn clone(&self) -> Stylesheet {
+        Stylesheet {
+            rules: self.rules.clone(),
+            media: self.media.clone(),
+            origin: self.origin,
+            url_data: self.url_data.clone(),
+            shared_lock: self.shared_lock.clone(),
+            namespaces: RwLock::new((*self.namespaces.read()).clone()),
+            dirty_on_viewport_size_change: AtomicBool::new(
+                self.dirty_on_viewport_size_change.load(Ordering::SeqCst)),
+            disabled: AtomicBool::new(self.disabled.load(Ordering::SeqCst)),
+            quirks_mode: self.quirks_mode,
+        }
+    }
+}
+
 fn effective_rules<F>(rules: &[CssRule],
                       device: &Device,
                       quirks_mode: QuirksMode,
                       guard: &SharedRwLockReadGuard,
                       f: &mut F)
     where F: FnMut(&CssRule)
 {
     for rule in rules {
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -787,16 +787,22 @@ pub extern "C" fn Servo_StyleSheet_HasRu
     !Stylesheet::as_arc(&raw_sheet).rules.read_with(&guard).0.is_empty()
 }
 
 #[no_mangle]
 pub extern "C" fn Servo_StyleSheet_GetRules(sheet: RawServoStyleSheetBorrowed) -> ServoCssRulesStrong {
     Stylesheet::as_arc(&sheet).rules.clone().into_strong()
 }
 
+#[no_mangle]
+pub extern "C" fn Servo_StyleSheet_Clone(raw_sheet: RawServoStyleSheetBorrowed) -> RawServoStyleSheetStrong {
+    let sheet: &Arc<Stylesheet> = HasArcFFI::as_arc(&raw_sheet);
+    Arc::new(sheet.as_ref().clone()).into_strong()
+}
+
 fn read_locked_arc<T, R, F>(raw: &<Locked<T> as HasFFI>::FFIType, func: F) -> R
     where Locked<T>: HasArcFFI, F: FnOnce(&T) -> R
 {
     let global_style_data = &*GLOBAL_STYLE_DATA;
     let guard = global_style_data.shared_lock.read();
     func(Locked::<T>::as_arc(&raw).read_with(&guard))
 }