diff options
Diffstat (limited to 'dom')
26 files changed, 182 insertions, 99 deletions
diff --git a/dom/base/PointerLockManager.cpp b/dom/base/PointerLockManager.cpp index 78f1d600af..4ec9d76abf 100644 --- a/dom/base/PointerLockManager.cpp +++ b/dom/base/PointerLockManager.cpp @@ -265,7 +265,7 @@ bool PointerLockManager::SetPointerLock(Element* aElement, Document* aDocument, } return false; } - nsPresContext* presContext = presShell->GetPresContext(); + RefPtr<nsPresContext> presContext = presShell->GetPresContext(); if (!presContext) { NS_WARNING("SetPointerLock(): Unable to get PresContext"); return false; @@ -288,7 +288,7 @@ bool PointerLockManager::SetPointerLock(Element* aElement, Document* aDocument, // Hide the cursor and set pointer lock for future mouse events RefPtr<EventStateManager> esm = presContext->EventStateManager(); esm->SetCursor(aCursorStyle, nullptr, {}, Nothing(), widget, true); - EventStateManager::SetPointerLock(widget, aElement); + EventStateManager::SetPointerLock(widget, presContext); return true; } diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index fd1dc60463..13a54f0214 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -10961,7 +10961,7 @@ bool nsContentUtils::IsURIInList(nsIURI* aURI, const nsCString& aList) { if (startIndexOfNextLevel <= 0) { break; } - host = "*"_ns + nsDependentCSubstring(host, startIndexOfNextLevel); + host.ReplaceLiteral(0, startIndexOfNextLevel, "*"); } } diff --git a/dom/bindings/mozwebidlcodegen/test/test_mozwebidlcodegen.py b/dom/bindings/mozwebidlcodegen/test/test_mozwebidlcodegen.py index 10129022e6..a2202f7b24 100644 --- a/dom/bindings/mozwebidlcodegen/test/test_mozwebidlcodegen.py +++ b/dom/bindings/mozwebidlcodegen/test/test_mozwebidlcodegen.py @@ -2,7 +2,6 @@ # 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/. -import imp import io import json import os @@ -12,7 +11,7 @@ import tempfile import unittest import mozpack.path as mozpath -from mozfile import NamedTemporaryFile +from mozfile import NamedTemporaryFile, load_source from mozunit import MockedOpen, main from mozwebidlcodegen import WebIDLCodegenManager, WebIDLCodegenManagerState @@ -242,7 +241,7 @@ class TestWebIDLCodegenManager(unittest.TestCase): with NamedTemporaryFile("wt") as fh: fh.write("# Original content") fh.flush() - mod = imp.load_source("mozwebidlcodegen.fakemodule", fh.name) + mod = load_source("mozwebidlcodegen.fakemodule", fh.name) mod.__file__ = fake_path args = self._get_manager_args() diff --git a/dom/canvas/CanvasUtils.cpp b/dom/canvas/CanvasUtils.cpp index 69f185cc20..9f4d66c011 100644 --- a/dom/canvas/CanvasUtils.cpp +++ b/dom/canvas/CanvasUtils.cpp @@ -110,6 +110,11 @@ bool IsImageExtractionAllowed(dom::Document* aDocument, JSContext* aCx, return true; } + // Allow chrome: and resource: (this especially includes PDF.js) + if (subjectPrincipal.SchemeIs("chrome") || subjectPrincipal.SchemeIs("resource")) { + return true; + } + // Allow extension principals. auto* principal = BasePrincipal::Cast(&subjectPrincipal); if (principal->AddonPolicy() || principal->ContentScriptAddonPolicy()) { @@ -126,13 +131,6 @@ bool IsImageExtractionAllowed(dom::Document* aDocument, JSContext* aCx, return true; } - // Don't show canvas prompt for PDF.js - JS::AutoFilename scriptFile; - if (JS::DescribeScriptedCaller(aCx, &scriptFile) && scriptFile.get() && - strcmp(scriptFile.get(), "resource://pdf.js/build/pdf.js") == 0) { - return true; - } - // ------------------------------------------------------------------- // Possibly block third parties diff --git a/dom/canvas/ClientWebGLContext.cpp b/dom/canvas/ClientWebGLContext.cpp index c32c4813ca..a66307b9b7 100644 --- a/dom/canvas/ClientWebGLContext.cpp +++ b/dom/canvas/ClientWebGLContext.cpp @@ -3393,9 +3393,7 @@ void ClientWebGLContext::BufferData(GLenum target, WebGLsizeiptr rawSize, EnqueueError(LOCAL_GL_OUT_OF_MEMORY, "`size` too large for platform."); return; } - - const auto data = RawBuffer<>{*size}; - Run<RPROC(BufferData)>(target, data, usage); + Run<RPROC(BufferData_SizeOnly)>(target, *size, usage); } void ClientWebGLContext::BufferData( @@ -3429,9 +3427,11 @@ void ClientWebGLContext::RawBufferData(GLenum target, const uint8_t* srcBytes, size_t srcLen, GLenum usage) { const FuncScope funcScope(*this, "bufferData"); - const auto srcBuffer = - srcBytes ? RawBuffer<>({srcBytes, srcLen}) : RawBuffer<>(srcLen); - Run<RPROC(BufferData)>(target, srcBuffer, usage); + if (srcBytes) { + Run<RPROC(BufferData)>(target, RawBuffer<>({srcBytes, srcLen}), usage); + } else { + Run<RPROC(BufferData_SizeOnly)>(target, srcLen, usage); + } } //// diff --git a/dom/canvas/HostWebGLContext.h b/dom/canvas/HostWebGLContext.h index 3532603d99..7c31ad30d9 100644 --- a/dom/canvas/HostWebGLContext.h +++ b/dom/canvas/HostWebGLContext.h @@ -477,9 +477,12 @@ class HostWebGLContext final : public SupportsWeakPtr { return GetWebGL2Context()->GetBufferSubData(target, srcByteOffset, dest); } - void BufferData(GLenum target, const RawBuffer<>& data, GLenum usage) const { - const auto& beginOrNull = data.begin(); - mContext->BufferData(target, data.size(), beginOrNull, usage); + void BufferData(GLenum target, const RawBuffer<>& srcData, GLenum usage) const { + mContext->BufferData(target, srcData.size(), srcData.begin(), usage); + } + + void BufferData_SizeOnly(GLenum target, size_t byteSize, GLenum usage) const { + mContext->BufferData(target, byteSize, nullptr, usage); } void BufferSubData(GLenum target, uint64_t dstByteOffset, diff --git a/dom/canvas/WebGLMethodDispatcher.h b/dom/canvas/WebGLMethodDispatcher.h index 804eaa14fe..b48c3e341c 100644 --- a/dom/canvas/WebGLMethodDispatcher.h +++ b/dom/canvas/WebGLMethodDispatcher.h @@ -102,6 +102,7 @@ DEFINE_ASYNC(HostWebGLContext::BindBuffer) DEFINE_ASYNC(HostWebGLContext::BindBufferRange) DEFINE_ASYNC(HostWebGLContext::CopyBufferSubData) DEFINE_ASYNC(HostWebGLContext::BufferData) +DEFINE_ASYNC(HostWebGLContext::BufferData_SizeOnly) DEFINE_ASYNC(HostWebGLContext::BufferSubData) DEFINE_ASYNC(HostWebGLContext::BlitFramebuffer) DEFINE_ASYNC(HostWebGLContext::InvalidateFramebuffer) diff --git a/dom/canvas/WebGLQueueParamTraits.h b/dom/canvas/WebGLQueueParamTraits.h index 3c130c4da6..ccb3e423ed 100644 --- a/dom/canvas/WebGLQueueParamTraits.h +++ b/dom/canvas/WebGLQueueParamTraits.h @@ -123,15 +123,10 @@ struct QueueParamTraits<RawBuffer<T>> { const auto& elemCount = in.size(); auto status = view.WriteParam(elemCount); if (!status) return status; - if (!elemCount) return status; - - const auto& begin = in.begin(); - const bool hasData = static_cast<bool>(begin); - status = view.WriteParam(hasData); - if (!status) return status; - if (!hasData) return status; + if (!elemCount) return status; status = view.WriteFromRange(in.Data()); + return status; } @@ -140,20 +135,12 @@ struct QueueParamTraits<RawBuffer<T>> { size_t elemCount = 0; auto status = view.ReadParam(&elemCount); if (!status) return status; + if (!elemCount) { *out = {}; return true; } - uint8_t hasData = 0; - status = view.ReadParam(&hasData); - if (!status) return status; - if (!hasData) { - auto temp = RawBuffer<T>{elemCount}; - *out = std::move(temp); - return true; - } - auto data = view.template ReadRange<T>(elemCount); if (!data) return false; *out = std::move(RawBuffer<T>{*data}); diff --git a/dom/canvas/WebGLTypes.h b/dom/canvas/WebGLTypes.h index b06aa8a314..092ab9e127 100644 --- a/dom/canvas/WebGLTypes.h +++ b/dom/canvas/WebGLTypes.h @@ -839,33 +839,31 @@ struct VertAttribPointerCalculated final { } // namespace webgl -/** - * Represents a block of memory that it may or may not own. The - * inner data type must be trivially copyable by memcpy. - */ +// TODO: s/RawBuffer/Span/ template <typename T = uint8_t> class RawBuffer final { const T* mBegin = nullptr; size_t mLen = 0; - UniqueBuffer mOwned; public: using ElementType = T; - /** - * If aTakeData is true, RawBuffer will delete[] the memory when destroyed. - */ - explicit RawBuffer(const Range<const T>& data, UniqueBuffer&& owned = {}) - : mBegin(data.begin().get()), - mLen(data.length()), - mOwned(std::move(owned)) {} - - explicit RawBuffer(const size_t len) : mLen(len) {} + explicit RawBuffer(const Range<const T>& data) + : mBegin(data.begin().get()), mLen(data.length()) { + if (mLen) { + MOZ_ASSERT(mBegin); + } + } ~RawBuffer() = default; - Range<const T> Data() const { return {mBegin, mLen}; } - const auto& begin() const { return mBegin; } + Range<const T> Data() const { return {begin(), mLen}; } + const auto& begin() const { + if (mLen) { + MOZ_RELEASE_ASSERT(mBegin); + } + return mBegin; + } const auto& size() const { return mLen; } void Shrink(const size_t newLen) { diff --git a/dom/chrome-webidl/WindowGlobalActors.webidl b/dom/chrome-webidl/WindowGlobalActors.webidl index 7e202ee445..281f73f47b 100644 --- a/dom/chrome-webidl/WindowGlobalActors.webidl +++ b/dom/chrome-webidl/WindowGlobalActors.webidl @@ -58,6 +58,11 @@ interface WindowGlobalParent : WindowContext { readonly attribute boolean isCurrentGlobal; + // This should return true if the window is currently visible in its tab. + // (A more technically accurate name would be something like + // "isActiveInRootNavigable".) + readonly attribute boolean isActiveInTab; + readonly attribute unsigned long long outerWindowId; readonly attribute unsigned long long contentParentId; diff --git a/dom/events/EventStateManager.cpp b/dom/events/EventStateManager.cpp index b633821d8b..1ba56447dc 100644 --- a/dom/events/EventStateManager.cpp +++ b/dom/events/EventStateManager.cpp @@ -247,7 +247,7 @@ int16_t EventStateManager::sCurrentMouseBtn = MouseButton::eNotPressed; EventStateManager* EventStateManager::sActiveESM = nullptr; Document* EventStateManager::sMouseOverDocument = nullptr; AutoWeakFrame EventStateManager::sLastDragOverFrame = nullptr; -LayoutDeviceIntPoint EventStateManager::sPreLockPoint = +LayoutDeviceIntPoint EventStateManager::sPreLockScreenPoint = LayoutDeviceIntPoint(0, 0); LayoutDeviceIntPoint EventStateManager::sLastRefPoint = kInvalidRefPoint; CSSIntPoint EventStateManager::sLastScreenPoint = CSSIntPoint(0, 0); @@ -4927,7 +4927,7 @@ OverOutElementsWrapper* EventStateManager::GetWrapperByEventID( /* static */ void EventStateManager::SetPointerLock(nsIWidget* aWidget, - nsIContent* aElement) { + nsPresContext* aPresContext) { // Reset mouse wheel transaction WheelTransaction::EndTransaction(); @@ -4937,6 +4937,7 @@ void EventStateManager::SetPointerLock(nsIWidget* aWidget, if (PointerLockManager::IsLocked()) { MOZ_ASSERT(aWidget, "Locking pointer requires a widget"); + MOZ_ASSERT(aPresContext, "Locking pointer requires a presContext"); // Release all pointer capture when a pointer lock is successfully applied // on an element. @@ -4944,7 +4945,8 @@ void EventStateManager::SetPointerLock(nsIWidget* aWidget, // Store the last known ref point so we can reposition the pointer after // unlock. - sPreLockPoint = sLastRefPoint; + sPreLockScreenPoint = LayoutDeviceIntPoint::Round( + sLastScreenPoint * aPresContext->CSSToDevPixelScale()); // Fire a synthetic mouse move to ensure event state is updated. We first // set the mouse to the center of the window, so that the mouse event @@ -4969,20 +4971,19 @@ void EventStateManager::SetPointerLock(nsIWidget* aWidget, aWidget->UnlockNativePointer(); } - // Unlocking, so return pointer to the original position by firing a - // synthetic mouse event. We first reset sLastRefPoint to its - // pre-pointerlock position, so that the synthetic mouse event reports - // no movement. - sLastRefPoint = sPreLockPoint; // Reset SynthCenteringPoint to invalid so that next time we start // locking pointer, it has its initial value. sSynthCenteringPoint = kInvalidRefPoint; if (aWidget) { + // Unlocking, so return pointer to the original position by firing a + // synthetic mouse event. We first reset sLastRefPoint to its + // pre-pointerlock position, so that the synthetic mouse event reports + // no movement. + sLastRefPoint = sPreLockScreenPoint - aWidget->WidgetToScreenOffset(); // XXX Cannot we do synthesize the native mousemove in the parent process // with calling `UnlockNativePointer` above? Then, we could make this // API work only in the automation mode. - aWidget->SynthesizeNativeMouseMove( - sPreLockPoint + aWidget->WidgetToScreenOffset(), nullptr); + aWidget->SynthesizeNativeMouseMove(sPreLockScreenPoint, nullptr); } // Unsuppress DnD diff --git a/dom/events/EventStateManager.h b/dom/events/EventStateManager.h index 7a43ade7a4..8d2ce6797e 100644 --- a/dom/events/EventStateManager.h +++ b/dom/events/EventStateManager.h @@ -1152,10 +1152,9 @@ class EventStateManager : public nsSupportsWeakReference, public nsIObserver { StyleCursorKind mLockCursor; bool mLastFrameConsumedSetCursor; - // Last mouse event mRefPoint (the offset from the widget's origin in - // device pixels) when mouse was locked, used to restore mouse position - // after unlocking. - static LayoutDeviceIntPoint sPreLockPoint; + // Last mouse event screen point (in device pixel) when mouse was locked, used + // to restore mouse position after unlocking. + static LayoutDeviceIntPoint sPreLockScreenPoint; // Stores the mRefPoint of the last synthetic mouse move we dispatched // to re-center the mouse when we were pointer locked. If this is (-1,-1) it @@ -1240,7 +1239,7 @@ class EventStateManager : public nsSupportsWeakReference, public nsIObserver { MOZ_CAN_RUN_SCRIPT_BOUNDARY void FireContextClick(); MOZ_CAN_RUN_SCRIPT static void SetPointerLock(nsIWidget* aWidget, - nsIContent* aElement); + nsPresContext* aPresContext); static void sClickHoldCallback(nsITimer* aTimer, void* aESM); }; diff --git a/dom/fetch/FetchDriver.cpp b/dom/fetch/FetchDriver.cpp index 8c527ffeae..9fca1de608 100644 --- a/dom/fetch/FetchDriver.cpp +++ b/dom/fetch/FetchDriver.cpp @@ -948,6 +948,7 @@ void FetchDriver::FailWithNetworkError(nsresult rv) { // mObserver could be null after OnResponseAvailable(). if (mObserver) { + mObserver->OnReportPerformanceTiming(); mObserver->OnResponseEnd(FetchDriverObserver::eByNetworking, JS::UndefinedHandleValue); mObserver = nullptr; diff --git a/dom/fetch/FetchService.cpp b/dom/fetch/FetchService.cpp index e32d6f178e..b285d65692 100644 --- a/dom/fetch/FetchService.cpp +++ b/dom/fetch/FetchService.cpp @@ -256,8 +256,13 @@ void FetchService::FetchInstance::Cancel() { FETCH_LOG(("FetchInstance::Cancel() [%p]", this)); + // If mFetchDriver is not null here, FetchInstance::Fetch() has already + // started, let mFetchDriver::RunAbortAlgorithm() to call + // FetchInstance::OnResponseEnd() to resolve the pending promises. + // Otherwise, resolving the pending promises here. if (mFetchDriver) { mFetchDriver->RunAbortAlgorithm(); + return; } MOZ_ASSERT(mPromises); @@ -294,18 +299,30 @@ void FetchService::FetchInstance::OnResponseEnd( MOZ_ASSERT(mPromises); - // If ResponseTimingPromise is not resolved, it means the fetch is aborted. - // Resolving ResponseTimingPromise with an emtpy ResponseTiming. - if (!mPromises->GetResponseTimingPromise()->IsResolved()) { - mPromises->ResolveResponseTimingPromise(ResponseTiming(), __func__); - } - // Resolve the ResponseEndPromise - mPromises->ResolveResponseEndPromise(ResponseEndArgs(aReason), __func__); - if (aReason == eAborted) { + // If ResponseAvailablePromise has not resolved yet, resolved with + // NS_ERROR_DOM_ABORT_ERR response. + if (!mPromises->GetResponseAvailablePromise()->IsResolved()) { + mPromises->ResolveResponseAvailablePromise( + InternalResponse::NetworkError(NS_ERROR_DOM_ABORT_ERR), __func__); + } + + // If ResponseTimingPromise has not resolved yet, resolved with empty + // ResponseTiming. + if (!mPromises->GetResponseTimingPromise()->IsResolved()) { + mPromises->ResolveResponseTimingPromise(ResponseTiming(), __func__); + } + // Resolve the ResponseEndPromise + mPromises->ResolveResponseEndPromise(ResponseEndArgs(aReason), __func__); return; } + MOZ_ASSERT(mPromises->GetResponseAvailablePromise()->IsResolved() && + mPromises->GetResponseTimingPromise()->IsResolved()); + + // Resolve the ResponseEndPromise + mPromises->ResolveResponseEndPromise(ResponseEndArgs(aReason), __func__); + // Remove the FetchInstance from FetchInstanceTable RefPtr<FetchService> fetchService = FetchService::GetInstance(); MOZ_ASSERT(fetchService); @@ -414,7 +431,10 @@ void FetchService::FetchInstance::OnReportPerformanceTiming() { UniquePtr<PerformanceTimingData> performanceTiming( mFetchDriver->GetPerformanceTimingData(timing.initiatorType(), timing.entryName())); + // FetchDriver has no corresponding performance timing when fetch() failed. + // Resolve the ResponseTimingPromise with empty timing. if (!performanceTiming) { + mPromises->ResolveResponseTimingPromise(ResponseTiming(), __func__); return; } timing.timingData() = performanceTiming->ToIPC(); diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index a6e95d04bf..b52017c3fd 100644 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -5981,11 +5981,13 @@ mozilla::ipc::IPCResult ContentParent::RecvInitializeFamily( } mozilla::ipc::IPCResult ContentParent::RecvSetCharacterMap( - const uint32_t& aGeneration, const mozilla::fontlist::Pointer& aFacePtr, + const uint32_t& aGeneration, const uint32_t& aFamilyIndex, + const bool& aAlias, const uint32_t& aFaceIndex, const gfxSparseBitSet& aMap) { auto* fontList = gfxPlatformFontList::PlatformFontList(); MOZ_RELEASE_ASSERT(fontList, "gfxPlatformFontList not initialized?"); - fontList->SetCharacterMap(aGeneration, aFacePtr, aMap); + fontList->SetCharacterMap(aGeneration, aFamilyIndex, aAlias, aFaceIndex, + aMap); return IPC_OK(); } @@ -5998,10 +6000,10 @@ mozilla::ipc::IPCResult ContentParent::RecvInitOtherFamilyNames( } mozilla::ipc::IPCResult ContentParent::RecvSetupFamilyCharMap( - const uint32_t& aGeneration, const mozilla::fontlist::Pointer& aFamilyPtr) { + const uint32_t& aGeneration, const uint32_t& aIndex, const bool& aAlias) { auto* fontList = gfxPlatformFontList::PlatformFontList(); MOZ_RELEASE_ASSERT(fontList, "gfxPlatformFontList not initialized?"); - fontList->SetupFamilyCharMap(aGeneration, aFamilyPtr); + fontList->SetupFamilyCharMap(aGeneration, aIndex, aAlias); return IPC_OK(); } diff --git a/dom/ipc/ContentParent.h b/dom/ipc/ContentParent.h index b4c1f45b35..e55fd9cef6 100644 --- a/dom/ipc/ContentParent.h +++ b/dom/ipc/ContentParent.h @@ -1171,17 +1171,19 @@ class ContentParent final : public PContentParent, const uint32_t& aFamilyIndex, const bool& aLoadCmaps); - mozilla::ipc::IPCResult RecvSetCharacterMap( - const uint32_t& aGeneration, const mozilla::fontlist::Pointer& aFacePtr, - const gfxSparseBitSet& aMap); + mozilla::ipc::IPCResult RecvSetCharacterMap(const uint32_t& aGeneration, + const uint32_t& aFamilyIndex, + const bool& aAlias, + const uint32_t& aFaceIndex, + const gfxSparseBitSet& aMap); mozilla::ipc::IPCResult RecvInitOtherFamilyNames(const uint32_t& aGeneration, const bool& aDefer, bool* aLoaded); - mozilla::ipc::IPCResult RecvSetupFamilyCharMap( - const uint32_t& aGeneration, - const mozilla::fontlist::Pointer& aFamilyPtr); + mozilla::ipc::IPCResult RecvSetupFamilyCharMap(const uint32_t& aGeneration, + const uint32_t& aIndex, + const bool& aAlias); mozilla::ipc::IPCResult RecvStartCmapLoading(const uint32_t& aGeneration, const uint32_t& aStartIndex); diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl index 3f93b5fb73..9ad1018d60 100644 --- a/dom/ipc/PContent.ipdl +++ b/dom/ipc/PContent.ipdl @@ -131,7 +131,6 @@ using mozilla::dom::PermitUnloadResult from "nsIContentViewer.h"; using mozilla::dom::MaybeDiscardedWindowContext from "mozilla/dom/WindowContext.h"; using mozilla::dom::WindowContextTransaction from "mozilla/dom/WindowContext.h"; [MoveOnly] using base::SharedMemoryHandle from "base/shared_memory.h"; -using mozilla::fontlist::Pointer from "SharedFontList.h"; using gfxSparseBitSet from "gfxFontUtils.h"; using FontVisibility from "gfxFontEntry.h"; using mozilla::dom::MediaControlAction from "mozilla/dom/MediaControlKeySource.h"; @@ -1473,24 +1472,27 @@ parent: * @param aGeneration * Font-list generation, so requests relating to an obsolete list can be * ignored (see comments for GetFontListShmBlock). - * @param aFacePtr - * Font-list shared-memory "pointer" to the Face record to be updated. - * A Pointer is a record of a shared-memory block index and an offset - * within that block, which each process that maps the block can convert - * into a real pointer in its address space. + * @param aFamilyIndex + * Index of the font family in the font list (see aAlias for which list). + * @param aAlias + * Whether aFamilyIndex refers to the Families() or AliasFamilies() list. + * @param aFaceIndex + * Index of the face within the family's Faces() list. * @param aMap * The character coverage map of the face. (This will be stored as a * SharedBitSet record within the shared font list, and the Face record * will be updated to reference it.) */ - async SetCharacterMap(uint32_t aGeneration, Pointer aFacePtr, gfxSparseBitSet aMap); + async SetCharacterMap(uint32_t aGeneration, uint32_t aFamilyIndex, bool aAlias, + uint32_t aFaceIndex, gfxSparseBitSet aMap); /** * Ask the parent to set up the merged charmap for a family, to accelerate * future fallback searches. - * aFamilyPtr may refer to an element of either the Families() or AliasFamilies(). + * aFamilyIndex may refer to an element in either Families() or AliasFamilies(), + * with aAlias determining which. */ - async SetupFamilyCharMap(uint32_t aGeneration, Pointer aFamilyPtr); + async SetupFamilyCharMap(uint32_t aGeneration, uint32_t aFamilyIndex, bool aAlias); /** * Ask the parent to try and complete the InitOtherFamilyNames task, because diff --git a/dom/ipc/WindowGlobalParent.cpp b/dom/ipc/WindowGlobalParent.cpp index 0e345e9107..c1fc607634 100644 --- a/dom/ipc/WindowGlobalParent.cpp +++ b/dom/ipc/WindowGlobalParent.cpp @@ -609,6 +609,23 @@ bool WindowGlobalParent::IsCurrentGlobal() { return CanSend() && BrowsingContext()->GetCurrentWindowGlobal() == this; } +bool WindowGlobalParent::IsActiveInTab() { + if (!CanSend()) { + return false; + } + + CanonicalBrowsingContext* bc = BrowsingContext(); + if (!bc || bc->GetCurrentWindowGlobal() != this) { + return false; + } + + // We check the top BC so we don't need to worry about getting a stale value. + // That may not be necessary. + MOZ_ASSERT(bc->Top()->IsInBFCache() == bc->IsInBFCache(), + "BFCache bit out of sync?"); + return bc->AncestorsAreCurrent() && !bc->Top()->IsInBFCache(); +} + namespace { class ShareHandler final : public PromiseNativeHandler { diff --git a/dom/ipc/WindowGlobalParent.h b/dom/ipc/WindowGlobalParent.h index de96207d0c..c497d8a689 100644 --- a/dom/ipc/WindowGlobalParent.h +++ b/dom/ipc/WindowGlobalParent.h @@ -145,6 +145,8 @@ class WindowGlobalParent final : public WindowContext, bool IsCurrentGlobal(); + bool IsActiveInTab(); + bool IsProcessRoot(); uint32_t ContentBlockingEvents(); diff --git a/dom/media/test/mochitest_bugs.ini b/dom/media/test/mochitest_bugs.ini index 26693a416c..662c2deb84 100644 --- a/dom/media/test/mochitest_bugs.ini +++ b/dom/media/test/mochitest_bugs.ini @@ -783,6 +783,7 @@ skip-if = (android_version == '25' && debug) # android(bug 1232305) [test_bug1113600.html] skip-if = os == 'win' && os_version == '10.0' && debug # Bug 1713410 + os == 'mac' # Bug 1198168 [test_bug1120222.html] tags=capturestream [test_bug1242338.html] diff --git a/dom/streams/ReadableStreamPipeTo.cpp b/dom/streams/ReadableStreamPipeTo.cpp index 45cc79b0b2..ed5db4f086 100644 --- a/dom/streams/ReadableStreamPipeTo.cpp +++ b/dom/streams/ReadableStreamPipeTo.cpp @@ -607,7 +607,7 @@ void PipeToPump::OnReadFulfilled(JSContext* aCx, JS::Handle<JS::Value> aChunk, // matches other engines' behavior. See // https://github.com/whatwg/streams/issues/1243. RefPtr<Promise> promise = - Promise::CreateInfallible(mWriter->GetParentObject()); + Promise::CreateInfallible(xpc::CurrentNativeGlobal(aCx)); promise->MaybeResolveWithUndefined(); auto result = promise->ThenWithCycleCollectedArgsJS( [](JSContext* aCx, JS::Handle<JS::Value>, ErrorResult& aRv, diff --git a/dom/webscheduling/WebTaskScheduler.h b/dom/webscheduling/WebTaskScheduler.h index fcddd09d36..92e0bb6a44 100644 --- a/dom/webscheduling/WebTaskScheduler.h +++ b/dom/webscheduling/WebTaskScheduler.h @@ -113,7 +113,7 @@ class WebTaskScheduler : public nsWrapperCache, public SupportsWeakPtr { WebTask* GetNextTask() const; - void Disconnect(); + virtual void Disconnect(); void RunTaskSignalPriorityChange(TaskSignal* aTaskSignal); diff --git a/dom/webscheduling/WebTaskSchedulerWorker.cpp b/dom/webscheduling/WebTaskSchedulerWorker.cpp index 89fbb6169f..479d12cf7b 100644 --- a/dom/webscheduling/WebTaskSchedulerWorker.cpp +++ b/dom/webscheduling/WebTaskSchedulerWorker.cpp @@ -36,6 +36,9 @@ bool WebTaskWorkerRunnable::WorkerRun(JSContext* aCx, nsresult WebTaskSchedulerWorker::SetTimeoutForDelayedTask(WebTask* aTask, uint64_t aDelay) { + if (!mWorkerPrivate) { + return NS_ERROR_UNEXPECTED; + } JSContext* cx = nsContentUtils::GetCurrentJSContext(); if (!cx) { return NS_ERROR_UNEXPECTED; @@ -52,8 +55,18 @@ nsresult WebTaskSchedulerWorker::SetTimeoutForDelayedTask(WebTask* aTask, } bool WebTaskSchedulerWorker::DispatchEventLoopRunnable() { + if (!mWorkerPrivate) { + return false; + } RefPtr<WebTaskWorkerRunnable> runnable = new WebTaskWorkerRunnable(mWorkerPrivate, this); return runnable->Dispatch(); } + +void WebTaskSchedulerWorker::Disconnect() { + if (mWorkerPrivate) { + mWorkerPrivate = nullptr; + } + WebTaskScheduler::Disconnect(); +} } // namespace mozilla::dom diff --git a/dom/webscheduling/WebTaskSchedulerWorker.h b/dom/webscheduling/WebTaskSchedulerWorker.h index 4af987736e..b27b1250ff 100644 --- a/dom/webscheduling/WebTaskSchedulerWorker.h +++ b/dom/webscheduling/WebTaskSchedulerWorker.h @@ -34,6 +34,8 @@ class WebTaskSchedulerWorker final : public WebTaskScheduler { public: explicit WebTaskSchedulerWorker(WorkerPrivate* aWorkerPrivate); + void Disconnect() override; + private: ~WebTaskSchedulerWorker() = default; diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp index fc349c1642..6998d02308 100644 --- a/dom/workers/WorkerPrivate.cpp +++ b/dom/workers/WorkerPrivate.cpp @@ -3770,7 +3770,9 @@ void WorkerPrivate::ScheduleDeletion(WorkerRanOrNot aRanOrNot) { if (WorkerRan == aRanOrNot) { nsIThread* currentThread = NS_GetCurrentThread(); MOZ_ASSERT(currentThread); - MOZ_ASSERT(!NS_HasPendingEvents(currentThread)); + // On the worker thread WorkerRunnable will refuse to run if not nested + // on top of a WorkerThreadPrimaryRunnable. + Unused << NS_WARN_IF(NS_HasPendingEvents(currentThread)); } #endif diff --git a/dom/workers/WorkerRunnable.cpp b/dom/workers/WorkerRunnable.cpp index ec461d3cfb..f5aaa759ef 100644 --- a/dom/workers/WorkerRunnable.cpp +++ b/dom/workers/WorkerRunnable.cpp @@ -13,6 +13,7 @@ #include "mozilla/AlreadyAddRefed.h" #include "mozilla/AppShutdown.h" #include "mozilla/Assertions.h" +#include "mozilla/CycleCollectedJSContext.h" #include "mozilla/DebugOnly.h" #include "mozilla/ErrorResult.h" #include "mozilla/Maybe.h" @@ -224,6 +225,33 @@ WorkerRunnable::Run() { bool targetIsWorkerThread = mBehavior == WorkerThreadModifyBusyCount || mBehavior == WorkerThreadUnchangedBusyCount; + if (targetIsWorkerThread) { + // On a worker thread, a WorkerRunnable should only run when there is an + // underlying WorkerThreadPrimaryRunnable active, which means we should + // find a CycleCollectedJSContext. + if (!CycleCollectedJSContext::Get()) { +#if (defined(MOZ_COLLECTING_RUNNABLE_TELEMETRY) && defined(DEBUG)) + // Temporarily set the LogLevel high enough to be certain the messages + // are visible. + LogModule* module = sWorkerRunnableLog; + LogLevel prevLevel = module->Level(); + if (prevLevel < LogLevel::Error) { + module->SetLevel(LogLevel::Error); + } + MOZ_LOG(sWorkerRunnableLog, LogLevel::Error, + ("Runnable '%s' was executed after WorkerThreadPrimaryRunnable " + "ended.", + "WorkerRunnable")); + module->SetLevel(prevLevel); +#endif + MOZ_DIAGNOSTIC_ASSERT(false, + "A WorkerRunnable was executed after " + "WorkerThreadPrimaryRunnable ended."); + + return NS_OK; + } + } + #ifdef DEBUG MOZ_ASSERT_IF(mCallingCancelWithinRun, targetIsWorkerThread); if (targetIsWorkerThread) { |