mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:30:27 +00:00
52a27516d8
- Bug 1261720 (part 1) - Separate js::ClassExtension from js::Class. r=jorendorff,bz. (6368952442)
- Bug 1261720 (part 2) - Move ClassExtension::isWrappedNative into js::Class::flags. r=jorendorff. (554fe695c2)
- Bug 1261723 (part 1) - Rename js::Class::ops as oOps. r=efaust. (e9dace574c)
- Bug 1261723 (part 2) - Separate class ops from js::Class. code=njn,h4writer. r=efaust,bz. (54bc06aec6)
- Bug 1263865 - Check the return value of GetSelfHostedFunction in ArraySpeciesCreate. r=efaust (cc6e1c0e50)
- Bug 1248948 - Don't pass non-SavedFrame objects to SavedFrame JSAPI functions; r=tromey r=evilpie (8c753c3c89)
- Bug 1260475 - Add an option to disable GC slices triggered by painting. r=terrence a=kwierso (df86be5e34)
- Bug 1263803 - Change AllocateArrayBuffer to receive byteLength instead of nelements. r=lth (751e333ff0)
- Bug 1264941 - Use byteLength of source typedArray in CloneArrayBuffer. r=lth (0095fce3aa)
- Bug 1263879 - Check the return value of AtomizeString in str_replace_string_raw. r=h4writer (31e1470bc3)
- Bug 1258453 - Compact arenas containing strings r=terrence (f6b4029d79)
- Bug 1258095 - patch 1/3 - OSFileSystem should have the root == the directory root, r=smaug (8cf74899f4)
- Bug 1258095 - patch 2/3 - Implement Directory::GetPath() correctly, r=smaug (776f503c98)
- Bug 1258095 - patch 3/3 - Directory tasks should use FallibleArray, r=smaug (b4888c92b9)
- Bug 1258221 - patch 1 - File::CreateFromFile only for main-thread, r=smaug (c106b37cb4)
- Bug 1258056 - Propagate the window opener full page zoom across the IPC layer; r=smaug (511386589f)
- Bug 1248772 - Trigger a OS window focus in ServiceWorkerClients::OpenWindow. r=ehsan (feb322b9f0)
- Bug 1259707 - Fix confusion between desktop and CSS pixels when session-restore is constraining window to the available screen space. r=emk (def9cc918b)
- Bug 1250266 - Always send a TTL in the Push mochitests. r=benbangert (43c7bde7b8)
- Bug 1244816 - Create PushService mock for mochitests backed by a mock web socket. r=kitcambridge (92270cbae5)
- Bug 1257395: Update comments for GCHashTable and GCPolicy. DONTBUILD r=terrence (fee0311ea0)
- Bug 1263772 - Use WeakCache wrapper to sweep BaseShape table; r=jonco (a0e015667c)
- Bug 1263777 - Use WeakCache to sweep the InitialShapeTable; r=jonco (84d1591585)
- Bug 1132502 (part 1) - Abort if compartmentStats is null during memory reporting. r=jandem. (bd144192b1)
- Bug 1132502 (part 2) - Don't call AddClassInfo() for BaseShapes. r=jandem. (10881fe48c)
- Bug 1259490 - Update the DtoA cache after compacting GC; r=jandem (6e3139501c)
- Bug 1257903 - Fix spurious GC hazard on a CLOSED TREE r=me (ce2935d8b2)
- Bug 1259042 - Re-introduce a version of ZoneCellIter for use under GC r=terrence (d1e4ca6e30)
- Bug 1259180 - Compact arenas containing scripts r=terrence (365d22ab00)
- Bug 1258407 - Limit GC heap growth parameters r=sfink (1c9ffb0e3f)
- Bug 1263966 - Compact arenas containing lazy scripts r=terrence (e22c571c37)
- Bug 1266107 - Update type descriptors first when compacting r=terrence (4c2ca98bb3)
- Bug 1266105 - Only purge runtime tables once per slice when compacting r=terrence (74e2977241)
- Bug 1263769 - Sweep WeakCaches in parallel; r=sfink (54b077b37b)
- Bug 1266107 - Track all existing typed object descriptor objects r=terrence (bc60425bf6)
- Bug 1260198 - Clear per-zone string cache after compacting r=terrence (c3002b8021)
- Bug 1259306 - Trace ShapeTables r=terrence (15abb48a33)
- Bug 1262203 - Skip shape table tracing where possible r=terrence (8a1ec15053)
- Bug 1164432 - Update test_try_registering_offline_disabled.html to use mock push server. r=kitcambridge (6d52de1a17)
- Bug 1263857 - Initialize the slots of the match result object before creating properties in generateRegExpMatcherStub. r=h4writer (802af47b3a)
- Bug 1263549 - Fix inlined RegExpPrototypeOptimizable and RegExpInstanceOptimizable. r=h4writer (5565bca590)
- Bug 1264998 - CodeGeneratorShared::assignBailoutId: Properly handle allocation errors. r=h4writer (258cbfc0b6)
- Bug 1257408 - Fix VS2015 C4312 warnings in js/src. r=nbp (d52a4d1fe7)
- Bug 1220466 - Don't build event region display items for pseudo stacking contexts, unless they are also an AGR. r=mstange (9f9a2c7eba)
- Bug 1220466 - Avoid doing unnecessary layer building work for inactive layers. r=mstange (372097e6df)
- Bug 1239151. Increase skia font cache size to 10mb on non-android platforms. r=lsalzman (8a2029da40)
- Bug 1255068 - Do not allow empty transaction transform changes if the scroll position has changed since the last paint. r=kats, r=mattwoodrow (f4a42e10c8)
- Bug 1255068 - Add a check for null scrollid. r=kats (3ddbb78fd3)
- Bug 1258910 - IonMonkey: MIPS: Implement float-point conditional move instructions. r=huangwenjun06 (b53499103b)
- Bug 1258910 - OdinMonkey: MIPS64: Implement AsmSelectI64. r=bbouvier (a36cfffa1d)
- Bug 1258910 - OdinMonkey: MIPS: Implement AsmSelect. r=bbouvier (e458724bc1)
- Bug 1254500 - IonMonkey: MIPS: Implement ma_ctz. r=arai (c8bfd7a6c9)
- Bug 1254500 - IonMonkey: MIPS: Implement CodeGeneratorMIPSShared::visitCtzI. r=arai (b65dad7d1b)
- Bug 1254500 - IonMonkey: MIPS: Implement CodeGeneratorMIPSShared::visitPopcntI. r=arai (58c00b603e)
- Bug 1258105 - Port object length stubs to CacheIR. r=efaust (ed0ec07678)
- Bug 1258301 - Use TraceNullableEdge for CacheIR pointers. r=jonco (3342ef24b4)
- Bug 1258327 - Part 1: Move ToAddress from CodeGeneratorMIPSShared to CodeGeneratorShared. r=hev (59e7494f02)
- Bug 1258327 - Part 2: Remove Operand variant from bailoutCmp32. r=nbp (c4609af383)
- Bug 1258327 - Part 3: Remove Operand variant from branch32 except x86-shared. r=nbp (dca4bc7577)
- Bug 1258327 - Part 4: Remove ToOperand call from arm CodeGenerator. r=jandem (395d7a004f)
- Bug 1258327 - Part 5: Remove dummy ToOperand definition from arm64 CodeGenerator. r=jandem (bc447cb6aa)
- Bug 1258327 - Part 6: Remove ToOperand call from mips-shared and mips64 CodeGenerator. r=hev (d01b028148)
- Bug 1258327 - Part 7: Move ToOperand from CodeGeneratorShared to CodeGeneratorX86Shared. r=nbp (71449d7c62)
- Bug 1248412 - Prevent immediate bailout from innermost for-of loops. r=h4writer (616897a580)
- Bug 1261326 - Fix a bogus assert. r=bhackett (ff715a7954)
- Bug 1260371 - Rearrange RelocationOverlay so that magic field does not overlay inline string chars r=terrence (f88fbb8927)
- Bug 1262203 - Do GC relocation writes in order; r=sfink (b82a25dd15)
- Bug 1247909 - Move MFunctionEnvironment after the entry resume points operands. r=h4writer (29d8d1c2df)
- Bug 1259925 - Port ModuleNamespace getprop stub to CacheIR. r=efaust (b31980bdc3)
- Bug 1264561 - Fix ClassOps::call and ClassOps::construct address calculation in visitIsCallable and visitIsConstructor. r=efaust (172037857b)
- Bug 1264823 - Add pre-barrier to the elements of mapIterationResultPair. r=jandem (b2e451c371)
- Bug 1263609: SharedStubs - Allow JSOP_POW in ion codegen ON CLOSED TREE, r=bbouvier (16bb4ca9af)
- Bug 1265159 - IonMonkey: Throw error when popping from an empty array in MArrayPopShift, r=jandem (e3a1b08614)
- Bug 1259392 - nail down isLockFree(4) for good. r=jolesen (72fa558eec)
- Bug 1244252 - Don't check object group generation when generating code to create unboxed objects off thread, r=terrence. (4191175759)
- Bug 1254578 - Fix OOM case when rematerializing frames. (r=jandem) (a213756a2b)
- Bug 1263139 - Apply ToString to non-standard flags argument of String.prototype.{match,search,replace}. r=till (91c8f6f592)
- Bug 1257810 - ReleaseAcquire should be adequate for a counter; r=sfink (e394a21b3d)
- Bug 1251833 - Part 4: Remove some unneeded qualification from GCRuntime and friends. r=terrence (e77de1a3ac)
- Bug 1260371 - Forward another pointer during TypedObject tracing to fix bustage r=me (24636e9463)
- Bug 1266107 - Simplify typed object tracing now type descriptors are traced first r=terrence (6872be4bfa)
- Bug 1260998 - Add support for HOST_CPPFLAGS for consistency. r=nalexander (9fe0ddee7e)
- Bug 1105556 - Don't call CheckLoadURIWithPrincipal() in DoCheckLoadURIChecks() for TYPE_DOCUMENT loads where we don't have a loadingPrincipal. Ensure SEC_COOKIES_SAME_ORIGIN isn't set for TYPE_DOCUMENT loads in CheckChannel(). r=ckerschb, sicking (fbebbf1017)
- Bug 1195172 - Use channel->ascynOpen2 layout/style/FontFaceSet.cpp (r=bz,cam) (3e943da95c)
- Bug 1250986 - Make Request.referrer a USVString; r=bzbarsky (6987ab9838)
- Bug 1250987 - Make RequestInit.body nullable; r=bzbarsky (2496ebea1f)
- Bug 1251448 - Add support for RequestInit.referrer; r=jdm (dcf1a668f8)
- Bug 1250985 - Part 1: Add a way to identify whether a WebIDL dictionary has any members present; r=bzbarsky (7ddd6e8043)
- Bug 1250985 - Part 2: Prevent copy constructing a Request object with navigate mode if a RequestInit member is present; r=bzbarsky (24c8c1ca56)
- Bug 1184550 - Move the check for bodyUsed before the check for a null body so subsequent fetches with the same Request fail. r=bkelly (60837c04eb)
- Bug 1251872 - Part 1: Implement Request.referrerPolicy; r=jdm (bd024c0614)
- bug 1252687 - make Migration's ctor constexpr r=bz (793d608bcd)
- Bug 1251872 - Part 2: Store the Request referrerPolicy in the DOM Cache; r=bkelly (e1511c07a6)
- Bug 1251229 P2 Add wpt test verifying FetchEvent.request.url does not include fragments. r=ehsan (1d74e2491e)
- Bug 1251229 P1 Strip fragment from request URL when creating FetchEvent. r=ehsan (5faddecc78)
- Bug 1120715 - Part 4: Add tests for Request.cache; r=bkelly (81537bd125)
- Bug 1237455 P1 Make file_CrossSiteXHR_server.sjs check headers on redirects. r=ehsan (597fdf223d)
- Bug 1237455 P2 Test headers on redirects in fetch mochitests. r=ehsan (2a19ac6a44)
- Bug 1237455 P3 Add a version of test_fetch_cors that reroutes through an empty service worker. r=ehsan (0550d5e115)
- Bug 1205288 - implement and test fetch spec changes for blob scheme with non-GET method. r=bkelly (bb519b1c71)
- Bug 1237455 P4 Create helper method to set fetch request headers. r=ehsan (20266aa708)
- Bug 1237455 P5 Set headers on fetch() redirects. r=ehsan (95dcfe7f71)
- Bug 1120715 - Part 5: Treat a default cache mode Request with a revalidation header as no-store; r=bkelly (4182fded21)
- fix! (c3097a682a)
- Bug 1204520 - Remove unused return value from FetchDriver::FailWithNetworkError. r=jdm (ddd84df514)
- Bug 1253054 - Stop warning if request has already failed. r=bkelly (52eb17afd2)
- Bug 1176824 - Intermittent browser_test_web_manifest.js. r=ckerschb (b8c1fc5757)
- Bug 1242051 - Add inter-directory test support file dependencies to ini manifests. r=gps (5d06d6b00c)
- Bug 1250048 - CSP manifest-src doesn't override default-src. r=ckerschb,bkelly,ehsan (3d77b91226)
- Bug 1262624 Move service worker wpt tests out of mozilla dir so they will be upstreamed. r=jgraham (cf1f010cd2)
- Bug 1263469 P1 Set FetchEvent.request.cache value correctly for non-fetch channels. r=mayhemer (0fac232769)
- Bug 1263469 P2 Validate FetchEvent.request.cache in refresh mochitest. r=ehsan (de0db7da84)
- Bug 1263469 P3 Test FetchEvent.request.cache value on reload in wpt test. r=ehsan (8b4fc58d08)
- Bug 1263469 P4 Update test_eventsource_intercept.html to validate FetchEvent.request.cache. r=ehsan (81843666c0)
- Bug 1263469 P5 Add a wpt test case for EventSource. r=ehsan (a32cbbaf80)
- Bug 1265941 - Rename the ReferrerPolicy "origin-only" enum value to "origin"; r=jdm (1b1dfcebbc)
788 lines
23 KiB
C++
788 lines
23 KiB
C++
/* -*- 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 "ServiceWorkerClients.h"
|
|
|
|
#include "mozilla/dom/Promise.h"
|
|
#include "mozilla/dom/PromiseWorkerProxy.h"
|
|
|
|
#include "ServiceWorkerClient.h"
|
|
#include "ServiceWorkerManager.h"
|
|
#include "ServiceWorkerPrivate.h"
|
|
#include "ServiceWorkerWindowClient.h"
|
|
|
|
#include "WorkerPrivate.h"
|
|
#include "WorkerRunnable.h"
|
|
#include "WorkerScope.h"
|
|
|
|
#include "nsContentUtils.h"
|
|
#include "nsIBrowserDOMWindow.h"
|
|
#include "nsIDocShell.h"
|
|
#include "nsIDOMChromeWindow.h"
|
|
#include "nsIDOMWindow.h"
|
|
#include "nsIWebNavigation.h"
|
|
#include "nsIWebProgress.h"
|
|
#include "nsIWebProgressListener.h"
|
|
#include "nsIWindowMediator.h"
|
|
#include "nsIWindowWatcher.h"
|
|
#include "nsNetUtil.h"
|
|
#include "nsPIWindowWatcher.h"
|
|
#include "nsWindowWatcher.h"
|
|
#include "nsWeakReference.h"
|
|
|
|
using namespace mozilla;
|
|
using namespace mozilla::dom;
|
|
using namespace mozilla::dom::workers;
|
|
|
|
NS_IMPL_CYCLE_COLLECTING_ADDREF(ServiceWorkerClients)
|
|
NS_IMPL_CYCLE_COLLECTING_RELEASE(ServiceWorkerClients)
|
|
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(ServiceWorkerClients, mWorkerScope)
|
|
|
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ServiceWorkerClients)
|
|
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
|
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
|
NS_INTERFACE_MAP_END
|
|
|
|
ServiceWorkerClients::ServiceWorkerClients(ServiceWorkerGlobalScope* aWorkerScope)
|
|
: mWorkerScope(aWorkerScope)
|
|
{
|
|
MOZ_ASSERT(mWorkerScope);
|
|
}
|
|
|
|
JSObject*
|
|
ServiceWorkerClients::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
|
{
|
|
return ClientsBinding::Wrap(aCx, this, aGivenProto);
|
|
}
|
|
|
|
namespace {
|
|
|
|
class GetRunnable final : public nsRunnable
|
|
{
|
|
class ResolvePromiseWorkerRunnable final : public WorkerRunnable
|
|
{
|
|
RefPtr<PromiseWorkerProxy> mPromiseProxy;
|
|
UniquePtr<ServiceWorkerClientInfo> mValue;
|
|
nsresult mRv;
|
|
|
|
public:
|
|
ResolvePromiseWorkerRunnable(WorkerPrivate* aWorkerPrivate,
|
|
PromiseWorkerProxy* aPromiseProxy,
|
|
UniquePtr<ServiceWorkerClientInfo>&& aValue,
|
|
nsresult aRv)
|
|
: WorkerRunnable(aWorkerPrivate, WorkerThreadModifyBusyCount),
|
|
mPromiseProxy(aPromiseProxy),
|
|
mValue(Move(aValue)),
|
|
mRv(Move(aRv))
|
|
{
|
|
AssertIsOnMainThread();
|
|
}
|
|
|
|
bool
|
|
WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
|
|
{
|
|
MOZ_ASSERT(aWorkerPrivate);
|
|
aWorkerPrivate->AssertIsOnWorkerThread();
|
|
|
|
Promise* promise = mPromiseProxy->WorkerPromise();
|
|
MOZ_ASSERT(promise);
|
|
|
|
if (NS_FAILED(mRv)) {
|
|
promise->MaybeReject(mRv);
|
|
} else if (mValue) {
|
|
RefPtr<ServiceWorkerWindowClient> windowClient =
|
|
new ServiceWorkerWindowClient(promise->GetParentObject(), *mValue);
|
|
promise->MaybeResolve(windowClient.get());
|
|
} else {
|
|
promise->MaybeResolve(JS::UndefinedHandleValue);
|
|
}
|
|
mPromiseProxy->CleanUp();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
RefPtr<PromiseWorkerProxy> mPromiseProxy;
|
|
nsString mClientId;
|
|
public:
|
|
GetRunnable(PromiseWorkerProxy* aPromiseProxy,
|
|
const nsAString& aClientId)
|
|
: mPromiseProxy(aPromiseProxy),
|
|
mClientId(aClientId)
|
|
{
|
|
}
|
|
|
|
NS_IMETHOD
|
|
Run() override
|
|
{
|
|
AssertIsOnMainThread();
|
|
|
|
MutexAutoLock lock(mPromiseProxy->Lock());
|
|
if (mPromiseProxy->CleanedUp()) {
|
|
return NS_OK;
|
|
}
|
|
|
|
WorkerPrivate* workerPrivate = mPromiseProxy->GetWorkerPrivate();
|
|
MOZ_ASSERT(workerPrivate);
|
|
|
|
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
|
ErrorResult rv;
|
|
UniquePtr<ServiceWorkerClientInfo> result = swm->GetClient(workerPrivate->GetPrincipal(),
|
|
mClientId, rv);
|
|
RefPtr<ResolvePromiseWorkerRunnable> r =
|
|
new ResolvePromiseWorkerRunnable(mPromiseProxy->GetWorkerPrivate(),
|
|
mPromiseProxy, Move(result),
|
|
rv.StealNSResult());
|
|
rv.SuppressException();
|
|
|
|
r->Dispatch();
|
|
return NS_OK;
|
|
}
|
|
};
|
|
|
|
class MatchAllRunnable final : public nsRunnable
|
|
{
|
|
class ResolvePromiseWorkerRunnable final : public WorkerRunnable
|
|
{
|
|
RefPtr<PromiseWorkerProxy> mPromiseProxy;
|
|
nsTArray<ServiceWorkerClientInfo> mValue;
|
|
|
|
public:
|
|
ResolvePromiseWorkerRunnable(WorkerPrivate* aWorkerPrivate,
|
|
PromiseWorkerProxy* aPromiseProxy,
|
|
nsTArray<ServiceWorkerClientInfo>& aValue)
|
|
: WorkerRunnable(aWorkerPrivate, WorkerThreadModifyBusyCount),
|
|
mPromiseProxy(aPromiseProxy)
|
|
{
|
|
AssertIsOnMainThread();
|
|
mValue.SwapElements(aValue);
|
|
}
|
|
|
|
bool
|
|
WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
|
|
{
|
|
MOZ_ASSERT(aWorkerPrivate);
|
|
aWorkerPrivate->AssertIsOnWorkerThread();
|
|
|
|
Promise* promise = mPromiseProxy->WorkerPromise();
|
|
MOZ_ASSERT(promise);
|
|
|
|
nsTArray<RefPtr<ServiceWorkerClient>> ret;
|
|
for (size_t i = 0; i < mValue.Length(); i++) {
|
|
ret.AppendElement(RefPtr<ServiceWorkerClient>(
|
|
new ServiceWorkerWindowClient(promise->GetParentObject(),
|
|
mValue.ElementAt(i))));
|
|
}
|
|
|
|
promise->MaybeResolve(ret);
|
|
mPromiseProxy->CleanUp();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
RefPtr<PromiseWorkerProxy> mPromiseProxy;
|
|
nsCString mScope;
|
|
bool mIncludeUncontrolled;
|
|
public:
|
|
MatchAllRunnable(PromiseWorkerProxy* aPromiseProxy,
|
|
const nsCString& aScope,
|
|
bool aIncludeUncontrolled)
|
|
: mPromiseProxy(aPromiseProxy),
|
|
mScope(aScope),
|
|
mIncludeUncontrolled(aIncludeUncontrolled)
|
|
{
|
|
MOZ_ASSERT(mPromiseProxy);
|
|
}
|
|
|
|
NS_IMETHOD
|
|
Run() override
|
|
{
|
|
AssertIsOnMainThread();
|
|
|
|
MutexAutoLock lock(mPromiseProxy->Lock());
|
|
if (mPromiseProxy->CleanedUp()) {
|
|
return NS_OK;
|
|
}
|
|
|
|
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
|
nsTArray<ServiceWorkerClientInfo> result;
|
|
|
|
swm->GetAllClients(mPromiseProxy->GetWorkerPrivate()->GetPrincipal(), mScope,
|
|
mIncludeUncontrolled, result);
|
|
RefPtr<ResolvePromiseWorkerRunnable> r =
|
|
new ResolvePromiseWorkerRunnable(mPromiseProxy->GetWorkerPrivate(),
|
|
mPromiseProxy, result);
|
|
|
|
r->Dispatch();
|
|
return NS_OK;
|
|
}
|
|
};
|
|
|
|
class ResolveClaimRunnable final : public WorkerRunnable
|
|
{
|
|
RefPtr<PromiseWorkerProxy> mPromiseProxy;
|
|
nsresult mResult;
|
|
|
|
public:
|
|
ResolveClaimRunnable(WorkerPrivate* aWorkerPrivate,
|
|
PromiseWorkerProxy* aPromiseProxy,
|
|
nsresult aResult)
|
|
: WorkerRunnable(aWorkerPrivate, WorkerThreadModifyBusyCount)
|
|
, mPromiseProxy(aPromiseProxy)
|
|
, mResult(aResult)
|
|
{
|
|
AssertIsOnMainThread();
|
|
}
|
|
|
|
bool
|
|
WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
|
|
{
|
|
MOZ_ASSERT(aWorkerPrivate);
|
|
aWorkerPrivate->AssertIsOnWorkerThread();
|
|
|
|
RefPtr<Promise> promise = mPromiseProxy->WorkerPromise();
|
|
MOZ_ASSERT(promise);
|
|
|
|
if (NS_SUCCEEDED(mResult)) {
|
|
promise->MaybeResolve(JS::UndefinedHandleValue);
|
|
} else {
|
|
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
|
|
}
|
|
|
|
mPromiseProxy->CleanUp();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class ClaimRunnable final : public nsRunnable
|
|
{
|
|
RefPtr<PromiseWorkerProxy> mPromiseProxy;
|
|
nsCString mScope;
|
|
uint64_t mServiceWorkerID;
|
|
|
|
public:
|
|
ClaimRunnable(PromiseWorkerProxy* aPromiseProxy, const nsCString& aScope)
|
|
: mPromiseProxy(aPromiseProxy)
|
|
, mScope(aScope)
|
|
// Safe to call GetWorkerPrivate() since we are being called on the worker
|
|
// thread via script (so no clean up has occured yet).
|
|
, mServiceWorkerID(aPromiseProxy->GetWorkerPrivate()->ServiceWorkerID())
|
|
{
|
|
MOZ_ASSERT(aPromiseProxy);
|
|
}
|
|
|
|
NS_IMETHOD
|
|
Run() override
|
|
{
|
|
MutexAutoLock lock(mPromiseProxy->Lock());
|
|
if (mPromiseProxy->CleanedUp()) {
|
|
return NS_OK;
|
|
}
|
|
|
|
WorkerPrivate* workerPrivate = mPromiseProxy->GetWorkerPrivate();
|
|
MOZ_ASSERT(workerPrivate);
|
|
|
|
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
|
MOZ_ASSERT(swm);
|
|
|
|
nsresult rv = swm->ClaimClients(workerPrivate->GetPrincipal(),
|
|
mScope, mServiceWorkerID);
|
|
|
|
RefPtr<ResolveClaimRunnable> r =
|
|
new ResolveClaimRunnable(workerPrivate, mPromiseProxy, rv);
|
|
|
|
r->Dispatch();
|
|
return NS_OK;
|
|
}
|
|
};
|
|
|
|
class ResolveOpenWindowRunnable final : public WorkerRunnable
|
|
{
|
|
public:
|
|
ResolveOpenWindowRunnable(PromiseWorkerProxy* aPromiseProxy,
|
|
UniquePtr<ServiceWorkerClientInfo>&& aClientInfo,
|
|
const nsresult aStatus)
|
|
: WorkerRunnable(aPromiseProxy->GetWorkerPrivate(), WorkerThreadModifyBusyCount)
|
|
, mPromiseProxy(aPromiseProxy)
|
|
, mClientInfo(Move(aClientInfo))
|
|
, mStatus(aStatus)
|
|
{
|
|
AssertIsOnMainThread();
|
|
MOZ_ASSERT(aPromiseProxy);
|
|
}
|
|
|
|
bool
|
|
WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
|
|
{
|
|
MOZ_ASSERT(aWorkerPrivate);
|
|
aWorkerPrivate->AssertIsOnWorkerThread();
|
|
|
|
Promise* promise = mPromiseProxy->WorkerPromise();
|
|
if (NS_WARN_IF(NS_FAILED(mStatus))) {
|
|
promise->MaybeReject(mStatus);
|
|
} else if (mClientInfo) {
|
|
RefPtr<ServiceWorkerWindowClient> client =
|
|
new ServiceWorkerWindowClient(promise->GetParentObject(),
|
|
*mClientInfo);
|
|
promise->MaybeResolve(client);
|
|
} else {
|
|
promise->MaybeResolve(JS::NullHandleValue);
|
|
}
|
|
|
|
mPromiseProxy->CleanUp();
|
|
return true;
|
|
}
|
|
|
|
private:
|
|
RefPtr<PromiseWorkerProxy> mPromiseProxy;
|
|
UniquePtr<ServiceWorkerClientInfo> mClientInfo;
|
|
const nsresult mStatus;
|
|
};
|
|
|
|
class WebProgressListener final : public nsIWebProgressListener,
|
|
public nsSupportsWeakReference
|
|
{
|
|
public:
|
|
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
|
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(WebProgressListener, nsIWebProgressListener)
|
|
|
|
WebProgressListener(PromiseWorkerProxy* aPromiseProxy,
|
|
ServiceWorkerPrivate* aServiceWorkerPrivate,
|
|
nsPIDOMWindow* aWindow,
|
|
nsIURI* aBaseURI)
|
|
: mPromiseProxy(aPromiseProxy)
|
|
, mServiceWorkerPrivate(aServiceWorkerPrivate)
|
|
, mWindow(aWindow)
|
|
, mBaseURI(aBaseURI)
|
|
{
|
|
MOZ_ASSERT(aPromiseProxy);
|
|
MOZ_ASSERT(aServiceWorkerPrivate);
|
|
MOZ_ASSERT(aWindow);
|
|
MOZ_ASSERT(aWindow->IsOuterWindow());
|
|
MOZ_ASSERT(aBaseURI);
|
|
AssertIsOnMainThread();
|
|
|
|
mServiceWorkerPrivate->StoreISupports(static_cast<nsIWebProgressListener*>(this));
|
|
}
|
|
|
|
NS_IMETHOD
|
|
OnStateChange(nsIWebProgress* aWebProgress,
|
|
nsIRequest* aRequest,
|
|
uint32_t aStateFlags, nsresult aStatus) override
|
|
{
|
|
if (!(aStateFlags & STATE_IS_DOCUMENT) ||
|
|
!(aStateFlags & (STATE_STOP | STATE_TRANSFERRING))) {
|
|
return NS_OK;
|
|
}
|
|
|
|
// Our caller keeps a strong reference, so it is safe to remove the listener
|
|
// from ServiceWorkerPrivate.
|
|
mServiceWorkerPrivate->RemoveISupports(static_cast<nsIWebProgressListener*>(this));
|
|
aWebProgress->RemoveProgressListener(this);
|
|
|
|
MutexAutoLock lock(mPromiseProxy->Lock());
|
|
if (mPromiseProxy->CleanedUp()) {
|
|
return NS_OK;
|
|
}
|
|
|
|
nsCOMPtr<nsIDocument> doc = mWindow->GetExtantDoc();
|
|
UniquePtr<ServiceWorkerClientInfo> clientInfo;
|
|
if (doc) {
|
|
// Check same origin.
|
|
nsCOMPtr<nsIScriptSecurityManager> securityManager =
|
|
nsContentUtils::GetSecurityManager();
|
|
nsresult rv = securityManager->CheckSameOriginURI(doc->GetOriginalURI(),
|
|
mBaseURI, false);
|
|
if (NS_SUCCEEDED(rv)) {
|
|
clientInfo.reset(new ServiceWorkerClientInfo(doc));
|
|
}
|
|
}
|
|
|
|
RefPtr<ResolveOpenWindowRunnable> r =
|
|
new ResolveOpenWindowRunnable(mPromiseProxy,
|
|
Move(clientInfo),
|
|
NS_OK);
|
|
r->Dispatch();
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHOD
|
|
OnProgressChange(nsIWebProgress* aWebProgress,
|
|
nsIRequest* aRequest,
|
|
int32_t aCurSelfProgress,
|
|
int32_t aMaxSelfProgress,
|
|
int32_t aCurTotalProgress,
|
|
int32_t aMaxTotalProgress) override
|
|
{
|
|
MOZ_ASSERT(false, "Unexpected notification.");
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHOD
|
|
OnLocationChange(nsIWebProgress* aWebProgress,
|
|
nsIRequest* aRequest,
|
|
nsIURI* aLocation,
|
|
uint32_t aFlags) override
|
|
{
|
|
MOZ_ASSERT(false, "Unexpected notification.");
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHOD
|
|
OnStatusChange(nsIWebProgress* aWebProgress,
|
|
nsIRequest* aRequest,
|
|
nsresult aStatus, const char16_t* aMessage) override
|
|
{
|
|
MOZ_ASSERT(false, "Unexpected notification.");
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHOD
|
|
OnSecurityChange(nsIWebProgress* aWebProgress,
|
|
nsIRequest* aRequest,
|
|
uint32_t aState) override
|
|
{
|
|
MOZ_ASSERT(false, "Unexpected notification.");
|
|
return NS_OK;
|
|
}
|
|
|
|
private:
|
|
~WebProgressListener()
|
|
{ }
|
|
|
|
RefPtr<PromiseWorkerProxy> mPromiseProxy;
|
|
RefPtr<ServiceWorkerPrivate> mServiceWorkerPrivate;
|
|
nsCOMPtr<nsPIDOMWindow> mWindow;
|
|
nsCOMPtr<nsIURI> mBaseURI;
|
|
};
|
|
|
|
NS_IMPL_CYCLE_COLLECTING_ADDREF(WebProgressListener)
|
|
NS_IMPL_CYCLE_COLLECTING_RELEASE(WebProgressListener)
|
|
NS_IMPL_CYCLE_COLLECTION(WebProgressListener, mPromiseProxy,
|
|
mServiceWorkerPrivate, mWindow)
|
|
|
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WebProgressListener)
|
|
NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener)
|
|
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
|
|
NS_INTERFACE_MAP_END
|
|
|
|
class OpenWindowRunnable final : public nsRunnable
|
|
{
|
|
RefPtr<PromiseWorkerProxy> mPromiseProxy;
|
|
nsString mUrl;
|
|
nsString mScope;
|
|
|
|
public:
|
|
OpenWindowRunnable(PromiseWorkerProxy* aPromiseProxy,
|
|
const nsAString& aUrl,
|
|
const nsAString& aScope)
|
|
: mPromiseProxy(aPromiseProxy)
|
|
, mUrl(aUrl)
|
|
, mScope(aScope)
|
|
{
|
|
MOZ_ASSERT(aPromiseProxy);
|
|
MOZ_ASSERT(aPromiseProxy->GetWorkerPrivate());
|
|
aPromiseProxy->GetWorkerPrivate()->AssertIsOnWorkerThread();
|
|
}
|
|
|
|
NS_IMETHOD
|
|
Run() override
|
|
{
|
|
AssertIsOnMainThread();
|
|
|
|
MutexAutoLock lock(mPromiseProxy->Lock());
|
|
if (mPromiseProxy->CleanedUp()) {
|
|
return NS_OK;
|
|
}
|
|
|
|
nsCOMPtr<nsPIDOMWindow> window;
|
|
nsresult rv = OpenWindow(getter_AddRefs(window));
|
|
if (NS_SUCCEEDED(rv)) {
|
|
MOZ_ASSERT(window);
|
|
|
|
rv = nsContentUtils::DispatchFocusChromeEvent(window);
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
return rv;
|
|
}
|
|
|
|
WorkerPrivate* workerPrivate = mPromiseProxy->GetWorkerPrivate();
|
|
MOZ_ASSERT(workerPrivate);
|
|
|
|
WorkerPrivate::LocationInfo& info = workerPrivate->GetLocationInfo();
|
|
nsCOMPtr<nsIURI> baseURI;
|
|
nsresult rv = NS_NewURI(getter_AddRefs(baseURI), info.mHref);
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
nsCOMPtr<nsIDocShell> docShell = window->GetDocShell();
|
|
nsCOMPtr<nsIWebProgress> webProgress = do_GetInterface(docShell);
|
|
|
|
if (!webProgress) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
|
MOZ_ASSERT(swm);
|
|
|
|
nsCOMPtr<nsIPrincipal> principal = workerPrivate->GetPrincipal();
|
|
MOZ_ASSERT(principal);
|
|
RefPtr<ServiceWorkerRegistrationInfo> registration =
|
|
swm->GetRegistration(principal, NS_ConvertUTF16toUTF8(mScope));
|
|
if (NS_WARN_IF(!registration)) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
RefPtr<ServiceWorkerInfo> serviceWorkerInfo =
|
|
registration->GetServiceWorkerInfoById(workerPrivate->ServiceWorkerID());
|
|
if (NS_WARN_IF(!serviceWorkerInfo)) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
nsCOMPtr<nsIWebProgressListener> listener =
|
|
new WebProgressListener(mPromiseProxy, serviceWorkerInfo->WorkerPrivate(),
|
|
window, baseURI);
|
|
|
|
rv = webProgress->AddProgressListener(listener,
|
|
nsIWebProgress::NOTIFY_STATE_DOCUMENT);
|
|
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
|
return NS_OK;
|
|
}
|
|
|
|
RefPtr<ResolveOpenWindowRunnable> resolveRunnable =
|
|
new ResolveOpenWindowRunnable(mPromiseProxy, nullptr, rv);
|
|
|
|
NS_WARN_IF(!resolveRunnable->Dispatch());
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
private:
|
|
nsresult
|
|
OpenWindow(nsPIDOMWindow** aWindow)
|
|
{
|
|
WorkerPrivate* workerPrivate = mPromiseProxy->GetWorkerPrivate();
|
|
|
|
// [[1. Let url be the result of parsing url with entry settings object's API
|
|
// base URL.]]
|
|
nsCOMPtr<nsIURI> uri;
|
|
WorkerPrivate::LocationInfo& info = workerPrivate->GetLocationInfo();
|
|
|
|
nsCOMPtr<nsIURI> baseURI;
|
|
nsresult rv = NS_NewURI(getter_AddRefs(baseURI), info.mHref);
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
return NS_ERROR_TYPE_ERR;
|
|
}
|
|
|
|
rv = NS_NewURI(getter_AddRefs(uri), mUrl, nullptr, baseURI);
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
return NS_ERROR_TYPE_ERR;
|
|
}
|
|
|
|
// [[6.1 Open Window]]
|
|
nsCOMPtr<nsIWindowMediator> wm = do_GetService(NS_WINDOWMEDIATOR_CONTRACTID,
|
|
&rv);
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
return rv;
|
|
}
|
|
|
|
if (XRE_IsContentProcess()) {
|
|
// ContentProcess
|
|
nsCOMPtr<nsIWindowWatcher> wwatch =
|
|
do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv);
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
return rv;
|
|
}
|
|
nsCOMPtr<nsPIWindowWatcher> pwwatch(do_QueryInterface(wwatch));
|
|
NS_ENSURE_STATE(pwwatch);
|
|
|
|
nsCString spec;
|
|
uri->GetSpec(spec);
|
|
|
|
nsCOMPtr<nsIDOMWindow> newWindow;
|
|
pwwatch->OpenWindow2(nullptr,
|
|
spec.get(),
|
|
nullptr,
|
|
nullptr,
|
|
false, false, true, nullptr, nullptr, nullptr, 1.0f, 0,
|
|
getter_AddRefs(newWindow));
|
|
nsCOMPtr<nsPIDOMWindow> pwindow = do_QueryInterface(newWindow);
|
|
pwindow.forget(aWindow);
|
|
return NS_OK;
|
|
}
|
|
|
|
// Find the most recent browser window and open a new tab in it.
|
|
nsCOMPtr<nsPIDOMWindow> browserWindow =
|
|
nsContentUtils::GetMostRecentNonPBWindow();
|
|
if (!browserWindow) {
|
|
// It is possible to be running without a browser window on Mac OS, so
|
|
// we need to open a new chrome window.
|
|
// TODO(catalinb): open new chrome window. Bug 1218080
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
nsCOMPtr<nsIDOMChromeWindow> chromeWin = do_QueryInterface(browserWindow);
|
|
if (NS_WARN_IF(!chromeWin)) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
nsCOMPtr<nsIBrowserDOMWindow> bwin;
|
|
chromeWin->GetBrowserDOMWindow(getter_AddRefs(bwin));
|
|
|
|
if (NS_WARN_IF(!bwin)) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
nsCOMPtr<nsIDOMWindow> win;
|
|
rv = bwin->OpenURI(uri, nullptr,
|
|
nsIBrowserDOMWindow::OPEN_DEFAULTWINDOW,
|
|
nsIBrowserDOMWindow::OPEN_NEW,
|
|
getter_AddRefs(win));
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
return rv;
|
|
}
|
|
NS_ENSURE_STATE(win);
|
|
|
|
nsCOMPtr<nsPIDOMWindow> pWin = do_QueryInterface(win);
|
|
pWin = pWin->GetOuterWindow();
|
|
pWin.forget(aWindow);
|
|
|
|
return NS_OK;
|
|
}
|
|
};
|
|
|
|
} // namespace
|
|
|
|
already_AddRefed<Promise>
|
|
ServiceWorkerClients::Get(const nsAString& aClientId, ErrorResult& aRv)
|
|
{
|
|
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
|
|
MOZ_ASSERT(workerPrivate);
|
|
workerPrivate->AssertIsOnWorkerThread();
|
|
|
|
RefPtr<Promise> promise = Promise::Create(mWorkerScope, aRv);
|
|
if (NS_WARN_IF(aRv.Failed())) {
|
|
return nullptr;
|
|
}
|
|
|
|
RefPtr<PromiseWorkerProxy> promiseProxy =
|
|
PromiseWorkerProxy::Create(workerPrivate, promise);
|
|
if (!promiseProxy) {
|
|
promise->MaybeReject(NS_ERROR_DOM_ABORT_ERR);
|
|
return promise.forget();
|
|
}
|
|
|
|
RefPtr<GetRunnable> r =
|
|
new GetRunnable(promiseProxy, aClientId);
|
|
MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(r));
|
|
return promise.forget();
|
|
}
|
|
|
|
already_AddRefed<Promise>
|
|
ServiceWorkerClients::MatchAll(const ClientQueryOptions& aOptions,
|
|
ErrorResult& aRv)
|
|
{
|
|
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
|
|
MOZ_ASSERT(workerPrivate);
|
|
workerPrivate->AssertIsOnWorkerThread();
|
|
|
|
nsString scope;
|
|
mWorkerScope->GetScope(scope);
|
|
|
|
if (aOptions.mType != ClientType::Window) {
|
|
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
|
return nullptr;
|
|
}
|
|
|
|
RefPtr<Promise> promise = Promise::Create(mWorkerScope, aRv);
|
|
if (NS_WARN_IF(aRv.Failed())) {
|
|
return nullptr;
|
|
}
|
|
|
|
RefPtr<PromiseWorkerProxy> promiseProxy =
|
|
PromiseWorkerProxy::Create(workerPrivate, promise);
|
|
if (!promiseProxy) {
|
|
promise->MaybeReject(NS_ERROR_DOM_ABORT_ERR);
|
|
return promise.forget();
|
|
}
|
|
|
|
RefPtr<MatchAllRunnable> r =
|
|
new MatchAllRunnable(promiseProxy,
|
|
NS_ConvertUTF16toUTF8(scope),
|
|
aOptions.mIncludeUncontrolled);
|
|
MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(r));
|
|
return promise.forget();
|
|
}
|
|
|
|
already_AddRefed<Promise>
|
|
ServiceWorkerClients::OpenWindow(const nsAString& aUrl,
|
|
ErrorResult& aRv)
|
|
{
|
|
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
|
|
MOZ_ASSERT(workerPrivate);
|
|
|
|
RefPtr<Promise> promise = Promise::Create(mWorkerScope, aRv);
|
|
if (NS_WARN_IF(aRv.Failed())) {
|
|
return nullptr;
|
|
}
|
|
|
|
if (aUrl.EqualsLiteral("about:blank")) {
|
|
promise->MaybeReject(NS_ERROR_TYPE_ERR);
|
|
return promise.forget();
|
|
}
|
|
|
|
// [[4. If this algorithm is not allowed to show a popup ..]]
|
|
// In Gecko the service worker is allowed to show a popup only if the user
|
|
// just clicked on a notification.
|
|
if (!workerPrivate->GlobalScope()->WindowInteractionAllowed()) {
|
|
promise->MaybeReject(NS_ERROR_DOM_INVALID_ACCESS_ERR);
|
|
return promise.forget();
|
|
}
|
|
|
|
RefPtr<PromiseWorkerProxy> promiseProxy =
|
|
PromiseWorkerProxy::Create(workerPrivate, promise);
|
|
|
|
if (!promiseProxy) {
|
|
return nullptr;
|
|
}
|
|
|
|
nsString scope;
|
|
mWorkerScope->GetScope(scope);
|
|
|
|
RefPtr<OpenWindowRunnable> r = new OpenWindowRunnable(promiseProxy,
|
|
aUrl, scope);
|
|
MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(r));
|
|
|
|
return promise.forget();
|
|
}
|
|
|
|
already_AddRefed<Promise>
|
|
ServiceWorkerClients::Claim(ErrorResult& aRv)
|
|
{
|
|
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
|
|
MOZ_ASSERT(workerPrivate);
|
|
|
|
RefPtr<Promise> promise = Promise::Create(mWorkerScope, aRv);
|
|
if (NS_WARN_IF(aRv.Failed())) {
|
|
return nullptr;
|
|
}
|
|
|
|
RefPtr<PromiseWorkerProxy> promiseProxy =
|
|
PromiseWorkerProxy::Create(workerPrivate, promise);
|
|
if (!promiseProxy) {
|
|
promise->MaybeReject(NS_ERROR_DOM_ABORT_ERR);
|
|
return promise.forget();
|
|
}
|
|
|
|
nsString scope;
|
|
mWorkerScope->GetScope(scope);
|
|
|
|
RefPtr<ClaimRunnable> runnable =
|
|
new ClaimRunnable(promiseProxy, NS_ConvertUTF16toUTF8(scope));
|
|
|
|
MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(runnable));
|
|
return promise.forget();
|
|
}
|