Merge m-i to m-c
authorPhil Ringnalda <philringnalda@gmail.com>
Sun, 08 Dec 2013 18:53:55 -0800
changeset 174159 5c7612dcd6dc406da18f98719cdb1d74b6730098
parent 174138 06b3a7aea2c0349d4361a1499a25a7fd9f476400 (current diff)
parent 174158 86ce0ae55c5dd0db6e93b8a5c9424f111b52c35a (diff)
child 174164 551efcc4de6f1c965179975e3b12ab9e9e4c208a
push id3224
push userlsblakk@mozilla.com
push dateTue, 04 Feb 2014 01:06:49 +0000
treeherdermozilla-beta@60c04d0987f1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone28.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge m-i to m-c
content/html/content/reftests/autofocus/reftest.list
content/html/content/src/HTMLInputElement.cpp
--- a/browser/installer/Makefile.in
+++ b/browser/installer/Makefile.in
@@ -107,16 +107,19 @@ BINPATH = $(_BINPATH)
 DEFINES += -DAPPNAME=$(_APPNAME)
 else
 # Every other platform just winds up in dist/bin
 BINPATH = bin
 endif
 DEFINES += -DBINPATH=$(BINPATH)
 
 DEFINES += -DMOZ_ICU_VERSION=$(MOZ_ICU_VERSION)
+ifdef MOZ_NATIVE_ICU
+DEFINES += -DMOZ_NATIVE_ICU
+endif
 ifdef MOZ_SHARED_ICU
 DEFINES += -DMOZ_SHARED_ICU
 endif
 
 libs::
 	$(MAKE) -C $(DEPTH)/browser/locales langpack
 
 ifeq (WINNT,$(OS_ARCH))
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -96,16 +96,17 @@
 @BINPATH@/msvcp120.dll
 @BINPATH@/msvcr120.dll
 #ifdef MOZ_METRO
 @BINPATH@/vccorlib120.dll
 #endif
 #endif
 #endif
 #endif
+#ifndef MOZ_NATIVE_ICU
 #ifdef MOZ_SHARED_ICU
 #ifdef XP_WIN
 #ifdef MOZ_DEBUG
 @BINPATH@/icudtd@MOZ_ICU_VERSION@.dll
 @BINPATH@/icuind@MOZ_ICU_VERSION@.dll
 @BINPATH@/icuucd@MOZ_ICU_VERSION@.dll
 #else
 @BINPATH@/icudt@MOZ_ICU_VERSION@.dll
@@ -117,16 +118,17 @@
 @BINPATH@/libicui18n.@MOZ_ICU_VERSION@.dylib
 @BINPATH@/libicuuc.@MOZ_ICU_VERSION@.dylib
 #elif defined(XP_UNIX)
 @BINPATH@/libicudata.so.@MOZ_ICU_VERSION@
 @BINPATH@/libicui18n.so.@MOZ_ICU_VERSION@
 @BINPATH@/libicuuc.so.@MOZ_ICU_VERSION@
 #endif
 #endif
+#endif
 
 [browser]
 ; [Base Browser Files]
 #ifndef XP_UNIX
 @BINPATH@/@MOZ_APP_NAME@.exe
 #else
 @BINPATH@/@MOZ_APP_NAME@-bin
 @BINPATH@/@MOZ_APP_NAME@
