Bug 1460295 - Don't dispatch mutation event for style attribute change from CSSOM. r?bz draft
authorXidorn Quan <me@upsuper.org>
Tue, 22 May 2018 16:34:23 +1000
changeset 798592 58c475b50237bd14355c95b4ac0c47412dab980d
parent 798586 3833bbfdd7fe4981a740bc4798b3e6756cb9e130
push id110802
push userxquan@mozilla.com
push dateWed, 23 May 2018 05:09:46 +0000
reviewersbz
bugs1460295
milestone62.0a1
Bug 1460295 - Don't dispatch mutation event for style attribute change from CSSOM. r?bz MozReview-Commit-ID: JWDpyg7czXI
dom/base/nsStyledElement.cpp
dom/base/test/test_bug338679.html
layout/style/test/test_style_attr_listener.html
modules/libpref/init/StaticPrefList.h
--- a/dom/base/nsStyledElement.cpp
+++ b/dom/base/nsStyledElement.cpp
@@ -7,16 +7,17 @@
 #include "nsStyledElement.h"
 #include "mozAutoDocUpdate.h"
 #include "nsGkAtoms.h"
 #include "nsAttrValue.h"
 #include "nsAttrValueInlines.h"
 #include "mozilla/dom/ElementInlines.h"
 #include "mozilla/dom/MutationEventBinding.h"
 #include "mozilla/InternalMutationEvent.h"
+#include "mozilla/StaticPrefs.h"
 #include "nsDOMCSSDeclaration.h"
 #include "nsDOMCSSAttrDeclaration.h"
 #include "nsServiceManagerUtils.h"
 #include "nsIDocument.h"
 #include "mozilla/DeclarationBlockInlines.h"
 #include "mozilla/css/Loader.h"
 #include "nsXULElement.h"
 #include "nsContentUtils.h"
@@ -72,16 +73,17 @@ nsStyledElement::SetInlineStyleDeclarati
                                            bool aNotify)
 {
   SetMayHaveStyle();
   bool modification = false;
   nsAttrValue oldValue;
   bool oldValueSet = false;
 
   bool hasListeners = aNotify &&
+    !StaticPrefs::dom_mutation_events_cssom_disabled() &&
     nsContentUtils::HasMutationListeners(this,
                                          NS_EVENT_BITS_MUTATION_ATTRMODIFIED,
                                          this);
 
   // There's no point in comparing the stylerule pointers since we're always
   // getting a new stylerule here. And we can't compare the stringvalues of
   // the old and the new rules since both will point to the same declaration
   // and thus will be the same.
--- a/dom/base/test/test_bug338679.html
+++ b/dom/base/test/test_bug338679.html
@@ -30,19 +30,23 @@ function nextTest() {
     phase = tests[i];
     i++;
     phase();
   } else {
     SimpleTest.finish();
   }
 }
 
-SimpleTest.waitForExplicitFinish();
-testDiv.addEventListener("DOMAttrModified", attr_modified);
-nextTest();
+if (SpecialPowers.getBoolPref("dom.mutation-events.cssom.disabled")) {
+  ok(true, "DOMAttrModified event from CSSOM change is disabled");
+} else {
+  SimpleTest.waitForExplicitFinish();
+  testDiv.addEventListener("DOMAttrModified", attr_modified);
+  nextTest();
+}
 
 /* event handler */
 function attr_modified(ev) {
   is(ev.newValue, e_new,
      phase.name + (recursive ? " recursive" : "") + ": newValue");
   is(ev.prevValue, e_prev,
      phase.name + (recursive ? " recursive" : "") + ": prevValue");
 
--- a/layout/style/test/test_style_attr_listener.html
+++ b/layout/style/test/test_style_attr_listener.html
@@ -16,11 +16,16 @@ div.addEventListener('DOMAttrModified', 
   count++;
   is(evt.prevValue, expectation.prevValue, "Previous value for event ${count}");
   is(evt.newValue, expectation.newValue, "New value for event ${count}");
 });
 expectation = { prevValue: 'color: red;', newValue: 'color: green;' };
 div.style.color = "green";
 expectation = { prevValue: 'color: green;', newValue: '' };
 div.style.color = '';
+if (SpecialPowers.getBoolPref("dom.mutation-events.cssom.disabled")) {
+  is(count, 0, "No DOMAttrModified event should be triggered");
+} else {
+  is(count, 2, "DOMAttrModified events should have been triggered");
+}
 </script>
 </body>
 </html>
--- a/modules/libpref/init/StaticPrefList.h
+++ b/modules/libpref/init/StaticPrefList.h
@@ -92,16 +92,24 @@ VARCACHE_PREF(
 //---------------------------------------------------------------------------
 
 VARCACHE_PREF(
   "dom.webcomponents.shadowdom.report_usage",
    dom_webcomponents_shadowdom_report_usage,
   bool, false
 )
 
+// Whether we disable triggering mutation events for changes to style
+// attribute via CSSOM.
+VARCACHE_PREF(
+  "dom.mutation-events.cssom.disabled",
+   dom_mutation_events_cssom_disabled,
+  bool, true
+)
+
 //---------------------------------------------------------------------------
 // Full-screen prefs
 //---------------------------------------------------------------------------
 
 #ifdef RELEASE_OR_BETA
 # define PREF_VALUE false
 #else
 # define PREF_VALUE true