Bug 1394233: Quirks mode changes can happen after a flush. r?xidorn draft
authorEmilio Cobos Álvarez <emilio@crisal.io>
Fri, 09 Feb 2018 17:07:42 +0100
changeset 753069 0a49b2638ba07e9e575a7fec6f01209d481ad962
parent 753068 f93437f738a3685402700688f5458ceef229d40f
push id98474
push userbmo:emilio@crisal.io
push dateFri, 09 Feb 2018 16:17:58 +0000
reviewersxidorn
bugs1394233, 1355721
milestone60.0a1
Bug 1394233: Quirks mode changes can happen after a flush. r?xidorn The reason why bug 1355721 regressed this is because in non-e10s we definitely flush before parsing the standards quirks-mode. And bug 1355721 introduced an unconditional UpdateStylistIfNeeded, unless the counter style / font equivalents. That means that the stylist wouldn't remain on its initial state after the first flush, which itself means that when the compat mode changed, the UA and user rules were already on the stylist with the quirks mode keys. That makes class-names be keyed in ascii lowercase. After that no user style changed, so no rebuild happens for the cascade data in the user origin, so we keep looking at the wrong keys indefinitely. MozReview-Commit-ID: 25dD2bca3tN
layout/reftests/usercss/reftest.list
layout/style/ServoStyleSet.cpp
servo/components/style/stylist.rs
servo/ports/geckolib/glue.rs
--- a/layout/reftests/usercss/reftest.list
+++ b/layout/reftests/usercss/reftest.list
@@ -1,4 +1,4 @@
 == usercss.html usercss-ref.html
-random-if(!browserIsRemote&&(stylo||styloVsGecko)) == usercss-uppercase.html usercss-ref.html
+== usercss-uppercase.html usercss-ref.html
 == usercss-xbl.html usercss-ref.html
 == usercss-moz-document.html usercss-moz-document-ref.html
--- a/layout/style/ServoStyleSet.cpp
+++ b/layout/style/ServoStyleSet.cpp
@@ -1310,16 +1310,17 @@ ServoStyleSet::ClearCachedStyleData()
   ClearNonInheritingStyleContexts();
   Servo_StyleSet_RebuildCachedData(mRawSet.get());
 }
 
 void
 ServoStyleSet::CompatibilityModeChanged()
 {
   Servo_StyleSet_CompatModeChanged(mRawSet.get());
+  SetStylistStyleSheetsDirty();
 }
 
 already_AddRefed<ServoStyleContext>
 ServoStyleSet::ResolveServoStyle(Element* aElement)
 {
   RefPtr<ServoStyleContext> result =
     Servo_ResolveStyle(aElement, mRawSet.get()).Consume();
   return result.forget();
--- a/servo/components/style/stylist.rs
+++ b/servo/components/style/stylist.rs
@@ -1141,23 +1141,21 @@ impl Stylist {
 
     /// Returns the Quirks Mode of the document.
     pub fn quirks_mode(&self) -> QuirksMode {
         self.quirks_mode
     }
 
     /// Sets the quirks mode of the document.
     pub fn set_quirks_mode(&mut self, quirks_mode: QuirksMode) {
-        // FIXME(emilio): We don't seem to change the quirks mode dynamically
-        // during multiple layout passes, but this is totally bogus, in the
-        // sense that it's updated asynchronously.
-        //
-        // This should probably be an argument to `update`, and use the quirks
-        // mode info in the `SharedLayoutContext`.
+        if self.quirks_mode == quirks_mode {
+            return;
+        }
         self.quirks_mode = quirks_mode;
+        self.force_stylesheet_origins_dirty(OriginSet::all());
     }
 
     /// Returns the applicable CSS declarations for the given element.
     ///
     /// This corresponds to `ElementRuleCollector` in WebKit.
     pub fn push_applicable_declarations<E, F>(
         &self,
         element: E,
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -2438,29 +2438,22 @@ pub extern "C" fn Servo_StyleSet_Rebuild
     data.stylist.device_mut().rebuild_cached_data();
 }
 
 #[no_mangle]
 pub extern "C" fn Servo_StyleSet_Drop(data: RawServoStyleSetOwned) {
     let _ = data.into_box::<PerDocumentStyleData>();
 }
 
-
-/// Updating the stylesheets and redoing selector matching is always happens
-/// before the document element is inserted. Therefore we don't need to call
-/// `force_dirty` here.
 #[no_mangle]
-pub extern "C" fn Servo_StyleSet_CompatModeChanged(raw_data: RawServoStyleSetBorrowed) {
+pub unsafe extern "C" fn Servo_StyleSet_CompatModeChanged(raw_data: RawServoStyleSetBorrowed) {
     let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();
-    let quirks_mode = unsafe {
-        (*data.stylist.device().pres_context().mDocument.raw::<nsIDocument>())
-            .mCompatMode
-    };
-
-    data.stylist.set_quirks_mode(quirks_mode.into());
+    let doc =
+        &*data.stylist.device().pres_context().mDocument.raw::<nsIDocument>();
+    data.stylist.set_quirks_mode(QuirksMode::from(quirks_mode));
 }
 
 fn parse_property_into<R>(
     declarations: &mut SourcePropertyDeclaration,
     property_id: PropertyId,
     value: *const nsACString,
     data: *mut URLExtraData,
     parsing_mode: structs::ParsingMode,