--- a/content/events/src/moz.build
+++ b/content/events/src/moz.build
@@ -81,16 +81,17 @@ FINAL_LIBRARY = 'gklayout'
 LOCAL_INCLUDES += [
     '/content/base/src',
     '/content/html/content/src',
     '/content/xml/content/src',
     '/content/xul/content/src',
     '/dom/base',
     '/dom/settings',
     '/dom/src/storage',
+    '/js/xpconnect/wrappers',
     '/layout/generic',
     '/layout/xul',
     '/layout/xul/tree/',
 ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
     LOCAL_INCLUDES += [
         '/dom/wifi',
--- a/content/events/src/nsDOMEvent.cpp
+++ b/content/events/src/nsDOMEvent.cpp
@@ -1,15 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "base/basictypes.h"
 
+#include "AccessCheck.h"
 #include "ipc/IPCMessageUtils.h"
 #include "nsCOMPtr.h"
 #include "nsError.h"
 #include "nsDOMEvent.h"
 #include "nsEventStateManager.h"
 #include "nsIFrame.h"
 #include "nsIContent.h"
 #include "nsIPresShell.h"
@@ -28,16 +29,24 @@
 #include "nsDOMEventTargetHelper.h"
 #include "nsPIWindowRoot.h"
 #include "nsGlobalWindow.h"
 #include "nsDeviceContext.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
+namespace mozilla {
+namespace dom {
+namespace workers {
+extern bool IsCurrentThreadRunningChromeWorker();
+} // namespace workers
+} // namespace dom
+} // namespace mozilla
+
 static char *sPopupAllowedEvents;
 
 
 nsDOMEvent::nsDOMEvent(mozilla::dom::EventTarget* aOwner,
                        nsPresContext* aPresContext, WidgetEvent* aEvent)
 {
   ConstructorInit(aOwner, aPresContext, aEvent);
 }
@@ -212,16 +221,24 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(
     }
   }
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPresContext)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mExplicitOriginalTarget)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOwner)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
+bool
+nsDOMEvent::IsChrome(JSContext* aCx) const
+{
+  return mIsMainThreadEvent ?
+    xpc::AccessCheck::isChrome(js::GetContextCompartment(aCx)) :
+    mozilla::dom::workers::IsCurrentThreadRunningChromeWorker();
+}
+
 // nsIDOMEventInterface
 NS_METHOD nsDOMEvent::GetType(nsAString& aType)
 {
   if (!mIsMainThreadEvent || !mEvent->typeString.IsEmpty()) {
     aType = mEvent->typeString;
     return NS_OK;
   }
   const char* name = GetEventName(mEvent->message);
@@ -431,35 +448,50 @@ nsDOMEvent::GetIsTrusted(bool *aIsTruste
 {
   *aIsTrusted = IsTrusted();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMEvent::PreventDefault()
 {
-  if (mEvent->mFlags.mCancelable) {
-    mEvent->mFlags.mDefaultPrevented = true;
+  // This method is called only from C++ code which must handle default action
+  // of this event.  So, pass true always.
+  PreventDefaultInternal(true);
+  return NS_OK;
+}
+
+void
+nsDOMEvent::PreventDefault(JSContext* aCx)
+{
+  MOZ_ASSERT(aCx, "JS context must be specified");
 
-    // Need to set an extra flag for drag events.
-    if (mEvent->eventStructType == NS_DRAG_EVENT && IsTrusted()) {
-      nsCOMPtr<nsINode> node = do_QueryInterface(mEvent->currentTarget);
-      if (!node) {
-        nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(mEvent->currentTarget);
-        if (win) {
-          node = win->GetExtantDoc();
-        }
-      }
-      if (node && !nsContentUtils::IsChromeDoc(node->OwnerDoc())) {
-        mEvent->mFlags.mDefaultPreventedByContent = true;
-      }
-    }
+  // Note that at handling default action, another event may be dispatched.
+  // Then, JS in content mey be call preventDefault()
+  // even in the event is in system event group.  Therefore, don't refer
+  // mInSystemGroup here.
+  PreventDefaultInternal(IsChrome(aCx));
+}
+
+void
+nsDOMEvent::PreventDefaultInternal(bool aCalledByDefaultHandler)
+{
+  if (!mEvent->mFlags.mCancelable) {
+    return;
   }
 
-  return NS_OK;
+  mEvent->mFlags.mDefaultPrevented = true;
+
+  // Note that even if preventDefault() has already been called by chrome,
+  // a call of preventDefault() by content needs to overwrite
+  // mDefaultPreventedByContent to true because in such case, defaultPrevented
+  // must be true when web apps check it after they call preventDefault().
+  if (!aCalledByDefaultHandler) {
+    mEvent->mFlags.mDefaultPreventedByContent = true;
+  }
 }
 
 void
 nsDOMEvent::SetEventType(const nsAString& aEventTypeArg)
 {
   if (mIsMainThreadEvent) {
     mEvent->userType =
       nsContentUtils::GetEventIdAndAtom(aEventTypeArg, mEvent->eventStructType,
@@ -1139,38 +1171,62 @@ const char* nsDOMEvent::GetEventName(uin
   // create and that are not user defined events since this function and
   // SetEventType are incomplete.  (But fixing that requires fixing the
   // arrays in nsEventListenerManager too, since the events for which
   // this is a problem generally *are* created by nsDOMEvent.)
   return nullptr;
 }
 
 bool
+nsDOMEvent::DefaultPrevented(JSContext* aCx) const
+{
+  MOZ_ASSERT(aCx, "JS context must be specified");
+
+  NS_ENSURE_TRUE(mEvent, false);
+
+  // If preventDefault() has never been called, just return false.
+  if (!mEvent->mFlags.mDefaultPrevented) {
+    return false;
+  }
+
+  // If preventDefault() has been called by content, return true.  Otherwise,
+  // i.e., preventDefault() has been called by chrome, return true only when
+  // this is called by chrome.
+  return mEvent->mFlags.mDefaultPreventedByContent || IsChrome(aCx);
+}
+
+bool
 nsDOMEvent::GetPreventDefault() const
 {
   if (mOwner) {
     if (nsIDocument* doc = mOwner->GetExtantDoc()) {
       doc->WarnOnceAbout(nsIDocument::eGetPreventDefault);
     }
   }
+  // GetPreventDefault() is legacy and Gecko specific method.  Although,
+  // the result should be same as defaultPrevented, we don't need to break
+  // backward compatibility of legacy method.  Let's behave traditionally.
   return DefaultPrevented();
 }
 
 NS_IMETHODIMP
 nsDOMEvent::GetPreventDefault(bool* aReturn)
 {
   NS_ENSURE_ARG_POINTER(aReturn);
   *aReturn = GetPreventDefault();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMEvent::GetDefaultPrevented(bool* aReturn)
 {
   NS_ENSURE_ARG_POINTER(aReturn);
+  // This method must be called by only event handlers implemented by C++.
+  // Then, the handlers must handle default action.  So, this method don't need
+  // to check if preventDefault() has been called by content or chrome.
   *aReturn = DefaultPrevented();
   return NS_OK;
 }
 
 NS_IMETHODIMP_(void)
 nsDOMEvent::Serialize(IPC::Message* aMsg, bool aSerializeInterfaceType)
 {
   if (aSerializeInterfaceType) {
--- a/content/events/src/nsDOMEvent.h
+++ b/content/events/src/nsDOMEvent.h
@@ -148,19 +148,30 @@ public:
   bool Cancelable() const
   {
     return mEvent->mFlags.mCancelable;
   }
 
   // xpidl implementation
   // void PreventDefault();
 
+  // You MUST NOT call PreventDefaultJ(JSContext*) from C++ code.  A call of
+  // this method always sets Event.defaultPrevented true for web contents.
+  // If default action handler calls this, web applications meet wrong
+  // defaultPrevented value.
+  void PreventDefault(JSContext* aCx);
+
+  // You MUST NOT call DefaultPrevented(JSContext*) from C++ code.  This may
+  // return false even if PreventDefault() has been called.
+  // See comments in its implementation for the detail.
+  bool DefaultPrevented(JSContext* aCx) const;
+
   bool DefaultPrevented() const
   {
-    return mEvent && mEvent->mFlags.mDefaultPrevented;
+    return mEvent->mFlags.mDefaultPrevented;
   }
 
   bool MultipleActionsPrevented() const
   {
     return mEvent->mFlags.mMultipleActionsPrevented;
   }
 
   bool IsTrusted() const
@@ -185,16 +196,30 @@ public:
   bool GetPreventDefault() const;
 
 protected:
 
   // Internal helper functions
   void SetEventType(const nsAString& aEventTypeArg);
   already_AddRefed<nsIContent> GetTargetFromFrame();
 
+  /**
+   * IsChrome() returns true if aCx is chrome context or the event is created
+   * in chrome's thread.  Otherwise, false.
+   */
+  bool IsChrome(JSContext* aCx) const;
+
+  /**
+   * @param aCalledByDefaultHandler     Should be true when this is called by
+   *                                    C++ or Chrome.  Otherwise, e.g., called
+   *                                    by a call of Event.preventDefault() in
+   *                                    content script, false.
+   */
+  void PreventDefaultInternal(bool aCalledByDefaultHandler);
+
   mozilla::WidgetEvent*       mEvent;
   nsRefPtr<nsPresContext>     mPresContext;
   nsCOMPtr<mozilla::dom::EventTarget> mExplicitOriginalTarget;
   nsCOMPtr<nsPIDOMWindow>     mOwner; // nsPIDOMWindow for now.
   bool                        mEventIsInternal;
   bool                        mPrivateDataDuplicated;
   bool                        mIsMainThreadEvent;
 };
--- a/content/events/src/nsEventStateManager.cpp
+++ b/content/events/src/nsEventStateManager.cpp
@@ -2605,134 +2605,140 @@ nsEventStateManager::DispatchLegacyMouse
   // Send the legacy events in following order:
   // 1. Vertical scroll
   // 2. Vertical pixel scroll (even if #1 isn't consumed)
   // 3. Horizontal scroll (even if #1 and/or #2 are consumed)
   // 4. Horizontal pixel scroll (even if #3 isn't consumed)
 
   nsWeakFrame targetFrame(aTargetFrame);
 
-  nsEventStatus statusX = *aStatus;
-  nsEventStatus statusY = *aStatus;
+  MOZ_ASSERT(*aStatus != nsEventStatus_eConsumeNoDefault &&
+             !aEvent->mFlags.mDefaultPrevented,
+             "If you make legacy events dispatched for default prevented wheel "
+             "event, you need to initialize stateX and stateY");
+  EventState stateX, stateY;
   if (scrollDeltaY) {
-    SendLineScrollEvent(aTargetFrame, aEvent, &statusY,
+    SendLineScrollEvent(aTargetFrame, aEvent, stateY,
                         scrollDeltaY, DELTA_DIRECTION_Y);
     if (!targetFrame.IsAlive()) {
       *aStatus = nsEventStatus_eConsumeNoDefault;
       return;
     }
   }
 
   if (pixelDeltaY) {
-    SendPixelScrollEvent(aTargetFrame, aEvent, &statusY,
+    SendPixelScrollEvent(aTargetFrame, aEvent, stateY,
                          pixelDeltaY, DELTA_DIRECTION_Y);
     if (!targetFrame.IsAlive()) {
       *aStatus = nsEventStatus_eConsumeNoDefault;
       return;
     }
   }
 
   if (scrollDeltaX) {
-    SendLineScrollEvent(aTargetFrame, aEvent, &statusX,
+    SendLineScrollEvent(aTargetFrame, aEvent, stateX,
                         scrollDeltaX, DELTA_DIRECTION_X);
     if (!targetFrame.IsAlive()) {
       *aStatus = nsEventStatus_eConsumeNoDefault;
       return;
     }
   }
 
   if (pixelDeltaX) {
-    SendPixelScrollEvent(aTargetFrame, aEvent, &statusX,
+    SendPixelScrollEvent(aTargetFrame, aEvent, stateX,
                          pixelDeltaX, DELTA_DIRECTION_X);
     if (!targetFrame.IsAlive()) {
       *aStatus = nsEventStatus_eConsumeNoDefault;
       return;
     }
   }
 
-  if (statusY == nsEventStatus_eConsumeNoDefault ||
-      statusX == nsEventStatus_eConsumeNoDefault) {
+  if (stateY.mDefaultPrevented || stateX.mDefaultPrevented) {
     *aStatus = nsEventStatus_eConsumeNoDefault;
-    return;
-  }
-  if (statusY == nsEventStatus_eConsumeDoDefault ||
-      statusX == nsEventStatus_eConsumeDoDefault) {
-    *aStatus = nsEventStatus_eConsumeDoDefault;
+    aEvent->mFlags.mDefaultPrevented = true;
+    aEvent->mFlags.mDefaultPreventedByContent |=
+      stateY.mDefaultPreventedByContent || stateX.mDefaultPreventedByContent;
   }
 }
 
 void
 nsEventStateManager::SendLineScrollEvent(nsIFrame* aTargetFrame,
                                          WidgetWheelEvent* aEvent,
-                                         nsEventStatus* aStatus,
+                                         EventState& aState,
                                          int32_t aDelta,
                                          DeltaDirection aDeltaDirection)
 {
   nsCOMPtr<nsIContent> targetContent = aTargetFrame->GetContent();
   if (!targetContent)
     targetContent = GetFocusedContent();
   if (!targetContent)
     return;
 
   while (targetContent->IsNodeOfType(nsINode::eTEXT)) {
     targetContent = targetContent->GetParent();
   }
 
   WidgetMouseScrollEvent event(aEvent->mFlags.mIsTrusted, NS_MOUSE_SCROLL,
                                aEvent->widget);
-  if (*aStatus == nsEventStatus_eConsumeNoDefault) {
-    event.mFlags.mDefaultPrevented = true;
-  }
+  event.mFlags.mDefaultPrevented = aState.mDefaultPrevented;
+  event.mFlags.mDefaultPreventedByContent = aState.mDefaultPreventedByContent;
   event.refPoint = aEvent->refPoint;
   event.widget = aEvent->widget;
   event.time = aEvent->time;
   event.modifiers = aEvent->modifiers;
   event.buttons = aEvent->buttons;
   event.isHorizontal = (aDeltaDirection == DELTA_DIRECTION_X);
   event.delta = aDelta;
   event.inputSource = aEvent->inputSource;
 
+  nsEventStatus status = nsEventStatus_eIgnore;
   nsEventDispatcher::Dispatch(targetContent, aTargetFrame->PresContext(),
-                              &event, nullptr, aStatus);
+                              &event, nullptr, &status);
+  aState.mDefaultPrevented =
+    event.mFlags.mDefaultPrevented || status == nsEventStatus_eConsumeNoDefault;
+  aState.mDefaultPreventedByContent = event.mFlags.mDefaultPreventedByContent;
 }
 
 void
 nsEventStateManager::SendPixelScrollEvent(nsIFrame* aTargetFrame,
                                           WidgetWheelEvent* aEvent,
-                                          nsEventStatus* aStatus,
+                                          EventState& aState,
                                           int32_t aPixelDelta,
                                           DeltaDirection aDeltaDirection)
 {
   nsCOMPtr<nsIContent> targetContent = aTargetFrame->GetContent();
   if (!targetContent) {
     targetContent = GetFocusedContent();
     if (!targetContent)
       return;
   }
 
   while (targetContent->IsNodeOfType(nsINode::eTEXT)) {
     targetContent = targetContent->GetParent();
   }
 
   WidgetMouseScrollEvent event(aEvent->mFlags.mIsTrusted, NS_MOUSE_PIXEL_SCROLL,
                                aEvent->widget);
-  if (*aStatus == nsEventStatus_eConsumeNoDefault) {
-    event.mFlags.mDefaultPrevented = true;
-  }
+  event.mFlags.mDefaultPrevented = aState.mDefaultPrevented;
+  event.mFlags.mDefaultPreventedByContent = aState.mDefaultPreventedByContent;
   event.refPoint = aEvent->refPoint;
   event.widget = aEvent->widget;
   event.time = aEvent->time;
   event.modifiers = aEvent->modifiers;
   event.buttons = aEvent->buttons;
   event.isHorizontal = (aDeltaDirection == DELTA_DIRECTION_X);
   event.delta = aPixelDelta;
   event.inputSource = aEvent->inputSource;
 
+  nsEventStatus status = nsEventStatus_eIgnore;
   nsEventDispatcher::Dispatch(targetContent, aTargetFrame->PresContext(),
-                              &event, nullptr, aStatus);
+                              &event, nullptr, &status);
+  aState.mDefaultPrevented =
+    event.mFlags.mDefaultPrevented || status == nsEventStatus_eConsumeNoDefault;
+  aState.mDefaultPreventedByContent = event.mFlags.mDefaultPreventedByContent;
 }
 
 nsIScrollableFrame*
 nsEventStateManager::ComputeScrollTarget(nsIFrame* aTargetFrame,
                                          WidgetWheelEvent* aEvent,
                                          ComputeScrollTargetOptions aOptions)
 {
   return ComputeScrollTarget(aTargetFrame, aEvent->deltaX, aEvent->deltaY,
--- a/content/events/src/nsEventStateManager.h
+++ b/content/events/src/nsEventStateManager.h
@@ -476,49 +476,62 @@ protected:
    * This is clearer than using bool.
    */
   enum DeltaDirection
   {
     DELTA_DIRECTION_X = 0,
     DELTA_DIRECTION_Y
   };
 
+  struct MOZ_STACK_CLASS EventState
+  {
+    bool mDefaultPrevented;
+    bool mDefaultPreventedByContent;
+
+    EventState() :
+      mDefaultPrevented(false), mDefaultPreventedByContent(false)
+    {
+    }
+  };
+
   /**
    * SendLineScrollEvent() dispatches a DOMMouseScroll event for the
    * WidgetWheelEvent.  This method shouldn't be called for non-trusted
    * wheel event because it's not necessary for compatiblity.
    *
    * @param aTargetFrame        The event target of wheel event.
    * @param aEvent              The original Wheel event.
-   * @param aStatus             The event status, must not be
-   *                            nsEventStatus_eConsumeNoDefault.
+   * @param aState              The event which should be set to the dispatching
+   *                            event.  This also returns the dispatched event
+   *                            state.
    * @param aDelta              The delta value of the event.
    * @param aDeltaDirection     The X/Y direction of dispatching event.
    */
   void SendLineScrollEvent(nsIFrame* aTargetFrame,
                            mozilla::WidgetWheelEvent* aEvent,
-                           nsEventStatus* aStatus,
+                           EventState& aState,
                            int32_t aDelta,
                            DeltaDirection aDeltaDirection);
 
   /**
    * SendPixelScrollEvent() dispatches a MozMousePixelScroll event for the
    * WidgetWheelEvent.  This method shouldn't be called for non-trusted
    * wheel event because it's not necessary for compatiblity.
    *
    * @param aTargetFrame        The event target of wheel event.
    * @param aEvent              The original Wheel event.
-   * @param aStatus             The event status, must not be
-   *                            nsEventStatus_eConsumeNoDefault.
+   * @param aState              The event which should be set to the dispatching
+   *                            event.  This also returns the dispatched event
+   *                            state.
    * @param aPixelDelta         The delta value of the event.
    * @param aDeltaDirection     The X/Y direction of dispatching event.
    */
   void SendPixelScrollEvent(nsIFrame* aTargetFrame,
                             mozilla::WidgetWheelEvent* aEvent,
-                            nsEventStatus* aStatus,
+                            EventState& aState,
                             int32_t aPixelDelta,
                             DeltaDirection aDeltaDirection);
 
   /**
    * ComputeScrollTarget() returns the scrollable frame which should be
    * scrolled.
    *
    * @param aTargetFrame        The event target of the wheel event.
--- a/content/events/test/chrome.ini
+++ b/content/events/test/chrome.ini
@@ -10,9 +10,10 @@ support-files =
 [test_bug336682.js]
 [test_bug336682_2.xul]
 [test_bug415498.xul]
 [test_bug586961.xul]
 [test_bug591249.xul]
 [test_bug602962.xul]
 [test_bug617528.xul]
 [test_bug679494.xul]
+[test_bug930374-chrome.html]
 [test_eventctors.xul]
--- a/content/events/test/mochitest.ini
+++ b/content/events/test/mochitest.ini
@@ -78,16 +78,17 @@ skip-if = true # Disabled due to timeout
 [test_bug689564.html]
 [test_bug698929.html]
 [test_bug741666.html]
 [test_bug742376.html]
 [test_bug812744.html]
 [test_bug847597.html]
 [test_bug855741.html]
 [test_bug864040.html]
+[test_bug930374-content.html]
 skip-if = toolkit == "gonk"
 [test_clickevent_on_input.html]
 [test_continuous_wheel_events.html]
 [test_dblclick_explicit_original_target.html]
 [test_dom_keyboard_event.html]
 [test_dom_mouse_event.html]
 [test_dom_wheel_event.html]
 [test_draggableprop.html]
new file mode 100644
--- /dev/null
+++ b/content/events/test/test_bug930374-chrome.html
@@ -0,0 +1,59 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=930374
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 930374</title>
+  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/ChromeUtils.js"></script>
+  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
+  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=930374">Mozilla Bug 930374</a>
+<div id="display">
+  <input id="input-text">
+</div>
+<div id="content" style="display: none">
+</div>
+<pre id="test">
+  <script type="application/javascript">
+    SimpleTest.waitForExplicitFinish();
+
+    var gKeyPress = null;
+    function onKeyPress(aEvent)
+    {
+      gKeyPress = aEvent;
+      is(aEvent.target, document.getElementById("input-text"), "input element should have focus");
+      ok(!aEvent.defaultPrevented, "keypress event should be consumed before keypress event handler");
+    }
+
+    function runTests()
+    {
+      document.addEventListener("keypress", onKeyPress, false);
+      var input = document.getElementById("input-text");
+      input.focus();
+
+      input.addEventListener("input", function (aEvent) {
+          input.removeEventListener("input", arguments.callee, false);
+          ok(gKeyPress,
+             "Test1: keypress event must be fired before an input event");
+          ok(gKeyPress.defaultPrevented,
+             "Test1: keypress event's defaultPrevented should be true in chrome even if it's consumed by default action handler of editor");
+          setTimeout(function () {
+            ok(gKeyPress.defaultPrevented,
+               "Test2: keypress event's defaultPrevented should be true after event dispatching finished");
+            SimpleTest.finish();
+          }, 0);
+        }, false);
+
+      sendChar("a");
+    }
+
+    SimpleTest.waitForFocus(runTests);
+  </script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/events/test/test_bug930374-content.html
@@ -0,0 +1,72 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=930374
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 930374</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=930374">Mozilla Bug 930374</a>
+<div id="display">
+  <input id="input-text">
+</div>
+<div id="content" style="display: none">
+</div>
+<pre id="test">
+  <script type="application/javascript">
+    SimpleTest.waitForExplicitFinish();
+
+    var gKeyPress = null;
+    function onKeyPress(aEvent)
+    {
+      gKeyPress = aEvent;
+      is(aEvent.target, document.getElementById("input-text"), "input element should have focus");
+      ok(!aEvent.defaultPrevented, "keypress event should be consumed before keypress event handler");
+    }
+
+    function runTests()
+    {
+      document.addEventListener("keypress", onKeyPress, false);
+      var input = document.getElementById("input-text");
+      input.focus();
+
+      input.addEventListener("input", function (aEvent) {
+          input.removeEventListener("input", arguments.callee, false);
+          ok(gKeyPress,
+             "Test1: keypress event must be fired before an input event");
+          ok(!gKeyPress.defaultPrevented,
+             "Test1: keypress event's defaultPrevented should be false even though it's consumed by the default action handler of editor");
+          gKeyPress.preventDefault();
+          ok(gKeyPress.defaultPrevented,
+             "Test1: keypress event's defaultPrevented should become true because of a call of preventDefault()");
+        }, false);
+
+      sendChar("a");
+      gKeyPress = null;
+
+      input.addEventListener("input", function (aEvent) {
+          input.removeEventListener("input", arguments.callee, false);
+          ok(gKeyPress,
+             "Test2: keypress event must be fired before an input event");
+          ok(!gKeyPress.defaultPrevented,
+             "Test2: keypress event's defaultPrevented should be false even though it's consumed by the default action handler of editor");
+          setTimeout(function () {
+            ok(!gKeyPress.defaultPrevented,
+               "Test2: keypress event's defaultPrevented should not become true after event dispatching finished");
+            SimpleTest.finish();
+          }, 0);
+        }, false);
+
+      sendChar("b");
+    }
+
+    SimpleTest.waitForFocus(runTests);
+  </script>
+</pre>
+</body>
+</html>
--- a/content/html/content/src/HTMLInputElement.cpp
+++ b/content/html/content/src/HTMLInputElement.cpp
@@ -3830,21 +3830,20 @@ HTMLInputElement::PostHandleEvent(nsEven
       // control and as a result aVisitor.mEventStatus will already have been
       // set to nsEventStatus_eConsumeNoDefault. However, we know that
       // whenever the up/down arrow keys cause the value of the number
       // control to change the string in the text control will change, and
       // the cursor will be moved to the end of the text control, overwriting
       // the editor's handling of up/down keypress events. For that reason we
       // just ignore aVisitor.mEventStatus here and go ahead and handle the
       // event to increase/decrease the value of the number control.
-      // XXX we still need to allow script to call preventDefault() on the
-      // event, but right now we can't tell the difference between the editor
-      // on script doing that (bug 930374).
-      StepNumberControlForUserEvent(keyEvent->keyCode == NS_VK_UP ? 1 : -1);
-      aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
+      if (!aVisitor.mEvent->mFlags.mDefaultPreventedByContent) {
+        StepNumberControlForUserEvent(keyEvent->keyCode == NS_VK_UP ? 1 : -1);
+        aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
+      }
     } else if (nsEventStatus_eIgnore == aVisitor.mEventStatus) {
       switch (aVisitor.mEvent->message) {
 
         case NS_FOCUS_CONTENT:
         {
           // see if we should select the contents of the textbox. This happens
           // for text and password fields when the field was focused by the
           // keyboard or a navigation, the platform allows it, and it wasn't
--- a/content/html/content/test/forms/test_input_number_key_events.html
+++ b/content/html/content/test/forms/test_input_number_key_events.html
@@ -172,15 +172,25 @@ function test() {
     expectedVal = expectedValAfterKeyEvent(key, elem);
     synthesizeKey(key, {});
     is(elem.value, expectedVal, "Test " + key + " for number control with value set to the minimum (" + oldVal + ")");
 
     // Same again:
     expectedVal = expectedValAfterKeyEvent(key, elem);
     synthesizeKey(key, {});
     is(elem.value, expectedVal, "Test repeat of " + key + " for number control");
+
+    // Test preventDefault():
+    elem.addEventListener("keypress", function(evt) {
+      evt.preventDefault();
+      elem.removeEventListener("keypress", arguments.callee, false);
+    }, false);
+    oldVal = elem.value = 0;
+    expectedVal = 0;
+    synthesizeKey(key, {});
+    is(elem.value, expectedVal, "Test " + key + " for number control where scripted preventDefault() should prevent the value changing");
   }
 }
 
 </script>
 </pre>
 </body>
 </html>
--- a/content/media/AudioStream.cpp
+++ b/content/media/AudioStream.cpp
@@ -156,18 +156,16 @@ AudioStream::~AudioStream()
 {
 #ifdef PR_LOGGING
   gAudioStreamLog = PR_NewLogModule("AudioStream");
 #endif
   PrefChanged(PREF_VOLUME_SCALE, nullptr);
   Preferences::RegisterCallback(PrefChanged, PREF_VOLUME_SCALE);
   PrefChanged(PREF_CUBEB_LATENCY, nullptr);
   Preferences::RegisterCallback(PrefChanged, PREF_CUBEB_LATENCY);
-
-  InitPreferredSampleRate();
 }
 
 /*static*/ void AudioStream::ShutdownLibrary()
 {
   Preferences::UnregisterCallback(PrefChanged, PREF_VOLUME_SCALE);
   Preferences::UnregisterCallback(PrefChanged, PREF_CUBEB_LATENCY);
 
   StaticMutexAutoLock lock(sMutex);
@@ -262,26 +260,38 @@ int64_t AudioStream::GetWritten()
       cubeb_get_max_channel_count(cubebContext,
                                   &maxNumberOfChannels) == CUBEB_OK) {
     return static_cast<int>(maxNumberOfChannels);
   }
 
   return 0;
 }
 
-/*static */ void AudioStream::InitPreferredSampleRate()
+/*static*/ int AudioStream::PreferredSampleRate()
 {
+  const int fallbackSampleRate = 44100;
+  StaticMutexAutoLock lock(sMutex);
+  if (sPreferredSampleRate != 0) {
+    return sPreferredSampleRate;
+  }
+
+  cubeb* cubebContext = GetCubebContextUnlocked();
+  if (!cubebContext) {
+    sPreferredSampleRate = fallbackSampleRate;
+  }
   // Get the preferred samplerate for this platform, or fallback to something
   // sensible if we fail. We cache the value, because this might be accessed
   // often, and the complexity of the function call below depends on the
   // backend used.
-  if (cubeb_get_preferred_sample_rate(GetCubebContext(),
+  if (cubeb_get_preferred_sample_rate(cubebContext,
                                       &sPreferredSampleRate) != CUBEB_OK) {
-    sPreferredSampleRate = 44100;
+    sPreferredSampleRate = fallbackSampleRate;
   }
+
+  return sPreferredSampleRate;
 }
 
 static void SetUint16LE(uint8_t* aDest, uint16_t aValue)
 {
   aDest[0] = aValue & 0xFF;
   aDest[1] = aValue >> 8;
 }
 
--- a/content/media/AudioStream.h
+++ b/content/media/AudioStream.h
@@ -174,23 +174,19 @@ public:
 
   // Shutdown Audio Library. Some Audio backends require shutting down the
   // library after using it.
   static void ShutdownLibrary();
 
   // Returns the maximum number of channels supported by the audio hardware.
   static int MaxNumberOfChannels();
 
-  static void InitPreferredSampleRate();
   // Returns the samplerate the systems prefer, because it is the
   // samplerate the hardware/mixer supports.
-  static int PreferredSampleRate() {
-    MOZ_ASSERT(sPreferredSampleRate);
-    return sPreferredSampleRate;
-  }
+  static int PreferredSampleRate();
 
   AudioStream();
   ~AudioStream();
 
   enum LatencyRequest {
     HighLatency,
     LowLatency
   };
@@ -372,24 +368,24 @@ private:
                  // cubeb, after which StateCallback will indicate drain
                  // completion.
     DRAINED,     // StateCallback has indicated that the drain is complete.
     ERRORED      // Stream disabled due to an internal error.
   };
 
   StreamState mState;
 
+  // This mutex protects the static members below.
+  static StaticMutex sMutex;
+  static cubeb* sCubebContext;
+
   // Prefered samplerate, in Hz (characteristic of the
   // hardware/mixer/platform/API used).
   static uint32_t sPreferredSampleRate;
 
-  // This mutex protects the static members below
-  static StaticMutex sMutex;
-  static cubeb* sCubebContext;
-
   static double sVolumeScale;
   static uint32_t sCubebLatency;
   static bool sCubebLatencyPrefSet;
 };
 
 } // namespace mozilla
 
 #endif
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -380,16 +380,17 @@ DOMInterfaces = {
         'classList', 'attributes', 'children', 'firstElementChild',
         'lastElementChild', 'previousElementSibling', 'nextElementSibling',
         'getAttributeNode', 'getAttributeNodeNS', 'querySelector'
     ]
 },
 
 'Event': {
     'nativeType': 'nsDOMEvent',
+    'implicitJSContext': [ 'defaultPrevented', 'preventDefault' ],
 },
 
 'EventTarget': {
     'hasXPConnectImpls': True,
     'concrete': False,
     'jsImplParent': 'nsDOMEventTargetHelper'
 },
 
--- a/editor/libeditor/html/tests/chrome.ini
+++ b/editor/libeditor/html/tests/chrome.ini
@@ -4,8 +4,9 @@ support-files = green.png
 [test_bug366682.html]
 [test_bug489202.xul]
 [test_bug490879.xul]
 [test_bug607584.xul]
 [test_bug616590.xul]
 [test_bug635636.html]
 [test_bug780908.xul]
 [test_contenteditable_text_input_handling.html]
+[test_htmleditor_keyevent_handling.html]
--- a/editor/libeditor/html/tests/mochitest.ini
+++ b/editor/libeditor/html/tests/mochitest.ini
@@ -125,13 +125,12 @@ support-files =
 [test_bug780035.html]
 [test_bug787432.html]
 [test_bug790475.html]
 [test_bug796839.html]
 [test_bug832025.html]
 [test_bug857487.html]
 [test_contenteditable_focus.html]
 [test_dom_input_event_on_htmleditor.html]
-[test_htmleditor_keyevent_handling.html]
 [test_keypress_untrusted_event.html]
 [test_root_element_replacement.html]
 [test_select_all_without_body.html]
 [test_spellcheck_pref.html]
--- a/editor/libeditor/html/tests/test_htmleditor_keyevent_handling.html
+++ b/editor/libeditor/html/tests/test_htmleditor_keyevent_handling.html
@@ -1,17 +1,17 @@
 <html>
 <head>
   <title>Test for key event handler of HTML editor</title>
   <script type="text/javascript"
-          src="/tests/SimpleTest/SimpleTest.js"></script>
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
   <script type="text/javascript"
-          src="/tests/SimpleTest/EventUtils.js"></script>
+          src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
   <link rel="stylesheet" type="text/css"
-          href="/tests/SimpleTest/test.css" />
+          href="chrome://mochikit/content/tests/SimpleTest/test.css" />
 </head>
 <body>
 <div id="display">
   <div id="htmlEditor" contenteditable="true"><br></div>
 </div>
 <div id="content" style="display: none">
   
 </div>
--- a/editor/libeditor/text/tests/Makefile.in
+++ b/editor/libeditor/text/tests/Makefile.in
@@ -1,13 +1,13 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 # disables the key handling test on gtk because gtk overrides some key events
 # on our editor, and the combinations depend on the system.
 ifndef MOZ_WIDGET_GTK
-MOCHITEST_FILES += \
+MOCHITEST_CHROME_FILES += \
 		test_texteditor_keyevent_handling.html \
 		$(NULL)
 endif
 
--- a/editor/libeditor/text/tests/test_texteditor_keyevent_handling.html
+++ b/editor/libeditor/text/tests/test_texteditor_keyevent_handling.html
@@ -1,17 +1,17 @@
 <html>
 <head>
   <title>Test for key event handler of text editor</title>
   <script type="text/javascript"
-          src="/tests/SimpleTest/SimpleTest.js"></script>
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
   <script type="text/javascript"
-          src="/tests/SimpleTest/EventUtils.js"></script>
+          src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
   <link rel="stylesheet" type="text/css"
-          href="/tests/SimpleTest/test.css" />
+          href="chrome://mochikit/content/tests/SimpleTest/test.css" />
 </head>
 <body>
 <div id="display">
   <input type="text" id="inputField">
   <input type="password" id="passwordField">
   <textarea id="textarea"></textarea>
 </div>
 <div id="content" style="display: none">
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -2543,20 +2543,40 @@ nsDisplayBorder::Paint(nsDisplayListBuil
                               nsRect(offset, mFrame->GetSize()),
                               mFrame->StyleContext(),
                               mFrame->GetSkipSides());
 }
 
 nsRect
 nsDisplayBorder::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap)
 {
+  *aSnap = true;
+  const nsStyleBorder *styleBorder = mFrame->StyleBorder();
   nsRect borderBounds(ToReferenceFrame(), mFrame->GetSize());
-  borderBounds.Inflate(mFrame->StyleBorder()->GetImageOutset());
-  *aSnap = true;
-  return borderBounds;
+  if (styleBorder->IsBorderImageLoaded()) {
+    borderBounds.Inflate(mFrame->StyleBorder()->GetImageOutset());
+    return borderBounds;
+  } else {
+    nsMargin border = styleBorder->GetComputedBorder();
+    nsRect result;
+    if (border.top > 0) {
+      result = nsRect(borderBounds.X(), borderBounds.Y(), borderBounds.Width(), border.top);
+    }
+    if (border.right > 0) {
+      result.UnionRect(result, nsRect(borderBounds.XMost() - border.right, borderBounds.Y(), border.right, borderBounds.Height()));
+    }
+    if (border.bottom > 0) {
+      result.UnionRect(result, nsRect(borderBounds.X(), borderBounds.YMost() - border.bottom, borderBounds.Width(), border.bottom));
+    }
+    if (border.left > 0) {
+      result.UnionRect(result, nsRect(borderBounds.X(), borderBounds.Y(), border.left, borderBounds.Height()));
+    }
+
+    return result;
+  }
 }
 
 // Given a region, compute a conservative approximation to it as a list
 // of rectangles that aren't vertically adjacent (i.e., vertically
 // adjacent or overlapping rectangles are combined).
 // Right now this is only approximate, some vertically overlapping rectangles
 // aren't guaranteed to be combined.
 static void
--- a/layout/generic/test/file_bug448987.html
+++ b/layout/generic/test/file_bug448987.html
@@ -27,18 +27,19 @@ function focus_area() {
       clearInterval(timer);
       parent.SimpleTest.executeSoon(parent.firstIframeLoaded, 0);
     }
 
     //XXX This code tries to shift focus to the image map for some reason. This is not 
     // working directly after page load, hence it is retried 10 times, see bug bug 922524
     timer = setInterval(function() {
       if (counter > 10) {
+        clearInterval(timer);
         parent.ok(false, "Too often tried to focus image map, giving up");
-        parent.Simpletest.finish();
+        parent.finish();
         return;
       }
       synthesizeKey("VK_TAB", { shiftKey: shiftKeyOn }, window); 
       shiftKeyOn = !shiftKeyOn;
       counter++;
     }, 100);
   };
   document.getElementById("pre").focus();
--- a/layout/generic/test/file_bug448987_ref.html
+++ b/layout/generic/test/file_bug448987_ref.html
@@ -27,18 +27,19 @@ function focus_area() {
       clearInterval(timer);
       parent.SimpleTest.executeSoon(parent.secondIframeLoaded, 0);
     }
 
     //XXX This code tries to shift focus to the image map for some reason. This is not 
     // working directly after page load, hence it is retried 10 times, see bug bug 922524
     timer = setInterval(function() {
       if (counter > 10) {
+        clearInterval(timer);
         parent.ok(false, "Too often tried to focus image map, giving up");
-        parent.Simpletest.finish();
+        parent.finish();
         return;
       }
       synthesizeKey("VK_TAB", { shiftKey: shiftKeyOn }, window); 
       shiftKeyOn = !shiftKeyOn;
       counter++;
     }, 100);
   };
   document.getElementById("pre").focus();
--- a/layout/generic/test/test_bug448987.html
+++ b/layout/generic/test/test_bug448987.html
@@ -25,16 +25,18 @@ https://bugzilla.mozilla.org/show_bug.cg
 <iframe id="f3"></iframe>
 </div>
 <pre id="test">
 <script type="application/javascript">
 
 /** Test for Bug 448987 **/
 SimpleTest.waitForExplicitFinish();
 
+SpecialPowers.setIntPref("accessibility.tabfocus", 7);
+
 var f1 = document.getElementById("f1");
 var f2 = document.getElementById("f2");
 var f3 = document.getElementById("f3");
 
 var snapshotf1;
 
 SimpleTest.waitForFocus(function() {
   f1.src = "file_bug448987.html";
@@ -51,14 +53,20 @@ function secondIframeLoaded() {
      "<area shape=default> should render focus outline");
   f3.src="file_bug448987_notref.html";
 }
 
 function thirdIframeLoaded() {
   ok(compareSnapshots(snapshotf1,
                       snapshotWindow(f3.contentWindow), false)[0],
      "file_bug448987.html should render focus outline, file_bug448987_notref.html should not");
+  finish();
+}
+
+function finish()
+{
+  SpecialPowers.clearUserPref("accessibility.tabfocus");
   SimpleTest.finish();
 }
 </script>
 </pre>
 </body>
 </html>
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -2499,17 +2499,17 @@ nsRuleNode::AdjustLogicalBoxProp(nsStyle
     } else {                                                                  \
       maybeFakeParentData.construct ctorargs_;                                \
       parentdata_ = maybeFakeParentData.addr();                               \
     }                                                                         \
   }                                                                           \
   bool canStoreInRuleTree = aCanStoreInRuleTree;
 
 /**
- * Begin an nsRuleNode::Compute*Data function for an inherited struct.
+ * End an nsRuleNode::Compute*Data function for an inherited struct.
  *
  * @param type_ The nsStyle* type this function computes.
  * @param data_ Variable holding the result of this function.
  */
 #define COMPUTE_END_INHERITED(type_, data_)                                   \
   NS_POSTCONDITION(!canStoreInRuleTree || aRuleDetail == eRuleFullReset ||    \
                    (aStartStruct && aRuleDetail == eRulePartialReset),        \
                    "canStoreInRuleTree must be false for inherited structs "  \
@@ -2534,17 +2534,17 @@ nsRuleNode::AdjustLogicalBoxProp(nsStyle
       AddStyleBit(nsCachedStyleData::GetBitForSID(eStyleStruct_##type_));     \
   }                                                                           \
   /* Always cache inherited data on the style context */                      \
   aContext->SetStyle##type_(data_);                                           \
                                                                               \
   return data_;
 
 /**
- * Begin an nsRuleNode::Compute*Data function for a reset struct.
+ * End an nsRuleNode::Compute*Data function for a reset struct.
  *
  * @param type_ The nsStyle* type this function computes.
  * @param data_ Variable holding the result of this function.
  */
 #define COMPUTE_END_RESET(type_, data_)                                       \
   NS_POSTCONDITION(!canStoreInRuleTree ||                                     \
                    aRuleDetail == eRuleNone ||                                \
                    aRuleDetail == eRulePartialReset ||                        \
--- a/layout/style/nsStyleAnimation.cpp
+++ b/layout/style/nsStyleAnimation.cpp
@@ -2262,17 +2262,17 @@ nsStyleAnimation::AddWeighted(nsCSSPrope
 
         // move to next list items
         if (list1) {
           list1 = list1->mNext;
         }
         if (list2) {
           list2 = list2->mNext;
         }
-      };
+      }
       NS_ABORT_IF_FALSE(!*resultTail,
                         "resultTail isn't pointing to the tail (may leak)");
 
       aResultValue.SetAndAdoptCSSValueListValue(result.forget(),
                                                 eUnit_Filter);
       return true;
     }
 
--- a/netwerk/cache/moz.build
+++ b/netwerk/cache/moz.build
@@ -15,16 +15,17 @@ XPIDL_SOURCES += [
 
 XPIDL_MODULE = 'necko_cache'
 
 EXPORTS += [
     'nsApplicationCacheService.h',
     'nsCacheService.h',
 ]
 
+# These files cannot be built in unified mode because they force NSPR logging.
 SOURCES += [
     'nsApplicationCacheService.cpp',
     'nsCache.cpp',
     'nsCacheEntry.cpp',
     'nsCacheEntryDescriptor.cpp',
     'nsCacheMetaData.cpp',
     'nsCacheService.cpp',
     'nsCacheSession.cpp',
--- a/testing/mochitest/tests/SimpleTest/EventUtils.js
+++ b/testing/mochitest/tests/SimpleTest/EventUtils.js
@@ -4,16 +4,17 @@
  *  sendMouseEvent
  *  sendChar
  *  sendString
  *  sendKey
  *  synthesizeMouse
  *  synthesizeMouseAtCenter
  *  synthesizeWheel
  *  synthesizeKey
+ *  synthesizeNativeKey
  *  synthesizeMouseExpectEvent
  *  synthesizeKeyExpectEvent
  *
  *  When adding methods to this file, please add a performance test for it.
  */
 
 // This file is used both in privileged and unprivileged contexts, so we have to
 // be careful about our access to Components.interfaces. We also want to avoid
@@ -563,16 +564,124 @@ function synthesizeKey(aKey, aEvent, aWi
       utils.sendKeyEvent(aEvent.type, keyCode, charCode, modifiers, flags);
     } else {
       // Send other standalone event than keypress.
       utils.sendKeyEvent(aEvent.type, keyCode, 0, modifiers, flags);
     }
   }
 }
 
+function _parseNativeModifiers(aModifiers)
+{
+  var modifiers;
+  if (aModifiers.capsLockKey) {
+    modifiers |= 0x00000001;
+  }
+  if (aModifiers.numLockKey) {
+    modifiers |= 0x00000002;
+  }
+  if (aModifiers.shiftKey) {
+    modifiers |= 0x00000100;
+  }
+  if (aModifiers.shiftRightKey) {
+    modifiers |= 0x00000200;
+  }
+  if (aModifiers.ctrlKey) {
+    modifiers |= 0x00000400;
+  }
+  if (aModifiers.ctrlRightKey) {
+    modifiers |= 0x00000800;
+  }
+  if (aModifiers.altKey) {
+    modifiers |= 0x00001000;
+  }
+  if (aModifiers.altRightKey) {
+    modifiers |= 0x00002000;
+  }
+  if (aModifiers.metaKey) {
+    modifiers |= 0x00004000;
+  }
+  if (aModifiers.metaRightKey) {
+    modifiers |= 0x00008000;
+  }
+  if (aModifiers.helpKey) {
+    modifiers |= 0x00010000;
+  }
+  if (aModifiers.fnKey) {
+    modifiers |= 0x00100000;
+  }
+  if (aModifiers.numericKeyPadKey) {
+    modifiers |= 0x01000000;
+  }
+
+  if (aModifiers.accelKey) {
+    modifiers |=
+      (navigator.platform.indexOf("Mac") == 0) ? 0x00004000 : 0x00000400;
+  }
+  if (aModifiers.accelRightKey) {
+    modifiers |=
+      (navigator.platform.indexOf("Mac") == 0) ? 0x00008000 : 0x00000800;
+  }
+  return modifiers;
+}
+
+const KEYBOARD_LAYOUT_EN_US = 0;
+
+/**
+ * synthesizeNativeKey() dispatches native key event on active window.
+ * This is implemented only on Windows and Mac.
+ *
+ * @param aKeyboardLayout       One of KEYBOARD_LAYOUT_* defined above.
+ * @param aNativeKeyCode        A native keycode value defined in
+ *                              NativeKeyCodes.js.
+ * @param aModifiers            Modifier keys.  If no modifire key is pressed,
+ *                              this must be {}.  Otherwise, one or more items
+ *                              referred in _parseNativeModifiers() must be
+ *                              true.
+ * @param aChars                Specify characters which should be generated
+ *                              by the key event.
+ * @param aUnmodifiedChars      Specify characters of unmodified (except Shift)
+ *                              aChar value.
+ * @return                      True if this function succeed dispatching
+ *                              native key event.  Otherwise, false.
+ */
+
+function synthesizeNativeKey(aKeyboardLayout, aNativeKeyCode, aModifiers,
+                             aChars, aUnmodifiedChars)
+{
+  var utils = _getDOMWindowUtils(window);
+  if (!utils) {
+    return false;
+  }
+  var nativeKeyboardLayout;
+  if (navigator.platform.indexOf("Mac") == 0) {
+    switch (aKeyboardLayout) {
+      case KEYBOARD_LAYOUT_EN_US:
+        nativeKeyboardLayout = 0;
+        break;
+      default:
+        return false;
+    }
+  } else if (navigator.platform.indexOf("Win") == 0) {
+    switch (aKeyboardLayout) {
+      case KEYBOARD_LAYOUT_EN_US:
+        nativeKeyboardLayout = 0x409;
+        break;
+      default:
+        return false;
+    }
+  } else {
+    return false;
+  }
+  utils.sendNativeKeyEvent(nativeKeyboardLayout, aNativeKeyCode,
+                           _parseNativeModifiers(aModifiers),
+                           aChars, aUnmodifiedChars);
+  return true;
+}
+
 var _gSeenEvent = false;
 
 /**
  * Indicate that an event with an original target of aExpectedTarget and
  * a type of aExpectedEvent is expected to be fired, or not expected to
  * be fired.
  */
 function _expectEvent(aExpectedTarget, aExpectedEvent, aTestName)
--- a/widget/tests/chrome.ini
+++ b/widget/tests/chrome.ini
@@ -21,17 +21,16 @@ support-files = window_wheeltransaction.
 support-files = window_imestate_iframes.html
 [test_plugin_scroll_consistency.html]
 [test_composition_text_querycontent.xul]
 support-files = window_composition_text_querycontent.xul
 [test_input_events_on_deactive_window.xul]
 [test_position_on_resize.xul]
 [test_sizemode_events.xul]
 [test_bug760802.xul]
-[test_assign_event_data.html]
 
 # Cocoa
 [test_native_menus.xul]
 skip-if = toolkit != "cocoa"
 support-files = native_menus_window.xul
 [test_native_mouse_mac.xul]
 skip-if = toolkit != "cocoa"
 support-files = native_mouse_mac_window.xul
--- a/widget/tests/mochitest.ini
+++ b/widget/tests/mochitest.ini
@@ -1,8 +1,10 @@
+[test_assign_event_data.html]
+skip-if = toolkit == "cocoa" # Bug 933303
 [test_bug565392.html]
 skip-if = toolkit != "windows"
 [test_picker_no_crash.html]
 skip-if = toolkit != "windows"
 support-files = window_picker_no_crash_child.html
 [test_plugin_scroll_invalidation.html]
 skip-if = toolkit != "gtk2"
 support-files = plugin_scroll_invalidation.html
--- a/widget/tests/test_assign_event_data.html
+++ b/widget/tests/test_assign_event_data.html
@@ -1,17 +1,16 @@
 <!DOCTYPE html>
 <html>
 <head>
   <title>Testing ns*Event::Assign*EventData()</title>
-  <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
-  <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/ChromeUtils.js"></script>
-  <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/NativeKeyCodes.js"></script>
-  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/NativeKeyCodes.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css">
   <style>
     #a {
       background-color: transparent;
       transition: background-color 0.1s linear;
     }
     #a:focus {
       background-color: red;
     }
@@ -45,44 +44,40 @@
 </div>
 <pre id="test">
 </pre>
 
 <script class="testbody" type="application/javascript">
 
 SimpleTest.waitForExplicitFinish();
 
-var gUtils = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIDOMWindowUtils);
 const kIsMac = (navigator.platform.indexOf("Mac") == 0);
 const kIsWin = (navigator.platform.indexOf("Win") == 0);
 
 var gEvent = null;
 var gCopiedEvent = [];
 var gCallback = null;
+var gCallPreventDefault = false;
 
 function onEvent(aEvent)
 {
+  if (gCallPreventDefault) {
+    aEvent.preventDefault();
+  }
   gEvent = aEvent;
   for (var attr in aEvent) {
     if (!attr.match(/^[A-Z0-9_]+$/) && // ignore const attributes
         attr != "multipleActionsPrevented" && // multipleActionsPrevented isn't defined in any DOM event specs.
         typeof(aEvent[attr]) != "function") {
       gCopiedEvent.push({ name: attr, value: aEvent[attr]});
     }
   }
   setTimeout(gCallback, 0);
 }
 
-const WIN_KL_US = 0x409;
-const MAC_KL_US = 0;
-
-const NATIVE_SHIFT_LEFT    = 0x0100;
-const NATIVE_CONTROL_RIGHT = 0x0800;
-const NATIVE_META_RIGHT    = 0x8000;
-
 const kTests = [
   { description: "InternalScriptErrorEvent",
     targetID: "input-text", eventType: "error",
     dispatchEvent: function () {
       return;
     },
     canRun: function () {
       todo(false, "InternalScriptErrorEvent isn't tested");
@@ -132,76 +127,62 @@ const kTests = [
     },
     todoMismatch: [],
   },
   { description: "WidgetKeyboardEvent (keydown of 'a' key without modifiers)",
     targetID: "input-text", eventType: "keydown",
     dispatchEvent: function () {
       document.getElementById(this.targetID).value = "";
       document.getElementById(this.targetID).focus();
-      if (kIsWin) {
-        gUtils.sendNativeKeyEvent(WIN_KL_US, WIN_VK_A, 0, "a", "a");
-      } else if (kIsMac) {
-        gUtils.sendNativeKeyEvent(MAC_KL_US, MAC_VK_ANSI_A, 0, "a", "a");
-      }
+      synthesizeNativeKey(KEYBOARD_LAYOUT_EN_US, kIsWin ? WIN_VK_A : MAC_VK_ANSI_A,
+                          {}, "a", "a");
     },
     canRun: function () {
       return (kIsMac || kIsWin);
     },
     todoMismatch: [],
   },
   { description: "WidgetKeyboardEvent (keyup of 'a' key without modifiers)",
     targetID: "input-text", eventType: "keydown",
     dispatchEvent: function () {
       document.getElementById(this.targetID).value = "";
       document.getElementById(this.targetID).focus();
-      if (kIsWin) {
-        gUtils.sendNativeKeyEvent(WIN_KL_US, WIN_VK_A, 0, "a", "a");
-      } else if (kIsMac) {
-        gUtils.sendNativeKeyEvent(MAC_KL_US, MAC_VK_ANSI_A, 0, "a", "a");
-      }
+      synthesizeNativeKey(KEYBOARD_LAYOUT_EN_US, kIsWin ? WIN_VK_A : MAC_VK_ANSI_A,
+                          {}, "a", "a");
     },
     canRun: function () {
       return (kIsMac || kIsWin);
     },
     todoMismatch: [],
   },
   { description: "WidgetKeyboardEvent (keypress of 'b' key with Shift)",
     targetID: "input-text", eventType: "keypress",
     dispatchEvent: function () {
       document.getElementById(this.targetID).value = "";
       document.getElementById(this.targetID).focus();
-      if (kIsWin) {
-        gUtils.sendNativeKeyEvent(WIN_KL_US, WIN_VK_B, NATIVE_SHIFT_LEFT, "B", "B");
-      } else if (kIsMac) {
-        gUtils.sendNativeKeyEvent(MAC_KL_US, MAC_VK_ANSI_B, NATIVE_SHIFT_LEFT, "B", "B");
-      }
+      synthesizeNativeKey(KEYBOARD_LAYOUT_EN_US, kIsWin ? WIN_VK_B : MAC_VK_ANSI_B,
+                          { shiftKey: true }, "B", "B");
     },
     canRun: function () {
       return (kIsMac || kIsWin);
     },
-    // "defaultPrevented" becomes true because the editor consumes the keypress event.
-    todoMismatch: [ "defaultPrevented" ],
+    todoMismatch: [],
   },
   { description: "WidgetKeyboardEvent (keypress of 'c' key with Accel)",
     targetID: "input-text", eventType: "keypress",
     dispatchEvent: function () {
       document.getElementById(this.targetID).value = "";
       document.getElementById(this.targetID).focus();
-      if (kIsWin) {
-        gUtils.sendNativeKeyEvent(WIN_KL_US, WIN_VK_C, NATIVE_CONTROL_RIGHT, "\u0003", "c");
-      } else if (kIsMac) {
-        gUtils.sendNativeKeyEvent(MAC_KL_US, MAC_VK_ANSI_C, NATIVE_META_RIGHT, "c", "c");
-      }
+      synthesizeNativeKey(KEYBOARD_LAYOUT_EN_US, kIsWin ? WIN_VK_C : MAC_VK_ANSI_C,
+                          { accelKey: true }, kIsWin ? "\u0003" : "c", "c");
     },
     canRun: function () {
       return (kIsMac || kIsWin);
     },
-    // "defaultPrevented" becomes true because the editor consumes the keypress event.
-    todoMismatch: [ "defaultPrevented" ],
+    todoMismatch: [],
   },
   { description: "WidgetMouseEvent (mousedown of left button without modifier)",
     targetID: "button", eventType: "mousedown",
     dispatchEvent: function () {
       synthesizeMouseAtCenter(document.getElementById(this.targetID),
                               { button: 0 });
     },
     canRun: function () {
@@ -534,43 +515,64 @@ function doTest(aTest)
     SimpleTest.executeSoon(runNextTest);
     return;
   }
   gEvent = null;
   gCopiedEvent = [];
   var target = aTest.target ? aTest.target() : document.getElementById(aTest.targetID);
   target.addEventListener(aTest.eventType, onEvent, true);
   gCallback = function () {
+    var description = aTest.description + " (gCallPreventDefault=" + gCallPreventDefault + ")";
     target.removeEventListener(aTest.eventType, onEvent, true);
-    ok(gEvent !== null, aTest.description + ": failed to get duplicated event");
-    ok(gCopiedEvent.length > 0, aTest.description + ": count of attribute of the event must be larger than 0");
+    ok(gEvent !== null, description + ": failed to get duplicated event");
+    ok(gCopiedEvent.length > 0, description + ": count of attribute of the event must be larger than 0");
     for (var i = 0; i < gCopiedEvent.length; ++i) {
       var name = gCopiedEvent[i].name;
       if (name == "rangeOffset") {
-        todo(false, aTest.description + ": " + name + " attribute value is never reset (" + gEvent[name] + ")");
+        todo(false, description + ": " + name + " attribute value is never reset (" + gEvent[name] + ")");
       } else if (name == "eventPhase") {
-        is(gEvent[name], 0, aTest.description + ": mismatch with fixed value (" + name + ")");
+        is(gEvent[name], 0, description + ": mismatch with fixed value (" + name + ")");
       } else if (name == "rangeParent" || name == "currentTarget") {
-        is(gEvent[name], null, aTest.description + ": mismatch with fixed value (" + name + ")");
+        is(gEvent[name], null, description + ": mismatch with fixed value (" + name + ")");
       } else if (aTest.todoMismatch.indexOf(name) >= 0) {
-        todo_is(gEvent[name], gCopiedEvent[i].value, aTest.description + ": mismatch (" + name + ")");
+        todo_is(gEvent[name], gCopiedEvent[i].value, description + ": mismatch (" + name + ")");
       } else {
-        is(gEvent[name], gCopiedEvent[i].value, aTest.description + ": mismatch (" + name + ")");
+        is(gEvent[name], gCopiedEvent[i].value, description + ": mismatch (" + name + ")");
       }
     }
     runNextTest();
   };
   aTest.dispatchEvent();
 }
 
 var gIndex = -1;
 function runNextTest()
 {
   if (++gIndex == kTests.length) {
-    finish();
+    if (gCallPreventDefault) {
+      finish();
+      return;
+    }
+    // Test with a call of preventDefault() of the events.
+    gCallPreventDefault = true;
+    gIndex = -1;
+    // Restoring the initial state of all elements.
+    document.getElementById("scrollable-div").style.height = "30px";
+    document.getElementById("scrollable-div").style.width = "30px";
+    document.getElementById("scrolled-div").style.height = "10px";
+    document.getElementById("scrolled-div").style.width = "10px";
+    document.getElementById("input-text").value = "";
+    document.getElementById("animated-div").className = "";
+    document.getElementById("animated-div").removeAttribute("x-data");
+    if (document.activeElement) {
+      document.activeElement.blur();
+    }
+    window.requestAnimationFrame(function () {
+      setTimeout(runNextTest, 0);
+    });
     return;
   }
   doTest(kTests[gIndex]);
 }
 
 function init()
 {
   SpecialPowers.setBoolPref("middlemouse.contentLoadURL", false);
--- a/xpcom/glue/nsCOMArray.h
+++ b/xpcom/glue/nsCOMArray.h
@@ -33,20 +33,20 @@ protected:
 
     int32_t IndexOfObject(nsISupports* aObject) const;
     bool ContainsObject(nsISupports* aObject) const {
         return IndexOfObject(aObject) != -1;
     }
 
     typedef bool (* nsBaseArrayEnumFunc)
         (void* aElement, void *aData);
-    
+
     // enumerate through the array with a callback.
     bool EnumerateForwards(nsBaseArrayEnumFunc aFunc, void* aData) const;
-    
+
     bool EnumerateBackwards(nsBaseArrayEnumFunc aFunc, void* aData) const;
 
     typedef int (* nsBaseArrayComparatorFunc)
         (nsISupports* aElement1, nsISupports* aElement2, void* aData);
 
     struct nsCOMArrayComparatorContext {
         nsBaseArrayComparatorFunc mComparatorFunc;
         void* mData;
@@ -116,17 +116,17 @@ public:
 
     nsISupports* ObjectAt(int32_t aIndex) const {
         return mArray[aIndex];
     }
     // nsTArray-compatible version
     nsISupports* ElementAt(uint32_t aIndex) const {
         return mArray[aIndex];
     }
-    
+
     nsISupports* SafeObjectAt(int32_t aIndex) const {
         return mArray.SafeElementAt(aIndex, nullptr);
     }
     // nsTArray-compatible version
     nsISupports* SafeElementAt(uint32_t aIndex) const {
         return mArray.SafeElementAt(aIndex, nullptr);
     }
 
@@ -167,17 +167,17 @@ public:
     // Measures the size of the array's element storage, and if
     // |aSizeOfElement| is non-nullptr, measures the size of things pointed to
     // by elements.
     size_t SizeOfExcludingThis(
              nsBaseArraySizeOfElementIncludingThisFunc aSizeOfElementIncludingThis,
              mozilla::MallocSizeOf aMallocSizeOf, void* aData = nullptr) const;
 
 private:
-    
+
     // the actual storage
     nsTArray<nsISupports*> mArray;
 
     // don't implement these, defaults will muck with refcounts!
     nsCOMArray_base& operator=(const nsCOMArray_base& other) MOZ_DELETE;
 };
 
 inline void
@@ -188,18 +188,18 @@ ImplCycleCollectionUnlink(nsCOMArray_bas
 
 inline void
 ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
                             nsCOMArray_base& aField,
                             const char* aName,
                             uint32_t aFlags = 0)
 {
     aFlags |= CycleCollectionEdgeNameArrayFlag;
-    size_t length = aField.Count();
-    for (size_t i = 0; i < length; ++i) {
+    int32_t length = aField.Count();
+    for (int32_t i = 0; i < length; ++i) {
         CycleCollectionNoteChild(aCallback, aField[i], aName, aFlags);
     }
 }
 
 
 // a non-XPCOM, refcounting array of XPCOM objects
 // used as a member variable or stack variable - this object is NOT
 // refcounted, but the objects that it holds are
@@ -221,17 +221,17 @@ ImplCycleCollectionTraverse(nsCycleColle
 template <class T>
 class nsCOMArray : public nsCOMArray_base
 {
  public:
     nsCOMArray() {}
 
     explicit
     nsCOMArray(int32_t aCount) : nsCOMArray_base(aCount) {}
-    
+
     explicit
     nsCOMArray(const nsCOMArray<T>& aOther) : nsCOMArray_base(aOther) { }
 
     ~nsCOMArray() {}
 
     // these do NOT refcount on the way out, for speed
     T* ObjectAt(int32_t aIndex) const {
         return static_cast<T*>(nsCOMArray_base::ObjectAt(aIndex));
@@ -310,31 +310,31 @@ class nsCOMArray : public nsCOMArray_bas
         nsCOMArray_base::ReplaceElementAt(aIndex, aElement);
     }
 
     // Enumerator callback function. Return false to stop
     // Here's a more readable form:
     // bool enumerate(T* aElement, void* aData)
     typedef bool (* nsCOMArrayEnumFunc)
         (T* aElement, void *aData);
-    
+
     // enumerate through the array with a callback. 
     bool EnumerateForwards(nsCOMArrayEnumFunc aFunc, void* aData) {
         return nsCOMArray_base::EnumerateForwards(nsBaseArrayEnumFunc(aFunc),
                                                   aData);
     }
 
     bool EnumerateBackwards(nsCOMArrayEnumFunc aFunc, void* aData) {
         return nsCOMArray_base::EnumerateBackwards(nsBaseArrayEnumFunc(aFunc),
                                                   aData);
     }
-    
+
     typedef int (* nsCOMArrayComparatorFunc)
         (T* aElement1, T* aElement2, void* aData);
-        
+
     void Sort(nsCOMArrayComparatorFunc aFunc, void* aData) {
         nsCOMArray_base::Sort(nsBaseArrayComparatorFunc(aFunc), aData);
     }
 
     // append an object, growing the array as necessary
     bool AppendObject(T *aObject) {
         return nsCOMArray_base::AppendObject(aObject);
     }
@@ -349,17 +349,17 @@ class nsCOMArray : public nsCOMArray_bas
     }
     // nsTArray-compatible version
     void AppendElements(const nsCOMArray<T>& aElements) {
         return nsCOMArray_base::AppendElements(aElements);
     }
     void AppendElements(T* const* aElements, uint32_t aCount) {
         InsertElementsAt(Length(), aElements, aCount);
     }
-    
+
     // remove the first instance of the given object and shrink the
     // array as necessary
     // Warning: if you pass null here, it will remove the first null element
     bool RemoveObject(T *aObject) {
         return nsCOMArray_base::RemoveObject(aObject);
     }
     // nsTArray-compatible version
     bool RemoveElement(T* aElement) {
@@ -373,17 +373,17 @@ class nsCOMArray : public nsCOMArray_bas
         nsCOMArray_base::SwapElements(aOther);
     }
 
     // Each element in an nsCOMArray<T> is actually a T*, so this function is
     // "IncludingThis" rather than "ExcludingThis" because it needs to measure
     // the memory taken by the T itself as well as anything it points to.
     typedef size_t (* nsCOMArraySizeOfElementIncludingThisFunc)
         (T* aElement, mozilla::MallocSizeOf aMallocSizeOf, void *aData);
-    
+
     size_t SizeOfExcludingThis(
              nsCOMArraySizeOfElementIncludingThisFunc aSizeOfElementIncludingThis, 
              mozilla::MallocSizeOf aMallocSizeOf, void *aData = nullptr) const {
         return nsCOMArray_base::SizeOfExcludingThis(
                  nsBaseArraySizeOfElementIncludingThisFunc(aSizeOfElementIncludingThis),
                  aMallocSizeOf, aData);
     }
 
@@ -403,15 +403,15 @@ ImplCycleCollectionUnlink(nsCOMArray<T>&
 template <typename E>
 inline void
 ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
                             nsCOMArray<E>& aField,
                             const char* aName,
                             uint32_t aFlags = 0)
 {
     aFlags |= CycleCollectionEdgeNameArrayFlag;
-    size_t length = aField.Count();
-    for (size_t i = 0; i < length; ++i) {
+    int32_t length = aField.Count();
+    for (int32_t i = 0; i < length; ++i) {
         CycleCollectionNoteChild(aCallback, aField[i], aName, aFlags);
     }
 }
 
 #endif