Merge inbound to m-c. a=merge
authorRyan VanderMeulen <ryanvm@gmail.com>
Mon, 08 Sep 2014 19:10:31 -0400
changeset 228704 6b8da5940f74dae0c315a014b572e7c4e78ddb35
parent 228673 9f988e041e3c5345609e4d7ea26cfdf6f3323737 (current diff)
parent 228703 f0fbb5c6c672985ae41b300f2cc1de590df51030 (diff)
child 228707 fcc8a9d69be9e7b54a2115f46328ea9733a2b95d
child 228760 8a0f3c42df5d799491970c015c634f8056a5ad84
child 228793 ed872b06ebbd8c73ed15f4b46eadcb8712e419ee
push id611
push userraliiev@mozilla.com
push dateMon, 05 Jan 2015 23:23:16 +0000
treeherdermozilla-release@345cd3b9c445 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone35.0a1
first release with
nightly linux32
6b8da5940f74 / 35.0a1 / 20140909030207 / files
nightly linux64
6b8da5940f74 / 35.0a1 / 20140909030207 / files
nightly mac
6b8da5940f74 / 35.0a1 / 20140909030207 / files
nightly win32
6b8da5940f74 / 35.0a1 / 20140909030207 / files
nightly win64
6b8da5940f74 / 35.0a1 / 20140909030207 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge inbound to m-c. a=merge
--- a/accessible/jsat/OutputGenerator.jsm
+++ b/accessible/jsat/OutputGenerator.jsm
@@ -591,16 +591,20 @@ this.UtteranceGenerator = {  // jshint i
   },
 
   _addState: function _addState(aOutput, aState) {
 
     if (aState.contains(States.UNAVAILABLE)) {
       aOutput.push({string: 'stateUnavailable'});
     }
 
+    if (aState.contains(States.READONLY)) {
+      aOutput.push({string: 'stateReadonly'});
+    }
+
     // Don't utter this in Jelly Bean, we let TalkBack do it for us there.
     // This is because we expose the checked information on the node itself.
     // XXX: this means the checked state is always appended to the end,
     // regardless of the utterance ordering preference.
     if ((Utils.AndroidSdkVersion < 16 || Utils.MozBuildApp === 'browser') &&
       aState.contains(States.CHECKABLE)) {
       let statetr = aState.contains(States.CHECKED) ?
         'stateChecked' : 'stateNotChecked';
--- a/accessible/tests/mochitest/jsat/test_output.html
+++ b/accessible/tests/mochitest/jsat/test_output.html
@@ -228,16 +228,32 @@ https://bugzilla.mozilla.org/show_bug.cg
           // test required state utterance
           accOrElmOrID: "requiredInput",
           expectedUtterance: [[{"string": "stateRequired"}, {"string": "entry"},
             "I am required"], ["I am required", {"string": "stateRequired"},
             {"string": "entry"}]],
           expectedBraille: [[{"string": "entryAbbr"}, "I am required"],
                             ["I am required", {"string": "entryAbbr"}]]
         }, {
+          // test unavailable state utterance on inputs
+          accOrElmOrID: "readonlyInput",
+          expectedUtterance: [[{"string": "stateReadonly"}, {"string": "entry"},
+            "No edits"], ["No edits", {"string": "stateReadonly"},
+            {"string": "entry"}]],
+          expectedBraille: [[{"string": "entryAbbr"}, "No edits"],
+                            ["No edits", {"string": "entryAbbr"}]]
+        }, {
+          // test unavailable state utterance on textareas
+          accOrElmOrID: "readonlyTextarea",
+          expectedUtterance: [[{"string": "stateReadonly"}, {"string": "textarea"},
+            "No editing"], ["No editing", {"string": "stateReadonly"},
+            {"string": "textarea"}]],
+          expectedBraille: [[{"string": "textareaAbbr"}, "No editing"],
+                            ["No editing", {"string": "textareaAbbr"}]]
+        }, {
           // test has popup state utterance
           accOrElmOrID: "hasPopupButton",
           expectedUtterance: [[{"string": "stateHasPopup"},
             {"string": "buttonmenu"}, "I have a popup"], ["I have a popup",
             {"string": "stateHasPopup"}, {"string": "buttonmenu"}]],
           expectedBraille: [[{"string": "buttonmenuAbbr"}, "I have a popup"],
                             ["I have a popup", {"string": "buttonmenuAbbr"}]]
         }, {
@@ -481,16 +497,18 @@ https://bugzilla.mozilla.org/show_bug.cg
             </ul>
           </td>
         </tr>
       </table>
       <button id="unavailableButton" disabled>I am unavailable</button>
       <button id="expandedButton" aria-expanded="true">I am expanded</button>
       <button id="collapsedButton" aria-expanded="false">I am collapsed</button>
       <input id="requiredInput" required placeholder="I am required" />
+      <input id="readonlyInput" readonly value="No edits" />
+      <textarea id="readonlyTextarea" readonly>No editing</textarea>
       <button id="hasPopupButton" aria-haspopup="true">I have a popup</button>
       <div role="tablist">
         <a id="tab1" href="#" role="tab" aria-selected="true">Account</a>
         <a id="tab2" href="#" role="tab" aria-selected="false">Advanced</a>
       </div>
       <form id="form1">
         <label id="label1"><input id="input1" type="checkbox">Orange</label>
         <input id="input2" type="checkbox"><label id="label2" for="input2">Blue</label>
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -966,17 +966,17 @@ pref("apz.fling_friction", "0.003");
 // Tweak default displayport values to reduce the risk of running out of
 // memory when zooming in
 pref("apz.x_skate_size_multiplier", "1.25");
 pref("apz.y_skate_size_multiplier", "1.5");
 pref("apz.x_stationary_size_multiplier", "1.5");
 pref("apz.y_stationary_size_multiplier", "1.8");
 pref("apz.enlarge_displayport_when_clipped", true);
 // Use "sticky" axis locking
-pref("apz.axis_lock_mode", 2);
+pref("apz.axis_lock.mode", 2);
 pref("apz.subframe.enabled", true);
 
 // Overscroll-related settings
 pref("apz.overscroll.enabled", true);
 pref("apz.overscroll.fling_friction", "0.02");
 pref("apz.overscroll.fling_stopped_threshold", "0.4");
 pref("apz.overscroll.stretch_factor", "0.5");
 pref("apz.overscroll.snap_back.spring_stiffness", "0.6");
--- a/browser/metro/profile/metro.js
+++ b/browser/metro/profile/metro.js
@@ -52,17 +52,17 @@ pref("apz.touch_start_tolerance", "0.1")
 pref("apz.pan_repaint_interval", 50);   // prefer 20 fps
 pref("apz.fling_repaint_interval", 50); // prefer 20 fps
 pref("apz.smooth_scroll_repaint_interval", 50); // prefer 20 fps
 pref("apz.fling_stopped_threshold", "0.2");
 pref("apz.x_skate_size_multiplier", "2.5");
 pref("apz.y_skate_size_multiplier", "2.5");
 pref("apz.min_skate_speed", "10.0");
 // 0 = free, 1 = standard, 2 = sticky
-pref("apz.axis_lock_mode", 2);
+pref("apz.axis_lock.mode", 2);
 pref("apz.cross_slide.enabled", true);
 pref("apz.subframe.enabled", true);
 
 // Enable Microsoft TSF support by default for imes.
 pref("intl.tsf.enable", true);
 pref("intl.tsf.support_imm", false);
 pref("intl.tsf.hack.atok.create_native_caret", false);
 
--- a/config/check_spidermonkey_style.py
+++ b/config/check_spidermonkey_style.py
@@ -394,16 +394,20 @@ class HashIfBlock(object):
         return False
 
 
 def do_file(filename, inclname, file_kind, f, all_inclnames, included_h_inclnames):
     block_stack = [HashIfBlock()]
 
     # Extract the #include statements as a tree of IBlocks and IIncludes.
     for linenum, line in enumerate(f, start=1):
+        # We're only interested in lines that contain a '#'.
+        if not '#' in line:
+            continue
+
         # Look for a |#include "..."| line.
         m = re.match(r'\s*#\s*include\s+"([^"]*)"', line)
         if m is not None:
             block_stack[-1].kids.append(Include(m.group(1), linenum, False))
 
         # Look for a |#include <...>| line.
         m = re.match(r'\s*#\s*include\s+<([^>]*)>', line)
         if m is not None:
@@ -477,26 +481,22 @@ def do_file(filename, inclname, file_kin
 
         section1 = include1.section(inclname)
         section2 = include2.section(inclname)
         if (section1 > section2) or \
            ((section1 == section2) and (include1.inclname.lower() > include2.inclname.lower())):
             error(filename, str(include1.linenum) + ':' + str(include2.linenum),
                   include1.quote() + ' should be included after ' + include2.quote())
 
-    # The #include statements in the files in assembler/ have all manner of implicit
-    # ordering requirements.  Boo.  Ignore them.
-    skip_order_checking = inclname.startswith('assembler/')
-
     # Check the extracted #include statements, both individually, and the ordering of
     # adjacent pairs that live in the same block.
     def pair_traverse(prev, this):
         if this.isLeaf():
             check_include_statement(this)
-            if prev is not None and prev.isLeaf() and not skip_order_checking:
+            if prev is not None and prev.isLeaf():
                 check_includes_order(prev, this)
         else:
             for prev2, this2 in zip([None] + this.kids[0:-1], this.kids):
                 pair_traverse(prev2, this2)
 
     pair_traverse(None, block_stack[-1])
 
 
--- a/content/media/gmp/GMPProcessParent.cpp
+++ b/content/media/gmp/GMPProcessParent.cpp
@@ -4,20 +4,16 @@
  * 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 "GMPProcessParent.h"
 
 #include "base/string_util.h"
 #include "base/process_util.h"
 
-#ifdef XP_WIN
-#include <codecvt>
-#endif
-
 #include <string>
 
 using std::vector;
 using std::string;
 
 using mozilla::gmp::GMPProcessParent;
 using mozilla::ipc::GeckoChildProcessHost;
 using base::ProcessArchitecture;
@@ -45,19 +41,18 @@ GMPProcessParent::~GMPProcessParent()
 }
 
 bool
 GMPProcessParent::Launch(int32_t aTimeoutMs)
 {
   vector<string> args;
   args.push_back(mGMPPath);
 
-#ifdef XP_WIN
-  std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
-  std::wstring wGMPPath = converter.from_bytes(mGMPPath.c_str());
+#if defined(XP_WIN) && defined(MOZ_SANDBOX)
+  std::wstring wGMPPath = UTF8ToWide(mGMPPath.c_str());
   mAllowedFilesRead.push_back(wGMPPath + L"\\*");
 #endif
 
   return SyncLaunch(args, aTimeoutMs, base::GetCurrentProcessArchitecture());
 }
 
 void
 GMPProcessParent::Delete()
--- a/content/media/gmp/GMPStorageParent.cpp
+++ b/content/media/gmp/GMPStorageParent.cpp
@@ -77,17 +77,17 @@ GetGMPStorageDir(nsIFile** aTempDir, con
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   // TODO: When aOrigin is the same node-id as the GMP sees in the child
   // process (a UUID or somesuch), we can just append it un-hashed here.
   // This should reduce the chance of hash collsions exposing data.
   nsAutoString nodeIdHash;
-  nodeIdHash.AppendInt(HashString(aOrigin.get()));
+  nodeIdHash.AppendInt(HashString(static_cast<const char16_t*>(aOrigin.get())));
   rv = tmpFile->Append(nodeIdHash);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   rv = tmpFile->Create(nsIFile::DIRECTORY_TYPE, 0700);
   if (rv != NS_ERROR_FILE_ALREADY_EXISTS && NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -1222,25 +1222,16 @@ nsDOMClassInfo::HasInstance(nsIXPConnect
                             JSObject *obj, JS::Handle<JS::Value> val, bool *bp,
                             bool *_retval)
 {
   NS_WARNING("nsDOMClassInfo::HasInstance Don't call me!");
 
   return NS_ERROR_UNEXPECTED;
 }
 
-NS_IMETHODIMP
-nsDOMClassInfo::OuterObject(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
-                            JSObject * obj, JSObject * *_retval)
-{
-  NS_WARNING("nsDOMClassInfo::OuterObject Don't call me!");
-
-  return NS_ERROR_UNEXPECTED;
-}
-
 static nsresult
 GetExternalClassInfo(nsScriptNameSpaceManager *aNameSpaceManager,
                      const nsAString &aName,
                      const nsGlobalNameStruct *aStruct,
                      const nsGlobalNameStruct **aResult)
 {
   NS_ASSERTION(aStruct->mType ==
                  nsGlobalNameStruct::eTypeExternalClassInfoCreator,
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -1211,31 +1211,36 @@ def UnionTypes(descriptors, dictionaries
             # FIXME: Unions are broken in workers.  See bug 809899.
             unionStructs[name] = CGUnionStruct(t, providers[0])
             owningUnionStructs[name] = CGUnionStruct(t, providers[0],
                                                      ownsMembers=True)
 
             def addHeadersForType(f):
                 if f.nullable():
                     headers.add("mozilla/dom/Nullable.h")
+                isSequence = f.isSequence()
                 f = f.unroll()
                 if f.isInterface():
                     if f.isSpiderMonkeyInterface():
                         headers.add("jsfriendapi.h")
                         headers.add("mozilla/dom/TypedArray.h")
                     else:
                         for p in providers:
                             try:
                                 typeDesc = p.getDescriptor(f.inner.identifier.name)
                             except NoSuchDescriptorError:
                                 continue
-                            if typeDesc.interface.isCallback():
+                            if typeDesc.interface.isCallback() or isSequence:
                                 # Callback interfaces always use strong refs, so
                                 # we need to include the right header to be able
                                 # to Release() in our inlined code.
+                                #
+                                # Similarly, sequences always contain strong
+                                # refs, so we'll need the header to handler
+                                # those.
                                 headers.add(typeDesc.headerFile)
                             else:
                                 declarations.add((typeDesc.nativeType, False))
                                 implheaders.add(typeDesc.headerFile)
                 elif f.isDictionary():
                     # For a dictionary, we need to see its declaration in
                     # UnionTypes.h so we have its sizeof and know how big to
                     # make our union.
@@ -4646,17 +4651,17 @@ def getJSToNativeConversionInfo(type, de
             holderType = CGGeneric(holderType)
         return JSToNativeConversionInfo(templateBody,
                                         declType=declType,
                                         holderType=holderType,
                                         dealWithOptional=isOptional)
 
     if type.isSpiderMonkeyInterface():
         assert not isEnforceRange and not isClamp
-        name = type.name
+        name = type.unroll().name # unroll() because it may be nullable
         arrayType = CGGeneric(name)
         declType = arrayType
         if type.nullable():
             declType = CGTemplatedType("Nullable", declType)
             objRef = "${declName}.SetValue()"
         else:
             objRef = "${declName}"
 
@@ -6197,18 +6202,16 @@ class CGCallGenerator(CGThing):
         return self.cgRoot.define()
 
 
 def getUnionMemberName(type):
     if type.isGeckoInterface():
         return type.inner.identifier.name
     if type.isEnum():
         return type.inner.identifier.name
-    if type.isArray() or type.isSequence() or type.isMozMap():
-        return str(type)
     return type.name
 
 
 class MethodNotNewObjectError(Exception):
     def __init__(self, typename):
         self.typename = typename
 
 # A counter for making sure that when we're wrapping up things in
@@ -12443,17 +12446,18 @@ class CGNativeMember(ClassMethod):
             return ((typeDecl %
                      self.descriptorProvider.getDescriptor(iface.identifier.name).prettyNativeType),
                     False, False)
 
         if type.isSpiderMonkeyInterface():
             if not self.typedArraysAreStructs:
                 return "JS::Handle<JSObject*>", False, False
 
-            return type.name, True, True
+            # Unroll for the name, in case we're nullable.
+            return type.unroll().name, True, True
 
         if type.isDOMString() or type.isScalarValueString():
             if isMember:
                 declType = "nsString"
             else:
                 declType = "nsAString"
             return declType, True, False
 
--- a/dom/bindings/parser/WebIDL.py
+++ b/dom/bindings/parser/WebIDL.py
@@ -1759,17 +1759,20 @@ class IDLUnresolvedType(IDLType):
         raise TypeError("Can't tell whether an unresolved type is or is not "
                         "distinguishable from other things")
 
 class IDLNullableType(IDLType):
     def __init__(self, location, innerType):
         assert not innerType.isVoid()
         assert not innerType == BuiltinTypes[IDLBuiltinType.Types.any]
 
-        IDLType.__init__(self, location, innerType.name)
+        name = innerType.name
+        if innerType.isComplete():
+            name += "OrNull"
+        IDLType.__init__(self, location, name)
         self.inner = innerType
         self.builtin = False
 
     def __eq__(self, other):
         return isinstance(other, IDLNullableType) and self.inner == other.inner
 
     def __str__(self):
         return self.inner.__str__() + "OrNull"
@@ -1872,17 +1875,17 @@ class IDLNullableType(IDLType):
                               "a nullable type",
                               [self.location, self.inner.location])
         if self.inner.isUnion():
             if self.inner.hasNullableType:
                 raise WebIDLError("The inner type of a nullable type must not "
                                   "be a union type that itself has a nullable "
                                   "type as a member type", [self.location])
 
-        self.name = self.inner.name
+        self.name = self.inner.name + "OrNull"
         return self
 
     def unroll(self):
         return self.inner.unroll()
 
     def isDistinguishableFrom(self, other):
         if (other.nullable() or (other.isUnion() and other.hasNullableType) or
             other.isDictionary()):
@@ -1895,16 +1898,20 @@ class IDLNullableType(IDLType):
 
 class IDLSequenceType(IDLType):
     def __init__(self, location, parameterType):
         assert not parameterType.isVoid()
 
         IDLType.__init__(self, location, parameterType.name)
         self.inner = parameterType
         self.builtin = False
+        # Need to set self.name up front if our inner type is already complete,
+        # since in that case our .complete() won't be called.
+        if self.inner.isComplete():
+            self.name = self.inner.name + "Sequence"
 
     def __eq__(self, other):
         return isinstance(other, IDLSequenceType) and self.inner == other.inner
 
     def __str__(self):
         return self.inner.__str__() + "Sequence"
 
     def nullable(self):
@@ -1956,17 +1963,17 @@ class IDLSequenceType(IDLType):
         assert isinstance(parentScope, IDLScope)
         self.inner.resolveType(parentScope)
 
     def isComplete(self):
         return self.inner.isComplete()
 
     def complete(self, scope):
         self.inner = self.inner.complete(scope)
-        self.name = self.inner.name
+        self.name = self.inner.name + "Sequence"
         return self
 
     def unroll(self):
         return self.inner.unroll()
 
     def isDistinguishableFrom(self, other):
         if other.isUnion():
             # Just forward to the union; it'll deal
@@ -1982,16 +1989,20 @@ class IDLMozMapType(IDLType):
     # And maybe to IDLNullableType.  Should we have a superclass for
     # "type containing this other type"?  Bug 1015318.
     def __init__(self, location, parameterType):
         assert not parameterType.isVoid()
 
         IDLType.__init__(self, location, parameterType.name)
         self.inner = parameterType
         self.builtin = False
+        # Need to set self.name up front if our inner type is already complete,
+        # since in that case our .complete() won't be called.
+        if self.inner.isComplete():
+            self.name = self.inner.name + "MozMap"
 
     def __eq__(self, other):
         return isinstance(other, IDLMozMapType) and self.inner == other.inner
 
     def __str__(self):
         return self.inner.__str__() + "MozMap"
 
     def isMozMap(self):
@@ -2007,17 +2018,17 @@ class IDLMozMapType(IDLType):
         assert isinstance(parentScope, IDLScope)
         self.inner.resolveType(parentScope)
 
     def isComplete(self):
         return self.inner.isComplete()
 
     def complete(self, scope):
         self.inner = self.inner.complete(scope)
-        self.name = self.inner.name
+        self.name = self.inner.name + "MozMap"
         return self
 
     def unroll(self):
         # We do not unroll our inner.  Just stop at ourselves.  That
         # lets us add headers for both ourselves and our inner as
         # needed.
         return self
 
@@ -2072,19 +2083,16 @@ class IDLUnionType(IDLType):
     def complete(self, scope):
         def typeName(type):
             if isinstance(type, IDLNullableType):
                 return typeName(type.inner) + "OrNull"
             if isinstance(type, IDLWrapperType):
                 return typeName(type._identifier.object())
             if isinstance(type, IDLObjectWithIdentifier):
                 return typeName(type.identifier)
-            if (isinstance(type, IDLType) and
-                (type.isArray() or type.isSequence() or type.isMozMap)):
-                return str(type)
             return type.name
 
         for (i, type) in enumerate(self.memberTypes):
             if not type.isComplete():
                 self.memberTypes[i] = type.complete(scope)
 
         self.name = "Or".join(typeName(type) for type in self.memberTypes)
         self.flatMemberTypes = list(self.memberTypes)
--- a/dom/bindings/parser/tests/test_nullable_equivalency.py
+++ b/dom/bindings/parser/tests/test_nullable_equivalency.py
@@ -85,17 +85,17 @@ def checkEquivalent(iface, harness):
     #  - names beginning with '_',
     #  - functions which throw when called with no args, and
     #  - class-level non-callables ("static variables").
     #
     # Yes, this is an ugly, fragile hack.  But it finds bugs...
     for attr in dir(type1):
         if attr.startswith('_') or \
            attr in ['nullable', 'builtin', 'filename', 'location',
-                    'inner', 'QName', 'getDeps'] or \
+                    'inner', 'QName', 'getDeps', 'name'] or \
            (hasattr(type(type1), attr) and not callable(getattr(type1, attr))):
             continue
 
         a1 = getattr(type1, attr)
 
         if callable(a1):
             try:
                 v1 = a1()
--- a/dom/bindings/parser/tests/test_typedef.py
+++ b/dom/bindings/parser/tests/test_typedef.py
@@ -7,17 +7,17 @@ def WebIDLTest(parser, harness):
         const mynullablelong Y = 7;
         const mynullablelong Z = null;
         void foo(mylong arg);
       };
     """)
 
     results = parser.finish()
 
-    harness.check(results[2].members[1].type.name, "Long",
+    harness.check(results[2].members[1].type.name, "LongOrNull",
                   "Should expand typedefs")
 
     parser = parser.reset()
     threw = False
     try:
         parser.parse("""
           typedef long? mynullablelong;
           interface Foo {
--- a/dom/bindings/test/TestBindingHeader.h
+++ b/dom/bindings/test/TestBindingHeader.h
@@ -598,16 +598,20 @@ public:
   void PassUnion15(const LongSequenceOrLong&);
   void PassUnion16(const Optional<LongSequenceOrLong>&);
   void PassUnion17(const LongSequenceOrNullOrLong&);
   void PassUnion18(JSContext*, const ObjectSequenceOrLong&);
   void PassUnion19(JSContext*, const Optional<ObjectSequenceOrLong>&);
   void PassUnion20(JSContext*, const ObjectSequenceOrLong&);
   void PassUnion21(const LongMozMapOrLong&);
   void PassUnion22(JSContext*, const ObjectMozMapOrLong&);
+  void PassUnion23(const ImageDataSequenceOrLong&);
+  void PassUnion24(const ImageDataOrNullSequenceOrLong&);
+  void PassUnion25(const ImageDataSequenceSequenceOrLong&);
+  void PassUnion26(const ImageDataOrNullSequenceSequenceOrLong&);
   void PassUnionWithCallback(const EventHandlerNonNullOrNullOrLong& arg);
   void PassUnionWithByteString(const ByteStringOrLong&);
   void PassUnionWithMozMap(const StringMozMapOrString&);
   void PassUnionWithMozMapAndSequence(const StringMozMapOrStringSequence&);
   void PassUnionWithSequenceAndMozMap(const StringSequenceOrStringMozMap&);
   void PassUnionWithSVS(const ScalarValueStringOrLong&);
 #endif
   void PassNullableUnion(JSContext*, const Nullable<ObjectOrLong>&);
--- a/dom/bindings/test/TestCodeGen.webidl
+++ b/dom/bindings/test/TestCodeGen.webidl
@@ -562,16 +562,20 @@ interface TestInterface {
   void passUnion15((sequence<long> or long) arg);
   void passUnion16(optional (sequence<long> or long) arg);
   void passUnion17(optional (sequence<long>? or long) arg = 5);
   void passUnion18((sequence<object> or long) arg);
   void passUnion19(optional (sequence<object> or long) arg);
   void passUnion20(optional (sequence<object> or long) arg = []);
   void passUnion21((MozMap<long> or long) arg);
   void passUnion22((MozMap<object> or long) arg);
+  void passUnion23((sequence<ImageData> or long) arg);
+  void passUnion24((sequence<ImageData?> or long) arg);
+  void passUnion25((sequence<sequence<ImageData>> or long) arg);
+  void passUnion26((sequence<sequence<ImageData?>> or long) arg);
   void passUnionWithCallback((EventHandler or long) arg);
   void passUnionWithByteString((ByteString or long) arg);
   void passUnionWithMozMap((MozMap<DOMString> or DOMString) arg);
   void passUnionWithMozMapAndSequence((MozMap<DOMString> or sequence<DOMString>) arg);
   void passUnionWithSequenceAndMozMap((sequence<DOMString> or MozMap<DOMString>) arg);
   void passUnionWithSVS((ScalarValueString or long) arg);
 #endif
   void passUnionWithNullable((object? or long) arg);
--- a/dom/bindings/test/TestExampleGen.webidl
+++ b/dom/bindings/test/TestExampleGen.webidl
@@ -426,16 +426,20 @@ interface TestExampleInterface {
   void passUnion15((sequence<long> or long) arg);
   void passUnion16(optional (sequence<long> or long) arg);
   void passUnion17(optional (sequence<long>? or long) arg = 5);
   void passUnion18((sequence<object> or long) arg);
   void passUnion19(optional (sequence<object> or long) arg);
   void passUnion20(optional (sequence<object> or long) arg = []);
   void passUnion21((MozMap<long> or long) arg);
   void passUnion22((MozMap<object> or long) arg);
+  void passUnion23((sequence<ImageData> or long) arg);
+  void passUnion24((sequence<ImageData?> or long) arg);
+  void passUnion25((sequence<sequence<ImageData>> or long) arg);
+  void passUnion26((sequence<sequence<ImageData?>> or long) arg);
   void passUnionWithCallback((EventHandler or long) arg);
   void passUnionWithByteString((ByteString or long) arg);
   void passUnionWithMozMap((MozMap<DOMString> or DOMString) arg);
   void passUnionWithMozMapAndSequence((MozMap<DOMString> or sequence<DOMString>) arg);
   void passUnionWithSequenceAndMozMap((sequence<DOMString> or MozMap<DOMString>) arg);
   void passUnionWithSVS((ScalarValueString or long) arg);
 #endif
   void passUnionWithNullable((object? or long) arg);
--- a/dom/bindings/test/TestJSImplGen.webidl
+++ b/dom/bindings/test/TestJSImplGen.webidl
@@ -446,16 +446,20 @@ interface TestJSImplInterface {
   void passUnion15((sequence<long> or long) arg);
   void passUnion16(optional (sequence<long> or long) arg);
   void passUnion17(optional (sequence<long>? or long) arg = 5);
   void passUnion18((sequence<object> or long) arg);
   void passUnion19(optional (sequence<object> or long) arg);
   void passUnion20(optional (sequence<object> or long) arg = []);
   void passUnion21((MozMap<long> or long) arg);
   void passUnion22((MozMap<object> or long) arg);
+  void passUnion23((sequence<ImageData> or long) arg);
+  void passUnion24((sequence<ImageData?> or long) arg);
+  void passUnion25((sequence<sequence<ImageData>> or long) arg);
+  void passUnion26((sequence<sequence<ImageData?>> or long) arg);
   void passUnionWithCallback((EventHandler or long) arg);
   void passUnionWithByteString((ByteString or long) arg);
   void passUnionWithMozMap((MozMap<DOMString> or DOMString) arg);
   void passUnionWithMozMapAndSequence((MozMap<DOMString> or sequence<DOMString>) arg);
   void passUnionWithSequenceAndMozMap((sequence<DOMString> or MozMap<DOMString>) arg);
   void passUnionWithSVS((ScalarValueString or long) arg);
 #endif
   void passUnionWithNullable((object? or long) arg);
--- a/dom/canvas/CanvasRenderingContext2D.cpp
+++ b/dom/canvas/CanvasRenderingContext2D.cpp
@@ -559,29 +559,35 @@ NS_INTERFACE_MAP_END
 
 // Initialize our static variables.
 uint32_t CanvasRenderingContext2D::sNumLivingContexts = 0;
 DrawTarget* CanvasRenderingContext2D::sErrorTarget = nullptr;
 
 
 
 CanvasRenderingContext2D::CanvasRenderingContext2D()
-  : mForceSoftware(false)
+  : mRenderingMode(RenderingMode::OpenGLBackendMode)
   // these are the default values from the Canvas spec
   , mWidth(0), mHeight(0)
   , mZero(false), mOpaque(false)
   , mResetLayer(true)
   , mIPC(false)
   , mStream(nullptr)
   , mIsEntireFrameInvalid(false)
   , mPredictManyRedrawCalls(false), mPathTransformWillUpdate(false)
   , mInvalidateCount(0)
 {
   sNumLivingContexts++;
   SetIsDOMBinding();
+
+  // The default is to use OpenGL mode
+  if (!gfxPlatform::GetPlatform()->UseAcceleratedSkiaCanvas()) {
+    mRenderingMode = RenderingMode::SoftwareBackendMode;
+  }
+
 }
 
 CanvasRenderingContext2D::~CanvasRenderingContext2D()
 {
   Reset();
   // Drop references from all CanvasRenderingContext2DUserData to this context
   for (uint32_t i = 0; i < mUserDatas.Length(); ++i) {
     mUserDatas[i]->Forget();
@@ -768,45 +774,55 @@ CanvasRenderingContext2D::RedrawUser(con
     return;
   }
 
   mgfx::Rect newr =
     mTarget->GetTransform().TransformBounds(ToRect(r));
   Redraw(newr);
 }
 
-void CanvasRenderingContext2D::Demote()
+bool CanvasRenderingContext2D::SwitchRenderingMode(RenderingMode aRenderingMode)
 {
-  if (!IsTargetValid() || mForceSoftware || !mStream)
-    return;
-
-  RemoveDemotableContext(this);
+  if (!IsTargetValid() || mRenderingMode == aRenderingMode) {
+    return false;
+  }
 
   RefPtr<SourceSurface> snapshot = mTarget->Snapshot();
   RefPtr<DrawTarget> oldTarget = mTarget;
   mTarget = nullptr;
   mStream = nullptr;
   mResetLayer = true;
-  mForceSoftware = true;
-
-  // Recreate target, now demoted to software only
-  EnsureTarget();
+
+  // Recreate target using the new rendering mode
+  RenderingMode attemptedMode = EnsureTarget(aRenderingMode);
   if (!IsTargetValid())
-    return;
+    return false;
+
+  // We succeeded, so update mRenderingMode to reflect reality
+  mRenderingMode = attemptedMode;
 
   // Restore the content from the old DrawTarget
   mgfx::Rect r(0, 0, mWidth, mHeight);
   mTarget->DrawSurface(snapshot, r, r);
 
   // Restore the clips and transform
   for (uint32_t i = 0; i < CurrentState().clipsPushed.size(); i++) {
     mTarget->PushClip(CurrentState().clipsPushed[i]);
   }
 
   mTarget->SetTransform(oldTarget->GetTransform());
+
+  return true;
+}
+
+void CanvasRenderingContext2D::Demote()
+{
+  if (SwitchRenderingMode(RenderingMode::SoftwareBackendMode)) {
+    RemoveDemotableContext(this);
+  }
 }
 
 std::vector<CanvasRenderingContext2D*>&
 CanvasRenderingContext2D::DemotableContexts()
 {
   static std::vector<CanvasRenderingContext2D*> contexts;
   return contexts;
 }
@@ -816,17 +832,19 @@ CanvasRenderingContext2D::DemoteOldestCo
 {
   const size_t kMaxContexts = 64;
 
   std::vector<CanvasRenderingContext2D*>& contexts = DemotableContexts();
   if (contexts.size() < kMaxContexts)
     return;
 
   CanvasRenderingContext2D* oldest = contexts.front();
-  oldest->Demote();
+  if (oldest->SwitchRenderingMode(RenderingMode::SoftwareBackendMode)) {
+    RemoveDemotableContext(oldest);
+  }
 }
 
 void
 CanvasRenderingContext2D::AddDemotableContext(CanvasRenderingContext2D* context)
 {
   std::vector<CanvasRenderingContext2D*>::iterator iter = std::find(DemotableContexts().begin(), DemotableContexts().end(), context);
   if (iter != DemotableContexts().end())
     return;
@@ -908,21 +926,26 @@ CanvasRenderingContext2D::CheckSizeForSk
 
   double scale = gDefaultScale > 0 ? gDefaultScale : 1.0;
   int32_t threshold = ceil(scale * scale * gScreenPixels);
 
   // screen size acts as max threshold
   return threshold < 0 || (size.width * size.height) <= threshold;
 }
 
-void
-CanvasRenderingContext2D::EnsureTarget()
+CanvasRenderingContext2D::RenderingMode
+CanvasRenderingContext2D::EnsureTarget(RenderingMode aRenderingMode)
 {
-  if (mTarget) {
-    return;
+  // This would make no sense, so make sure we don't get ourselves in a mess
+  MOZ_ASSERT(mRenderingMode != RenderingMode::DefaultBackendMode);
+
+  RenderingMode mode = (aRenderingMode == RenderingMode::DefaultBackendMode) ? mRenderingMode : aRenderingMode;
+
+  if (mTarget && mode == mRenderingMode) {
+    return mRenderingMode;
   }
 
    // Check that the dimensions are sane
   IntSize size(mWidth, mHeight);
   if (size.width <= 0xFFFF && size.height <= 0xFFFF &&
       size.width >= 0 && size.height >= 0) {
     SurfaceFormat format = GetSurfaceFormat();
     nsIDocument* ownerDoc = nullptr;
@@ -933,42 +956,43 @@ CanvasRenderingContext2D::EnsureTarget()
     nsRefPtr<LayerManager> layerManager = nullptr;
 
     if (ownerDoc) {
       layerManager =
         nsContentUtils::PersistentLayerManagerForDocument(ownerDoc);
     }
 
      if (layerManager) {
-      if (gfxPlatform::GetPlatform()->UseAcceleratedSkiaCanvas() &&
-          !mForceSoftware &&
-          CheckSizeForSkiaGL(size)) {
+      if (mode == RenderingMode::OpenGLBackendMode && CheckSizeForSkiaGL(size)) {
         DemoteOldestContextIfNecessary();
 
         SkiaGLGlue* glue = gfxPlatform::GetPlatform()->GetSkiaGLGlue();
 
 #if USE_SKIA
         if (glue && glue->GetGrContext() && glue->GetGLContext()) {
           mTarget = Factory::CreateDrawTargetSkiaWithGrContext(glue->GetGrContext(), size, format);
           if (mTarget) {
             mStream = gl::SurfaceStream::CreateForType(gl::SurfaceStreamType::TripleBuffer,
                                                        glue->GetGLContext());
             AddDemotableContext(this);
           } else {
             printf_stderr("Failed to create a SkiaGL DrawTarget, falling back to software\n");
+            mode = RenderingMode::SoftwareBackendMode;
           }
         }
 #endif
         if (!mTarget) {
           mTarget = layerManager->CreateDrawTarget(size, format);
         }
       } else
         mTarget = layerManager->CreateDrawTarget(size, format);
+        mode = RenderingMode::SoftwareBackendMode;
      } else {
         mTarget = gfxPlatform::GetPlatform()->CreateOffscreenCanvasDrawTarget(size, format);
+        mode = RenderingMode::SoftwareBackendMode;
      }
   }
 
   if (mTarget) {
     static bool registered = false;
     if (!registered) {
       registered = true;
       RegisterStrongMemoryReporter(new Canvas2dPixelsReporter());
@@ -997,16 +1021,18 @@ CanvasRenderingContext2D::EnsureTarget()
     }
     // Calling Redraw() tells our invalidation machinery that the entire
     // canvas is already invalid, which can speed up future drawing.
     Redraw();
   } else {
     EnsureErrorTarget();
     mTarget = sErrorTarget;
   }
+
+  return mode;
 }
 
 #ifdef DEBUG
 int32_t
 CanvasRenderingContext2D::GetWidth() const
 {
   return mWidth;
 }
@@ -1109,22 +1135,27 @@ CanvasRenderingContext2D::SetIsIPC(bool 
 
 NS_IMETHODIMP
 CanvasRenderingContext2D::SetContextOptions(JSContext* aCx, JS::Handle<JS::Value> aOptions)
 {
   if (aOptions.isNullOrUndefined()) {
     return NS_OK;
   }
 
+  // This shouldn't be called before drawing starts, so there should be no drawtarget yet
+  MOZ_ASSERT(!mTarget);
+
   ContextAttributes2D attributes;
   NS_ENSURE_TRUE(attributes.Init(aCx, aOptions), NS_ERROR_UNEXPECTED);
 
   if (Preferences::GetBool("gfx.canvas.willReadFrequently.enable", false)) {
     // Use software when there is going to be a lot of readback
-    mForceSoftware = attributes.mWillReadFrequently;
+    if (attributes.mWillReadFrequently) {
+      mRenderingMode = RenderingMode::SoftwareBackendMode;
+    }
   }
 
   if (!attributes.mAlpha) {
     SetIsOpaque(true);
   }
 
   return NS_OK;
 }
--- a/dom/canvas/CanvasRenderingContext2D.h
+++ b/dom/canvas/CanvasRenderingContext2D.h
@@ -452,16 +452,25 @@ public:
 
   void DrawWindow(nsGlobalWindow& window, double x, double y, double w, double h,
                   const nsAString& bgColor, uint32_t flags,
                   mozilla::ErrorResult& error);
   void AsyncDrawXULElement(nsXULElement& elem, double x, double y, double w,
                            double h, const nsAString& bgColor, uint32_t flags,
                            mozilla::ErrorResult& error);
 
+  enum RenderingMode {
+    SoftwareBackendMode,
+    OpenGLBackendMode,
+    DefaultBackendMode
+  };
+
+  bool SwitchRenderingMode(RenderingMode aRenderingMode);
+
+  // Eventually this should be deprecated. Keeping for now to keep the binding functional.
   void Demote();
 
   nsresult Redraw();
 
 #ifdef DEBUG
     virtual int32_t GetWidth() const MOZ_OVERRIDE;
     virtual int32_t GetHeight() const MOZ_OVERRIDE;
 #endif
@@ -639,18 +648,20 @@ protected:
   // Report the fillRule has changed.
   void FillRuleChanged();
 
    /**
    * Create the backing surfacing, if it doesn't exist. If there is an error
    * in creating the target then it will put sErrorTarget in place. If there
    * is in turn an error in creating the sErrorTarget then they would both
    * be null so IsTargetValid() would still return null.
+   *
+   * Returns the actual rendering mode being used by the created target.
    */
-  void EnsureTarget();
+  RenderingMode EnsureTarget(RenderingMode aRenderMode = RenderingMode::DefaultBackendMode);
 
   /*
    * Disposes an old target and prepares to lazily create a new target.
    */
   void ClearTarget();
 
   /**
    * Check if the target is valid after calling EnsureTarget.
@@ -683,18 +694,17 @@ protected:
   }
 
   static std::vector<CanvasRenderingContext2D*>& DemotableContexts();
   static void DemoteOldestContextIfNecessary();
 
   static void AddDemotableContext(CanvasRenderingContext2D* context);
   static void RemoveDemotableContext(CanvasRenderingContext2D* context);
 
-  // Do not use GL
-  bool mForceSoftware;
+  RenderingMode mRenderingMode;
 
   // Member vars
   int32_t mWidth, mHeight;
 
   // This is true when the canvas is valid, but of zero size, this requires
   // specific behavior on some operations.
   bool mZero;
 
--- a/dom/locales/en-US/chrome/accessibility/AccessFu.properties
+++ b/dom/locales/en-US/chrome/accessibility/AccessFu.properties
@@ -152,16 +152,17 @@ tabReload      =      reloading
 # Object states
 stateChecked     =    checked
 stateNotChecked  =    not checked
 statePressed     =    pressed
 # No string for a not pressed toggle button
 stateExpanded    =    expanded
 stateCollapsed   =    collapsed
 stateUnavailable =    unavailable
+stateReadonly    =    readonly
 stateRequired    =    required
 stateTraversed   =    visited
 stateHasPopup    =    has pop up
 stateSelected    =    selected
 
 # App modes
 editingMode    =      editing
 navigationMode =      navigating
--- a/gfx/layers/apz/src/AsyncPanZoomController.cpp
+++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp
@@ -146,19 +146,39 @@ typedef mozilla::gfx::Matrix4x4 Matrix4x
  * "apz.asyncscroll.throttle"
  * The time period that throttles mozbrowserasyncscroll event.
  * Units: milliseconds
  *
  * "apz.asyncscroll.timeout"
  * The timeout for mAsyncScrollTimeoutTask delay task.
  * Units: milliseconds
  *
- * "apz.axis_lock_mode"
+ * "apz.axis_lock.mode"
  * The preferred axis locking style. See AxisLockMode for possible values.
  *
+ * "apz.axis_lock.lock_angle"
+ * Angle from axis within which we stay axis-locked.
+ * Units: radians
+ *
+ * "apz.axis_lock.breakout_threshold"
+ * Distance in inches the user must pan before axis lock can be broken.
+ * Units: (real-world, i.e. screen) inches
+ *
+ * "apz.axis_lock.breakout_angle"
+ * Angle at which axis lock can be broken.
+ * Units: radians
+ *
+ * "apz.axis_lock.direct_pan_angle"
+ * If the angle from an axis to the line drawn by a pan move is less than
+ * this value, we can assume that panning can be done in the allowed direction
+ * (horizontal or vertical).
+ * Currently used only for touch-action css property stuff and was addded to
+ * keep behaviour consistent with IE.
+ * Units: radians
+ *
  * "apz.content_response_timeout"
  * Amount of time before we timeout response from content. For example, if
  * content is being unruly/slow and we don't get a response back within this
  * time, we will just pretend that content did not preventDefault any touch
  * events we dispatched to it.
  * Units: milliseconds
  *
  * "apz.cross_slide_enabled"
@@ -319,40 +339,16 @@ typedef mozilla::gfx::Matrix4x4 Matrix4x
  * documentation for the skate size multipliers above).
  *
  * "apz.zoom_animation_duration_ms"
  * This controls how long the zoom-to-rect animation takes.
  * Units: ms
  */
 
 /**
- * Angle from axis within which we stay axis-locked
- */
-static const double AXIS_LOCK_ANGLE = M_PI / 6.0; // 30 degrees
-
-/**
- * The distance in inches the user must pan before axis lock can be broken
- */
-static const float AXIS_BREAKOUT_THRESHOLD = 1.0f/32.0f;
-
-/**
- * The angle at which axis lock can be broken
- */
-static const double AXIS_BREAKOUT_ANGLE = M_PI / 8.0; // 22.5 degrees
-
-/**
- * Angle from axis to the line drawn by pan move.
- * If angle is less than this value we can assume that panning
- * can be done in allowed direction (horizontal or vertical).
- * Currently used only for touch-action css property stuff and was
- * added to keep behavior consistent with IE.
- */
-static const double ALLOWED_DIRECT_PAN_ANGLE = M_PI / 3.0; // 60 degrees
-
-/**
  * Computed time function used for sampling frames of a zoom to animation.
  */
 StaticAutoPtr<ComputedTimingFunction> gComputedTimingFunction;
 
 /**
  * Maximum zoom amount, always used, even if a page asks for higher.
  */
 static const CSSToScreenScale MAX_ZOOM(8.0f);
@@ -1707,68 +1703,68 @@ const ScreenPoint AsyncPanZoomController
   return ScreenPoint(mX.GetVelocity(), mY.GetVelocity());
 }
 
 void AsyncPanZoomController::HandlePanningWithTouchAction(double aAngle) {
   // Handling of cross sliding will need to be added in this method after touch-action released
   // enabled by default.
   if (CurrentTouchBlock()->TouchActionAllowsPanningXY()) {
     if (mX.CanScrollNow() && mY.CanScrollNow()) {
-      if (IsCloseToHorizontal(aAngle, AXIS_LOCK_ANGLE)) {
+      if (IsCloseToHorizontal(aAngle, gfxPrefs::APZAxisLockAngle())) {
         mY.SetAxisLocked(true);
         SetState(PANNING_LOCKED_X);
-      } else if (IsCloseToVertical(aAngle, AXIS_LOCK_ANGLE)) {
+      } else if (IsCloseToVertical(aAngle, gfxPrefs::APZAxisLockAngle())) {
         mX.SetAxisLocked(true);
         SetState(PANNING_LOCKED_Y);
       } else {
         SetState(PANNING);
       }
     } else if (mX.CanScrollNow() || mY.CanScrollNow()) {
       SetState(PANNING);
     } else {
       SetState(NOTHING);
     }
   } else if (CurrentTouchBlock()->TouchActionAllowsPanningX()) {
     // Using bigger angle for panning to keep behavior consistent
     // with IE.
-    if (IsCloseToHorizontal(aAngle, ALLOWED_DIRECT_PAN_ANGLE)) {
+    if (IsCloseToHorizontal(aAngle, gfxPrefs::APZAllowedDirectPanAngle())) {
       mY.SetAxisLocked(true);
       SetState(PANNING_LOCKED_X);
       mPanDirRestricted = true;
     } else {
       // Don't treat these touches as pan/zoom movements since 'touch-action' value
       // requires it.
       SetState(NOTHING);
     }
   } else if (CurrentTouchBlock()->TouchActionAllowsPanningY()) {
-    if (IsCloseToVertical(aAngle, ALLOWED_DIRECT_PAN_ANGLE)) {
+    if (IsCloseToVertical(aAngle, gfxPrefs::APZAllowedDirectPanAngle())) {
       mX.SetAxisLocked(true);
       SetState(PANNING_LOCKED_Y);
       mPanDirRestricted = true;
     } else {
       SetState(NOTHING);
     }
   } else {
     SetState(NOTHING);
   }
 }
 
 void AsyncPanZoomController::HandlePanning(double aAngle) {
   ReentrantMonitorAutoEnter lock(mMonitor);
   if (!gfxPrefs::APZCrossSlideEnabled() && (!mX.CanScrollNow() || !mY.CanScrollNow())) {
     SetState(PANNING);
-  } else if (IsCloseToHorizontal(aAngle, AXIS_LOCK_ANGLE)) {
+  } else if (IsCloseToHorizontal(aAngle, gfxPrefs::APZAxisLockAngle())) {
     mY.SetAxisLocked(true);
     if (mX.CanScrollNow()) {
       SetState(PANNING_LOCKED_X);
     } else {
       SetState(CROSS_SLIDING_X);
       mX.SetAxisLocked(true);
     }
-  } else if (IsCloseToVertical(aAngle, AXIS_LOCK_ANGLE)) {
+  } else if (IsCloseToVertical(aAngle, gfxPrefs::APZAxisLockAngle())) {
     mX.SetAxisLocked(true);
     if (mY.CanScrollNow()) {
       SetState(PANNING_LOCKED_Y);
     } else {
       SetState(CROSS_SLIDING_Y);
       mY.SetAxisLocked(true);
     }
   } else {
@@ -1778,26 +1774,26 @@ void AsyncPanZoomController::HandlePanni
 
 void AsyncPanZoomController::HandlePanningUpdate(float aDX, float aDY) {
   // If we're axis-locked, check if the user is trying to break the lock
   if (GetAxisLockMode() == STICKY && !mPanDirRestricted) {
 
     double angle = atan2(aDY, aDX); // range [-pi, pi]
     angle = fabs(angle); // range [0, pi]
 
-    float breakThreshold = AXIS_BREAKOUT_THRESHOLD * APZCTreeManager::GetDPI();
+    float breakThreshold = gfxPrefs::APZAxisBreakoutThreshold() * APZCTreeManager::GetDPI();
 
     if (fabs(aDX) > breakThreshold || fabs(aDY) > breakThreshold) {
       if (mState == PANNING_LOCKED_X || mState == CROSS_SLIDING_X) {
-        if (!IsCloseToHorizontal(angle, AXIS_BREAKOUT_ANGLE)) {
+        if (!IsCloseToHorizontal(angle, gfxPrefs::APZAxisBreakoutAngle())) {
           mY.SetAxisLocked(false);
           SetState(PANNING);
         }
       } else if (mState == PANNING_LOCKED_Y || mState == CROSS_SLIDING_Y) {
-        if (!IsCloseToVertical(angle, AXIS_BREAKOUT_ANGLE)) {
+        if (!IsCloseToVertical(angle, gfxPrefs::APZAxisLockAngle())) {
           mX.SetAxisLocked(false);
           SetState(PANNING);
         }
       }
     }
   }
 }
 
--- a/gfx/layers/opengl/CompositorOGL.cpp
+++ b/gfx/layers/opengl/CompositorOGL.cpp
@@ -716,25 +716,16 @@ CompositorOGL::BeginFrame(const nsIntReg
   MOZ_ASSERT(!mFrameInProgress, "frame still in progress (should have called EndFrame or AbortFrame");
 
   mFrameInProgress = true;
   gfx::Rect rect;
   if (mUseExternalSurfaceSize) {
     rect = gfx::Rect(0, 0, mSurfaceSize.width, mSurfaceSize.height);
   } else {
     rect = gfx::Rect(aRenderBounds.x, aRenderBounds.y, aRenderBounds.width, aRenderBounds.height);
-    // If render bounds is not updated explicitly, try to infer it from widget
-    if (rect.width == 0 || rect.height == 0) {
-      // FIXME/bug XXXXXX this races with rotation changes on the main
-      // thread, and undoes all the care we take with layers txns being
-      // sent atomically with rotation changes
-      nsIntRect intRect;
-      mWidget->GetClientBounds(intRect);
-      rect = gfx::Rect(0, 0, intRect.width, intRect.height);
-    }
   }
 
   rect = aTransform.TransformBounds(rect);
   if (aRenderBoundsOut) {
     *aRenderBoundsOut = rect;
   }
 
   GLint width = rect.width;
--- a/gfx/thebes/gfxHarfBuzzShaper.cpp
+++ b/gfx/thebes/gfxHarfBuzzShaper.cpp
@@ -102,16 +102,20 @@ gfxHarfBuzzShaper::GetGlyph(hb_codepoint
                 if (compat) {
                     switch (mCmapFormat) {
                     case 4:
                         if (compat < UNICODE_BMP_LIMIT) {
                             gid = gfxFontUtils::MapCharToGlyphFormat4(data + mSubtableOffset,
                                                                       compat);
                         }
                         break;
+                    case 10:
+                        gid = gfxFontUtils::MapCharToGlyphFormat10(data + mSubtableOffset,
+                                                                   compat);
+                        break;
                     case 12:
                         gid = gfxFontUtils::MapCharToGlyphFormat12(data + mSubtableOffset,
                                                                    compat);
                         break;
                     }
                 }
             }
             // If the variation sequence was not supported, return zero here;
@@ -120,16 +124,20 @@ gfxHarfBuzzShaper::GetGlyph(hb_codepoint
         }
 
         switch (mCmapFormat) {
         case 4:
             gid = unicode < UNICODE_BMP_LIMIT ?
                 gfxFontUtils::MapCharToGlyphFormat4(data + mSubtableOffset,
                                                     unicode) : 0;
             break;
+        case 10:
+            gid = gfxFontUtils::MapCharToGlyphFormat10(data + mSubtableOffset,
+                                                       unicode);
+            break;
         case 12:
             gid = gfxFontUtils::MapCharToGlyphFormat12(data + mSubtableOffset,
                                                        unicode);
             break;
         default:
             NS_WARNING("unsupported cmap format, glyphs will be missing");
             break;
         }
--- a/gfx/thebes/gfxPrefs.h
+++ b/gfx/thebes/gfxPrefs.h
@@ -3,16 +3,17 @@
  * 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/. */
 
 #ifndef GFX_PREFS_H
 #define GFX_PREFS_H
 
 #include <stdint.h>
 #include "mozilla/Assertions.h"
+#include "mozilla/Constants.h"   // for M_PI
 #include "mozilla/TypedEnum.h"
 
 // First time gfxPrefs::GetSingleton() needs to be called on the main thread,
 // before any of the methods accessing the values are used, but after
 // the Preferences system has been initialized.
 
 // The static methods to access the preference value are safe to call
 // from any thread after that first call.
@@ -127,17 +128,21 @@ private:
   // This is where DECL_GFX_PREF for each of the preferences should go.
   // We will keep these in an alphabetical order to make it easier to see if
   // a method accessing a pref already exists. Just add yours in the list.
 
   // The apz prefs are explained in AsyncPanZoomController.cpp
   DECL_GFX_PREF(Live, "apz.allow_checkerboarding",             APZAllowCheckerboarding, bool, true);
   DECL_GFX_PREF(Live, "apz.asyncscroll.throttle",              APZAsyncScrollThrottleTime, int32_t, 100);
   DECL_GFX_PREF(Live, "apz.asyncscroll.timeout",               APZAsyncScrollTimeout, int32_t, 300);
-  DECL_GFX_PREF(Live, "apz.axis_lock_mode",                    APZAxisLockMode, int32_t, 0);
+  DECL_GFX_PREF(Live, "apz.axis_lock.mode",                    APZAxisLockMode, int32_t, 0);
+  DECL_GFX_PREF(Live, "apz.axis_lock.lock_angle",              APZAxisLockAngle, float, float(M_PI / 6.0) /* 30 degrees */);
+  DECL_GFX_PREF(Live, "apz.axis_lock.breakout_threshold",      APZAxisBreakoutThreshold, float, 1.0f / 32.0f);
+  DECL_GFX_PREF(Live, "apz.axis_lock.breakout_angle",          APZAxisBreakoutAngle, float, float(M_PI / 8.0) /* 22.5 degrees */);
+  DECL_GFX_PREF(Live, "apz.axis_lock.direct_pan_angle",        APZAllowedDirectPanAngle, float, float(M_PI / 3.0) /* 60 degrees */);
   DECL_GFX_PREF(Live, "apz.content_response_timeout",          APZContentResponseTimeout, int32_t, 300);
   DECL_GFX_PREF(Live, "apz.cross_slide.enabled",               APZCrossSlideEnabled, bool, false);
   DECL_GFX_PREF(Live, "apz.danger_zone_x",                     APZDangerZoneX, int32_t, 50);
   DECL_GFX_PREF(Live, "apz.danger_zone_y",                     APZDangerZoneY, int32_t, 100);
   DECL_GFX_PREF(Live, "apz.enlarge_displayport_when_clipped",  APZEnlargeDisplayPortWhenClipped, bool, false);
   DECL_GFX_PREF(Live, "apz.fling_accel_interval_ms",           APZFlingAccelInterval, int32_t, 500);
   DECL_GFX_PREF(Live, "apz.fling_accel_base_mult",             APZFlingAccelBaseMultiplier, float, 1.0f);
   DECL_GFX_PREF(Live, "apz.fling_accel_supplemental_mult",     APZFlingAccelSupplementalMultiplier, float, 1.0f);
--- a/ipc/glue/GeckoChildProcessHost.cpp
+++ b/ipc/glue/GeckoChildProcessHost.cpp
@@ -815,23 +815,25 @@ GeckoChildProcessHost::PerformAsyncLaunc
 #endif
       break;
     case GeckoProcessType_Default:
     default:
       MOZ_CRASH("Bad process type in GeckoChildProcessHost");
       break;
   };
 
+#ifdef MOZ_SANDBOX
   if (shouldSandboxCurrentProcess) {
     for (auto it = mAllowedFilesRead.begin();
          it != mAllowedFilesRead.end();
          ++it) {
       mSandboxBroker.AllowReadFile(it->c_str());
     }
   }
+#endif
 
 #endif // XP_WIN
 
   // Add the application directory path (-appdir path)
   AddAppDirToCommandLine(cmdLine);
 
   // XXX Command line params past this point are expected to be at
   // the end of the command line string, and in a specific order.
--- a/js/src/jit/mips/Assembler-mips.h
+++ b/js/src/jit/mips/Assembler-mips.h
@@ -109,18 +109,20 @@ static MOZ_CONSTEXPR_VAR FloatRegister I
 
 static MOZ_CONSTEXPR_VAR Register JSReturnReg_Type = a3;
 static MOZ_CONSTEXPR_VAR Register JSReturnReg_Data = a2;
 static MOZ_CONSTEXPR_VAR Register StackPointer = sp;
 static MOZ_CONSTEXPR_VAR Register FramePointer = InvalidReg;
 static MOZ_CONSTEXPR_VAR Register ReturnReg = v0;
 static MOZ_CONSTEXPR_VAR FloatRegister ReturnFloat32Reg = { FloatRegisters::f0, FloatRegister::Single };
 static MOZ_CONSTEXPR_VAR FloatRegister ReturnDoubleReg = { FloatRegisters::f0, FloatRegister::Double };
+static MOZ_CONSTEXPR_VAR FloatRegister ReturnSimdReg = InvalidFloatReg;
 static MOZ_CONSTEXPR_VAR FloatRegister ScratchFloat32Reg = { FloatRegisters::f18, FloatRegister::Single };
 static MOZ_CONSTEXPR_VAR FloatRegister ScratchDoubleReg = { FloatRegisters::f18, FloatRegister::Double };
+static MOZ_CONSTEXPR_VAR FloatRegister ScratchSimdReg = InvalidFloatReg;
 static MOZ_CONSTEXPR_VAR FloatRegister SecondScratchFloat32Reg = { FloatRegisters::f16, FloatRegister::Single };
 static MOZ_CONSTEXPR_VAR FloatRegister SecondScratchDoubleReg = { FloatRegisters::f16, FloatRegister::Double };
 
 // A bias applied to the GlobalReg to allow the use of instructions with small
 // negative immediate offsets which doubles the range of global data that can be
 // accessed with a single instruction.
 static const int32_t AsmJSGlobalRegBias = 32768;
 
@@ -1010,16 +1012,19 @@ class Assembler : public AssemblerShared
 
     static bool SupportsFloatingPoint() {
 #if (defined(__mips_hard_float) && !defined(__mips_single_float)) || defined(JS_MIPS_SIMULATOR)
         return true;
 #else
         return false;
 #endif
     }
+    static bool SupportsSimd() {
+        return js::jit::SupportsSimd;
+    }
 
   protected:
     InstImm invertBranch(InstImm branch, BOffImm16 skipOffset);
     void bind(InstImm *inst, uint32_t branch, uint32_t target);
     void addPendingJump(BufferOffset src, ImmPtr target, Relocation::Kind kind) {
         enoughMemory_ &= jumps_.append(RelativePatch(src, target.value, kind));
         if (kind == Relocation::JITCODE)
             writeRelocation(src);
--- a/js/src/jit/mips/CodeGenerator-mips.h
+++ b/js/src/jit/mips/CodeGenerator-mips.h
@@ -260,16 +260,31 @@ class CodeGeneratorMIPS : public CodeGen
 
     bool generateInvalidateEpilogue();
   protected:
     void postAsmJSCall(LAsmJSCall *lir) {}
 
     bool visitEffectiveAddress(LEffectiveAddress *ins);
     bool visitUDiv(LUDiv *ins);
     bool visitUMod(LUMod *ins);
+
+  public:
+    // Unimplemented SIMD instructions
+    bool visitSimdValueX4(LSimdValueX4 *lir) { MOZ_CRASH("NYI"); }
+    bool visitSimdSplatX4(LSimdSplatX4 *lir) { MOZ_CRASH("NYI"); }
+    bool visitInt32x4(LInt32x4 *ins) { MOZ_CRASH("NYI"); }
+    bool visitFloat32x4(LFloat32x4 *ins) { MOZ_CRASH("NYI"); }
+    bool visitSimdExtractElementI(LSimdExtractElementI *ins) { MOZ_CRASH("NYI"); }
+    bool visitSimdExtractElementF(LSimdExtractElementF *ins) { MOZ_CRASH("NYI"); }
+    bool visitSimdSignMaskX4(LSimdSignMaskX4 *ins) { MOZ_CRASH("NYI"); }
+    bool visitSimdBinaryCompIx4(LSimdBinaryCompIx4 *lir) { MOZ_CRASH("NYI"); }
+    bool visitSimdBinaryCompFx4(LSimdBinaryCompFx4 *lir) { MOZ_CRASH("NYI"); }
+    bool visitSimdBinaryArithIx4(LSimdBinaryArithIx4 *lir) { MOZ_CRASH("NYI"); }
+    bool visitSimdBinaryArithFx4(LSimdBinaryArithFx4 *lir) { MOZ_CRASH("NYI"); }
+    bool visitSimdBinaryBitwiseX4(LSimdBinaryBitwiseX4 *lir) { MOZ_CRASH("NYI"); }
 };
 
 typedef CodeGeneratorMIPS CodeGeneratorSpecific;
 
 // An out-of-line bailout thunk.
 class OutOfLineBailout : public OutOfLineCodeBase<CodeGeneratorMIPS>
 {
     LSnapshot *snapshot_;
--- a/js/src/jit/mips/MacroAssembler-mips.cpp
+++ b/js/src/jit/mips/MacroAssembler-mips.cpp
@@ -1555,17 +1555,17 @@ void
 MacroAssemblerMIPSCompat::freeStack(Register amount)
 {
     as_addu(StackPointer, StackPointer, amount);
 }
 
 void
 MacroAssembler::PushRegsInMask(RegisterSet set, FloatRegisterSet simdSet)
 {
-    JS_ASSERT(!SupportsSimd && simdSet.size() == 0);
+    JS_ASSERT(!SupportsSimd() && simdSet.size() == 0);
     int32_t diffF = set.fpus().getPushSizeInBytes();
     int32_t diffG = set.gprs().size() * sizeof(intptr_t);
 
     reserveStack(diffG);
     for (GeneralRegisterBackwardIterator iter(set.gprs()); iter.more(); iter++) {
         diffG -= sizeof(intptr_t);
         storePtr(*iter, Address(StackPointer, diffG));
     }
@@ -1583,17 +1583,17 @@ MacroAssembler::PushRegsInMask(RegisterS
         diffF -= sizeof(double);
     }
     MOZ_ASSERT(diffF == 0);
 }
 
 void
 MacroAssembler::PopRegsInMaskIgnore(RegisterSet set, RegisterSet ignore, FloatRegisterSet simdSet)
 {
-    JS_ASSERT(!SupportsSimd && simdSet.size() == 0);
+    JS_ASSERT(!SupportsSimd() && simdSet.size() == 0);
     int32_t diffG = set.gprs().size() * sizeof(intptr_t);
     int32_t diffF = set.fpus().getPushSizeInBytes();
     const int32_t reservedG = diffG;
     const int32_t reservedF = diffF;
 
     // Read the buffer form the first aligned location.
     ma_addu(SecondScratchReg, sp, Imm32(reservedF + sizeof(double)));
     ma_and(SecondScratchReg, SecondScratchReg, Imm32(~(ABIStackAlignment - 1)));
@@ -3280,17 +3280,17 @@ MacroAssemblerMIPSCompat::restoreStackPo
 {
     loadPtr(Address(StackPointer, 0), StackPointer);
 }
 
 void
 MacroAssembler::alignFrameForICArguments(AfterICSaveLive &aic)
 {
     if (framePushed() % ABIStackAlignment != 0) {
-        aic.alignmentPadding = ABIStackAlignment - (framePushed() % StackAlignment);
+        aic.alignmentPadding = ABIStackAlignment - (framePushed() % ABIStackAlignment);
         reserveStack(aic.alignmentPadding);
     } else {
         aic.alignmentPadding = 0;
     }
     MOZ_ASSERT(framePushed() % ABIStackAlignment == 0);
     checkStackAlignment();
 }
 
--- a/js/src/jit/mips/MacroAssembler-mips.h
+++ b/js/src/jit/mips/MacroAssembler-mips.h
@@ -1062,16 +1062,26 @@ public:
 
     void loadPtr(const Address &address, Register dest);
     void loadPtr(const BaseIndex &src, Register dest);
     void loadPtr(AbsoluteAddress address, Register dest);
     void loadPtr(AsmJSAbsoluteAddress address, Register dest);
 
     void loadPrivate(const Address &address, Register dest);
 
+    void loadAlignedInt32x4(const Address &addr, FloatRegister dest) { MOZ_CRASH("NYI"); }
+    void storeAlignedInt32x4(FloatRegister src, Address addr) { MOZ_CRASH("NYI"); }
+    void loadUnalignedInt32x4(const Address &addr, FloatRegister dest) { MOZ_CRASH("NYI"); }
+    void storeUnalignedInt32x4(FloatRegister src, Address addr) { MOZ_CRASH("NYI"); }
+
+    void loadAlignedFloat32x4(const Address &addr, FloatRegister dest) { MOZ_CRASH("NYI"); }
+    void storeAlignedFloat32x4(FloatRegister src, Address addr) { MOZ_CRASH("NYI"); }
+    void loadUnalignedFloat32x4(const Address &addr, FloatRegister dest) { MOZ_CRASH("NYI"); }
+    void storeUnalignedFloat32x4(FloatRegister src, Address addr) { MOZ_CRASH("NYI"); }
+
     void loadDouble(const Address &addr, FloatRegister dest);
     void loadDouble(const BaseIndex &src, FloatRegister dest);
 
     // Load a float value into a register, then expand it to a double.
     void loadFloatAsDouble(const Address &addr, FloatRegister dest);
     void loadFloatAsDouble(const BaseIndex &src, FloatRegister dest);
 
     void loadFloat32(const Address &addr, FloatRegister dest);
--- a/js/xpconnect/idl/nsIXPCScriptable.idl
+++ b/js/xpconnect/idl/nsIXPCScriptable.idl
@@ -26,17 +26,17 @@ interface nsIXPConnectWrappedNative;
 [ref] native JSCallArgsRef(const JS::CallArgs);
 
 /**
  * Note: This is not really an XPCOM interface.  For example, callers must
  * guarantee that they set the *_retval of the various methods that return a
  * boolean to PR_TRUE before making the call.  Implementations may skip writing
  * to *_retval unless they want to return PR_FALSE.
  */
-[uuid(9bae4ff5-5618-4ccd-b106-8e21e3fb64d3)]
+[uuid(d945a647-a60e-462d-9635-c79d5fa694ce)]
 interface nsIXPCScriptable : nsISupports
 {
     /* bitflags used for 'flags' (only 32 bits available!) */
 
     const uint32_t WANT_PRECREATE                   = 1 <<  0;
     const uint32_t WANT_CREATE                      = 1 <<  1;
     const uint32_t WANT_POSTCREATE                  = 1 <<  2;
     const uint32_t WANT_ADDPROPERTY                 = 1 <<  3;
@@ -59,18 +59,16 @@ interface nsIXPCScriptable : nsISupports
     const uint32_t DONT_ENUM_STATIC_PROPS           = 1 << 20;
     const uint32_t DONT_ENUM_QUERY_INTERFACE        = 1 << 21;
     const uint32_t DONT_ASK_INSTANCE_FOR_SCRIPTABLE = 1 << 22;
     const uint32_t CLASSINFO_INTERFACES_ONLY        = 1 << 23;
     const uint32_t ALLOW_PROP_MODS_DURING_RESOLVE   = 1 << 24;
     const uint32_t ALLOW_PROP_MODS_TO_PROTOTYPE     = 1 << 25;
     const uint32_t IS_GLOBAL_OBJECT                 = 1 << 26;
     const uint32_t DONT_REFLECT_INTERFACE_NAMES     = 1 << 27;
-    // Unused bit here!
-    const uint32_t WANT_OUTER_OBJECT                = 1 << 29;
 
     // The high order bit is RESERVED for consumers of these flags. 
     // No implementor of this interface should ever return flags 
     // with this bit set.
     const uint32_t RESERVED                         = 1 << 31;
 
     readonly attribute string   className;
     [notxpcom,nostdcall] uint32_t getScriptableFlags();
@@ -135,19 +133,16 @@ interface nsIXPCScriptable : nsISupports
     boolean construct(in nsIXPConnectWrappedNative wrapper,
                      in JSContextPtr cx, in JSObjectPtr obj,
                      in JSCallArgsRef args);
 
     boolean hasInstance(in nsIXPConnectWrappedNative wrapper,
                        in JSContextPtr cx, in JSObjectPtr obj,
                        in jsval val, out boolean bp);
 
-    JSObjectPtr outerObject(in nsIXPConnectWrappedNative wrapper,
-                            in JSContextPtr cx, in JSObjectPtr obj);
-
     void postCreatePrototype(in JSContextPtr cx, in JSObjectPtr proto);
 };
 
 %{ C++
 
 #include "nsAutoPtr.h"
 
 #define NS_XPCCLASSINFO_IID \
--- a/js/xpconnect/public/xpc_map_end.h
+++ b/js/xpconnect/public/xpc_map_end.h
@@ -71,19 +71,16 @@ XPC_MAP_CLASSNAME::GetScriptableFlags()
     nsIXPCScriptable::WANT_CALL |
 #endif
 #ifdef XPC_MAP_WANT_CONSTRUCT
     nsIXPCScriptable::WANT_CONSTRUCT |
 #endif
 #ifdef XPC_MAP_WANT_HASINSTANCE
     nsIXPCScriptable::WANT_HASINSTANCE |
 #endif
-#ifdef XPC_MAP_WANT_OUTER_OBJECT
-    nsIXPCScriptable::WANT_OUTER_OBJECT |
-#endif
 #ifdef XPC_MAP_FLAGS
     XPC_MAP_FLAGS |
 #endif
     0;
 }
 
 /**************************************************************/
 
@@ -161,21 +158,16 @@ NS_IMETHODIMP XPC_MAP_CLASSNAME::Constru
     {NS_ERROR("never called"); return NS_ERROR_NOT_IMPLEMENTED;}
 #endif
 
 #ifndef XPC_MAP_WANT_HASINSTANCE
 NS_IMETHODIMP XPC_MAP_CLASSNAME::HasInstance(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj, JS::HandleValue val, bool *bp, bool *_retval)
     {NS_ERROR("never called"); return NS_ERROR_NOT_IMPLEMENTED;}
 #endif
 
-#ifndef XPC_MAP_WANT_OUTER_OBJECT
-NS_IMETHODIMP XPC_MAP_CLASSNAME::OuterObject(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj, JSObject * *_retval)
-    {NS_ERROR("never called"); return NS_ERROR_NOT_IMPLEMENTED;}
-#endif
-
 #ifndef XPC_MAP_WANT_POST_CREATE_PROTOTYPE
 NS_IMETHODIMP XPC_MAP_CLASSNAME::PostCreatePrototype(JSContext *cx, JSObject *proto)
     {return NS_OK;}
 #endif
 
 /**************************************************************/
 
 #undef XPC_MAP_CLASSNAME
@@ -236,19 +228,15 @@ NS_IMETHODIMP XPC_MAP_CLASSNAME::PostCre
 #ifdef XPC_MAP_WANT_CONSTRUCT
 #undef XPC_MAP_WANT_CONSTRUCT
 #endif
 
 #ifdef XPC_MAP_WANT_HASINSTANCE
 #undef XPC_MAP_WANT_HASINSTANCE
 #endif
 
-#ifdef XPC_MAP_WANT_OUTER_OBJECT
-#undef XPC_MAP_WANT_OUTER_OBJECT
-#endif
-
 #ifdef XPC_MAP_WANT_POST_CREATE_PROTOTYPE
 #undef XPC_MAP_WANT_POST_CREATE_PROTOTYPE
 #endif
 
 #ifdef XPC_MAP_FLAGS
 #undef XPC_MAP_FLAGS
 #endif
--- a/js/xpconnect/src/XPCWrappedNativeJSOps.cpp
+++ b/js/xpconnect/src/XPCWrappedNativeJSOps.cpp
@@ -624,52 +624,16 @@ XPC_WN_NoHelper_Resolve(JSContext *cx, H
     return DefinePropertyIfFound(ccx, obj, id,
                                  set, nullptr, nullptr, wrapper->GetScope(),
                                  true, wrapper, wrapper, nullptr,
                                  JSPROP_ENUMERATE |
                                  JSPROP_READONLY |
                                  JSPROP_PERMANENT, nullptr);
 }
 
-static JSObject *
-XPC_WN_OuterObject(JSContext *cx, HandleObject objArg)
-{
-    JSObject *obj = objArg;
-
-    XPCWrappedNative *wrapper = XPCWrappedNative::Get(obj);
-    if (!wrapper) {
-        Throw(NS_ERROR_XPC_BAD_OP_ON_WN_PROTO, cx);
-
-        return nullptr;
-    }
-
-    if (!wrapper->IsValid()) {
-        Throw(NS_ERROR_XPC_HAS_BEEN_SHUTDOWN, cx);
-
-        return nullptr;
-    }
-
-    XPCNativeScriptableInfo* si = wrapper->GetScriptableInfo();
-    if (si && si->GetFlags().WantOuterObject()) {
-        RootedObject newThis(cx);
-        nsresult rv =
-            si->GetCallback()->OuterObject(wrapper, cx, obj, newThis.address());
-
-        if (NS_FAILED(rv)) {
-            Throw(rv, cx);
-
-            return nullptr;
-        }
-
-        obj = newThis;
-    }
-
-    return obj;
-}
-
 const XPCWrappedNativeJSClass XPC_WN_NoHelper_JSClass = {
   { // base
     "XPCWrappedNative_NoHelper",    // name;
     WRAPPER_SLOTS |
     JSCLASS_PRIVATE_IS_NSISUPPORTS, // flags
 
     /* Mandatory non-null function pointer members. */
     XPC_WN_OnlyIWrite_AddPropertyStub, // addProperty
@@ -1167,34 +1131,18 @@ XPCNativeScriptableShared::PopulateJSCla
         mFlags.DontEnumStaticProps())
         mJSClass.base.enumerate = JS_EnumerateStub;
     else
         mJSClass.base.enumerate = XPC_WN_Shared_Enumerate;
 
     // We have to figure out resolve strategy at call time
     mJSClass.base.resolve = (JSResolveOp) XPC_WN_Helper_NewResolve;
 
-    // We need to respect content-defined toString() hooks on Window objects.
-    // In particular, js::DefaultValue checks for a convert stub, and the one
-    // we would install below ignores anything implemented in JS.
-    //
-    // We've always had this behavior for most XPCWrappedNative-implemented
-    // objects. However, Window was special, because the outer-window proxy
-    // had a null convert hook, which means that we'd end up with the default
-    // JS-engine behavior (which respects toString() overrides). We've fixed
-    // the convert hook on the outer-window proxy to invoke the defaultValue
-    // hook on the proxy, which in this case invokes js::DefaultValue on the
-    // target. So now we need to special-case this for Window to maintain
-    // consistent behavior. This can go away once Window is on WebIDL bindings.
-    //
-    // Note that WantOuterObject() is true if and only if this is a Window object.
     if (mFlags.WantConvert())
         mJSClass.base.convert = XPC_WN_Helper_Convert;
-    else if (mFlags.WantOuterObject())
-        mJSClass.base.convert = JS_ConvertStub;
     else
         mJSClass.base.convert = XPC_WN_Shared_Convert;
 
     if (mFlags.WantFinalize())
         mJSClass.base.finalize = XPC_WN_Helper_Finalize;
     else
         mJSClass.base.finalize = XPC_WN_NoHelper_Finalize;
 
@@ -1211,19 +1159,16 @@ XPCNativeScriptableShared::PopulateJSCla
     if (mFlags.WantHasInstance())
         mJSClass.base.hasInstance = XPC_WN_Helper_HasInstance;
 
     if (mFlags.IsGlobalObject())
         mJSClass.base.trace = JS_GlobalObjectTraceHook;
     else
         mJSClass.base.trace = XPCWrappedNative::Trace;
 
-    if (mFlags.WantOuterObject())
-        mJSClass.base.ext.outerObject = XPC_WN_OuterObject;
-
     mJSClass.base.ext.isWrappedNative = true;
 }
 
 /***************************************************************************/
 /***************************************************************************/
 
 // Compatibility hack.
 //
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -1618,17 +1618,16 @@ public:
     bool WantEnumerate()                GET_IT(WANT_ENUMERATE)
     bool WantNewEnumerate()             GET_IT(WANT_NEWENUMERATE)
     bool WantNewResolve()               GET_IT(WANT_NEWRESOLVE)
     bool WantConvert()                  GET_IT(WANT_CONVERT)
     bool WantFinalize()                 GET_IT(WANT_FINALIZE)
     bool WantCall()                     GET_IT(WANT_CALL)
     bool WantConstruct()                GET_IT(WANT_CONSTRUCT)
     bool WantHasInstance()              GET_IT(WANT_HASINSTANCE)
-    bool WantOuterObject()              GET_IT(WANT_OUTER_OBJECT)
     bool UseJSStubForAddProperty()      GET_IT(USE_JSSTUB_FOR_ADDPROPERTY)
     bool UseJSStubForDelProperty()      GET_IT(USE_JSSTUB_FOR_DELPROPERTY)
     bool UseJSStubForSetProperty()      GET_IT(USE_JSSTUB_FOR_SETPROPERTY)
     bool DontEnumStaticProps()          GET_IT(DONT_ENUM_STATIC_PROPS)
     bool DontEnumQueryInterface()       GET_IT(DONT_ENUM_QUERY_INTERFACE)
     bool DontAskInstanceForScriptable() GET_IT(DONT_ASK_INSTANCE_FOR_SCRIPTABLE)
     bool ClassInfoInterfacesOnly()      GET_IT(CLASSINFO_INTERFACES_ONLY)
     bool AllowPropModsDuringResolve()   GET_IT(ALLOW_PROP_MODS_DURING_RESOLVE)
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -434,18 +434,21 @@ pref("layout.async-containerless-scrolli
 pref("apz.allow_checkerboarding", true);
 pref("apz.asyncscroll.throttle", 100);
 pref("apz.asyncscroll.timeout", 300);
 
 // Whether to lock touch scrolling to one axis at a time
 // 0 = FREE (No locking at all)
 // 1 = STANDARD (Once locked, remain locked until scrolling ends)
 // 2 = STICKY (Allow lock to be broken, with hysteresis)
-pref("apz.axis_lock_mode", 0);
-
+pref("apz.axis_lock.mode", 0);
+pref("apz.axis_lock.lock_angle", "0.5235987");        // PI / 6 (30 degrees)
+pref("apz.axis_lock.breakout_threshold", "0.03125");  // 1/32 inches
+pref("apz.axis_lock.breakout_angle", "0.3926991");    // PI / 8 (22.5 degrees)
+pref("apz.axis_lock.direct_pan_angle", "1.047197");   // PI / 3 (60 degrees)
 pref("apz.content_response_timeout", 300);
 pref("apz.cross_slide.enabled", false);
 pref("apz.danger_zone_x", 50);
 pref("apz.danger_zone_y", 100);
 pref("apz.enlarge_displayport_when_clipped", false);
 pref("apz.fling_accel_base_mult", "1.0");
 pref("apz.fling_accel_interval_ms", 500);
 pref("apz.fling_accel_supplemental_mult", "1.0");
--- a/security/manager/boot/src/StaticHPKPins.h
+++ b/security/manager/boot/src/StaticHPKPins.h
@@ -74,16 +74,20 @@ static const char kComodo_Trusted_Servic
 /* Cybertrust Global Root */
 static const char kCybertrust_Global_RootFingerprint[] =
   "foeCwVDOOVL4AuY2AjpdPpW7XWjjPoWtsroXgSXOvxU=";
 
 /* DigiCert Assured ID Root CA */
 static const char kDigiCert_Assured_ID_Root_CAFingerprint[] =
   "I/Lt/z7ekCWanjD0Cvj5EqXls2lOaThEA0H2Bg4BT/o=";
 
+/* DigiCert ECC Secure Server CA */
+static const char kDigiCert_ECC_Secure_Server_CAFingerprint[] =
+  "PZXN3lRAy+8tBKk2Ox6F7jIlnzr2Yzmwqc3JnyfXoCw=";
+
 /* DigiCert Global Root CA */
 static const char kDigiCert_Global_Root_CAFingerprint[] =
   "r/mIkG3eEpVdm+u/ko/cwxzOMo1bk4TyHIlByibiA5E=";
 
 /* DigiCert High Assurance EV Root CA */
 static const char kDigiCert_High_Assurance_EV_Root_CAFingerprint[] =
   "WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18=";
 
@@ -359,16 +363,17 @@ struct StaticFingerprints {
 
 struct StaticPinset {
   const StaticFingerprints* sha1;
   const StaticFingerprints* sha256;
 };
 
 /* PreloadedHPKPins.json pinsets */
 static const char* kPinset_facebook_sha256_Data[] = {
+  kDigiCert_ECC_Secure_Server_CAFingerprint,
   kVerisign_Class_3_Public_Primary_Certification_Authority___G3Fingerprint,
   kDigiCert_High_Assurance_EV_Root_CAFingerprint,
 };
 static const StaticFingerprints kPinset_facebook_sha256 = {
   sizeof(kPinset_facebook_sha256_Data) / sizeof(const char*),
   kPinset_facebook_sha256_Data
 };
 
@@ -1082,9 +1087,9 @@ static const TransportSecurityPreload kP
   { "youtube.com", true, false, false, -1, &kPinset_google_root_pems },
   { "ytimg.com", true, false, false, -1, &kPinset_google_root_pems },
 };
 
 // Pinning Preload List Length = 331;
 
 static const int32_t kUnknownId = -1;
 
-static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1418465237331000);
+static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1418659817121000);
--- a/security/manager/tools/PreloadedHPKPins.json
+++ b/security/manager/tools/PreloadedHPKPins.json
@@ -14,16 +14,20 @@
 // For a given pinset, a certificate is accepted if at least one of the
 // Subject Public Key Infos (SPKIs) is found in the chain.  SPKIs are specified
 // as names, which must match up with the name given in the Mozilla root store.
 //
 // "entries" is a list of objects. Each object has the following members:
 //   name: (string) the DNS name of the host in question
 //   include_subdomains: (optional bool) whether subdomains of |name| are also covered
 //   pins: (string) the |name| member of an object in |pinsets|
+//
+// "extra_certs" is a list of base64-encoded certificates. These are used in
+// pinsets that reference certificates not in our root program (for example,
+// Facebook).
 
 // equifax -> aus3
 // Geotrust Primary -> www.mozilla.org
 // Geotrust Global -> *. addons.mozilla.org
 {
   "chromium_data" : {
     "cert_file_url": "https://src.chromium.org/chrome/trunk/src/net/http/transport_security_state_static.certs",
     "json_file_url": "https://src.chromium.org/chrome/trunk/src/net/http/transport_security_state_static.json",
@@ -181,23 +185,22 @@
         "Verisign Class 3 Public Primary Certification Authority - G3",
         "VeriSign Class 3 Public Primary Certification Authority - G4",
         "VeriSign Class 3 Public Primary Certification Authority - G5",
         "Verisign Class 4 Public Primary Certification Authority - G3",
         "VeriSign Universal Root Certification Authority",
         "XRamp Global CA Root"
       ]
     },
-    // For pinning tests on pinning.example.com, the certificate must be 'End
-    // Entity Test Cert'
     {
       "name": "facebook",
       "sha256_hashes": [
         "Verisign Class 3 Public Primary Certification Authority - G3",
-        "DigiCert High Assurance EV Root CA"
+        "DigiCert High Assurance EV Root CA",
+        "DigiCert ECC Secure Server CA"
       ]
     }
   ],
 
   "entries": [
     // Only domains that are operationally crucial to Firefox can have per-host
     // telemetry reporting (the "id") field
     { "name": "addons.mozilla.org", "include_subdomains": true,
@@ -230,10 +233,15 @@
     // Expand twitter's pinset to include all of *.twitter.com and use
     // twitterCDN. More specific rules take precedence because we search for
     // exact domain name first.
     { "name": "twitter.com", "include_subdomains": true,
       "pins": "twitterCDN", "test_mode": false },
     // Facebook (not pinned by Chrome)
     { "name": "facebook.com", "include_subdomains": true,
       "pins": "facebook", "test_mode": true }
+  ],
+
+  "extra_certificates": [
+     // DigiCert ECC Secure Server CA (for Facebook)
+     "MIIDrDCCApSgAwIBAgIQCssoukZe5TkIdnRw883GEjANBgkqhkiG9w0BAQwFADBhMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBDQTAeFw0xMzAzMDgxMjAwMDBaFw0yMzAzMDgxMjAwMDBaMEwxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxJjAkBgNVBAMTHURpZ2lDZXJ0IEVDQyBTZWN1cmUgU2VydmVyIENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE4ghC6nfYJN6gLGSkE85AnCNyqQIKDjc/ITa4jVMU9tWRlUvzlgKNcR7E2Munn17voOZ/WpIRllNv68DLP679Wz9HJOeaBy6Wvqgvu1cYr3GkvXg6HuhbPGtkESvMNCuMo4IBITCCAR0wEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQgYDVR0fBDswOTA3oDWgM4YxaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0R2xvYmFsUm9vdENBLmNybDA9BgNVHSAENjA0MDIGBFUdIAAwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAdBgNVHQ4EFgQUo53mH/naOU/AbuiRy5Wl2jHiCp8wHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUwDQYJKoZIhvcNAQEMBQADggEBAMeKoENL7HTJxavVHzA1Nm6YVntIrAVjrnuaVyRXzG/63qttnMe2uuzO58pzZNvfBDcKAEmzP58mrZGMIOgfiA4q+2Y3yDDo0sIkp0VILeoBUEoxlBPfjV/aKrtJPGHzecicZpIalir0ezZYoyxBEHQa0+1IttK7igZFcTMQMHp6mCHdJLnsnLWSB62DxsRq+HfmNb4TDydkskO/g+l3VtsIh5RHFPVfKK+jaEyDj2D3loB5hWp2Jp2VDCADjT7ueihlZGak2YPqmXTNbk19HOuNssWvFhtOyPNV6og4ETQdEa8/B6hPatJ0ES8q/HO3X8IVQwVs1n3aAr0im0/T+Xc="
   ]
 }
--- a/security/manager/tools/genHPKPStaticPins.js
+++ b/security/manager/tools/genHPKPStaticPins.js
@@ -331,31 +331,39 @@ function downloadAndParseChromePins(file
         pins: pinsetName });
     }
   });
   return [ chromeImportedPinsets, chromeImportedEntries ];
 }
 
 // Returns a pair of maps [certNameToSKD, certSKDToName] between cert
 // nicknames and digests of the SPKInfo for the mozilla trust store
-function loadNSSCertinfo(derTestFile) {
+function loadNSSCertinfo(derTestFile, extraCertificates) {
   let allCerts = gCertDB.getCerts();
   let enumerator = allCerts.getEnumerator();
   let certNameToSKD = {};
   let certSKDToName = {};
   while (enumerator.hasMoreElements()) {
     let cert = enumerator.getNext().QueryInterface(Ci.nsIX509Cert);
     if (!isCertBuiltIn(cert)) {
       continue;
     }
     let name = cert.nickname.substr(BUILT_IN_NICK_PREFIX.length);
     let SKD = cert.sha256SubjectPublicKeyInfoDigest;
     certNameToSKD[name] = SKD;
     certSKDToName[SKD] = name;
   }
+
+  for (let cert of extraCertificates) {
+    let name = cert.commonName;
+    let SKD = cert.sha256SubjectPublicKeyInfoDigest;
+    certNameToSKD[name] = SKD;
+    certSKDToName[SKD] = name;
+  }
+
   {
     // A certificate for *.example.com.
     let der = readFileToString(derTestFile);
     let testCert = gCertDB.constructX509(der, der.length);
     // We can't include this cert in the previous loop, because it skips
     // non-builtin certs and the nickname is not built-in to the cert.
     let name = "End Entity Test Cert";
     let SKD  = testCert.sha256SubjectPublicKeyInfoDigest;
@@ -540,17 +548,27 @@ function writeFile(certNameToSKD, certSK
 
   // Write the domainlist entries.
   writeString(DOMAINHEADER);
   writeDomainList(chromeImportedEntries);
   writeString("\n");
   writeString(genExpirationTime());
 }
 
-let [ certNameToSKD, certSKDToName ] = loadNSSCertinfo(gTestCertFile);
+function loadExtraCertificates(certStringList) {
+  let constructedCerts = [];
+  for (let certString of certStringList) {
+    constructedCerts.push(gCertDB.constructX509FromBase64(certString));
+  }
+  return constructedCerts;
+}
+
+let extraCertificates = loadExtraCertificates(gStaticPins.extra_certificates);
+let [ certNameToSKD, certSKDToName ] = loadNSSCertinfo(gTestCertFile,
+                                                       extraCertificates);
 let [ chromeNameToHash, chromeNameToMozName ] = downloadAndParseChromeCerts(
   gStaticPins.chromium_data.cert_file_url, certSKDToName);
 let [ chromeImportedPinsets, chromeImportedEntries ] =
   downloadAndParseChromePins(gStaticPins.chromium_data.json_file_url,
     chromeNameToHash, chromeNameToMozName, certNameToSKD, certSKDToName);
 
 writeFile(certNameToSKD, certSKDToName, chromeImportedPinsets,
           chromeImportedEntries);
--- a/testing/marionette/client/marionette/errors.py
+++ b/testing/marionette/client/marionette/errors.py
@@ -26,16 +26,17 @@ class ErrorCodes(object):
     INVALID_ELEMENT_COORDINATES = 29
     INVALID_SELECTOR = 32
     MOVE_TARGET_OUT_OF_BOUNDS = 34
     INVALID_XPATH_SELECTOR = 51
     INVALID_XPATH_SELECTOR_RETURN_TYPER = 52
     INVALID_RESPONSE = 53
     FRAME_SEND_NOT_INITIALIZED_ERROR = 54
     FRAME_SEND_FAILURE_ERROR = 55
+    UNSUPPORTED_OPERATION = 405
     MARIONETTE_ERROR = 500
 
 class MarionetteException(Exception):
     """Raised when a generic non-recoverable exception has occured."""
 
     def __init__(self, message=None,
                  status=ErrorCodes.MARIONETTE_ERROR, cause=None,
                  stacktrace=None):
@@ -133,8 +134,11 @@ class InvalidSelectorException(Marionett
 class MoveTargetOutOfBoundsException(MarionetteException):
     pass
 
 class FrameSendNotInitializedError(MarionetteException):
     pass
 
 class FrameSendFailureError(MarionetteException):
     pass
+
+class UnsupportedOperationException(MarionetteException):
+    pass
--- a/testing/marionette/client/marionette/marionette.py
+++ b/testing/marionette/client/marionette/marionette.py
@@ -703,16 +703,18 @@ class Marionette(object):
                  or status == errors.ErrorCodes.INVALID_XPATH_SELECTOR_RETURN_TYPER:
                 raise errors.InvalidSelectorException(message=message, status=status, stacktrace=stacktrace)
             elif status == errors.ErrorCodes.MOVE_TARGET_OUT_OF_BOUNDS:
                 raise errors.MoveTargetOutOfBoundsException(message=message, status=status, stacktrace=stacktrace)
             elif status == errors.ErrorCodes.FRAME_SEND_NOT_INITIALIZED_ERROR:
                 raise errors.FrameSendNotInitializedError(message=message, status=status, stacktrace=stacktrace)
             elif status == errors.ErrorCodes.FRAME_SEND_FAILURE_ERROR:
                 raise errors.FrameSendFailureError(message=message, status=status, stacktrace=stacktrace)
+            elif status == errors.ErrorCodes.UNSUPPORTED_OPERATION:
+                raise errors.UnsupportedOperationException(message=message, status=status, stacktrace=stacktrace)
             else:
                 raise errors.MarionetteException(message=message, status=status, stacktrace=stacktrace)
         raise errors.MarionetteException(message=response, status=500)
 
     def _reset_timeouts(self):
         if self.timeout is not None:
             self.timeouts(self.TIMEOUT_SEARCH, self.timeout)
             self.timeouts(self.TIMEOUT_SCRIPT, self.timeout)
@@ -878,17 +880,16 @@ class Marionette(object):
         Return an opaque server-assigned identifier to this window
         that uniquely identifies it within this Marionette instance.
         This can be used to switch to this window at a later point.
 
         :returns: unique window handle
         :rtype: string
 
         """
-
         self.window = self._send_message("getWindowHandle", "value")
         return self.window
 
     @property
     def title(self):
         '''
         Current title of the active window.
         '''
@@ -1510,8 +1511,36 @@ class Marionette(object):
         "landscape-secondary".
 
         :param orientation: The orientation to lock the screen in.
 
         """
         self._send_message("setScreenOrientation", "ok", orientation=orientation)
         if self.emulator:
             self.emulator.screen.orientation = orientation.lower()
+
+    @property
+    def window_size(self):
+        """Get the current browser window size.
+
+        Will return the current browser window size in pixels. Refers to
+        window outerWidth and outerHeight values, which include scroll bars,
+        title bars, etc.
+
+        :returns: dictionary representation of current window width and height
+
+        """
+        return self._send_message("getWindowSize", "value")
+
+    def set_window_size(self, width, height):
+        """Resize the browser window currently in focus.
+
+        The supplied width and height values refer to the window outerWidth
+        and outerHeight values, which include scroll bars, title bars, etc.
+
+        An error will be returned if the requested window size would result
+        in the window being in the maximised state.
+
+        :param width: The width to resize the window to.
+        :param height: The height to resize the window to.
+
+        """
+        self._send_message("setWindowSize", "ok", width=width, height=height)
new file mode 100644
--- /dev/null
+++ b/testing/marionette/client/marionette/tests/unit/test_set_window_size.py
@@ -0,0 +1,50 @@
+# 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/.
+
+from errors import MarionetteException
+from marionette_test import MarionetteTestCase
+
+class TestSetWindowSize(MarionetteTestCase):
+    def setUp(self):
+        super(MarionetteTestCase, self).setUp()
+        self.start_size = self.marionette.window_size
+        self.max_width = self.marionette.execute_script("return window.screen.availWidth;")
+        self.max_height = self.marionette.execute_script("return window.screen.availHeight;")
+
+    def tearDown(self):
+        # WebDriver spec says a resize cannot result in window being maximized, an
+        # error is returned if that is the case; therefore if the window is maximized
+        # at the start of this test, returning to the original size via set_window_size
+        # size will result in error; so reset to original size minus 1 pixel width
+        if self.start_size['width'] == self.max_width and self.start_size['height'] == self.max_height:
+            self.start_size['width']-=1
+        self.marionette.set_window_size(self.start_size['width'], self.start_size['height'])
+        super(MarionetteTestCase, self).tearDown()
+
+    def test_set_window_size(self):
+        # event handler
+        self.marionette.execute_script("""
+        window.wrappedJSObject.rcvd_event = false;
+        window.onresize = function() {
+            window.wrappedJSObject.rcvd_event = true;
+        };
+        """)
+
+        # valid size
+        width = self.max_width - 100
+        height = self.max_height - 100
+        self.marionette.set_window_size(width, height)
+        self.wait_for_condition(lambda m: m.execute_script("return window.wrappedJSObject.rcvd_event;"))
+        size = self.marionette.window_size
+        self.assertEqual(size['width'], width,
+                         "Window width is %s but should be %s" % (size['width'], width))
+        self.assertEqual(size['height'], height,
+                         "Window height is %s but should be %s" % (size['height'], height))
+
+        # invalid size (cannot maximize)
+        with self.assertRaisesRegexp(MarionetteException, "Invalid requested size"):
+            self.marionette.set_window_size(self.max_width, self.max_height)
+        size = self.marionette.window_size
+        self.assertEqual(size['width'], width, "Window width should not have changed")
+        self.assertEqual(size['height'], height, "Window height should not have changed")
--- a/testing/marionette/client/marionette/tests/unit/unit-tests.ini
+++ b/testing/marionette/client/marionette/tests/unit/unit-tests.ini
@@ -115,10 +115,12 @@ disabled = "Bug 925688"
 [test_screen_orientation.py]
 browser = false
 [test_errors.py]
 
 [test_execute_isolate.py]
 [test_click_scrolling.py]
 [test_profile_management.py]
 b2g = false
+[test_set_window_size.py]
+b2g = false
 
 [include:oop/manifest.ini]
--- a/testing/marionette/marionette-server.js
+++ b/testing/marionette/marionette-server.js
@@ -2349,16 +2349,69 @@ MarionetteServerConnection.prototype = {
     if (!curWindow.screen.mozLockOrientation(mozOr)) {
       this.sendError("Unable to set screen orientation: " + or, 500,
                      null, this.command_id);
     }
     this.sendOk(this.command_id);
   },
 
   /**
+   * Get the size of the browser window currently in focus.
+   *
+   * Will return the current browser window size in pixels. Refers to
+   * window outerWidth and outerHeight values, which include scroll bars,
+   * title bars, etc.
+   *
+   */
+  getWindowSize: function MDA_getWindowSize(aRequest) {
+    this.command_id = this.getCommandId();
+    let curWindow = this.getCurrentWindow();
+    let curWidth = curWindow.outerWidth;
+    let curHeight = curWindow.outerHeight;
+    this.sendResponse({width: curWidth, height: curHeight}, this.command_id);
+  },
+
+  /**
+   * Set the size of the browser window currently in focus.
+   *
+   * Not supported on B2G. The supplied width and height values refer to
+   * the window outerWidth and outerHeight values, which include scroll
+   * bars, title bars, etc.
+   *
+   * An error will be returned if the requested window size would result
+   * in the window being in the maximized state.
+   */
+  setWindowSize: function MDA_setWindowSize(aRequest) {
+    this.command_id = this.getCommandId();
+
+    if (appName == "B2G") {
+      this.sendError("Not supported on B2G", 405, null, this.command_id);
+      return;
+    }
+
+    try {
+      var width = parseInt(aRequest.parameters.width);
+      var height = parseInt(aRequest.parameters.height);
+    }
+    catch(e) {
+      this.sendError(e.message, e.code, e.stack, this.command_id);
+      return;
+    }
+
+    let curWindow = this.getCurrentWindow();
+    if (width >= curWindow.screen.availWidth && height >= curWindow.screen.availHeight) {
+      this.sendError("Invalid requested size, cannot maximize", 405, null, this.command_id);
+      return;
+    }
+
+    curWindow.resizeTo(width, height);
+    this.sendOk(this.command_id);
+  },
+
+  /**
    * Helper function to convert an outerWindowID into a UID that Marionette
    * tracks.
    */
   generateFrameId: function MDA_generateFrameId(id) {
     let uid = id + (appName == "B2G" ? "-b2g" : "");
     return uid;
   },
 
@@ -2553,17 +2606,19 @@ MarionetteServerConnection.prototype.req
   "screenshot": MarionetteServerConnection.prototype.takeScreenshot,  // Selenium 2 compat
   "addCookie": MarionetteServerConnection.prototype.addCookie,
   "getCookies": MarionetteServerConnection.prototype.getCookies,
   "getAllCookies": MarionetteServerConnection.prototype.getCookies,  // deprecated
   "deleteAllCookies": MarionetteServerConnection.prototype.deleteAllCookies,
   "deleteCookie": MarionetteServerConnection.prototype.deleteCookie,
   "getActiveElement": MarionetteServerConnection.prototype.getActiveElement,
   "getScreenOrientation": MarionetteServerConnection.prototype.getScreenOrientation,
-  "setScreenOrientation": MarionetteServerConnection.prototype.setScreenOrientation
+  "setScreenOrientation": MarionetteServerConnection.prototype.setScreenOrientation,
+  "getWindowSize": MarionetteServerConnection.prototype.getWindowSize,
+  "setWindowSize": MarionetteServerConnection.prototype.setWindowSize
 };
 
 /**
  * Creates a BrowserObj. BrowserObjs handle interactions with the
  * browser, according to the current environment (desktop, b2g, etc.)
  *
  * @param nsIDOMWindow win
  *        The window whose browser needs to be accessed
--- a/xpcom/build/XPCOMModule.inc
+++ b/xpcom/build/XPCOMModule.inc
@@ -58,17 +58,17 @@
     COMPONENT(THREADPOOL, nsThreadPoolConstructor)
 
     COMPONENT(STRINGINPUTSTREAM, nsStringInputStreamConstructor)
     COMPONENT(MULTIPLEXINPUTSTREAM, nsMultiplexInputStreamConstructor)
 
     COMPONENT(VARIANT, nsVariantConstructor)
     COMPONENT(INTERFACEINFOMANAGER_SERVICE, nsXPTIInterfaceInfoManagerGetSingleton)
 
-    COMPONENT(HASH_PROPERTY_BAG, nsHashPropertyBagConstructor)
+    COMPONENT(HASH_PROPERTY_BAG, nsHashPropertyBagCCConstructor)
 
     COMPONENT(UUID_GENERATOR, nsUUIDGeneratorConstructor)
 
 #if defined(XP_WIN)
     COMPONENT(WINDOWSREGKEY, nsWindowsRegKeyConstructor)
 #endif
 
 #if defined(MOZ_WIDGET_COCOA)
--- a/xpcom/build/nsXPComInit.cpp
+++ b/xpcom/build/nsXPComInit.cpp
@@ -210,17 +210,17 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsStorage
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsVersionComparatorImpl)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsScriptableBase64Encoder)
 #ifdef MOZ_VISUAL_EVENT_TRACER
 NS_GENERIC_FACTORY_CONSTRUCTOR(VisualEventTracer)
 #endif
 
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsVariant)
 
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsHashPropertyBag)
+NS_GENERIC_FACTORY_CONSTRUCTOR(nsHashPropertyBagCC)
 
 NS_GENERIC_AGGREGATED_CONSTRUCTOR(nsProperties)
 
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsUUIDGenerator, Init)
 
 #ifdef MOZ_WIDGET_COCOA
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsMacUtilsImpl)
 #endif
--- a/xpcom/ds/nsHashPropertyBag.cpp
+++ b/xpcom/ds/nsHashPropertyBag.cpp
@@ -1,86 +1,68 @@
-/* -*- Mode: C++; tab-width: 50; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* vim:set ts=4 sw=4 sts=4: */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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 "nsHashPropertyBag.h"
 #include "nsArray.h"
 #include "nsArrayEnumerator.h"
 #include "nsIVariant.h"
 #include "nsIProperty.h"
 #include "nsVariant.h"
 #include "mozilla/Attributes.h"
 
-nsresult
-NS_NewHashPropertyBag(nsIWritablePropertyBag** aResult)
-{
-  nsRefPtr<nsHashPropertyBag> hpb = new nsHashPropertyBag();
-  hpb.forget(aResult);
-  return NS_OK;
-}
-
 /*
- * nsHashPropertyBag impl
+ * nsHashPropertyBagBase implementation.
  */
 
-NS_IMPL_ADDREF(nsHashPropertyBag)
-NS_IMPL_RELEASE(nsHashPropertyBag)
-NS_INTERFACE_MAP_BEGIN(nsHashPropertyBag)
-  NS_INTERFACE_MAP_ENTRY(nsIWritablePropertyBag)
-  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIPropertyBag, nsIWritablePropertyBag)
-  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWritablePropertyBag)
-  NS_INTERFACE_MAP_ENTRY(nsIPropertyBag2)
-  NS_INTERFACE_MAP_ENTRY(nsIWritablePropertyBag2)
-NS_INTERFACE_MAP_END
-
 NS_IMETHODIMP
-nsHashPropertyBag::HasKey(const nsAString& aName, bool* aResult)
+nsHashPropertyBagBase::HasKey(const nsAString& aName, bool* aResult)
 {
   *aResult = mPropertyHash.Get(aName, nullptr);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsHashPropertyBag::Get(const nsAString& aName, nsIVariant** aResult)
+nsHashPropertyBagBase::Get(const nsAString& aName, nsIVariant** aResult)
 {
   if (!mPropertyHash.Get(aName, aResult)) {
     *aResult = nullptr;
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsHashPropertyBag::GetProperty(const nsAString& aName, nsIVariant** aResult)
+nsHashPropertyBagBase::GetProperty(const nsAString& aName, nsIVariant** aResult)
 {
   bool isFound = mPropertyHash.Get(aName, aResult);
   if (!isFound) {
     return NS_ERROR_FAILURE;
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsHashPropertyBag::SetProperty(const nsAString& aName, nsIVariant* aValue)
+nsHashPropertyBagBase::SetProperty(const nsAString& aName, nsIVariant* aValue)
 {
   if (NS_WARN_IF(!aValue)) {
     return NS_ERROR_INVALID_ARG;
   }
 
   mPropertyHash.Put(aName, aValue);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsHashPropertyBag::DeleteProperty(const nsAString& aName)
+nsHashPropertyBagBase::DeleteProperty(const nsAString& aName)
 {
   // is it too much to ask for ns*Hashtable to return
   // a boolean indicating whether RemoveEntry succeeded
   // or not?!?!
   bool isFound = mPropertyHash.Get(aName, nullptr);
   if (!isFound) {
     return NS_ERROR_FAILURE;
   }
@@ -140,89 +122,89 @@ PropertyHashToArrayFunc(const nsAString&
   nsIMutableArray* propertyArray = static_cast<nsIMutableArray*>(aUserArg);
   nsSimpleProperty* sprop = new nsSimpleProperty(aKey, aData);
   propertyArray->AppendElement(sprop, false);
   return PL_DHASH_NEXT;
 }
 
 
 NS_IMETHODIMP
-nsHashPropertyBag::GetEnumerator(nsISimpleEnumerator** aResult)
+nsHashPropertyBagBase::GetEnumerator(nsISimpleEnumerator** aResult)
 {
   nsCOMPtr<nsIMutableArray> propertyArray = nsArray::Create();
   if (!propertyArray) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   mPropertyHash.EnumerateRead(PropertyHashToArrayFunc, propertyArray.get());
 
   return NS_NewArrayEnumerator(aResult, propertyArray);
 }
 
 #define IMPL_GETSETPROPERTY_AS(Name, Type) \
 NS_IMETHODIMP \
-nsHashPropertyBag::GetPropertyAs ## Name (const nsAString & prop, Type *_retval) \
+nsHashPropertyBagBase::GetPropertyAs ## Name (const nsAString & prop, Type *_retval) \
 { \
     nsIVariant* v = mPropertyHash.GetWeak(prop); \
     if (!v) \
         return NS_ERROR_NOT_AVAILABLE; \
     return v->GetAs ## Name(_retval); \
 } \
 \
 NS_IMETHODIMP \
-nsHashPropertyBag::SetPropertyAs ## Name (const nsAString & prop, Type value) \
+nsHashPropertyBagBase::SetPropertyAs ## Name (const nsAString & prop, Type value) \
 { \
     nsCOMPtr<nsIWritableVariant> var = new nsVariant(); \
     var->SetAs ## Name(value); \
     return SetProperty(prop, var); \
 }
 
 IMPL_GETSETPROPERTY_AS(Int32, int32_t)
 IMPL_GETSETPROPERTY_AS(Uint32, uint32_t)
 IMPL_GETSETPROPERTY_AS(Int64, int64_t)
 IMPL_GETSETPROPERTY_AS(Uint64, uint64_t)
 IMPL_GETSETPROPERTY_AS(Double, double)
 IMPL_GETSETPROPERTY_AS(Bool, bool)
 
 
 NS_IMETHODIMP
-nsHashPropertyBag::GetPropertyAsAString(const nsAString& aProp,
+nsHashPropertyBagBase::GetPropertyAsAString(const nsAString& aProp,
                                         nsAString& aResult)
 {
   nsIVariant* v = mPropertyHash.GetWeak(aProp);
   if (!v) {
     return NS_ERROR_NOT_AVAILABLE;
   }
   return v->GetAsAString(aResult);
 }
 
 NS_IMETHODIMP
-nsHashPropertyBag::GetPropertyAsACString(const nsAString& aProp,
+nsHashPropertyBagBase::GetPropertyAsACString(const nsAString& aProp,
                                          nsACString& aResult)
 {
   nsIVariant* v = mPropertyHash.GetWeak(aProp);
   if (!v) {
     return NS_ERROR_NOT_AVAILABLE;
   }
   return v->GetAsACString(aResult);
 }
 
 NS_IMETHODIMP
-nsHashPropertyBag::GetPropertyAsAUTF8String(const nsAString& aProp,
+nsHashPropertyBagBase::GetPropertyAsAUTF8String(const nsAString& aProp,
                                             nsACString& aResult)
 {
   nsIVariant* v = mPropertyHash.GetWeak(aProp);
   if (!v) {
     return NS_ERROR_NOT_AVAILABLE;
   }
   return v->GetAsAUTF8String(aResult);
 }
 
 NS_IMETHODIMP
-nsHashPropertyBag::GetPropertyAsInterface(const nsAString& aProp,
+nsHashPropertyBagBase::GetPropertyAsInterface(const nsAString& aProp,
                                           const nsIID& aIID,
                                           void** aResult)
 {
   nsIVariant* v = mPropertyHash.GetWeak(aProp);
   if (!v) {
     return NS_ERROR_NOT_AVAILABLE;
   }
   nsCOMPtr<nsISupports> val;
@@ -234,43 +216,76 @@ nsHashPropertyBag::GetPropertyAsInterfac
     // We have a value, but it's null
     *aResult = nullptr;
     return NS_OK;
   }
   return val->QueryInterface(aIID, aResult);
 }
 
 NS_IMETHODIMP
-nsHashPropertyBag::SetPropertyAsAString(const nsAString& aProp,
+nsHashPropertyBagBase::SetPropertyAsAString(const nsAString& aProp,
                                         const nsAString& aValue)
 {
   nsCOMPtr<nsIWritableVariant> var = new nsVariant();
   var->SetAsAString(aValue);
   return SetProperty(aProp, var);
 }
 
 NS_IMETHODIMP
-nsHashPropertyBag::SetPropertyAsACString(const nsAString& aProp,
+nsHashPropertyBagBase::SetPropertyAsACString(const nsAString& aProp,
                                          const nsACString& aValue)
 {
   nsCOMPtr<nsIWritableVariant> var = new nsVariant();
   var->SetAsACString(aValue);
   return SetProperty(aProp, var);
 }
 
 NS_IMETHODIMP
-nsHashPropertyBag::SetPropertyAsAUTF8String(const nsAString& aProp,
+nsHashPropertyBagBase::SetPropertyAsAUTF8String(const nsAString& aProp,
                                             const nsACString& aValue)
 {
   nsCOMPtr<nsIWritableVariant> var = new nsVariant();
   var->SetAsAUTF8String(aValue);
   return SetProperty(aProp, var);
 }
 
 NS_IMETHODIMP
-nsHashPropertyBag::SetPropertyAsInterface(const nsAString& aProp,
+nsHashPropertyBagBase::SetPropertyAsInterface(const nsAString& aProp,
                                           nsISupports* aValue)
 {
   nsCOMPtr<nsIWritableVariant> var = new nsVariant();
   var->SetAsISupports(aValue);
   return SetProperty(aProp, var);
 }
 
+
+/*
+ * nsHashPropertyBag implementation.
+ */
+
+NS_IMPL_ADDREF(nsHashPropertyBag)
+NS_IMPL_RELEASE(nsHashPropertyBag)
+
+NS_INTERFACE_MAP_BEGIN(nsHashPropertyBag)
+  NS_INTERFACE_MAP_ENTRY(nsIWritablePropertyBag)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIPropertyBag, nsIWritablePropertyBag)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWritablePropertyBag)
+  NS_INTERFACE_MAP_ENTRY(nsIPropertyBag2)
+  NS_INTERFACE_MAP_ENTRY(nsIWritablePropertyBag2)
+NS_INTERFACE_MAP_END
+
+
+/*
+ * nsHashPropertyBagCC implementation.
+ */
+
+NS_IMPL_CYCLE_COLLECTION(nsHashPropertyBagCC, mPropertyHash)
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF(nsHashPropertyBagCC)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(nsHashPropertyBagCC)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsHashPropertyBagCC)
+  NS_INTERFACE_MAP_ENTRY(nsIWritablePropertyBag)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIPropertyBag, nsIWritablePropertyBag)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWritablePropertyBag)
+  NS_INTERFACE_MAP_ENTRY(nsIPropertyBag2)
+  NS_INTERFACE_MAP_ENTRY(nsIWritablePropertyBag2)
+NS_INTERFACE_MAP_END
--- a/xpcom/ds/nsHashPropertyBag.h
+++ b/xpcom/ds/nsHashPropertyBag.h
@@ -1,40 +1,57 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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/. */
 
 #ifndef nsHashPropertyBag_h___
 #define nsHashPropertyBag_h___
 
 #include "nsIVariant.h"
 #include "nsIWritablePropertyBag.h"
 #include "nsIWritablePropertyBag2.h"
+
+#include "nsCycleCollectionParticipant.h"
 #include "nsInterfaceHashtable.h"
 
-class nsHashPropertyBag
+class nsHashPropertyBagBase
   : public nsIWritablePropertyBag
   , public nsIWritablePropertyBag2
 {
 public:
-  nsHashPropertyBag() {}
-
-  NS_DECL_THREADSAFE_ISUPPORTS
+  nsHashPropertyBagBase() {}
 
   NS_DECL_NSIPROPERTYBAG
   NS_DECL_NSIPROPERTYBAG2
 
   NS_DECL_NSIWRITABLEPROPERTYBAG
   NS_DECL_NSIWRITABLEPROPERTYBAG2
 
 protected:
   // a hash table of string -> nsIVariant
   nsInterfaceHashtable<nsStringHashKey, nsIVariant> mPropertyHash;
+};
 
+class nsHashPropertyBag : public nsHashPropertyBagBase
+{
+public:
+  nsHashPropertyBag() {}
+  NS_DECL_THREADSAFE_ISUPPORTS
+
+protected:
   virtual ~nsHashPropertyBag() {}
 };
 
-// Note: NS_NewHashPropertyBag returns a HPB that
-// uses a non-thread-safe internal hash
-extern "C" nsresult NS_NewHashPropertyBag(nsIWritablePropertyBag** aResult);
+/* A cycle collected nsHashPropertyBag for main-thread-only use. */
+class nsHashPropertyBagCC MOZ_FINAL : public nsHashPropertyBagBase
+{
+public:
+  nsHashPropertyBagCC() {}
+  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+  NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsHashPropertyBagCC,
+                                           nsIWritablePropertyBag)
+protected:
+  virtual ~nsHashPropertyBagCC() {}
+};
 
 #endif /* nsHashPropertyBag_h___ */