From 1d6a3196e296edd468b7e1df7debae01cf7dfb92 Mon Sep 17 00:00:00 2001 From: roytam1 Date: Tue, 3 Nov 2020 11:00:45 +0800 Subject: [PATCH] import changes from `dev' branch of rmottola/Arctic-Fox: - Bug 1121855 - Fix camera crash. r=aosmond (6ad4335ae) - Bug 1139721 - Fix camera memory leaks for onfacedetected events, failed initializations and capabilities. r=mikeh (663bbde8c) - Bug 1165729 - Check SetCapacity return value in nsSMILAnimationFunction::GetValues. r=dholbert (100ecf2f7) - Bug 968520 - Add mozilla::fallible to Fallible{Auto,}TArray::SetCapacity calls. r=froydnj (2c120f71a) - Scrollbar thumbs can overlap scrollbar arrows during APZ scrolling. (bug 1152469, r=botond,mstange) (a2e9ac1bf) - Bug 1148889 - Treat subclasses of scrollframes as animated geometry roots. r=mstange (434719455) - Bug 1155025. Make the root layer on fennec have null scroll id with containerless scrolling. r=mstange (eb1bb3acd) - remove test (63f014d13) - Bug 1151306 - Add a reftest. r=roc (56c4137ae) - Bug 1151145 - Add a reftest. r=jrmuizel (9684c3f0a) - Bug 1150021. Make sure that boxes inside vertical RTL boxes are placed on the right. r=roc (c4b3e7e06) - Bug 1156129 - Take border radius into account when calculating the bounds of border display items. r=roc (35b70f9a8) - Bug 1152902 part 2. Add a fast path for the case when a Promise is resolved with another Promise. r=nsm (33a210977) --- dom/base/nsDOMMutationObserver.cpp | 2 +- dom/base/nsJSTimeoutHandler.cpp | 2 +- dom/bindings/Codegen.py | 2 +- dom/camera/DOMCameraCapabilities.cpp | 1 + dom/camera/DOMCameraControl.cpp | 13 +++- dom/indexedDB/ActorsParent.cpp | 18 +++-- dom/indexedDB/IDBObjectStore.cpp | 2 +- dom/mobilemessage/ipc/SmsChild.cpp | 8 +- dom/promise/Promise.cpp | 77 ++++++++++++++++++- dom/promise/Promise.h | 1 + dom/promise/tests/mochitest.ini | 1 + .../test_thenable_vs_promise_ordering.html | 27 +++++++ dom/smil/nsSMILAnimationFunction.cpp | 4 +- dom/svg/DOMSVGLengthList.cpp | 2 +- dom/svg/DOMSVGNumberList.cpp | 2 +- dom/svg/DOMSVGPathSegList.cpp | 5 +- dom/svg/DOMSVGPointList.cpp | 2 +- dom/svg/DOMSVGTransformList.cpp | 2 +- dom/svg/SVGLengthList.cpp | 2 +- dom/svg/SVGLengthList.h | 2 +- dom/svg/SVGMotionSMILType.cpp | 2 +- dom/svg/SVGNumberList.cpp | 2 +- dom/svg/SVGNumberList.h | 2 +- dom/svg/SVGPathData.cpp | 2 +- dom/svg/SVGPathData.h | 2 +- dom/svg/SVGPointList.h | 2 +- dom/svg/SVGStringList.cpp | 2 +- dom/svg/SVGStringList.h | 2 +- dom/svg/SVGTransformList.cpp | 2 +- dom/svg/SVGTransformList.h | 2 +- dom/svg/SVGTransformListSMILType.cpp | 6 +- dom/webidl/Promise.webidl | 2 +- gfx/layers/Layers.cpp | 1 + gfx/layers/Layers.h | 10 ++- .../composite/AsyncCompositionManager.cpp | 12 +-- gfx/layers/ipc/LayerTransactionParent.cpp | 3 +- gfx/layers/ipc/LayersMessages.ipdlh | 1 + gfx/layers/ipc/ShadowLayers.cpp | 1 + intl/uconv/nsConverterInputStream.cpp | 4 +- ipc/glue/IPCMessageUtils.h | 2 +- layout/base/nsDisplayList.cpp | 40 ++++++++-- layout/base/nsDisplayList.h | 4 +- layout/reftests/bugs/1150021-1-ref.css | 9 +++ layout/reftests/bugs/1150021-1-ref.xul | 20 +++++ layout/reftests/bugs/1150021-1.css | 10 +++ layout/reftests/bugs/1150021-1.xul | 20 +++++ layout/reftests/bugs/1151145-1-ref.html | 10 +++ layout/reftests/bugs/1151145-1.html | 21 +++++ layout/reftests/bugs/1151306-1-ref.html | 30 ++++++++ layout/reftests/bugs/1151306-1.html | 41 ++++++++++ layout/reftests/bugs/1156129-1-ref.html | 36 +++++++++ layout/reftests/bugs/1156129-1.html | 44 +++++++++++ layout/reftests/bugs/reftest.list | 5 +- layout/xul/nsBoxFrame.cpp | 8 +- layout/xul/nsSliderFrame.cpp | 8 ++ layout/xul/nsSliderFrame.h | 4 + layout/xul/nsSprocketLayout.cpp | 14 +++- netwerk/base/Dashboard.cpp | 17 ++-- xpcom/io/nsUnicharInputStream.cpp | 4 +- 59 files changed, 503 insertions(+), 79 deletions(-) create mode 100644 dom/promise/tests/test_thenable_vs_promise_ordering.html create mode 100644 layout/reftests/bugs/1150021-1-ref.css create mode 100644 layout/reftests/bugs/1150021-1-ref.xul create mode 100644 layout/reftests/bugs/1150021-1.css create mode 100644 layout/reftests/bugs/1150021-1.xul create mode 100644 layout/reftests/bugs/1151145-1-ref.html create mode 100644 layout/reftests/bugs/1151145-1.html create mode 100644 layout/reftests/bugs/1151306-1-ref.html create mode 100644 layout/reftests/bugs/1151306-1.html create mode 100644 layout/reftests/bugs/1156129-1-ref.html create mode 100644 layout/reftests/bugs/1156129-1.html diff --git a/dom/base/nsDOMMutationObserver.cpp b/dom/base/nsDOMMutationObserver.cpp index ddf5a6a61f..281adbb1eb 100644 --- a/dom/base/nsDOMMutationObserver.cpp +++ b/dom/base/nsDOMMutationObserver.cpp @@ -747,7 +747,7 @@ nsDOMMutationObserver::HandleMutation() mozilla::dom::Sequence > mutations; - if (mutations.SetCapacity(mPendingMutationCount)) { + if (mutations.SetCapacity(mPendingMutationCount, mozilla::fallible)) { // We can't use TakeRecords easily here, because it deals with a // different type of array, and we want to optimize out any extra copying. nsRefPtr current; diff --git a/dom/base/nsJSTimeoutHandler.cpp b/dom/base/nsJSTimeoutHandler.cpp index 30a5cdef53..fba0a362ee 100644 --- a/dom/base/nsJSTimeoutHandler.cpp +++ b/dom/base/nsJSTimeoutHandler.cpp @@ -363,7 +363,7 @@ nsJSScriptTimeoutHandler::Init(nsGlobalWindow *aWindow, bool *aIsInterval, uint32_t argCount = std::max(argc, 2u) - 2; FallibleTArray > args; - if (!args.SetCapacity(argCount)) { + if (!args.SetCapacity(argCount, fallible)) { // No need to drop here, since we already have a non-null mFunction return NS_ERROR_OUT_OF_MEMORY; } diff --git a/dom/bindings/Codegen.py b/dom/bindings/Codegen.py index 2ec3b3d327..bb1d72c957 100644 --- a/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -5537,7 +5537,7 @@ class CGArgumentConverter(CGThing): rooterDecl + dedent(""" if (${argc} > ${index}) { - if (!${declName}.SetCapacity(${argc} - ${index})) { + if (!${declName}.SetCapacity(${argc} - ${index}, mozilla::fallible)) { JS_ReportOutOfMemory(cx); return false; } diff --git a/dom/camera/DOMCameraCapabilities.cpp b/dom/camera/DOMCameraCapabilities.cpp index ff124eac1a..5a98a2fb11 100644 --- a/dom/camera/DOMCameraCapabilities.cpp +++ b/dom/camera/DOMCameraCapabilities.cpp @@ -323,6 +323,7 @@ CameraCapabilities::CameraCapabilities(nsPIDOMWindow* aWindow, , mCameraControl(aCameraControl) { DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this); + MOZ_COUNT_CTOR(CameraCapabilities); if (mCameraControl) { mListener = new CameraClosedListenerProxy(this); mCameraControl->AddListener(mListener); diff --git a/dom/camera/DOMCameraControl.cpp b/dom/camera/DOMCameraControl.cpp index d317c5b52c..d6befde08f 100644 --- a/dom/camera/DOMCameraControl.cpp +++ b/dom/camera/DOMCameraControl.cpp @@ -306,6 +306,8 @@ nsDOMCameraControl::nsDOMCameraControl(uint32_t aCameraId, nsDOMCameraControl::~nsDOMCameraControl() { DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this); + /*invoke DOMMediaStream destroy*/ + Destroy(); } JSObject* @@ -1370,11 +1372,10 @@ nsDOMCameraControl::OnFacesDetected(const nsTArray& aFaces Sequence > faces; uint32_t len = aFaces.Length(); - if (faces.SetCapacity(len)) { - nsRefPtr f; + if (faces.SetCapacity(len, fallible)) { for (uint32_t i = 0; i < len; ++i) { - f = new DOMCameraDetectedFace(static_cast(this), aFaces[i]); - *faces.AppendElement() = f.forget().take(); + *faces.AppendElement() = + new DOMCameraDetectedFace(static_cast(this), aFaces[i]); } } @@ -1425,6 +1426,10 @@ nsDOMCameraControl::OnUserError(CameraControlListener::UserContext aContext, nsr switch (aContext) { case CameraControlListener::kInStartCamera: promise = mGetCameraPromise.forget(); + // If we failed to open the camera, we never actually provided a reference + // for the application to release explicitly. Thus we must clear our handle + // here to ensure everything is freed. + mCameraControl = nullptr; break; case CameraControlListener::kInStopCamera: diff --git a/dom/indexedDB/ActorsParent.cpp b/dom/indexedDB/ActorsParent.cpp index f0aa1e3033..d138e4b526 100644 --- a/dom/indexedDB/ActorsParent.cpp +++ b/dom/indexedDB/ActorsParent.cpp @@ -2715,7 +2715,8 @@ InsertIndexDataValuesFunction::OnFunctionCall(mozIStorageValueArray* aValues, } // Update the array with the new addition. - if (NS_WARN_IF(!indexValues.SetCapacity(indexValues.Length() + 1))) { + if (NS_WARN_IF(!indexValues.SetCapacity(indexValues.Length() + 1, + fallible))) { IDB_REPORT_INTERNAL_ERR(); return NS_ERROR_OUT_OF_MEMORY; } @@ -8029,14 +8030,15 @@ ConvertBlobsToActors(PBackgroundParent* aBackgroundActor, const uint32_t count = aFiles.Length(); - if (NS_WARN_IF(!aActors.SetCapacity(count))) { + if (NS_WARN_IF(!aActors.SetCapacity(count, fallible))) { return NS_ERROR_OUT_OF_MEMORY; } const bool collectFileInfos = !BackgroundParent::IsOtherProcessActor(aBackgroundActor); - if (collectFileInfos && NS_WARN_IF(!aFileInfos.SetCapacity(count))) { + if (collectFileInfos && + NS_WARN_IF(!aFileInfos.SetCapacity(count, fallible))) { return NS_ERROR_OUT_OF_MEMORY; } @@ -11294,7 +11296,7 @@ Database::Invalidate() } FallibleTArray> transactions; - if (NS_WARN_IF(!transactions.SetCapacity(count))) { + if (NS_WARN_IF(!transactions.SetCapacity(count, fallible))) { return false; } @@ -11646,7 +11648,7 @@ Database::AllocPBackgroundIDBTransactionParent( } FallibleTArray> fallibleObjectStores; - if (NS_WARN_IF(!fallibleObjectStores.SetCapacity(nameCount))) { + if (NS_WARN_IF(!fallibleObjectStores.SetCapacity(nameCount, fallible))) { return nullptr; } @@ -15627,7 +15629,7 @@ DatabaseOperationBase::IndexDataValuesFromUpdateInfos( return NS_OK; } - if (NS_WARN_IF(!aIndexValues.SetCapacity(count))) { + if (NS_WARN_IF(!aIndexValues.SetCapacity(count, fallible))) { IDB_REPORT_INTERNAL_ERR(); return NS_ERROR_OUT_OF_MEMORY; } @@ -20046,7 +20048,7 @@ UpdateIndexDataValuesFunction::OnFunctionCall(mozIStorageValueArray* aValues, const uint32_t updateInfoCount = updateInfos.Length(); if (NS_WARN_IF(!indexValues.SetCapacity(indexValues.Length() + - updateInfoCount))) { + updateInfoCount, fallible))) { IDB_REPORT_INTERNAL_ERR(); return NS_ERROR_OUT_OF_MEMORY; } @@ -20801,7 +20803,7 @@ ObjectStoreAddOrPutRequestOp::Init(TransactionBase* aTransaction) if (!files.IsEmpty()) { const uint32_t count = files.Length(); - if (NS_WARN_IF(!mStoredFileInfos.SetCapacity(count))) { + if (NS_WARN_IF(!mStoredFileInfos.SetCapacity(count, fallible))) { return false; } diff --git a/dom/indexedDB/IDBObjectStore.cpp b/dom/indexedDB/IDBObjectStore.cpp index e61b22f23b..3edb19be2f 100644 --- a/dom/indexedDB/IDBObjectStore.cpp +++ b/dom/indexedDB/IDBObjectStore.cpp @@ -1221,7 +1221,7 @@ IDBObjectStore::AddOrPut(JSContext* aCx, const uint32_t count = blobOrFileInfos.Length(); FallibleTArray fileActorOrMutableFileIds; - if (NS_WARN_IF(!fileActorOrMutableFileIds.SetCapacity(count))) { + if (NS_WARN_IF(!fileActorOrMutableFileIds.SetCapacity(count, fallible))) { aRv = NS_ERROR_OUT_OF_MEMORY; return nullptr; } diff --git a/dom/mobilemessage/ipc/SmsChild.cpp b/dom/mobilemessage/ipc/SmsChild.cpp index d126edf542..c106b81d97 100644 --- a/dom/mobilemessage/ipc/SmsChild.cpp +++ b/dom/mobilemessage/ipc/SmsChild.cpp @@ -342,10 +342,10 @@ MobileMessageCursorChild::DoNotifyResult(const nsTArray& aDat MOZ_ASSERT(length); AutoFallibleTArray autoArray; - NS_ENSURE_TRUE_VOID(autoArray.SetCapacity(length)); + NS_ENSURE_TRUE_VOID(autoArray.SetCapacity(length, fallible)); AutoFallibleTArray, 1> messages; - NS_ENSURE_TRUE_VOID(messages.SetCapacity(length)); + NS_ENSURE_TRUE_VOID(messages.SetCapacity(length, fallible)); for (uint32_t i = 0; i < length; i++) { nsCOMPtr message = CreateMessageFromMessageData(aDataArray[i]); @@ -363,10 +363,10 @@ MobileMessageCursorChild::DoNotifyResult(const nsTArray& aDataArray) MOZ_ASSERT(length); AutoFallibleTArray autoArray; - NS_ENSURE_TRUE_VOID(autoArray.SetCapacity(length)); + NS_ENSURE_TRUE_VOID(autoArray.SetCapacity(length, fallible)); AutoFallibleTArray, 1> threads; - NS_ENSURE_TRUE_VOID(threads.SetCapacity(length)); + NS_ENSURE_TRUE_VOID(threads.SetCapacity(length, fallible)); for (uint32_t i = 0; i < length; i++) { nsCOMPtr thread = new MobileMessageThread(aDataArray[i]); diff --git a/dom/promise/Promise.cpp b/dom/promise/Promise.cpp index 22218aa317..e6766d8f57 100644 --- a/dom/promise/Promise.cpp +++ b/dom/promise/Promise.cpp @@ -157,7 +157,7 @@ GetPromise(JSContext* aCx, JS::Handle aFunc) } } // namespace -// Main thread runnable to resolve thenables. +// Runnable to resolve thenables. // Equivalent to the specification's ResolvePromiseViaThenableTask. class ThenableResolverTask final : public nsRunnable { @@ -188,6 +188,8 @@ protected: ThreadsafeAutoJSContext cx; JS::Rooted wrapper(cx, mPromise->GetWrapper()); MOZ_ASSERT(wrapper); // It was preserved! + // If we ever change which compartment we're working in here, make sure to + // fix the fast-path for resolved-with-a-Promise in ResolveInternal. JSAutoCompartment ac(cx, wrapper); JS::Rooted resolveFunc(cx, @@ -258,6 +260,48 @@ private: NS_DECL_OWNINGTHREAD; }; +// Fast version of ThenableResolverTask for use in the cases when we know we're +// calling the canonical Promise.prototype.then on an actual DOM Promise. In +// that case we can just bypass the jumping into and out of JS and call +// AppendCallbacks on that promise directly. +class FastThenableResolverTask final : public nsRunnable +{ +public: + FastThenableResolverTask(PromiseCallback* aResolveCallback, + PromiseCallback* aRejectCallback, + Promise* aNextPromise) + : mResolveCallback(aResolveCallback) + , mRejectCallback(aRejectCallback) + , mNextPromise(aNextPromise) + { + MOZ_ASSERT(aResolveCallback); + MOZ_ASSERT(aRejectCallback); + MOZ_ASSERT(aNextPromise); + MOZ_COUNT_CTOR(FastThenableResolverTask); + } + + virtual + ~FastThenableResolverTask() + { + NS_ASSERT_OWNINGTHREAD(FastThenableResolverTask); + MOZ_COUNT_DTOR(FastThenableResolverTask); + } + +protected: + NS_IMETHOD + Run() override + { + NS_ASSERT_OWNINGTHREAD(FastThenableResolverTask); + mNextPromise->AppendCallbacks(mResolveCallback, mRejectCallback); + return NS_OK; + } + +private: + nsRefPtr mResolveCallback; + nsRefPtr mRejectCallback; + nsRefPtr mNextPromise; +}; + // Promise NS_IMPL_CYCLE_COLLECTION_CLASS(Promise) @@ -1200,6 +1244,37 @@ Promise::ResolveInternal(JSContext* aCx, if (then.isObject() && JS::IsCallable(&then.toObject())) { // This is the then() function of the thenable aValueObj. JS::Rooted thenObj(aCx, &then.toObject()); + + // Add a fast path for the case when we're resolved with an actual + // Promise. This has two requirements: + // + // 1) valueObj is a Promise. + // 2) thenObj is a JSFunction backed by our actual Promise::Then + // implementation. + // + // If those requirements are satisfied, then we know exactly what + // thenObj.call(valueObj) will do, so we can optimize a bit and avoid ever + // entering JS for this stuff. + Promise* nextPromise; + if (PromiseBinding::IsThenMethod(thenObj) && + NS_SUCCEEDED(UNWRAP_OBJECT(Promise, valueObj, nextPromise))) { + // If we were taking the codepath that involves ThenableResolverTask and + // PromiseInit below, then eventually, in ThenableResolverTask::Run, we + // would create some JSFunctions in the compartment of + // this->GetWrapper() and pass them to the PromiseInit. So by the time + // we'd see the resolution value it would be wrapped into the + // compartment of this->GetWrapper(). The global of that compartment is + // this->GetGlobalJSObject(), so use that as the global for + // ResolvePromiseCallback/RejectPromiseCallback. + JS::Rooted glob(aCx, GlobalJSObject()); + nsRefPtr resolveCb = new ResolvePromiseCallback(this, glob); + nsRefPtr rejectCb = new RejectPromiseCallback(this, glob); + nsRefPtr task = + new FastThenableResolverTask(resolveCb, rejectCb, nextPromise); + DispatchToMicroTask(task); + return; + } + nsRefPtr thenCallback = new PromiseInit(thenObj, mozilla::dom::GetIncumbentGlobal()); nsRefPtr task = diff --git a/dom/promise/Promise.h b/dom/promise/Promise.h index 7a40b2e6ed..2aa3891c28 100644 --- a/dom/promise/Promise.h +++ b/dom/promise/Promise.h @@ -84,6 +84,7 @@ class Promise : public nsISupports, friend class RejectPromiseCallback; friend class ResolvePromiseCallback; friend class ThenableResolverTask; + friend class FastThenableResolverTask; friend class WrapperPromiseCallback; public: diff --git a/dom/promise/tests/mochitest.ini b/dom/promise/tests/mochitest.ini index 019353ba56..3b621b1e19 100644 --- a/dom/promise/tests/mochitest.ini +++ b/dom/promise/tests/mochitest.ini @@ -6,3 +6,4 @@ [test_promise_utils.html] [test_resolve.html] [test_resolver_return_value.html] +[test_thenable_vs_promise_ordering.html] diff --git a/dom/promise/tests/test_thenable_vs_promise_ordering.html b/dom/promise/tests/test_thenable_vs_promise_ordering.html new file mode 100644 index 0000000000..161e95d75b --- /dev/null +++ b/dom/promise/tests/test_thenable_vs_promise_ordering.html @@ -0,0 +1,27 @@ + + +Test for promise resolution ordering with thenables and promises + + +
+ diff --git a/dom/smil/nsSMILAnimationFunction.cpp b/dom/smil/nsSMILAnimationFunction.cpp index 19dce397df..03acf2ac13 100644 --- a/dom/smil/nsSMILAnimationFunction.cpp +++ b/dom/smil/nsSMILAnimationFunction.cpp @@ -780,10 +780,10 @@ nsSMILAnimationFunction::GetValues(const nsISMILAttr& aSMILAttr, mValueNeedsReparsingEverySample = true; } - if (!parseOk) + if (!parseOk || !result.SetCapacity(2, mozilla::fallible)) { return NS_ERROR_FAILURE; + } - result.SetCapacity(2); if (!to.IsNull()) { if (!from.IsNull()) { result.AppendElement(from); diff --git a/dom/svg/DOMSVGLengthList.cpp b/dom/svg/DOMSVGLengthList.cpp index 0fdcdd78f9..52f83e7dca 100644 --- a/dom/svg/DOMSVGLengthList.cpp +++ b/dom/svg/DOMSVGLengthList.cpp @@ -255,7 +255,7 @@ DOMSVGLengthList::InsertItemBefore(DOMSVGLength& newItem, } // Ensure we have enough memory so we can avoid complex error handling below: - if (!mItems.SetCapacity(mItems.Length() + 1) || + if (!mItems.SetCapacity(mItems.Length() + 1, fallible) || !InternalList().SetCapacity(InternalList().Length() + 1)) { error.Throw(NS_ERROR_OUT_OF_MEMORY); return nullptr; diff --git a/dom/svg/DOMSVGNumberList.cpp b/dom/svg/DOMSVGNumberList.cpp index 0913ab3303..6f4460f8f7 100644 --- a/dom/svg/DOMSVGNumberList.cpp +++ b/dom/svg/DOMSVGNumberList.cpp @@ -239,7 +239,7 @@ DOMSVGNumberList::InsertItemBefore(DOMSVGNumber& aItem, nsRefPtr domItem = aItem.HasOwner() ? aItem.Clone() : &aItem; // Ensure we have enough memory so we can avoid complex error handling below: - if (!mItems.SetCapacity(mItems.Length() + 1) || + if (!mItems.SetCapacity(mItems.Length() + 1, fallible) || !InternalList().SetCapacity(InternalList().Length() + 1)) { error.Throw(NS_ERROR_OUT_OF_MEMORY); return nullptr; diff --git a/dom/svg/DOMSVGPathSegList.cpp b/dom/svg/DOMSVGPathSegList.cpp index 438550f606..b1300e4d31 100644 --- a/dom/svg/DOMSVGPathSegList.cpp +++ b/dom/svg/DOMSVGPathSegList.cpp @@ -369,8 +369,9 @@ DOMSVGPathSegList::InsertItemBefore(DOMSVGPathSeg& aNewItem, uint32_t argCount = SVGPathSegUtils::ArgCountForType(domItem->Type()); // Ensure we have enough memory so we can avoid complex error handling below: - if (!mItems.SetCapacity(mItems.Length() + 1) || - !InternalList().mData.SetCapacity(InternalList().mData.Length() + 1 + argCount)) { + if (!mItems.SetCapacity(mItems.Length() + 1, fallible) || + !InternalList().mData.SetCapacity(InternalList().mData.Length() + 1 + argCount, + fallible)) { aError.Throw(NS_ERROR_OUT_OF_MEMORY); return nullptr; } diff --git a/dom/svg/DOMSVGPointList.cpp b/dom/svg/DOMSVGPointList.cpp index 2f90b62144..a80b5fde12 100644 --- a/dom/svg/DOMSVGPointList.cpp +++ b/dom/svg/DOMSVGPointList.cpp @@ -306,7 +306,7 @@ DOMSVGPointList::InsertItemBefore(nsISVGPoint& aNewItem, uint32_t aIndex, } // Ensure we have enough memory so we can avoid complex error handling below: - if (!mItems.SetCapacity(mItems.Length() + 1) || + if (!mItems.SetCapacity(mItems.Length() + 1, fallible) || !InternalList().SetCapacity(InternalList().Length() + 1)) { aError.Throw(NS_ERROR_OUT_OF_MEMORY); return nullptr; diff --git a/dom/svg/DOMSVGTransformList.cpp b/dom/svg/DOMSVGTransformList.cpp index ea87c1822d..ff88ead19b 100644 --- a/dom/svg/DOMSVGTransformList.cpp +++ b/dom/svg/DOMSVGTransformList.cpp @@ -247,7 +247,7 @@ DOMSVGTransformList::InsertItemBefore(SVGTransform& newItem, } // Ensure we have enough memory so we can avoid complex error handling below: - if (!mItems.SetCapacity(mItems.Length() + 1) || + if (!mItems.SetCapacity(mItems.Length() + 1, fallible) || !InternalList().SetCapacity(InternalList().Length() + 1)) { error.Throw(NS_ERROR_OUT_OF_MEMORY); return nullptr; diff --git a/dom/svg/SVGLengthList.cpp b/dom/svg/SVGLengthList.cpp index 72dc851f56..b44de345ff 100644 --- a/dom/svg/SVGLengthList.cpp +++ b/dom/svg/SVGLengthList.cpp @@ -18,7 +18,7 @@ namespace mozilla { nsresult SVGLengthList::CopyFrom(const SVGLengthList& rhs) { - if (!mLengths.SetCapacity(rhs.Length())) { + if (!mLengths.SetCapacity(rhs.Length(), fallible)) { // Yes, we do want fallible alloc here return NS_ERROR_OUT_OF_MEMORY; } diff --git a/dom/svg/SVGLengthList.h b/dom/svg/SVGLengthList.h index b5196423d9..41951eda84 100644 --- a/dom/svg/SVGLengthList.h +++ b/dom/svg/SVGLengthList.h @@ -59,7 +59,7 @@ public: bool operator==(const SVGLengthList& rhs) const; bool SetCapacity(uint32_t size) { - return mLengths.SetCapacity(size); + return mLengths.SetCapacity(size, fallible); } void Compact() { diff --git a/dom/svg/SVGMotionSMILType.cpp b/dom/svg/SVGMotionSMILType.cpp index d5b340f7b7..a5d556c531 100644 --- a/dom/svg/SVGMotionSMILType.cpp +++ b/dom/svg/SVGMotionSMILType.cpp @@ -197,7 +197,7 @@ SVGMotionSMILType::Assign(nsSMILValue& aDest, const nsSMILValue& aSrc) const MotionSegmentArray& dstArr = ExtractMotionSegmentArray(aDest); // Ensure we have sufficient memory. - if (!dstArr.SetCapacity(srcArr.Length())) { + if (!dstArr.SetCapacity(srcArr.Length(), fallible)) { return NS_ERROR_OUT_OF_MEMORY; } diff --git a/dom/svg/SVGNumberList.cpp b/dom/svg/SVGNumberList.cpp index dec44187da..c32f4a3b31 100644 --- a/dom/svg/SVGNumberList.cpp +++ b/dom/svg/SVGNumberList.cpp @@ -17,7 +17,7 @@ namespace mozilla { nsresult SVGNumberList::CopyFrom(const SVGNumberList& rhs) { - if (!mNumbers.SetCapacity(rhs.Length())) { + if (!mNumbers.SetCapacity(rhs.Length(), fallible)) { // Yes, we do want fallible alloc here return NS_ERROR_OUT_OF_MEMORY; } diff --git a/dom/svg/SVGNumberList.h b/dom/svg/SVGNumberList.h index 99ee34997d..43726e339e 100644 --- a/dom/svg/SVGNumberList.h +++ b/dom/svg/SVGNumberList.h @@ -60,7 +60,7 @@ public: } bool SetCapacity(uint32_t size) { - return mNumbers.SetCapacity(size); + return mNumbers.SetCapacity(size, fallible); } void Compact() { diff --git a/dom/svg/SVGPathData.cpp b/dom/svg/SVGPathData.cpp index 599f710453..146d916a91 100644 --- a/dom/svg/SVGPathData.cpp +++ b/dom/svg/SVGPathData.cpp @@ -34,7 +34,7 @@ static bool IsMoveto(uint16_t aSegType) nsresult SVGPathData::CopyFrom(const SVGPathData& rhs) { - if (!mData.SetCapacity(rhs.mData.Length())) { + if (!mData.SetCapacity(rhs.mData.Length(), fallible)) { // Yes, we do want fallible alloc here return NS_ERROR_OUT_OF_MEMORY; } diff --git a/dom/svg/SVGPathData.h b/dom/svg/SVGPathData.h index 5fd504cd61..60dffc2533 100644 --- a/dom/svg/SVGPathData.h +++ b/dom/svg/SVGPathData.h @@ -135,7 +135,7 @@ public: } bool SetCapacity(uint32_t aSize) { - return mData.SetCapacity(aSize); + return mData.SetCapacity(aSize, fallible); } void Compact() { diff --git a/dom/svg/SVGPointList.h b/dom/svg/SVGPointList.h index 54844ce97d..8d94f80763 100644 --- a/dom/svg/SVGPointList.h +++ b/dom/svg/SVGPointList.h @@ -68,7 +68,7 @@ public: } bool SetCapacity(uint32_t aSize) { - return mItems.SetCapacity(aSize); + return mItems.SetCapacity(aSize, fallible); } void Compact() { diff --git a/dom/svg/SVGStringList.cpp b/dom/svg/SVGStringList.cpp index 8d3f2a0bf3..0184bc1f7e 100644 --- a/dom/svg/SVGStringList.cpp +++ b/dom/svg/SVGStringList.cpp @@ -16,7 +16,7 @@ namespace mozilla { nsresult SVGStringList::CopyFrom(const SVGStringList& rhs) { - if (!mStrings.SetCapacity(rhs.Length())) { + if (!mStrings.SetCapacity(rhs.Length(), fallible)) { // Yes, we do want fallible alloc here return NS_ERROR_OUT_OF_MEMORY; } diff --git a/dom/svg/SVGStringList.h b/dom/svg/SVGStringList.h index e1b346fdb6..6a2f9c8fc0 100644 --- a/dom/svg/SVGStringList.h +++ b/dom/svg/SVGStringList.h @@ -56,7 +56,7 @@ public: } bool SetCapacity(uint32_t size) { - return mStrings.SetCapacity(size); + return mStrings.SetCapacity(size, fallible); } void Compact() { diff --git a/dom/svg/SVGTransformList.cpp b/dom/svg/SVGTransformList.cpp index eea7e5c823..d37e79ce22 100644 --- a/dom/svg/SVGTransformList.cpp +++ b/dom/svg/SVGTransformList.cpp @@ -43,7 +43,7 @@ SVGTransformList::CopyFrom(const SVGTransformList& rhs) nsresult SVGTransformList::CopyFrom(const nsTArray& aTransformArray) { - if (!mItems.SetCapacity(aTransformArray.Length())) { + if (!mItems.SetCapacity(aTransformArray.Length(), fallible)) { // Yes, we do want fallible alloc here return NS_ERROR_OUT_OF_MEMORY; } diff --git a/dom/svg/SVGTransformList.h b/dom/svg/SVGTransformList.h index e757c3ea9b..334fa3dbba 100644 --- a/dom/svg/SVGTransformList.h +++ b/dom/svg/SVGTransformList.h @@ -60,7 +60,7 @@ public: } bool SetCapacity(uint32_t size) { - return mItems.SetCapacity(size); + return mItems.SetCapacity(size, fallible); } void Compact() { diff --git a/dom/svg/SVGTransformListSMILType.cpp b/dom/svg/SVGTransformListSMILType.cpp index 960ebb5ed0..0aaab80be3 100644 --- a/dom/svg/SVGTransformListSMILType.cpp +++ b/dom/svg/SVGTransformListSMILType.cpp @@ -50,7 +50,7 @@ SVGTransformListSMILType::Assign(nsSMILValue& aDest, TransformArray* dstTransforms = static_cast(aDest.mU.mPtr); // Before we assign, ensure we have sufficient memory - bool result = dstTransforms->SetCapacity(srcTransforms->Length()); + bool result = dstTransforms->SetCapacity(srcTransforms->Length(), fallible); NS_ENSURE_TRUE(result,NS_ERROR_OUT_OF_MEMORY); *dstTransforms = *srcTransforms; @@ -336,7 +336,7 @@ SVGTransformListSMILType::AppendTransforms(const SVGTransformList& aList, TransformArray& transforms = *static_cast(aValue.mU.mPtr); - if (!transforms.SetCapacity(transforms.Length() + aList.Length())) + if (!transforms.SetCapacity(transforms.Length() + aList.Length(), fallible)) return false; for (uint32_t i = 0; i < aList.Length(); ++i) { @@ -358,7 +358,7 @@ SVGTransformListSMILType::GetTransforms(const nsSMILValue& aValue, *static_cast(aValue.mU.mPtr); aTransforms.Clear(); - if (!aTransforms.SetCapacity(smilTransforms.Length())) + if (!aTransforms.SetCapacity(smilTransforms.Length(), fallible)) return false; for (uint32_t i = 0; i < smilTransforms.Length(); ++i) { diff --git a/dom/webidl/Promise.webidl b/dom/webidl/Promise.webidl index 1f22f58e20..a98bca780c 100644 --- a/dom/webidl/Promise.webidl +++ b/dom/webidl/Promise.webidl @@ -34,7 +34,7 @@ interface _Promise { // The [TreatNonCallableAsNull] annotation is required since then() should do // nothing instead of throwing errors when non-callable arguments are passed. - [NewObject] + [NewObject, MethodIdentityTestable] Promise then([TreatNonCallableAsNull] optional AnyCallback? fulfillCallback = null, [TreatNonCallableAsNull] optional AnyCallback? rejectCallback = null); diff --git a/gfx/layers/Layers.cpp b/gfx/layers/Layers.cpp index 442aead112..76eb5af87c 100644 --- a/gfx/layers/Layers.cpp +++ b/gfx/layers/Layers.cpp @@ -208,6 +208,7 @@ Layer::Layer(LayerManager* aManager, void* aImplData) : mStickyPositionData(nullptr), mScrollbarTargetId(FrameMetrics::NULL_SCROLL_ID), mScrollbarDirection(ScrollDirection::NONE), + mScrollbarThumbRatio(0.0f), mIsScrollbarContainer(false), mDebugColorIndex(0), mAnimationGeneration(0) diff --git a/gfx/layers/Layers.h b/gfx/layers/Layers.h index 0d5816ac9c..3dfa7019ff 100644 --- a/gfx/layers/Layers.h +++ b/gfx/layers/Layers.h @@ -1195,13 +1195,16 @@ public: * If a layer is a scrollbar layer, |aScrollId| holds the scroll identifier * of the scrollable content that the scrollbar is for. */ - void SetScrollbarData(FrameMetrics::ViewID aScrollId, ScrollDirection aDir) + void SetScrollbarData(FrameMetrics::ViewID aScrollId, ScrollDirection aDir, float aThumbRatio) { if (mScrollbarTargetId != aScrollId || - mScrollbarDirection != aDir) { + mScrollbarDirection != aDir || + mScrollbarThumbRatio != aThumbRatio) + { MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) ScrollbarData", this)); mScrollbarTargetId = aScrollId; mScrollbarDirection = aDir; + mScrollbarThumbRatio = aThumbRatio; Mutated(); } } @@ -1249,6 +1252,7 @@ public: const LayerRect& GetStickyScrollRangeInner() { return mStickyPositionData->mInner; } FrameMetrics::ViewID GetScrollbarTargetContainerId() { return mScrollbarTargetId; } ScrollDirection GetScrollbarDirection() { return mScrollbarDirection; } + float GetScrollbarThumbRatio() { return mScrollbarThumbRatio; } bool IsScrollbarContainer() { return mIsScrollbarContainer; } Layer* GetMaskLayer() const { return mMaskLayer; } @@ -1707,6 +1711,8 @@ protected: nsAutoPtr mStickyPositionData; FrameMetrics::ViewID mScrollbarTargetId; ScrollDirection mScrollbarDirection; + float mScrollbarThumbRatio; // Ratio of the thumb position to the scroll + // position, in app units. bool mIsScrollbarContainer; DebugOnly mDebugColorIndex; // If this layer is used for OMTA, then this counter is used to ensure we diff --git a/gfx/layers/composite/AsyncCompositionManager.cpp b/gfx/layers/composite/AsyncCompositionManager.cpp index 2254acf5eb..c52aefee45 100644 --- a/gfx/layers/composite/AsyncCompositionManager.cpp +++ b/gfx/layers/composite/AsyncCompositionManager.cpp @@ -727,13 +727,8 @@ ApplyAsyncTransformToScrollbarForContent(Layer* aScrollbar, const CSSCoord compositedHeight = (metrics.mCompositionBounds / effectiveZoom).height; const CSSCoord scrollableHeight = metrics.GetScrollableRect().height; - // The scroll thumb needs to be translated in opposite direction of the - // async scroll. This is because scrolling down, which translates the layer - // content up, should result in moving the scroll thumb down. - // The amount of the translation should be such that the ratio of the - // translation to the size of the scroll port is the same as the ratio of - // the scroll amount of the size of the scrollable rect. - const float ratio = compositedHeight / scrollableHeight; + // The scrollbar thumb ratio is in AppUnits. + const float ratio = aScrollbar->GetScrollbarThumbRatio(); ParentLayerCoord yTranslation = -asyncScrollY * ratio; // The scroll thumb additionally needs to be translated to compensate for @@ -779,7 +774,8 @@ ApplyAsyncTransformToScrollbarForContent(Layer* aScrollbar, const CSSCoord compositedWidth = (metrics.mCompositionBounds / effectiveZoom).width; const CSSCoord scrollableWidth = metrics.GetScrollableRect().width; - const float ratio = compositedWidth / scrollableWidth; + // The scrollbar thumb ratio is in AppUnits. + const float ratio = aScrollbar->GetScrollbarThumbRatio(); ParentLayerCoord xTranslation = -asyncScrollX * ratio; const CSSCoord thumbOrigin = (metrics.GetScrollOffset().x / scrollableWidth) * compositedWidth; diff --git a/gfx/layers/ipc/LayerTransactionParent.cpp b/gfx/layers/ipc/LayerTransactionParent.cpp index 1e47f0a6ea..8433c4366a 100644 --- a/gfx/layers/ipc/LayerTransactionParent.cpp +++ b/gfx/layers/ipc/LayerTransactionParent.cpp @@ -339,7 +339,8 @@ LayerTransactionParent::RecvUpdate(InfallibleTArray&& cset, common.stickyScrollRangeInner()); } layer->SetScrollbarData(common.scrollbarTargetContainerId(), - static_cast(common.scrollbarDirection())); + static_cast(common.scrollbarDirection()), + common.scrollbarThumbRatio()); layer->SetMixBlendMode((gfx::CompositionOp)common.mixBlendMode()); layer->SetForceIsolatedGroup(common.forceIsolatedGroup()); if (PLayerParent* maskLayer = common.maskLayerParent()) { diff --git a/gfx/layers/ipc/LayersMessages.ipdlh b/gfx/layers/ipc/LayersMessages.ipdlh index 83d916ab67..f226ecff01 100644 --- a/gfx/layers/ipc/LayersMessages.ipdlh +++ b/gfx/layers/ipc/LayersMessages.ipdlh @@ -215,6 +215,7 @@ struct CommonLayerAttributes { LayerRect stickyScrollRangeInner; uint64_t scrollbarTargetContainerId; uint32_t scrollbarDirection; + float scrollbarThumbRatio; int8_t mixBlendMode; bool forceIsolatedGroup; nullable PLayer maskLayer; diff --git a/gfx/layers/ipc/ShadowLayers.cpp b/gfx/layers/ipc/ShadowLayers.cpp index 974ebb364e..8a807a80f6 100644 --- a/gfx/layers/ipc/ShadowLayers.cpp +++ b/gfx/layers/ipc/ShadowLayers.cpp @@ -619,6 +619,7 @@ ShadowLayerForwarder::EndTransaction(InfallibleTArray* aReplies, } common.scrollbarTargetContainerId() = mutant->GetScrollbarTargetContainerId(); common.scrollbarDirection() = mutant->GetScrollbarDirection(); + common.scrollbarThumbRatio() = mutant->GetScrollbarThumbRatio(); common.mixBlendMode() = (int8_t)mutant->GetMixBlendMode(); common.forceIsolatedGroup() = mutant->GetForceIsolatedGroup(); if (Layer* maskLayer = mutant->GetMaskLayer()) { diff --git a/intl/uconv/nsConverterInputStream.cpp b/intl/uconv/nsConverterInputStream.cpp index daeda3cc0b..11d0142c04 100644 --- a/intl/uconv/nsConverterInputStream.cpp +++ b/intl/uconv/nsConverterInputStream.cpp @@ -45,8 +45,8 @@ nsConverterInputStream::Init(nsIInputStream* aStream, mConverter = EncodingUtils::DecoderForEncoding(encoding); // set up our buffers - if (!mByteData.SetCapacity(aBufferSize) || - !mUnicharData.SetCapacity(aBufferSize)) { + if (!mByteData.SetCapacity(aBufferSize, mozilla::fallible) || + !mUnicharData.SetCapacity(aBufferSize, mozilla::fallible)) { return NS_ERROR_OUT_OF_MEMORY; } diff --git a/ipc/glue/IPCMessageUtils.h b/ipc/glue/IPCMessageUtils.h index 7e59e9771a..bef52daaf8 100644 --- a/ipc/glue/IPCMessageUtils.h +++ b/ipc/glue/IPCMessageUtils.h @@ -520,7 +520,7 @@ struct ParamTraits > memcpy(elements, outdata, pickledLength); } else { - if (!aResult->SetCapacity(length)) { + if (!aResult->SetCapacity(length, mozilla::fallible)) { return false; } diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index 7eb21ee689..eb285993e9 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -1229,7 +1229,7 @@ nsDisplayListBuilder::IsAnimatedGeometryRoot(nsIFrame* aFrame, nsIFrame** aParen return true; } - if (parentType == nsGkAtoms::scrollFrame) { + if (parentType == nsGkAtoms::scrollFrame || parentType == nsGkAtoms::listControlFrame) { nsIScrollableFrame* sf = do_QueryFrame(parent); if (sf->IsScrollingActive(this) && sf->GetScrolledFrame() == aFrame) { return true; @@ -1702,7 +1702,11 @@ already_AddRefed nsDisplayList::PaintRoot(nsDisplayListBuilder* aB } else if (!gfxPrefs::LayoutUseContainersForRootFrames()) { // If there is no root scroll frame, and we're using containerless // scrolling, pick the document element instead. + // On Android we want the root xul document to get a null scroll id + // so that the root content document gets the first non-null scroll id. +#ifndef MOZ_WIDGET_ANDROID content = document->GetDocumentElement(); +#endif } root->SetFrameMetrics( @@ -3402,6 +3406,26 @@ nsDisplayBorder::CalculateBounds(const nsStyleBorder& aStyleBorder) result.UnionRect(result, nsRect(borderBounds.X(), borderBounds.Y(), border.left, borderBounds.Height())); } + nscoord radii[8]; + if (mFrame->GetBorderRadii(radii)) { + if (border.left > 0 || border.top > 0) { + nsSize cornerSize(radii[NS_CORNER_TOP_LEFT_X], radii[NS_CORNER_TOP_LEFT_Y]); + result.UnionRect(result, nsRect(borderBounds.TopLeft(), cornerSize)); + } + if (border.top > 0 || border.right > 0) { + nsSize cornerSize(radii[NS_CORNER_TOP_RIGHT_X], radii[NS_CORNER_TOP_RIGHT_Y]); + result.UnionRect(result, nsRect(borderBounds.TopRight() - nsPoint(cornerSize.width, 0), cornerSize)); + } + if (border.right > 0 || border.bottom > 0) { + nsSize cornerSize(radii[NS_CORNER_BOTTOM_RIGHT_X], radii[NS_CORNER_BOTTOM_RIGHT_Y]); + result.UnionRect(result, nsRect(borderBounds.BottomRight() - nsPoint(cornerSize.width, cornerSize.height), cornerSize)); + } + if (border.bottom > 0 || border.left > 0) { + nsSize cornerSize(radii[NS_CORNER_BOTTOM_LEFT_X], radii[NS_CORNER_BOTTOM_LEFT_Y]); + result.UnionRect(result, nsRect(borderBounds.BottomLeft() - nsPoint(0, cornerSize.height), cornerSize)); + } + } + return result; } } @@ -4162,10 +4186,13 @@ bool nsDisplayBlendContainer::TryMerge(nsDisplayListBuilder* aBuilder, nsDisplay nsDisplayOwnLayer::nsDisplayOwnLayer(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, nsDisplayList* aList, - uint32_t aFlags, ViewID aScrollTarget) + uint32_t aFlags, ViewID aScrollTarget, + float aScrollbarThumbRatio) : nsDisplayWrapList(aBuilder, aFrame, aList) , mFlags(aFlags) - , mScrollTarget(aScrollTarget) { + , mScrollTarget(aScrollTarget) + , mScrollbarThumbRatio(aScrollbarThumbRatio) +{ MOZ_COUNT_CTOR(nsDisplayOwnLayer); } @@ -4179,16 +4206,17 @@ nsDisplayOwnLayer::~nsDisplayOwnLayer() { already_AddRefed nsDisplayOwnLayer::BuildLayer(nsDisplayListBuilder* aBuilder, LayerManager* aManager, - const ContainerLayerParameters& aContainerParameters) { + const ContainerLayerParameters& aContainerParameters) +{ nsRefPtr layer = aManager->GetLayerBuilder()-> BuildContainerLayerFor(aBuilder, aManager, mFrame, this, &mList, aContainerParameters, nullptr, FrameLayerBuilder::CONTAINER_ALLOW_PULL_BACKGROUND_COLOR); if (mFlags & VERTICAL_SCROLLBAR) { - layer->SetScrollbarData(mScrollTarget, Layer::ScrollDirection::VERTICAL); + layer->SetScrollbarData(mScrollTarget, Layer::ScrollDirection::VERTICAL, mScrollbarThumbRatio); } if (mFlags & HORIZONTAL_SCROLLBAR) { - layer->SetScrollbarData(mScrollTarget, Layer::ScrollDirection::HORIZONTAL); + layer->SetScrollbarData(mScrollTarget, Layer::ScrollDirection::HORIZONTAL, mScrollbarThumbRatio); } if (mFlags & SCROLLBAR_CONTAINER) { layer->SetIsScrollbarContainer(); diff --git a/layout/base/nsDisplayList.h b/layout/base/nsDisplayList.h index 25a18d587e..4eb8661e37 100644 --- a/layout/base/nsDisplayList.h +++ b/layout/base/nsDisplayList.h @@ -3059,7 +3059,8 @@ public: */ nsDisplayOwnLayer(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, nsDisplayList* aList, uint32_t aFlags = 0, - ViewID aScrollTarget = mozilla::layers::FrameMetrics::NULL_SCROLL_ID); + ViewID aScrollTarget = mozilla::layers::FrameMetrics::NULL_SCROLL_ID, + float aScrollbarThumbRatio = 0.0f); #ifdef NS_BUILD_REFCNT_LOGGING virtual ~nsDisplayOwnLayer(); #endif @@ -3086,6 +3087,7 @@ public: protected: uint32_t mFlags; ViewID mScrollTarget; + float mScrollbarThumbRatio; }; /** diff --git a/layout/reftests/bugs/1150021-1-ref.css b/layout/reftests/bugs/1150021-1-ref.css new file mode 100644 index 0000000000..9c5fb95d6b --- /dev/null +++ b/layout/reftests/bugs/1150021-1-ref.css @@ -0,0 +1,9 @@ +.wide { background: red; width: 800px; height: 30px; display: inline-block;} + +#container { + background-color: yellow; +} + +#rightBox { + margin-left: 1000px; +} diff --git a/layout/reftests/bugs/1150021-1-ref.xul b/layout/reftests/bugs/1150021-1-ref.xul new file mode 100644 index 0000000000..d1e9cacf44 --- /dev/null +++ b/layout/reftests/bugs/1150021-1-ref.xul @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + diff --git a/layout/reftests/bugs/1150021-1.css b/layout/reftests/bugs/1150021-1.css new file mode 100644 index 0000000000..239bf6cabc --- /dev/null +++ b/layout/reftests/bugs/1150021-1.css @@ -0,0 +1,10 @@ +window { direction: rtl; } +.wide { background: red; width: 800px; height: 30px; display: inline-block;} + +#container { + background-color: yellow; +} + +#rightBox { + margin-left: 1000px; +} diff --git a/layout/reftests/bugs/1150021-1.xul b/layout/reftests/bugs/1150021-1.xul new file mode 100644 index 0000000000..9f8d375020 --- /dev/null +++ b/layout/reftests/bugs/1150021-1.xul @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + diff --git a/layout/reftests/bugs/1151145-1-ref.html b/layout/reftests/bugs/1151145-1-ref.html new file mode 100644 index 0000000000..239b416d55 --- /dev/null +++ b/layout/reftests/bugs/1151145-1-ref.html @@ -0,0 +1,10 @@ + + +Reference for test for bug 1151145 + +
+ +
+ +
+ diff --git a/layout/reftests/bugs/1151145-1.html b/layout/reftests/bugs/1151145-1.html new file mode 100644 index 0000000000..a5f0617019 --- /dev/null +++ b/layout/reftests/bugs/1151145-1.html @@ -0,0 +1,21 @@ + + +Test for bug 1151145 + +
+ +
+ +
+ + diff --git a/layout/reftests/bugs/1151306-1-ref.html b/layout/reftests/bugs/1151306-1-ref.html new file mode 100644 index 0000000000..06889060c8 --- /dev/null +++ b/layout/reftests/bugs/1151306-1-ref.html @@ -0,0 +1,30 @@ + + + +The div should have a white filling. + + + +
diff --git a/layout/reftests/bugs/1151306-1.html b/layout/reftests/bugs/1151306-1.html new file mode 100644 index 0000000000..c23fc9ce30 --- /dev/null +++ b/layout/reftests/bugs/1151306-1.html @@ -0,0 +1,41 @@ + + + +The div shouldn't pull the html element's background color through the body background. There should be no red on this page. + + + +
diff --git a/layout/reftests/bugs/1156129-1-ref.html b/layout/reftests/bugs/1156129-1-ref.html new file mode 100644 index 0000000000..461fea3538 --- /dev/null +++ b/layout/reftests/bugs/1156129-1-ref.html @@ -0,0 +1,36 @@ + + + +The bounds calculation for border display items needs to take the border radius into account + + + +
+
+
diff --git a/layout/reftests/bugs/1156129-1.html b/layout/reftests/bugs/1156129-1.html new file mode 100644 index 0000000000..58f82fe4f5 --- /dev/null +++ b/layout/reftests/bugs/1156129-1.html @@ -0,0 +1,44 @@ + + + +The bounds calculation for border display items needs to take the border radius into account + + + +
+
+
+ + diff --git a/layout/reftests/bugs/reftest.list b/layout/reftests/bugs/reftest.list index 737589213b..8ef67975f4 100644 --- a/layout/reftests/bugs/reftest.list +++ b/layout/reftests/bugs/reftest.list @@ -1872,4 +1872,7 @@ fuzzy-if(d2d,36,304) HTTP(..) == 1116480-1-fakeitalic-overflow.html 1116480-1-fa == 1128354-1.html 1128354-1-ref.html == 1130231-1-button-padding-rtl.html 1130231-1-button-padding-rtl-ref.html == 1130231-2-button-padding-rtl.html 1130231-2-button-padding-rtl-ref.html -pref(dom.use_xbl_scopes_for_remote_xul,true) HTTP(..) == 1157127-1.html 1157127-1-ref.html +skip-if(B2G||Mulet) == 1150021-1.xul 1150021-1-ref.xul +== 1151145-1.html 1151145-1-ref.html +== 1151306-1.html 1151306-1-ref.html +== 1156129-1.html 1156129-1-ref.html diff --git a/layout/xul/nsBoxFrame.cpp b/layout/xul/nsBoxFrame.cpp index 278758dab3..c9e66e6227 100644 --- a/layout/xul/nsBoxFrame.cpp +++ b/layout/xul/nsBoxFrame.cpp @@ -66,6 +66,7 @@ #include "mozilla/Preferences.h" #include "nsThemeConstants.h" #include "nsLayoutUtils.h" +#include "nsSliderFrame.h" #include // Needed for Print Preview @@ -1312,6 +1313,7 @@ nsBoxFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, uint32_t flags = 0; mozilla::layers::FrameMetrics::ViewID scrollTargetId = mozilla::layers::FrameMetrics::NULL_SCROLL_ID; + float scrollbarThumbRatio = 0.0f; if (GetContent()->IsXULElement()) { // forcelayer is only supported on XUL elements with box layout @@ -1323,6 +1325,9 @@ nsBoxFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, aBuilder->GetScrollbarInfo(&scrollTargetId, &flags); forceLayer = (scrollTargetId != layers::FrameMetrics::NULL_SCROLL_ID); nsLayoutUtils::SetScrollbarThumbLayerization(this, forceLayer); + + nsSliderFrame* slider = do_QueryFrame(parent); + scrollbarThumbRatio = slider->GetThumbRatio(); } } // Check for frames that are marked as a part of the region used @@ -1369,7 +1374,8 @@ nsBoxFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, // Wrap the list to make it its own layer aLists.Content()->AppendNewToTop(new (aBuilder) - nsDisplayOwnLayer(aBuilder, this, &masterList, flags, scrollTargetId)); + nsDisplayOwnLayer(aBuilder, this, &masterList, flags, scrollTargetId, + scrollbarThumbRatio)); } } diff --git a/layout/xul/nsSliderFrame.cpp b/layout/xul/nsSliderFrame.cpp index 2a6e67de23..3aa0171ab1 100644 --- a/layout/xul/nsSliderFrame.cpp +++ b/layout/xul/nsSliderFrame.cpp @@ -1277,5 +1277,13 @@ nsSliderFrame::PageScroll(nscoord aChange) PageUpDown(aChange); } +float +nsSliderFrame::GetThumbRatio() const +{ + // mRatio is in thumb app units per scrolled css pixels. Convert it to a + // a true unitless ratio. + return mRatio / mozilla::AppUnitsPerCSSPixel(); +} + NS_IMPL_ISUPPORTS(nsSliderMediator, nsIDOMEventListener) diff --git a/layout/xul/nsSliderFrame.h b/layout/xul/nsSliderFrame.h index df180a03be..2b2a74818f 100644 --- a/layout/xul/nsSliderFrame.h +++ b/layout/xul/nsSliderFrame.h @@ -131,6 +131,10 @@ public: mozilla::WidgetGUIEvent* aEvent, nsEventStatus* aEventStatus) override; + // Return the ratio the scrollbar thumb should move in proportion to the + // scrolled frame. + float GetThumbRatio() const; + private: bool GetScrollToClick(); diff --git a/layout/xul/nsSprocketLayout.cpp b/layout/xul/nsSprocketLayout.cpp index 8fd67b2ad8..e33de8cd00 100644 --- a/layout/xul/nsSprocketLayout.cpp +++ b/layout/xul/nsSprocketLayout.cpp @@ -400,7 +400,12 @@ nsSprocketLayout::Layout(nsIFrame* aBox, nsBoxLayoutState& aState) nextY += (childBoxSize->right); else nextY -= (childBoxSize->left); - childRect.x = originalClientRect.x; + if (GetFrameDirection(aBox) == NS_STYLE_DIRECTION_LTR) { + childRect.x = originalClientRect.x; + } else { + // keep the right edge of the box the same + childRect.x = clientRect.x + originalClientRect.width - childRect.width; + } } // If we encounter a completely bogus box size, we just leave this child completely @@ -532,6 +537,13 @@ nsSprocketLayout::Layout(nsIFrame* aBox, nsBoxLayoutState& aState) newChildRect.y = childRect.YMost() - newChildRect.height; } + if (!(frameState & NS_STATE_IS_HORIZONTAL)) { + if (GetFrameDirection(aBox) != NS_STYLE_DIRECTION_LTR) { + // keep the right edge the same + newChildRect.x = childRect.XMost() - newChildRect.width; + } + } + // If the child resized then recompute its position. ComputeChildsNextPosition(aBox, x, y, nextX, nextY, newChildRect); diff --git a/netwerk/base/Dashboard.cpp b/netwerk/base/Dashboard.cpp index d07fa6ce5b..d1438c564d 100644 --- a/netwerk/base/Dashboard.cpp +++ b/netwerk/base/Dashboard.cpp @@ -387,7 +387,7 @@ Dashboard::GetSockets(SocketData *aSocketData) Sequence &sockets = dict.mSockets.Value(); uint32_t length = socketData->mData.Length(); - if (!sockets.SetCapacity(length)) { + if (!sockets.SetCapacity(length, fallible)) { JS_ReportOutOfMemory(cx); return NS_ERROR_OUT_OF_MEMORY; } @@ -457,7 +457,7 @@ Dashboard::GetHttpConnections(HttpData *aHttpData) Sequence &connections = dict.mConnections.Value(); uint32_t length = httpData->mData.Length(); - if (!connections.SetCapacity(length)) { + if (!connections.SetCapacity(length, fallible)) { JS_ReportOutOfMemory(cx); return NS_ERROR_OUT_OF_MEMORY; } @@ -478,9 +478,10 @@ Dashboard::GetHttpConnections(HttpData *aHttpData) Sequence &idle = connection.mIdle.Value(); Sequence &halfOpens = connection.mHalfOpens.Value(); - if (!active.SetCapacity(httpData->mData[i].active.Length()) || - !idle.SetCapacity(httpData->mData[i].idle.Length()) || - !halfOpens.SetCapacity(httpData->mData[i].halfOpens.Length())) { + if (!active.SetCapacity(httpData->mData[i].active.Length(), fallible) || + !idle.SetCapacity(httpData->mData[i].idle.Length(), fallible) || + !halfOpens.SetCapacity(httpData->mData[i].halfOpens.Length(), + fallible)) { JS_ReportOutOfMemory(cx); return NS_ERROR_OUT_OF_MEMORY; } @@ -619,7 +620,7 @@ Dashboard::GetWebSocketConnections(WebSocketRequest *aWsRequest) mozilla::MutexAutoLock lock(mWs.lock); uint32_t length = mWs.data.Length(); - if (!websockets.SetCapacity(length)) { + if (!websockets.SetCapacity(length, fallible)) { JS_ReportOutOfMemory(cx); return NS_ERROR_OUT_OF_MEMORY; } @@ -692,7 +693,7 @@ Dashboard::GetDNSCacheEntries(DnsData *dnsData) Sequence &entries = dict.mEntries.Value(); uint32_t length = dnsData->mData.Length(); - if (!entries.SetCapacity(length)) { + if (!entries.SetCapacity(length, fallible)) { JS_ReportOutOfMemory(cx); return NS_ERROR_OUT_OF_MEMORY; } @@ -702,7 +703,7 @@ Dashboard::GetDNSCacheEntries(DnsData *dnsData) entry.mHostaddr.Construct(); Sequence &addrs = entry.mHostaddr.Value(); - if (!addrs.SetCapacity(dnsData->mData[i].hostaddr.Length())) { + if (!addrs.SetCapacity(dnsData->mData[i].hostaddr.Length(), fallible)) { JS_ReportOutOfMemory(cx); return NS_ERROR_OUT_OF_MEMORY; } diff --git a/xpcom/io/nsUnicharInputStream.cpp b/xpcom/io/nsUnicharInputStream.cpp index 6ba2312896..02bfc983c0 100644 --- a/xpcom/io/nsUnicharInputStream.cpp +++ b/xpcom/io/nsUnicharInputStream.cpp @@ -162,8 +162,8 @@ UTF8InputStream::UTF8InputStream() : nsresult UTF8InputStream::Init(nsIInputStream* aStream) { - if (!mByteData.SetCapacity(STRING_BUFFER_SIZE) || - !mUnicharData.SetCapacity(STRING_BUFFER_SIZE)) { + if (!mByteData.SetCapacity(STRING_BUFFER_SIZE, mozilla::fallible) || + !mUnicharData.SetCapacity(STRING_BUFFER_SIZE, mozilla::fallible)) { return NS_ERROR_OUT_OF_MEMORY; } mInput = aStream;