Bug 1348481 Part 3: Servo-side implementation of the styleset regenerate function. draft
authorBrad Werth <bwerth@mozilla.com>
Tue, 25 Apr 2017 15:03:04 -0700
changeset 568278 7e35f0523e8841de16641355cc4db6c0d611d34d
parent 568277 ef9074386f5a42ffa0a201e8b142c7d645dd016b
child 568279 1ed0f961aae3304f994bda50363d7fd269cad6f5
push id55811
push userbwerth@mozilla.com
push dateTue, 25 Apr 2017 22:15:27 +0000
bugs1348481
milestone55.0a1
Bug 1348481 Part 3: Servo-side implementation of the styleset regenerate function. MozReview-Commit-ID: 5kZWS5Lu8Sp
servo/components/style/build_gecko.rs
servo/ports/geckolib/glue.rs
--- a/servo/components/style/build_gecko.rs
+++ b/servo/components/style/build_gecko.rs
@@ -636,16 +636,17 @@ mod bindings {
             "RawServoAnimationValue",
             "RawServoAnimationValueMap",
             "RawServoDeclarationBlock",
             "RawServoStyleRule",
             "RawGeckoPresContext",
             "RawGeckoPresContextOwned",
             "RawGeckoStyleAnimationList",
             "RawGeckoServoStyleRuleList",
+            "RawGeckoServoStyleSheetList",
             "RawGeckoURLExtraData",
             "RefPtr",
             "CSSPseudoClassType",
             "TraversalRestyleBehavior",
             "TraversalRootBehavior",
             "ComputedTimingFunction_BeforeFlag",
             "FontFamilyList",
             "FontFamilyType",
@@ -753,16 +754,17 @@ mod bindings {
             "nsTimingFunction",
             "RawGeckoAnimationPropertySegment",
             "RawGeckoAnimationValueList",
             "RawGeckoComputedTiming",
             "RawGeckoKeyframeList",
             "RawGeckoComputedKeyframeValuesList",
             "RawGeckoFontFaceRuleList",
             "RawGeckoServoStyleRuleList",
+            "RawGeckoServoStyleSheetList",
         ];
         for &ty in structs_types.iter() {
             builder = builder.hide_type(ty)
                 .raw_line(format!("use gecko_bindings::structs::{};", ty));
             // TODO this is hacky, figure out a better way to do it without
             // hardcoding everything...
             if ty.starts_with("nsStyle") {
                 builder = builder
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -6,16 +6,17 @@ use atomic_refcell::AtomicRefMut;
 use cssparser::Parser;
 use cssparser::ToCss as ParserToCss;
 use env_logger::LogBuilder;
 use parking_lot::RwLock;
 use selectors::Element;
 use std::borrow::Cow;
 use std::env;
 use std::fmt::Write;
+use std::mem;
 use std::ptr;
 use std::sync::{Arc, Mutex};
 use style::context::{QuirksMode, SharedStyleContext, StyleContext};
 use style::context::{ThreadLocalStyleContext, ThreadLocalStyleContextCreationInfo};
 use style::data::{ElementData, ElementStyles, RestyleData};
 use style::dom::{AnimationOnlyDirtyDescendants, DirtyDescendants};
 use style::dom::{ShowSubtreeData, TElement, TNode};
 use style::error_reporting::RustLogReporter;
@@ -40,27 +41,28 @@ use style::gecko_bindings::bindings::{Se
 use style::gecko_bindings::bindings::{nsACString, nsAString};
 use style::gecko_bindings::bindings::Gecko_AnimationAppendKeyframe;
 use style::gecko_bindings::bindings::RawGeckoAnimationPropertySegmentBorrowed;
 use style::gecko_bindings::bindings::RawGeckoComputedKeyframeValuesListBorrowedMut;
 use style::gecko_bindings::bindings::RawGeckoComputedTimingBorrowed;
 use style::gecko_bindings::bindings::RawGeckoElementBorrowed;
 use style::gecko_bindings::bindings::RawGeckoFontFaceRuleListBorrowedMut;
 use style::gecko_bindings::bindings::RawGeckoServoStyleRuleListBorrowedMut;
+use style::gecko_bindings::bindings::RawGeckoServoStyleSheetListBorrowed;
 use style::gecko_bindings::bindings::RawServoAnimationValueBorrowed;
 use style::gecko_bindings::bindings::RawServoAnimationValueMapBorrowed;
 use style::gecko_bindings::bindings::RawServoAnimationValueStrong;
 use style::gecko_bindings::bindings::RawServoImportRuleBorrowed;
 use style::gecko_bindings::bindings::RawServoStyleRuleBorrowed;
 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::{RawServoStyleRule, ServoStyleSheet};
+use style::gecko_bindings::structs::{RawServoStyleRule, RawServoStyleSheet, ServoStyleSheet};
 use style::gecko_bindings::structs::{SheetParsingMode, nsIAtom, nsCSSPropertyID};
 use style::gecko_bindings::structs::{nsRestyleHint, nsChangeHint, nsCSSFontFaceRule};
 use style::gecko_bindings::structs::Loader;
 use style::gecko_bindings::structs::RawGeckoPresContextOwned;
 use style::gecko_bindings::structs::URLExtraData;
 use style::gecko_bindings::structs::nsCSSValueSharedList;
 use style::gecko_bindings::structs::nsresult;
 use style::gecko_bindings::sugar::ownership::{FFIArcHelpers, HasFFI, HasArcFFI, HasBoxFFI};
@@ -639,16 +641,43 @@ pub extern "C" fn Servo_StyleSet_RemoveS
     let sheet = HasArcFFI::as_arc(&raw_sheet);
     data.stylesheets.remove_stylesheet(sheet);
     if flush {
         data.flush_stylesheets(&guard);
     }
 }
 
 #[no_mangle]
+pub extern "C" fn Servo_StyleSet_Regenerate(raw_data: RawServoStyleSetBorrowed,
+                                            raw_sheets: RawGeckoServoStyleSheetListBorrowed) {
+    let global_style_data = &*GLOBAL_STYLE_DATA;
+    let guard = global_style_data.shared_lock.read();
+    let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();
+
+    // Clear the stylesheets, then regenerate them from raw_sheets.
+    data.stylesheets.clear();
+    for raw_sheet in raw_sheets.iter() {
+        // This transmute is necessary to convert the value from the iter
+        // into the proper borrowed type.
+        let unsafeSheet: RawServoStyleSheetBorrowed =
+        unsafe {
+            mem::transmute::<
+                &RawServoStyleSheet,
+                RawServoStyleSheetBorrowed>(&**raw_sheet)
+        };
+        let sheet = HasArcFFI::as_arc(&unsafeSheet);
+        data.stylesheets.append_stylesheet(sheet);
+    }
+
+    // Always flush -- we assume callers will only call this once if there are
+    // consecutive changes on the Gecko side.
+    data.flush_stylesheets(&guard);
+}
+
+#[no_mangle]
 pub extern "C" fn Servo_StyleSet_FlushStyleSheets(raw_data: RawServoStyleSetBorrowed) {
     let global_style_data = &*GLOBAL_STYLE_DATA;
     let guard = global_style_data.shared_lock.read();
     let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();
     data.flush_stylesheets(&guard);
 }
 
 #[no_mangle]