Bug 830858 - Implement a generic way to dispatch events to chrome only. r=jst a=akeybl
authorOlli Pettay <Olli.Pettay@helsinki.fi>
Wed, 16 Jan 2013 11:27:06 +0200
changeset 127421 df5345414bb18ad5ad5d36e55cb7c861631f1c19
parent 127420 c55dbea12268c556f5acc5837973679ae7db577b
child 127422 46d904f2f2525a38e4c7f8859407cdc56024292f
push id2151
push userlsblakk@mozilla.com
push dateTue, 19 Feb 2013 18:06:57 +0000
treeherdermozilla-beta@4952e88741ec [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjst, akeybl
bugs830858
milestone20.0a2
Bug 830858 - Implement a generic way to dispatch events to chrome only. r=jst a=akeybl
dom/base/nsDOMWindowUtils.cpp
dom/interfaces/base/nsIDOMWindowUtils.idl
dom/tests/mochitest/chrome/Makefile.in
dom/tests/mochitest/chrome/file_bug830858.xul
dom/tests/mochitest/chrome/test_bug830858.xul
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -3116,8 +3116,23 @@ nsDOMWindowUtils::IsNodeDisabledForEvent
         break;
       }
     }
     node = node->GetParentNode();
   }
 
   return NS_OK;
 }
+
+NS_IMETHODIMP
+nsDOMWindowUtils::DispatchEventToChromeOnly(nsIDOMEventTarget* aTarget,
+                                            nsIDOMEvent* aEvent,
+                                            bool* aRetVal)
+{
+  *aRetVal = false;
+  if (!nsContentUtils::IsCallerChrome()) {
+    return NS_ERROR_DOM_SECURITY_ERR;
+  }
+  NS_ENSURE_STATE(aTarget && aEvent);
+  aEvent->GetInternalNSEvent()->mFlags.mOnlyChromeDispatch = true;
+  aTarget->DispatchEvent(aEvent, aRetVal);
+  return NS_OK;
+}
--- a/dom/interfaces/base/nsIDOMWindowUtils.idl
+++ b/dom/interfaces/base/nsIDOMWindowUtils.idl
@@ -34,18 +34,19 @@ interface nsITransferable;
 interface nsIQueryContentEventResult;
 interface nsIDOMWindow;
 interface nsIDOMBlob;
 interface nsIDOMFile;
 interface nsIFile;
 interface nsIDOMTouch;
 interface nsIDOMClientRect;
 interface nsIURI;
+interface nsIDOMEventTarget;
 
