Bug 1451966. Don't warn or assert for events firing while !IsSafeToRunScript() inside documents that are never exposed to script. r=smaug
authorBoris Zbarsky <bzbarsky@mit.edu>
Mon, 09 Apr 2018 16:48:35 -0400
changeset 779620 cc9c9128b1f62a6d90ec06d3440815e235eb62e5
parent 779619 17eff95cd1e45c4d2ff2e020695f0773ad5cf505
child 779621 28328eb3e63f8e5cc923dc07e2f2049ee06dbc99
push id105824
push usernnethercote@mozilla.com
push dateTue, 10 Apr 2018 09:55:33 +0000
reviewerssmaug
bugs1451966
milestone61.0a1
Bug 1451966. Don't warn or assert for events firing while !IsSafeToRunScript() inside documents that are never exposed to script. r=smaug MozReview-Commit-ID: HgvQFJtW9Z6
dom/events/EventDispatcher.cpp
--- a/dom/events/EventDispatcher.cpp
+++ b/dom/events/EventDispatcher.cpp
@@ -744,20 +744,39 @@ EventDispatcher::Dispatch(nsISupports* a
     }
   }
 
 #ifdef DEBUG
   if (NS_IsMainThread() &&
       aEvent->mMessage != eVoidEvent &&
       !nsContentUtils::IsSafeToRunScript()) {
     nsCOMPtr<nsINode> node = do_QueryInterface(target);
-    if (node && nsContentUtils::IsChromeDoc(node->OwnerDoc())) {
-      NS_WARNING("Fix the caller!");
+    if (!node) {
+      // If the target is not a node, just go ahead and assert that this is
+      // unsafe.  There really shouldn't be any other event targets in documents
+      // that are not being rendered or scripted.
+      NS_ERROR("This is unsafe! Fix the caller!");
     } else {
-      NS_ERROR("This is unsafe! Fix the caller!");
+      // If this is a node, it's possible that this is some sort of DOM tree
+      // that is never accessed by script (for example an SVG image or XBL
+      // binding document or whatnot).  We really only want to warn/assert here
+      // if there might be actual scripted listeners for this event, so restrict
+      // the warnings/asserts to the case when script can or once could touch
+      // this node's document.
+      nsIDocument* doc = node->OwnerDoc();
+      bool hasHadScriptHandlingObject;
+      nsIGlobalObject* global =
+        doc->GetScriptHandlingObject(hasHadScriptHandlingObject);
+      if (global || hasHadScriptHandlingObject) {
+        if (nsContentUtils::IsChromeDoc(doc)) {
+          NS_WARNING("Fix the caller!");
+        } else {
+          NS_ERROR("This is unsafe! Fix the caller!");
+        }
+      }
     }
   }
 
   if (aDOMEvent) {
     WidgetEvent* innerEvent = aDOMEvent->WidgetEventPtr();
     NS_ASSERTION(innerEvent == aEvent,
                   "The inner event of aDOMEvent is not the same as aEvent!");
   }