-[scriptable, uuid(c98249a5-d38a-4ec6-b6e0-6866ea87d6bb)]
+[scriptable, uuid(7cd26372-d2e2-463a-bce3-3f02d4b23fa8)]
 interface nsIDOMWindowUtils : nsISupports {
 
   /**
    * Image animation mode of the window. When this attribute's value
    * is changed, the implementation should set all images in the window
    * to the given value. That is, when set to kDontAnimMode, all images
    * will stop animating. The attribute's value must be one of the
    * animationMode values from imgIContainer.
@@ -716,16 +717,25 @@ interface nsIDOMWindowUtils : nsISupport
    * @note Event handlers won't get aEvent as parameter, but a similar event.
    *       Also, aEvent should not be reused.
    */
   boolean dispatchDOMEventViaPresShell(in nsIDOMNode aTarget,
                                        in nsIDOMEvent aEvent,
                                        in boolean aTrusted);
 
   /**
+   * Sets nsEvent::mFlags::mOnlyChromeDispatch to true to ensure that
+   * the event is propagated only to chrome.
+   * Event's .target property will be aTarget.
+   * Returns the same value as what EventTarget.dispatchEvent does.
+   */
+  boolean dispatchEventToChromeOnly(in nsIDOMEventTarget aTarget,
+                                    in nsIDOMEvent aEvent);
+
+  /**
    * Returns the real classname (possibly of the mostly-transparent security
    * wrapper) of aObj.
    */
   [implicit_jscontext] string getClassName(in jsval aObject);
 
   /**
    * Generate a content command event.
    *
--- a/dom/tests/mochitest/chrome/Makefile.in
+++ b/dom/tests/mochitest/chrome/Makefile.in
@@ -52,16 +52,18 @@ MOCHITEST_CHROME_FILES = \
 		test_bug800817.xul \
 		file_bug800817.xul \
 		test_bug830396.xul \
 		test_subscript_bindings.xul \
 		file_subscript_bindings.js \
 		test_sandbox_eventhandler.xul \
 		test_DOM_element_instanceof.xul \
 		file_DOM_element_instanceof.xul \
+		test_bug830858.xul \
+		file_bug830858.xul \
 		$(NULL)
 
 ifeq (WINNT,$(OS_ARCH))
 MOCHITEST_CHROME_FILES += \
 		test_sizemode_attribute.xul \
 		sizemode_attribute.xul \
 		$(NULL)
 endif
new file mode 100644
--- /dev/null
+++ b/dom/tests/mochitest/chrome/file_bug830858.xul
@@ -0,0 +1,67 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
+<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=830858
+-->
+<window title="Mozilla Bug 830858"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
+  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
+
+  <!-- test results are displayed in the html:body -->
+  <body xmlns="http://www.w3.org/1999/xhtml">
+  <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=830858"
+     target="_blank">Mozilla Bug 830858</a>
+  </body>
+
+  <!-- test code goes here -->
+  <script type="application/javascript">
+  <![CDATA[
+  /** Test for Bug 830858 **/
+
+  function runTests() {
+    var b = document.getElementById("b");
+    var win = b.contentWindow;
+    var doc = win.document;
+    var wu = win.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
+                .getInterface(Components.interfaces.nsIDOMWindowUtils);
+
+    var docListenerCalled = 0;
+    doc.addEventListener("foo", function() { ++docListenerCalled; }, true);
+    var winListenerCalled = 0;
+    win.addEventListener("foo", function() { ++winListenerCalled; }, true);
+    var iframeListenerCalled = 0;
+    b.addEventListener("foo", function() { ++iframeListenerCalled; }, true);
+
+    doc.dispatchEvent(new Event("foo"));
+    opener.wrappedJSObject.is(docListenerCalled, 1, "Normal dispatch to Document");
+    opener.wrappedJSObject.is(winListenerCalled, 1, "Normal dispatch to Document");
+    opener.wrappedJSObject.is(iframeListenerCalled, 1, "Normal dispatch to Document");
+
+    win.dispatchEvent(new Event("foo"));
+    opener.wrappedJSObject.is(docListenerCalled, 1, "Normal dispatch to Window");
+    opener.wrappedJSObject.is(winListenerCalled, 2, "Normal dispatch to Window");
+    opener.wrappedJSObject.is(iframeListenerCalled, 2, "Normal dispatch to Window");
+
+    wu.dispatchEventToChromeOnly(doc, new Event("foo"));
+    opener.wrappedJSObject.is(docListenerCalled, 1, "Chrome-only dispatch to Document");
+    opener.wrappedJSObject.is(winListenerCalled, 2, "Chrome-only dispatch to Document");
+    opener.wrappedJSObject.is(iframeListenerCalled, 3, "Chrome-only dispatch to Document");
+
+    wu.dispatchEventToChromeOnly(win, new Event("foo"));
+    opener.wrappedJSObject.is(docListenerCalled, 1, "Chrome-only dispatch to Window");
+    opener.wrappedJSObject.is(winListenerCalled, 2, "Chrome-only dispatch to Window");
+    opener.wrappedJSObject.is(iframeListenerCalled, 4, "Chrome-only dispatch to Window");
+
+    window.close();
+    opener.wrappedJSObject.finishedTests();
+  }
+
+  SimpleTest.waitForFocus(runTests);
+  ]]>
+  </script>
+  <iframe xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+          id="b" type="content" src="about:blank"
+          style="width: 300px; height: 550px; border: 1px solid black;"/>
+</window>
new file mode 100644
--- /dev/null
+++ b/dom/tests/mochitest/chrome/test_bug830858.xul
@@ -0,0 +1,36 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
+<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=830858
+-->
+<window title="Mozilla Bug 830858"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+         onload="runTests()">
+  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
+
+  <!-- test code goes here -->
+  <script type="application/javascript">
+  <![CDATA[
+
+  /** Test for Bug 830858 **/
+
+  function runTests() {
+    window.open("file_bug830858.xul", "_blank", "chrome,width=600,height=550");
+  }
+
+  function finishedTests() {
+    SimpleTest.finish();
+  }
+
+  SimpleTest.waitForExplicitFinish();
+
+  ]]>
+  </script>
+
+  <!-- test results are displayed in the html:body -->
+  <body xmlns="http://www.w3.org/1999/xhtml">
+  <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=830858"
+     target="_blank">Mozilla Bug 830858</a>
+  </body>
+</window>