mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 05:37:11 +00:00
Merge commit '65d6aee9e0d586b5a069c6f816e7fe3d18cc381e' into pm27100-vc2010
This commit is contained in:
@@ -14213,7 +14213,8 @@ nsDocShell::ChannelIntercepted(nsIInterceptedChannel* aChannel)
|
||||
}
|
||||
}
|
||||
|
||||
return swm->DispatchFetchEvent(doc, aChannel);
|
||||
bool isReload = mLoadType & LOAD_CMD_RELOAD;
|
||||
return swm->DispatchFetchEvent(doc, aChannel, isReload);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
||||
@@ -1406,7 +1406,7 @@ nsSHistory::RemoveEntries(nsTArray<uint64_t>& aIDs, int32_t aStartIndex)
|
||||
--index;
|
||||
}
|
||||
if (didRemove && mRootDocShell) {
|
||||
nsRefPtr<nsIRunnable> ev =
|
||||
nsCOMPtr<nsIRunnable> ev =
|
||||
NS_NewRunnableMethod(static_cast<nsDocShell*>(mRootDocShell),
|
||||
&nsDocShell::FireDummyOnLocationChange);
|
||||
NS_DispatchToCurrentThread(ev);
|
||||
|
||||
@@ -4403,7 +4403,7 @@ nsDocument::SetStyleSheetApplicableState(nsIStyleSheet* aSheet,
|
||||
}
|
||||
|
||||
if (!mSSApplicableStateNotificationPending) {
|
||||
nsRefPtr<nsIRunnable> notification = NS_NewRunnableMethod(this,
|
||||
nsCOMPtr<nsIRunnable> notification = NS_NewRunnableMethod(this,
|
||||
&nsDocument::NotifyStyleSheetApplicableStateChanged);
|
||||
mSSApplicableStateNotificationPending =
|
||||
NS_SUCCEEDED(NS_DispatchToCurrentThread(notification));
|
||||
@@ -5206,7 +5206,7 @@ nsDocument::UnblockDOMContentLoaded()
|
||||
|
||||
MOZ_ASSERT(mReadyState == READYSTATE_INTERACTIVE);
|
||||
if (!mSynchronousDOMContentLoaded) {
|
||||
nsRefPtr<nsIRunnable> ev =
|
||||
nsCOMPtr<nsIRunnable> ev =
|
||||
NS_NewRunnableMethod(this, &nsDocument::DispatchContentLoadedEvents);
|
||||
NS_DispatchToCurrentThread(ev);
|
||||
} else {
|
||||
|
||||
@@ -2360,7 +2360,7 @@ nsFrameLoader::DoSendAsyncMessage(JSContext* aCx,
|
||||
}
|
||||
|
||||
if (mChildMessageManager) {
|
||||
nsRefPtr<nsIRunnable> ev = new nsAsyncMessageToChild(aCx, this, aMessage,
|
||||
nsCOMPtr<nsIRunnable> ev = new nsAsyncMessageToChild(aCx, this, aMessage,
|
||||
aData, aCpows,
|
||||
aPrincipal);
|
||||
NS_DispatchToCurrentThread(ev);
|
||||
|
||||
@@ -1742,7 +1742,7 @@ public:
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal) override
|
||||
{
|
||||
nsRefPtr<nsIRunnable> ev =
|
||||
nsCOMPtr<nsIRunnable> ev =
|
||||
new nsAsyncMessageToSameProcessChild(aCx, aMessage, aData, aCpows,
|
||||
aPrincipal);
|
||||
NS_DispatchToCurrentThread(ev);
|
||||
|
||||
@@ -9046,7 +9046,7 @@ private:
|
||||
void
|
||||
nsGlobalWindow::NotifyWindowIDDestroyed(const char* aTopic)
|
||||
{
|
||||
nsRefPtr<nsIRunnable> runnable = new WindowDestroyedEvent(this, mWindowID, aTopic);
|
||||
nsCOMPtr<nsIRunnable> runnable = new WindowDestroyedEvent(this, mWindowID, aTopic);
|
||||
nsresult rv = NS_DispatchToCurrentThread(runnable);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mNotifiedIDDestroyed = true;
|
||||
|
||||
Vendored
+1
-1
@@ -162,7 +162,7 @@ FetchPut::DispatchToMainThread()
|
||||
{
|
||||
MOZ_ASSERT(!mRunnable);
|
||||
|
||||
nsRefPtr<nsIRunnable> runnable = new Runnable(this);
|
||||
nsCOMPtr<nsIRunnable> runnable = new Runnable(this);
|
||||
|
||||
nsresult rv = NS_DispatchToMainThread(runnable, nsIThread::DISPATCH_NORMAL);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
|
||||
Vendored
+25
-30
@@ -229,7 +229,7 @@ TypeUtils::ToPCacheResponseWithoutBody(PCacheResponse& aOut,
|
||||
|
||||
aOut.status() = aIn.GetStatus();
|
||||
aOut.statusText() = aIn.GetStatusText();
|
||||
nsRefPtr<InternalHeaders> headers = aIn.Headers();
|
||||
nsRefPtr<InternalHeaders> headers = aIn.UnfilteredHeaders();
|
||||
MOZ_ASSERT(headers);
|
||||
headers->GetPHeaders(aOut.headers());
|
||||
aOut.headersGuard() = headers->Guard();
|
||||
@@ -279,37 +279,14 @@ TypeUtils::ToPCacheQueryParams(PCacheQueryParams& aOut,
|
||||
already_AddRefed<Response>
|
||||
TypeUtils::ToResponse(const PCacheResponse& aIn)
|
||||
{
|
||||
nsRefPtr<InternalResponse> ir;
|
||||
switch (aIn.type())
|
||||
{
|
||||
case ResponseType::Error:
|
||||
ir = InternalResponse::NetworkError();
|
||||
break;
|
||||
case ResponseType::Opaque:
|
||||
ir = InternalResponse::OpaqueResponse();
|
||||
break;
|
||||
case ResponseType::Default:
|
||||
ir = new InternalResponse(aIn.status(), aIn.statusText());
|
||||
break;
|
||||
case ResponseType::Basic:
|
||||
{
|
||||
nsRefPtr<InternalResponse> inner = new InternalResponse(aIn.status(),
|
||||
aIn.statusText());
|
||||
ir = InternalResponse::BasicResponse(inner);
|
||||
break;
|
||||
}
|
||||
case ResponseType::Cors:
|
||||
{
|
||||
nsRefPtr<InternalResponse> inner = new InternalResponse(aIn.status(),
|
||||
aIn.statusText());
|
||||
ir = InternalResponse::CORSResponse(inner);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
MOZ_CRASH("Unexpected ResponseType!");
|
||||
if (aIn.type() == ResponseType::Error) {
|
||||
nsRefPtr<InternalResponse> error = InternalResponse::NetworkError();
|
||||
nsRefPtr<Response> r = new Response(GetGlobalObject(), error);
|
||||
return r.forget();
|
||||
}
|
||||
MOZ_ASSERT(ir);
|
||||
|
||||
nsRefPtr<InternalResponse> ir = new InternalResponse(aIn.status(),
|
||||
aIn.statusText());
|
||||
ir->SetUrl(NS_ConvertUTF16toUTF8(aIn.url()));
|
||||
|
||||
nsRefPtr<InternalHeaders> internalHeaders =
|
||||
@@ -325,6 +302,24 @@ TypeUtils::ToResponse(const PCacheResponse& aIn)
|
||||
nsCOMPtr<nsIInputStream> stream = ReadStream::Create(aIn.body());
|
||||
ir->SetBody(stream);
|
||||
|
||||
switch (aIn.type())
|
||||
{
|
||||
case ResponseType::Default:
|
||||
break;
|
||||
case ResponseType::Opaque:
|
||||
ir = ir->OpaqueResponse();
|
||||
break;
|
||||
case ResponseType::Basic:
|
||||
ir = ir->BasicResponse();
|
||||
break;
|
||||
case ResponseType::Cors:
|
||||
ir = ir->CORSResponse();
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("Unexpected ResponseType!");
|
||||
}
|
||||
MOZ_ASSERT(ir);
|
||||
|
||||
nsRefPtr<Response> ref = new Response(GetGlobalObject(), ir);
|
||||
return ref.forget();
|
||||
}
|
||||
|
||||
+1
-2
@@ -13,8 +13,7 @@
|
||||
<script class="testbody" type="text/javascript">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({
|
||||
"set": [["dom.caches.enabled", true],
|
||||
["dom.fetch.enabled", true]]
|
||||
"set": [["dom.caches.enabled", true]]
|
||||
}, function() {
|
||||
var frame = document.getElementById("frame");
|
||||
frame.src = "test_cache_frame.html";
|
||||
|
||||
@@ -24,7 +24,7 @@ static const TrackID TRACK_VIDEO = 2;
|
||||
void
|
||||
FakeMediaStreamGraph::DispatchToMainThreadAfterStreamStateUpdate(already_AddRefed<nsIRunnable> aRunnable)
|
||||
{
|
||||
nsRefPtr<nsIRunnable> task = aRunnable;
|
||||
nsCOMPtr<nsIRunnable> task = aRunnable;
|
||||
NS_DispatchToMainThread(task);
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
#include "jsapi.h"
|
||||
#include "nsGlobalWindow.h" // So we can assign an nsGlobalWindow* to mWindowSource
|
||||
|
||||
#include "ServiceWorker.h"
|
||||
#include "ServiceWorkerClient.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
@@ -103,12 +106,14 @@ MessageEvent::GetSource(nsIDOMWindow** aSource)
|
||||
}
|
||||
|
||||
void
|
||||
MessageEvent::GetSource(Nullable<OwningWindowProxyOrMessagePort>& aValue) const
|
||||
MessageEvent::GetSource(Nullable<OwningWindowProxyOrMessagePortOrClient>& aValue) const
|
||||
{
|
||||
if (mWindowSource) {
|
||||
aValue.SetValue().SetAsWindowProxy() = mWindowSource;
|
||||
} else if (mPortSource) {
|
||||
aValue.SetValue().SetAsMessagePort() = mPortSource;
|
||||
} else if (mClientSource) {
|
||||
aValue.SetValue().SetAsClient() = mClientSource;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -206,6 +211,12 @@ MessageEvent::SetSource(mozilla::dom::MessagePort* aPort)
|
||||
mPortSource = aPort;
|
||||
}
|
||||
|
||||
void
|
||||
MessageEvent::SetSource(mozilla::dom::workers::ServiceWorkerClient* aClient)
|
||||
{
|
||||
mClientSource = aClient;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
|
||||
@@ -15,7 +15,13 @@ namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
struct MessageEventInit;
|
||||
class OwningWindowProxyOrMessagePort;
|
||||
class OwningWindowProxyOrMessagePortOrClient;
|
||||
|
||||
namespace workers {
|
||||
|
||||
class ServiceWorkerClient;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements the MessageEvent event, used for cross-document messaging and
|
||||
@@ -45,7 +51,7 @@ public:
|
||||
void GetData(JSContext* aCx, JS::MutableHandle<JS::Value> aData,
|
||||
ErrorResult& aRv);
|
||||
|
||||
void GetSource(Nullable<OwningWindowProxyOrMessagePort>& aValue) const;
|
||||
void GetSource(Nullable<OwningWindowProxyOrMessagePortOrClient>& aValue) const;
|
||||
|
||||
MessagePortList* GetPorts()
|
||||
{
|
||||
@@ -57,6 +63,8 @@ public:
|
||||
// Non WebIDL methods
|
||||
void SetSource(mozilla::dom::MessagePort* aPort);
|
||||
|
||||
void SetSource(workers::ServiceWorkerClient* aClient);
|
||||
|
||||
void SetSource(nsPIDOMWindow* aWindow)
|
||||
{
|
||||
mWindowSource = aWindow;
|
||||
@@ -83,6 +91,7 @@ private:
|
||||
nsString mLastEventId;
|
||||
nsCOMPtr<nsIDOMWindow> mWindowSource;
|
||||
nsRefPtr<MessagePortBase> mPortSource;
|
||||
nsRefPtr<workers::ServiceWorkerClient> mClientSource;
|
||||
nsRefPtr<MessagePortList> mPorts;
|
||||
};
|
||||
|
||||
|
||||
@@ -548,13 +548,13 @@ FetchDriver::BeginAndGetFilteredResponse(InternalResponse* aResponse)
|
||||
nsRefPtr<InternalResponse> filteredResponse;
|
||||
switch (mRequest->GetResponseTainting()) {
|
||||
case InternalRequest::RESPONSETAINT_BASIC:
|
||||
filteredResponse = InternalResponse::BasicResponse(aResponse);
|
||||
filteredResponse = aResponse->BasicResponse();
|
||||
break;
|
||||
case InternalRequest::RESPONSETAINT_CORS:
|
||||
filteredResponse = InternalResponse::CORSResponse(aResponse);
|
||||
filteredResponse = aResponse->CORSResponse();
|
||||
break;
|
||||
case InternalRequest::RESPONSETAINT_OPAQUE:
|
||||
filteredResponse = InternalResponse::OpaqueResponse();
|
||||
filteredResponse = aResponse->OpaqueResponse();
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("Unexpected case");
|
||||
|
||||
@@ -22,32 +22,6 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Headers)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
// static
|
||||
bool
|
||||
Headers::PrefEnabled(JSContext* aCx, JSObject* aObj)
|
||||
{
|
||||
using mozilla::dom::workers::WorkerPrivate;
|
||||
using mozilla::dom::workers::GetWorkerPrivateFromContext;
|
||||
|
||||
if (NS_IsMainThread()) {
|
||||
static bool sPrefCacheInit = false;
|
||||
static bool sPrefEnabled = false;
|
||||
if (sPrefCacheInit) {
|
||||
return sPrefEnabled;
|
||||
}
|
||||
Preferences::AddBoolVarCache(&sPrefEnabled, "dom.fetch.enabled");
|
||||
sPrefCacheInit = true;
|
||||
return sPrefEnabled;
|
||||
}
|
||||
|
||||
WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(aCx);
|
||||
if (!workerPrivate) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return workerPrivate->DOMFetchEnabled();
|
||||
}
|
||||
|
||||
// static
|
||||
already_AddRefed<Headers>
|
||||
Headers::Constructor(const GlobalObject& aGlobal,
|
||||
|
||||
@@ -23,25 +23,17 @@ InternalResponse::InternalResponse(uint16_t aStatus, const nsACString& aStatusTe
|
||||
{
|
||||
}
|
||||
|
||||
// Headers are not copied since BasicResponse and CORSResponse both need custom
|
||||
// header handling. Body is not copied as it cannot be shared directly.
|
||||
InternalResponse::InternalResponse(const InternalResponse& aOther)
|
||||
: mType(aOther.mType)
|
||||
, mTerminationReason(aOther.mTerminationReason)
|
||||
, mURL(aOther.mURL)
|
||||
, mFinalURL(aOther.mFinalURL)
|
||||
, mStatus(aOther.mStatus)
|
||||
, mStatusText(aOther.mStatusText)
|
||||
, mContentType(aOther.mContentType)
|
||||
, mSecurityInfo(aOther.mSecurityInfo)
|
||||
{
|
||||
}
|
||||
|
||||
already_AddRefed<InternalResponse>
|
||||
InternalResponse::Clone()
|
||||
{
|
||||
nsRefPtr<InternalResponse> clone = new InternalResponse(*this);
|
||||
nsRefPtr<InternalResponse> clone = CreateIncompleteCopy();
|
||||
|
||||
clone->mHeaders = new InternalHeaders(*mHeaders);
|
||||
if (mWrappedResponse) {
|
||||
clone->mWrappedResponse = mWrappedResponse->Clone();
|
||||
MOZ_ASSERT(!mBody);
|
||||
return clone.forget();
|
||||
}
|
||||
|
||||
if (!mBody) {
|
||||
return clone.forget();
|
||||
@@ -62,27 +54,25 @@ InternalResponse::Clone()
|
||||
return clone.forget();
|
||||
}
|
||||
|
||||
// static
|
||||
already_AddRefed<InternalResponse>
|
||||
InternalResponse::BasicResponse(InternalResponse* aInner)
|
||||
InternalResponse::BasicResponse()
|
||||
{
|
||||
MOZ_ASSERT(aInner);
|
||||
nsRefPtr<InternalResponse> basic = new InternalResponse(*aInner);
|
||||
MOZ_ASSERT(!mWrappedResponse, "Can't BasicResponse a already wrapped response");
|
||||
nsRefPtr<InternalResponse> basic = CreateIncompleteCopy();
|
||||
basic->mType = ResponseType::Basic;
|
||||
basic->mHeaders = InternalHeaders::BasicHeaders(aInner->mHeaders);
|
||||
basic->mBody.swap(aInner->mBody);
|
||||
basic->mHeaders = InternalHeaders::BasicHeaders(Headers());
|
||||
basic->mWrappedResponse = this;
|
||||
return basic.forget();
|
||||
}
|
||||
|
||||
// static
|
||||
already_AddRefed<InternalResponse>
|
||||
InternalResponse::CORSResponse(InternalResponse* aInner)
|
||||
InternalResponse::CORSResponse()
|
||||
{
|
||||
MOZ_ASSERT(aInner);
|
||||
nsRefPtr<InternalResponse> cors = new InternalResponse(*aInner);
|
||||
MOZ_ASSERT(!mWrappedResponse, "Can't CORSResponse a already wrapped response");
|
||||
nsRefPtr<InternalResponse> cors = CreateIncompleteCopy();
|
||||
cors->mType = ResponseType::Cors;
|
||||
cors->mHeaders = InternalHeaders::CORSHeaders(aInner->mHeaders);
|
||||
cors->mBody.swap(aInner->mBody);
|
||||
cors->mHeaders = InternalHeaders::CORSHeaders(Headers());
|
||||
cors->mWrappedResponse = this;
|
||||
return cors.forget();
|
||||
}
|
||||
|
||||
|
||||
@@ -35,27 +35,34 @@ public:
|
||||
return response.forget();
|
||||
}
|
||||
|
||||
static already_AddRefed<InternalResponse>
|
||||
already_AddRefed<InternalResponse>
|
||||
OpaqueResponse()
|
||||
{
|
||||
MOZ_ASSERT(!mWrappedResponse, "Can't OpaqueResponse a already wrapped response");
|
||||
nsRefPtr<InternalResponse> response = new InternalResponse(0, EmptyCString());
|
||||
response->mType = ResponseType::Opaque;
|
||||
response->mTerminationReason = mTerminationReason;
|
||||
response->mURL = mURL;
|
||||
response->mFinalURL = mFinalURL;
|
||||
response->mSecurityInfo = mSecurityInfo;
|
||||
response->mWrappedResponse = this;
|
||||
return response.forget();
|
||||
}
|
||||
|
||||
// DO NOT use the inner response after filtering it since the filtered
|
||||
// response will adopt the inner response's body.
|
||||
static already_AddRefed<InternalResponse>
|
||||
BasicResponse(InternalResponse* aInner);
|
||||
already_AddRefed<InternalResponse>
|
||||
BasicResponse();
|
||||
|
||||
// DO NOT use the inner response after filtering it since the filtered
|
||||
// response will adopt the inner response's body.
|
||||
static already_AddRefed<InternalResponse>
|
||||
CORSResponse(InternalResponse* aInner);
|
||||
already_AddRefed<InternalResponse>
|
||||
CORSResponse();
|
||||
|
||||
ResponseType
|
||||
Type() const
|
||||
{
|
||||
MOZ_ASSERT_IF(mType == ResponseType::Error, !mWrappedResponse);
|
||||
MOZ_ASSERT_IF(mType == ResponseType::Default, !mWrappedResponse);
|
||||
MOZ_ASSERT_IF(mType == ResponseType::Basic, mWrappedResponse);
|
||||
MOZ_ASSERT_IF(mType == ResponseType::Cors, mWrappedResponse);
|
||||
MOZ_ASSERT_IF(mType == ResponseType::Opaque, mWrappedResponse);
|
||||
return mType;
|
||||
}
|
||||
|
||||
@@ -108,9 +115,28 @@ public:
|
||||
return mHeaders;
|
||||
}
|
||||
|
||||
InternalHeaders*
|
||||
UnfilteredHeaders()
|
||||
{
|
||||
if (mWrappedResponse) {
|
||||
return mWrappedResponse->Headers();
|
||||
};
|
||||
|
||||
return Headers();
|
||||
}
|
||||
|
||||
void
|
||||
GetBody(nsIInputStream** aStream)
|
||||
{
|
||||
if (Type() == ResponseType::Opaque) {
|
||||
*aStream = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
if (mWrappedResponse) {
|
||||
MOZ_ASSERT(!mBody);
|
||||
return mWrappedResponse->GetBody(aStream);
|
||||
}
|
||||
nsCOMPtr<nsIInputStream> stream = mBody;
|
||||
stream.forget(aStream);
|
||||
}
|
||||
@@ -118,6 +144,9 @@ public:
|
||||
void
|
||||
SetBody(nsIInputStream* aBody)
|
||||
{
|
||||
if (mWrappedResponse) {
|
||||
return mWrappedResponse->SetBody(aBody);
|
||||
}
|
||||
// A request's body may not be reset once set.
|
||||
MOZ_ASSERT(!mBody);
|
||||
mBody = aBody;
|
||||
@@ -139,9 +168,22 @@ private:
|
||||
~InternalResponse()
|
||||
{ }
|
||||
|
||||
// Used to create filtered and cloned responses.
|
||||
// Does not copy headers or body stream.
|
||||
explicit InternalResponse(const InternalResponse& aOther);
|
||||
explicit InternalResponse(const InternalResponse& aOther) = delete;
|
||||
InternalResponse& operator=(const InternalResponse&) = delete;
|
||||
|
||||
// Returns an instance of InternalResponse which is a copy of this
|
||||
// InternalResponse, except headers, body and wrapped response (if any) which
|
||||
// are left uninitialized. Used for cloning and filtering.
|
||||
already_AddRefed<InternalResponse> CreateIncompleteCopy()
|
||||
{
|
||||
nsRefPtr<InternalResponse> copy = new InternalResponse(mStatus, mStatusText);
|
||||
copy->mType = mType;
|
||||
copy->mTerminationReason = mTerminationReason;
|
||||
copy->mURL = mURL;
|
||||
copy->mFinalURL = mFinalURL;
|
||||
copy->mSecurityInfo = mSecurityInfo;
|
||||
return copy.forget();
|
||||
}
|
||||
|
||||
ResponseType mType;
|
||||
nsCString mTerminationReason;
|
||||
@@ -151,8 +193,13 @@ private:
|
||||
const nsCString mStatusText;
|
||||
nsRefPtr<InternalHeaders> mHeaders;
|
||||
nsCOMPtr<nsIInputStream> mBody;
|
||||
nsCString mContentType;
|
||||
nsCString mSecurityInfo;
|
||||
|
||||
// For filtered responses.
|
||||
// Cache, and SW interception should always serialize/access the underlying
|
||||
// unfiltered headers and when deserializing, create an InternalResponse
|
||||
// with the unfiltered headers followed by wrapping it.
|
||||
nsRefPtr<InternalResponse> mWrappedResponse;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
||||
@@ -19,7 +19,7 @@ interface nsIServiceWorkerUnregisterCallback : nsISupports
|
||||
[noscript] void UnregisterFailed();
|
||||
};
|
||||
|
||||
[builtinclass, uuid(464882c8-81c0-4620-b9c4-44c12085b65b)]
|
||||
[builtinclass, uuid(e4c8baa5-237a-4bf6-82d4-ea06eb4b76ba)]
|
||||
interface nsIServiceWorkerManager : nsISupports
|
||||
{
|
||||
/**
|
||||
@@ -30,7 +30,7 @@ interface nsIServiceWorkerManager : nsISupports
|
||||
*
|
||||
* Returns a Promise.
|
||||
*/
|
||||
nsISupports register(in nsIDOMWindow aWindow, in DOMString aScope, in DOMString aScriptURI);
|
||||
nsISupports register(in nsIDOMWindow aWindow, in nsIURI aScope, in nsIURI aScriptURI);
|
||||
|
||||
/**
|
||||
* Unregister an existing ServiceWorker registration for `aScope`.
|
||||
@@ -59,7 +59,8 @@ interface nsIServiceWorkerManager : nsISupports
|
||||
bool isControlled(in nsIDocument aDocument);
|
||||
|
||||
// Cause a fetch event to be dispatched to the worker global associated with the given document.
|
||||
void dispatchFetchEvent(in nsIDocument aDoc, in nsIInterceptedChannel aChannel);
|
||||
void dispatchFetchEvent(in nsIDocument aDoc, in nsIInterceptedChannel aChannel,
|
||||
in boolean aIsReload);
|
||||
|
||||
// aTarget MUST be a ServiceWorkerRegistration.
|
||||
[noscript] void AddRegistrationEventListener(in DOMString aScope, in nsIDOMEventTarget aTarget);
|
||||
|
||||
@@ -280,7 +280,7 @@ class MediaRecorder::Session: public nsIObserver
|
||||
LOG(PR_LOG_DEBUG, ("Session.ExtractRunnable shutdown = %d", mSession->mEncoder->IsShutdown()));
|
||||
if (!mSession->mEncoder->IsShutdown()) {
|
||||
mSession->Extract(false);
|
||||
nsRefPtr<nsIRunnable> event = new ExtractRunnable(mSession);
|
||||
nsCOMPtr<nsIRunnable> event = new ExtractRunnable(mSession);
|
||||
if (NS_FAILED(NS_DispatchToCurrentThread(event))) {
|
||||
NS_WARNING("Failed to dispatch ExtractRunnable to encoder thread");
|
||||
}
|
||||
@@ -634,7 +634,7 @@ private:
|
||||
// shutdown notification and stop Read Thread.
|
||||
nsContentUtils::RegisterShutdownObserver(this);
|
||||
|
||||
nsRefPtr<nsIRunnable> event = new ExtractRunnable(this);
|
||||
nsCOMPtr<nsIRunnable> event = new ExtractRunnable(this);
|
||||
if (NS_FAILED(mReadThread->Dispatch(event, NS_DISPATCH_NORMAL))) {
|
||||
NS_WARNING("Failed to dispatch ExtractRunnable at beginning");
|
||||
}
|
||||
|
||||
@@ -2236,7 +2236,7 @@ MediaStream::RemoveListener(MediaStreamListener* aListener)
|
||||
}
|
||||
|
||||
void
|
||||
MediaStream::RunAfterPendingUpdates(nsRefPtr<nsIRunnable> aRunnable)
|
||||
MediaStream::RunAfterPendingUpdates(nsCOMPtr<nsIRunnable> aRunnable)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MediaStreamGraphImpl* graph = GraphImpl();
|
||||
@@ -2266,7 +2266,7 @@ MediaStream::RunAfterPendingUpdates(nsRefPtr<nsIRunnable> aRunnable)
|
||||
NS_DispatchToCurrentThread(mRunnable);
|
||||
}
|
||||
private:
|
||||
nsRefPtr<nsIRunnable> mRunnable;
|
||||
nsCOMPtr<nsIRunnable> mRunnable;
|
||||
};
|
||||
|
||||
graph->AppendMessage(new Message(this, aRunnable.forget()));
|
||||
|
||||
@@ -397,7 +397,7 @@ public:
|
||||
*
|
||||
* Main thread only.
|
||||
*/
|
||||
void RunAfterPendingUpdates(nsRefPtr<nsIRunnable> aRunnable);
|
||||
void RunAfterPendingUpdates(nsCOMPtr<nsIRunnable> aRunnable);
|
||||
|
||||
// Signal that the client is done with this MediaStream. It will be deleted later.
|
||||
virtual void Destroy();
|
||||
|
||||
@@ -625,7 +625,7 @@ GoannaMediaPluginService::AsyncShutdownComplete(GMPParent* aParent)
|
||||
if (mAsyncShutdownPlugins.IsEmpty() && mShuttingDownOnGMPThread) {
|
||||
// The main thread may be waiting for async shutdown of plugins,
|
||||
// which has completed. Break the main thread out of its waiting loop.
|
||||
nsRefPtr<nsIRunnable> task(NS_NewRunnableMethod(
|
||||
nsCOMPtr<nsIRunnable> task(NS_NewRunnableMethod(
|
||||
this, &GoannaMediaPluginService::SetAsyncShutdownComplete));
|
||||
NS_DispatchToMainThread(task);
|
||||
}
|
||||
@@ -659,7 +659,7 @@ GoannaMediaPluginService::UnloadPlugins()
|
||||
}
|
||||
|
||||
if (mAsyncShutdownPlugins.IsEmpty()) {
|
||||
nsRefPtr<nsIRunnable> task(NS_NewRunnableMethod(
|
||||
nsCOMPtr<nsIRunnable> task(NS_NewRunnableMethod(
|
||||
this, &GoannaMediaPluginService::SetAsyncShutdownComplete));
|
||||
NS_DispatchToMainThread(task);
|
||||
}
|
||||
|
||||
@@ -221,8 +221,8 @@ public:
|
||||
|
||||
private:
|
||||
virtual ~GMPShutdownObserver() {}
|
||||
nsRefPtr<nsIRunnable> mShutdownTask;
|
||||
nsRefPtr<nsIRunnable> mContinuation;
|
||||
nsCOMPtr<nsIRunnable> mShutdownTask;
|
||||
nsCOMPtr<nsIRunnable> mContinuation;
|
||||
const nsString mNodeId;
|
||||
};
|
||||
|
||||
@@ -290,7 +290,7 @@ public:
|
||||
|
||||
private:
|
||||
virtual ~ClearGMPStorageTask() {}
|
||||
nsRefPtr<nsIRunnable> mContinuation;
|
||||
nsCOMPtr<nsIRunnable> mContinuation;
|
||||
nsCOMPtr<nsIThread> mTarget;
|
||||
const PRTime mSince;
|
||||
};
|
||||
@@ -1093,7 +1093,7 @@ class GMPStorageTest : public GMPDecryptorProxyCallback
|
||||
bool matches = mExpected[0].mMessage.Equals(msg);
|
||||
EXPECT_STREQ(mExpected[0].mMessage.get(), msg.get());
|
||||
if (mExpected.Length() > 0 && matches) {
|
||||
nsRefPtr<nsIRunnable> continuation = mExpected[0].mContinuation;
|
||||
nsCOMPtr<nsIRunnable> continuation = mExpected[0].mContinuation;
|
||||
mExpected.RemoveElementAt(0);
|
||||
if (continuation) {
|
||||
NS_DispatchToCurrentThread(continuation);
|
||||
@@ -1134,7 +1134,7 @@ private:
|
||||
, mContinuation(aContinuation)
|
||||
{}
|
||||
nsCString mMessage;
|
||||
nsRefPtr<nsIRunnable> mContinuation;
|
||||
nsCOMPtr<nsIRunnable> mContinuation;
|
||||
};
|
||||
|
||||
nsTArray<ExpectedMessage> mExpected;
|
||||
|
||||
@@ -529,7 +529,7 @@ MediaSource::QueueInitializationEvent()
|
||||
}
|
||||
mFirstSourceBufferInitialized = true;
|
||||
MSE_DEBUG("");
|
||||
nsRefPtr<nsIRunnable> task =
|
||||
nsCOMPtr<nsIRunnable> task =
|
||||
NS_NewRunnableMethod(this, &MediaSource::InitializationEvent);
|
||||
NS_DispatchToMainThread(task);
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ MediaDataDecoderProxy::Input(MediaRawData* aSample)
|
||||
MOZ_ASSERT(!IsOnProxyThread());
|
||||
MOZ_ASSERT(!mIsShutdown);
|
||||
|
||||
nsRefPtr<nsIRunnable> task(new InputTask(mProxyDecoder, aSample));
|
||||
nsCOMPtr<nsIRunnable> task(new InputTask(mProxyDecoder, aSample));
|
||||
nsresult rv = mProxyThread->Dispatch(task, NS_DISPATCH_NORMAL);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
@@ -54,7 +54,7 @@ MediaDataDecoderProxy::Flush()
|
||||
|
||||
mFlushComplete.Set(false);
|
||||
|
||||
nsRefPtr<nsIRunnable> task;
|
||||
nsCOMPtr<nsIRunnable> task;
|
||||
task = NS_NewRunnableMethod(mProxyDecoder, &MediaDataDecoder::Flush);
|
||||
nsresult rv = mProxyThread->Dispatch(task, NS_DISPATCH_NORMAL);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
@@ -70,7 +70,7 @@ MediaDataDecoderProxy::Drain()
|
||||
MOZ_ASSERT(!IsOnProxyThread());
|
||||
MOZ_ASSERT(!mIsShutdown);
|
||||
|
||||
nsRefPtr<nsIRunnable> task;
|
||||
nsCOMPtr<nsIRunnable> task;
|
||||
task = NS_NewRunnableMethod(mProxyDecoder, &MediaDataDecoder::Drain);
|
||||
nsresult rv = mProxyThread->Dispatch(task, NS_DISPATCH_NORMAL);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
@@ -85,7 +85,7 @@ MediaDataDecoderProxy::Shutdown()
|
||||
#if defined(DEBUG)
|
||||
mIsShutdown = true;
|
||||
#endif
|
||||
nsRefPtr<nsIRunnable> task;
|
||||
nsCOMPtr<nsIRunnable> task;
|
||||
task = NS_NewRunnableMethod(mProxyDecoder, &MediaDataDecoder::Shutdown);
|
||||
nsresult rv = mProxyThread->Dispatch(task, NS_DISPATCH_SYNC);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
@@ -348,7 +348,7 @@ AudioNode::Disconnect(uint32_t aOutput, ErrorResult& aRv)
|
||||
// Remove one instance of 'dest' from mOutputNodes. There could be
|
||||
// others, and it's not correct to remove them all since some of them
|
||||
// could be for different output ports.
|
||||
nsRefPtr<nsIRunnable> runnable =
|
||||
nsCOMPtr<nsIRunnable> runnable =
|
||||
new RunnableRelease(mOutputNodes[i].forget());
|
||||
mOutputNodes.RemoveElementAt(i);
|
||||
mStream->RunAfterPendingUpdates(runnable.forget());
|
||||
|
||||
@@ -385,7 +385,7 @@ bool
|
||||
Promise::PerformMicroTaskCheckpoint()
|
||||
{
|
||||
CycleCollectedJSRuntime* runtime = CycleCollectedJSRuntime::Get();
|
||||
nsTArray<nsRefPtr<nsIRunnable>>& microtaskQueue =
|
||||
nsTArray<nsCOMPtr<nsIRunnable>>& microtaskQueue =
|
||||
runtime->GetPromiseMicroTaskQueue();
|
||||
|
||||
if (microtaskQueue.IsEmpty()) {
|
||||
@@ -393,7 +393,7 @@ Promise::PerformMicroTaskCheckpoint()
|
||||
}
|
||||
|
||||
do {
|
||||
nsRefPtr<nsIRunnable> runnable = microtaskQueue.ElementAt(0);
|
||||
nsCOMPtr<nsIRunnable> runnable = microtaskQueue.ElementAt(0);
|
||||
MOZ_ASSERT(runnable);
|
||||
|
||||
// This function can re-enter, so we remove the element before calling.
|
||||
@@ -1038,7 +1038,7 @@ Promise::DispatchToMicroTask(nsIRunnable* aRunnable)
|
||||
MOZ_ASSERT(aRunnable);
|
||||
|
||||
CycleCollectedJSRuntime* runtime = CycleCollectedJSRuntime::Get();
|
||||
nsTArray<nsRefPtr<nsIRunnable>>& microtaskQueue =
|
||||
nsTArray<nsCOMPtr<nsIRunnable>>& microtaskQueue =
|
||||
runtime->GetPromiseMicroTaskQueue();
|
||||
|
||||
microtaskQueue.AppendElement(aRunnable);
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
function testScript(script) {
|
||||
function workerTest() {
|
||||
return new Promise(function(resolve, reject) {
|
||||
var worker = new Worker("worker_wrapper.js");
|
||||
worker.onmessage = function(event) {
|
||||
if (event.data.type == 'finish') {
|
||||
resolve();
|
||||
} else if (event.data.type == 'status') {
|
||||
ok(event.data.status, "Worker fetch test: " + event.data.msg);
|
||||
}
|
||||
}
|
||||
worker.onerror = function(event) {
|
||||
reject("Worker error: " + event.message);
|
||||
};
|
||||
|
||||
worker.postMessage({ "script": script });
|
||||
});
|
||||
}
|
||||
|
||||
function windowTest() {
|
||||
return new Promise(function(resolve, reject) {
|
||||
var scriptEl = document.createElement("script");
|
||||
scriptEl.setAttribute("src", script);
|
||||
scriptEl.onload = function() {
|
||||
runTest().then(resolve, reject);
|
||||
};
|
||||
document.body.appendChild(scriptEl);
|
||||
});
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
// We have to run the window and worker tests sequentially since some tests
|
||||
// set and compare cookies and running in parallel can lead to conflicting
|
||||
// values.
|
||||
windowTest()
|
||||
.then(function() {
|
||||
return workerTest();
|
||||
})
|
||||
.catch(function(e) {
|
||||
ok(false, "Some test failed in " + script);
|
||||
info(e);
|
||||
info(e.message);
|
||||
return Promise.resolve();
|
||||
})
|
||||
.then(function() {
|
||||
SimpleTest.finish();
|
||||
});
|
||||
}
|
||||
|
||||
// Utilities
|
||||
// =========
|
||||
|
||||
// Helper that uses FileReader or FileReaderSync based on context and returns
|
||||
// a Promise that resolves with the text or rejects with error.
|
||||
function readAsText(blob) {
|
||||
if (typeof FileReader !== "undefined") {
|
||||
return new Promise(function(resolve, reject) {
|
||||
var fs = new FileReader();
|
||||
fs.onload = function() {
|
||||
resolve(fs.result);
|
||||
}
|
||||
fs.onerror = reject;
|
||||
fs.readAsText(blob);
|
||||
});
|
||||
} else {
|
||||
var fs = new FileReaderSync();
|
||||
return Promise.resolve(fs.readAsText(blob));
|
||||
}
|
||||
}
|
||||
|
||||
function readAsArrayBuffer(blob) {
|
||||
if (typeof FileReader !== "undefined") {
|
||||
return new Promise(function(resolve, reject) {
|
||||
var fs = new FileReader();
|
||||
fs.onload = function() {
|
||||
resolve(fs.result);
|
||||
}
|
||||
fs.onerror = reject;
|
||||
fs.readAsArrayBuffer(blob);
|
||||
});
|
||||
} else {
|
||||
var fs = new FileReaderSync();
|
||||
return Promise.resolve(fs.readAsArrayBuffer(blob));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,12 +42,8 @@ function testOnWorker(done) {
|
||||
// Driver
|
||||
//
|
||||
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["dom.fetch.enabled", true]
|
||||
]}, function() {
|
||||
testOnWorker(function() {
|
||||
SimpleTest.finish();
|
||||
});
|
||||
testOnWorker(function() {
|
||||
SimpleTest.finish();
|
||||
});
|
||||
</script>
|
||||
</script>
|
||||
|
||||
@@ -42,12 +42,8 @@ function testOnWorker(done) {
|
||||
// Driver
|
||||
//
|
||||
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["dom.fetch.enabled", true]
|
||||
]}, function() {
|
||||
testOnWorker(function() {
|
||||
SimpleTest.finish();
|
||||
});
|
||||
testOnWorker(function() {
|
||||
SimpleTest.finish();
|
||||
});
|
||||
</script>
|
||||
</script>
|
||||
|
||||
@@ -36,11 +36,7 @@
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["dom.fetch.enabled", true]
|
||||
]}, function() {
|
||||
runTest();
|
||||
});
|
||||
runTest();
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
@@ -42,12 +42,8 @@ function testOnWorker(done) {
|
||||
// Driver
|
||||
//
|
||||
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["dom.fetch.enabled", true]
|
||||
]}, function() {
|
||||
testOnWorker(function() {
|
||||
SimpleTest.finish();
|
||||
});
|
||||
testOnWorker(function() {
|
||||
SimpleTest.finish();
|
||||
});
|
||||
</script>
|
||||
</script>
|
||||
|
||||
@@ -53,13 +53,9 @@ function testOnMainThread(done) {
|
||||
// Driver
|
||||
//
|
||||
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["dom.fetch.enabled", true]
|
||||
]}, function() {
|
||||
testOnMainThread(function() {
|
||||
testOnWorker(function() {
|
||||
SimpleTest.finish();
|
||||
});
|
||||
testOnMainThread(function() {
|
||||
testOnWorker(function() {
|
||||
SimpleTest.finish();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Bug XXXXXX - Test Request object in worker</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
<script type="text/javascript" src="fetch_test_framework.js"> </script>
|
||||
<script class="testbody" type="text/javascript">
|
||||
testScript("test_request.js");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Bug 1039846 - Test Response object in worker</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
<script type="text/javascript" src="fetch_test_framework.js"> </script>
|
||||
<script class="testbody" type="text/javascript">
|
||||
testScript("test_response.js");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -437,7 +437,7 @@ var interfaceNamesInGlobalScope =
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"HashChangeEvent",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "Headers", pref: "dom.fetch.enabled"},
|
||||
"Headers",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"History",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
@@ -873,9 +873,9 @@ var interfaceNamesInGlobalScope =
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"Rect",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "Request", pref: "dom.fetch.enabled"},
|
||||
"Request",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "Response", pref: "dom.fetch.enabled"},
|
||||
"Response",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"RGBColor",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
|
||||
@@ -27,7 +27,7 @@ interface Body {
|
||||
|
||||
[NoInterfaceObject, Exposed=(Window,Worker)]
|
||||
interface GlobalFetch {
|
||||
[Throws, Func="mozilla::dom::Headers::PrefEnabled"]
|
||||
[Throws]
|
||||
Promise<Response> fetch(RequestInfo input, optional RequestInit init);
|
||||
};
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ interface FetchEvent : Event {
|
||||
readonly attribute boolean isReload;
|
||||
|
||||
[Throws] void respondWith(Promise<Response> r);
|
||||
[Throws] void respondWith(Response r);
|
||||
Promise<Response> forwardTo(USVString url);
|
||||
Promise<Response> default();
|
||||
};
|
||||
|
||||
@@ -19,8 +19,7 @@ enum HeadersGuardEnum {
|
||||
};
|
||||
|
||||
[Constructor(optional HeadersInit init),
|
||||
Exposed=(Window,Worker),
|
||||
Func="mozilla::dom::Headers::PrefEnabled"]
|
||||
Exposed=(Window,Worker)]
|
||||
interface Headers {
|
||||
[Throws] void append(ByteString name, ByteString value);
|
||||
[Throws] void delete(ByteString name);
|
||||
|
||||
@@ -31,9 +31,12 @@ interface MessageEvent : Event {
|
||||
readonly attribute DOMString lastEventId;
|
||||
|
||||
/**
|
||||
* The window or the port which originated this event.
|
||||
* The window, port or client which originated this event.
|
||||
* FIXME(catalinb): Update this when the spec changes are implemented.
|
||||
* https://www.w3.org/Bugs/Public/show_bug.cgi?id=28199
|
||||
* https://bugzilla.mozilla.org/show_bug.cgi?id=1143717
|
||||
*/
|
||||
readonly attribute (WindowProxy or MessagePort)? source;
|
||||
readonly attribute (WindowProxy or MessagePort or Client)? source;
|
||||
|
||||
/**
|
||||
* Initializes this event with the given data, in a manner analogous to
|
||||
|
||||
@@ -10,8 +10,7 @@
|
||||
typedef (Request or USVString) RequestInfo;
|
||||
|
||||
[Constructor(RequestInfo input, optional RequestInit init),
|
||||
Exposed=(Window,Worker),
|
||||
Func="mozilla::dom::Headers::PrefEnabled"]
|
||||
Exposed=(Window,Worker)]
|
||||
interface Request {
|
||||
readonly attribute ByteString method;
|
||||
readonly attribute USVString url;
|
||||
|
||||
@@ -8,8 +8,7 @@
|
||||
*/
|
||||
|
||||
[Constructor(optional BodyInit body, optional ResponseInit init),
|
||||
Exposed=(Window,Worker),
|
||||
Func="mozilla::dom::Headers::PrefEnabled"]
|
||||
Exposed=(Window,Worker)]
|
||||
interface Response {
|
||||
[NewObject] static Response error();
|
||||
[Throws,
|
||||
|
||||
@@ -21,7 +21,7 @@ interface ServiceWorkerContainer : EventTarget {
|
||||
|
||||
[Throws]
|
||||
Promise<ServiceWorkerRegistration> register(USVString scriptURL,
|
||||
optional RegistrationOptionList options);
|
||||
optional RegistrationOptions options);
|
||||
|
||||
[Throws]
|
||||
Promise<ServiceWorkerRegistration> getRegistration(optional USVString documentURL = "");
|
||||
@@ -47,6 +47,6 @@ partial interface ServiceWorkerContainer {
|
||||
DOMString getControllingWorkerScriptURLForPath(DOMString path);
|
||||
};
|
||||
|
||||
dictionary RegistrationOptionList {
|
||||
USVString scope = "/";
|
||||
dictionary RegistrationOptions {
|
||||
USVString scope;
|
||||
};
|
||||
|
||||
@@ -59,7 +59,6 @@
|
||||
#endif
|
||||
|
||||
#include "Principal.h"
|
||||
#include "ServiceWorker.h"
|
||||
#include "SharedWorker.h"
|
||||
#include "WorkerPrivate.h"
|
||||
#include "WorkerRunnable.h"
|
||||
@@ -155,7 +154,6 @@ static_assert(MAX_WORKERS_PER_DOMAIN >= 1,
|
||||
#define PREF_DOM_WINDOW_DUMP_ENABLED "browser.dom.window.dump.enabled"
|
||||
#endif
|
||||
|
||||
#define PREF_DOM_FETCH_ENABLED "dom.fetch.enabled"
|
||||
#define PREF_DOM_CACHES_ENABLED "dom.caches.enabled"
|
||||
#define PREF_WORKERS_LATEST_JS_VERSION "dom.workers.latestJSVersion"
|
||||
#define PREF_INTL_ACCEPT_LANGUAGES "intl.accept_languages"
|
||||
@@ -1433,6 +1431,13 @@ RuntimeService::RegisterWorker(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
|
||||
NS_ASSERTION(!sharedWorkerScriptSpec.IsEmpty(), "Empty spec!");
|
||||
}
|
||||
|
||||
bool exemptFromPerDomainMax = false;
|
||||
if (aWorkerPrivate->IsServiceWorker()) {
|
||||
AssertIsOnMainThread();
|
||||
exemptFromPerDomainMax = Preferences::GetBool("dom.serviceWorkers.exemptFromPerDomainMax",
|
||||
false);
|
||||
}
|
||||
|
||||
const nsCString& domain = aWorkerPrivate->Domain();
|
||||
|
||||
WorkerDomainInfo* domainInfo;
|
||||
@@ -1450,7 +1455,8 @@ RuntimeService::RegisterWorker(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
|
||||
|
||||
queued = gMaxWorkersPerDomain &&
|
||||
domainInfo->ActiveWorkerCount() >= gMaxWorkersPerDomain &&
|
||||
!domain.IsEmpty();
|
||||
!domain.IsEmpty() &&
|
||||
!exemptFromPerDomainMax;
|
||||
|
||||
if (queued) {
|
||||
domainInfo->mQueuedWorkers.AppendElement(aWorkerPrivate);
|
||||
@@ -1838,10 +1844,6 @@ RuntimeService::Init()
|
||||
PREF_DOM_WINDOW_DUMP_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_DUMP))) ||
|
||||
#endif
|
||||
NS_FAILED(Preferences::RegisterCallbackAndCall(
|
||||
WorkerPrefChanged,
|
||||
PREF_DOM_FETCH_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_DOM_FETCH))) ||
|
||||
NS_FAILED(Preferences::RegisterCallbackAndCall(
|
||||
WorkerPrefChanged,
|
||||
PREF_DOM_CACHES_ENABLED,
|
||||
@@ -2039,10 +2041,6 @@ RuntimeService::Cleanup()
|
||||
WorkerPrefChanged,
|
||||
PREF_DOM_CACHES_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_DOM_CACHES))) ||
|
||||
NS_FAILED(Preferences::UnregisterCallback(
|
||||
WorkerPrefChanged,
|
||||
PREF_DOM_FETCH_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_DOM_FETCH))) ||
|
||||
#if DUMP_CONTROLLED_BY_PREF
|
||||
NS_FAILED(Preferences::UnregisterCallback(
|
||||
WorkerPrefChanged,
|
||||
@@ -2260,61 +2258,6 @@ RuntimeService::ResumeWorkersForWindow(nsPIDOMWindow* aWindow)
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
RuntimeService::CreateServiceWorker(const GlobalObject& aGlobal,
|
||||
const nsAString& aScriptURL,
|
||||
const nsACString& aScope,
|
||||
ServiceWorker** aServiceWorker)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aGlobal.GetAsSupports());
|
||||
MOZ_ASSERT(window);
|
||||
|
||||
nsRefPtr<SharedWorker> sharedWorker;
|
||||
rv = CreateSharedWorkerInternal(aGlobal, aScriptURL, aScope,
|
||||
WorkerTypeService,
|
||||
getter_AddRefs(sharedWorker));
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsRefPtr<ServiceWorker> serviceWorker =
|
||||
new ServiceWorker(window, sharedWorker);
|
||||
|
||||
serviceWorker->mURL = aScriptURL;
|
||||
|
||||
serviceWorker.forget(aServiceWorker);
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
RuntimeService::CreateServiceWorkerFromLoadInfo(JSContext* aCx,
|
||||
WorkerPrivate::LoadInfo* aLoadInfo,
|
||||
const nsAString& aScriptURL,
|
||||
const nsACString& aScope,
|
||||
ServiceWorker** aServiceWorker)
|
||||
{
|
||||
|
||||
nsRefPtr<SharedWorker> sharedWorker;
|
||||
nsresult rv = CreateSharedWorkerFromLoadInfo(aCx, aLoadInfo, aScriptURL, aScope,
|
||||
WorkerTypeService,
|
||||
getter_AddRefs(sharedWorker));
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsRefPtr<ServiceWorker> serviceWorker =
|
||||
new ServiceWorker(nullptr, sharedWorker);
|
||||
|
||||
serviceWorker->mURL = aScriptURL;
|
||||
|
||||
serviceWorker.forget(aServiceWorker);
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
RuntimeService::CreateSharedWorkerInternal(const GlobalObject& aGlobal,
|
||||
const nsAString& aScriptURL,
|
||||
@@ -2330,7 +2273,7 @@ RuntimeService::CreateSharedWorkerInternal(const GlobalObject& aGlobal,
|
||||
|
||||
JSContext* cx = aGlobal.Context();
|
||||
|
||||
WorkerPrivate::LoadInfo loadInfo;
|
||||
WorkerLoadInfo loadInfo;
|
||||
nsresult rv = WorkerPrivate::GetLoadInfo(cx, window, nullptr, aScriptURL,
|
||||
false,
|
||||
WorkerPrivate::OverrideLoadGroup,
|
||||
@@ -2343,7 +2286,7 @@ RuntimeService::CreateSharedWorkerInternal(const GlobalObject& aGlobal,
|
||||
|
||||
nsresult
|
||||
RuntimeService::CreateSharedWorkerFromLoadInfo(JSContext* aCx,
|
||||
WorkerPrivate::LoadInfo* aLoadInfo,
|
||||
WorkerLoadInfo* aLoadInfo,
|
||||
const nsAString& aScriptURL,
|
||||
const nsACString& aName,
|
||||
WorkerType aType,
|
||||
@@ -2628,18 +2571,11 @@ RuntimeService::WorkerPrefChanged(const char* aPrefName, void* aClosure)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (key == WORKERPREF_DOM_FETCH) {
|
||||
key = WORKERPREF_DOM_FETCH;
|
||||
sDefaultPreferences[WORKERPREF_DOM_FETCH] =
|
||||
Preferences::GetBool(PREF_DOM_FETCH_ENABLED, false);
|
||||
}
|
||||
|
||||
if (key == WORKERPREF_DOM_CACHES) {
|
||||
key = WORKERPREF_DOM_CACHES;
|
||||
sDefaultPreferences[WORKERPREF_DOM_CACHES] =
|
||||
Preferences::GetBool(PREF_DOM_CACHES_ENABLED, false);
|
||||
}
|
||||
|
||||
// This function should never be registered as a callback for a preference it
|
||||
// does not handle.
|
||||
MOZ_ASSERT(key != WORKERPREF_COUNT);
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#define mozilla_dom_workers_runtimeservice_h__
|
||||
|
||||
#include "Workers.h"
|
||||
#include "WorkerPrivate.h" // For the WorkerType enum.
|
||||
|
||||
#include "nsIObserver.h"
|
||||
|
||||
@@ -16,7 +15,6 @@
|
||||
#include "nsClassHashtable.h"
|
||||
#include "nsHashKeys.h"
|
||||
#include "nsTArray.h"
|
||||
#include "WorkerPrivate.h"
|
||||
|
||||
class nsIRunnable;
|
||||
class nsITimer;
|
||||
@@ -24,7 +22,6 @@ class nsPIDOMWindow;
|
||||
|
||||
BEGIN_WORKERS_NAMESPACE
|
||||
|
||||
class ServiceWorker;
|
||||
class SharedWorker;
|
||||
class WorkerThread;
|
||||
|
||||
@@ -148,17 +145,25 @@ public:
|
||||
}
|
||||
|
||||
nsresult
|
||||
CreateServiceWorker(const GlobalObject& aGlobal,
|
||||
const nsAString& aScriptURL,
|
||||
const nsACString& aScope,
|
||||
ServiceWorker** aServiceWorker);
|
||||
CreateSharedWorkerForServiceWorker(const GlobalObject& aGlobal,
|
||||
const nsAString& aScriptURL,
|
||||
const nsACString& aScope,
|
||||
SharedWorker** aSharedWorker)
|
||||
{
|
||||
return CreateSharedWorkerInternal(aGlobal, aScriptURL, aScope,
|
||||
WorkerTypeService, aSharedWorker);
|
||||
}
|
||||
|
||||
nsresult
|
||||
CreateServiceWorkerFromLoadInfo(JSContext* aCx,
|
||||
WorkerPrivate::LoadInfo* aLoadInfo,
|
||||
const nsAString& aScriptURL,
|
||||
const nsACString& aScope,
|
||||
ServiceWorker** aServiceWorker);
|
||||
CreateSharedWorkerForServiceWorkerFromLoadInfo(JSContext* aCx,
|
||||
WorkerLoadInfo* aLoadInfo,
|
||||
const nsAString& aScriptURL,
|
||||
const nsACString& aScope,
|
||||
SharedWorker** aSharedWorker)
|
||||
{
|
||||
return CreateSharedWorkerFromLoadInfo(aCx, aLoadInfo, aScriptURL, aScope,
|
||||
WorkerTypeService, aSharedWorker);
|
||||
}
|
||||
|
||||
void
|
||||
ForgetSharedWorker(WorkerPrivate* aWorkerPrivate);
|
||||
@@ -308,7 +313,7 @@ private:
|
||||
|
||||
nsresult
|
||||
CreateSharedWorkerFromLoadInfo(JSContext* aCx,
|
||||
WorkerPrivate::LoadInfo* aLoadInfo,
|
||||
WorkerLoadInfo* aLoadInfo,
|
||||
const nsAString& aScriptURL,
|
||||
const nsACString& aName,
|
||||
WorkerType aType,
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
#include "ServiceWorker.h"
|
||||
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "ServiceWorkerClient.h"
|
||||
#include "ServiceWorkerManager.h"
|
||||
#include "SharedWorker.h"
|
||||
#include "WorkerPrivate.h"
|
||||
|
||||
@@ -38,18 +40,24 @@ ServiceWorkerVisible(JSContext* aCx, JSObject* aObj)
|
||||
}
|
||||
|
||||
ServiceWorker::ServiceWorker(nsPIDOMWindow* aWindow,
|
||||
ServiceWorkerInfo* aInfo,
|
||||
SharedWorker* aSharedWorker)
|
||||
: DOMEventTargetHelper(aWindow),
|
||||
mState(ServiceWorkerState::Installing),
|
||||
mInfo(aInfo),
|
||||
mSharedWorker(aSharedWorker)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(aInfo);
|
||||
MOZ_ASSERT(mSharedWorker);
|
||||
|
||||
// This will update our state too.
|
||||
mInfo->AppendWorker(this);
|
||||
}
|
||||
|
||||
ServiceWorker::~ServiceWorker()
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
mInfo->RemoveWorker(this);
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(ServiceWorker, DOMEventTargetHelper)
|
||||
@@ -69,6 +77,12 @@ ServiceWorker::WrapObject(JSContext* aCx)
|
||||
return ServiceWorkerBinding::Wrap(aCx, this);
|
||||
}
|
||||
|
||||
void
|
||||
ServiceWorker::GetScriptURL(nsString& aURL) const
|
||||
{
|
||||
CopyUTF8toUTF16(mInfo->ScriptSpec(), aURL);
|
||||
}
|
||||
|
||||
void
|
||||
ServiceWorker::PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
||||
const Optional<Sequence<JS::Value>>& aTransferable,
|
||||
@@ -82,7 +96,12 @@ ServiceWorker::PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
||||
return;
|
||||
}
|
||||
|
||||
workerPrivate->PostMessage(aCx, aMessage, aTransferable, aRv);
|
||||
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(GetParentObject());
|
||||
nsCOMPtr<nsIDocument> doc = window->GetExtantDoc();
|
||||
nsAutoPtr<ServiceWorkerClientInfo> clientInfo(new ServiceWorkerClientInfo(doc));
|
||||
|
||||
workerPrivate->PostMessageToServiceWorker(aCx, aMessage, aTransferable,
|
||||
clientInfo, aRv);
|
||||
}
|
||||
|
||||
WorkerPrivate*
|
||||
@@ -95,6 +114,16 @@ ServiceWorker::GetWorkerPrivate() const
|
||||
return mSharedWorker->GetWorkerPrivate();
|
||||
}
|
||||
|
||||
void
|
||||
ServiceWorker::QueueStateChangeEvent(ServiceWorkerState aState)
|
||||
{
|
||||
nsCOMPtr<nsIRunnable> r =
|
||||
NS_NewRunnableMethodWithArg<ServiceWorkerState>(this,
|
||||
&ServiceWorker::DispatchStateChange,
|
||||
aState);
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToMainThread(r)));
|
||||
}
|
||||
|
||||
} // namespace workers
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
+14
-10
@@ -19,6 +19,8 @@ class Promise;
|
||||
|
||||
namespace workers {
|
||||
|
||||
class ServiceWorkerInfo;
|
||||
class ServiceWorkerManager;
|
||||
class SharedWorker;
|
||||
|
||||
bool
|
||||
@@ -26,7 +28,7 @@ ServiceWorkerVisible(JSContext* aCx, JSObject* aObj);
|
||||
|
||||
class ServiceWorker final : public DOMEventTargetHelper
|
||||
{
|
||||
friend class RuntimeService;
|
||||
friend class ServiceWorkerManager;
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ServiceWorker, DOMEventTargetHelper)
|
||||
@@ -50,16 +52,17 @@ public:
|
||||
}
|
||||
|
||||
void
|
||||
GetScriptURL(nsString& aURL) const
|
||||
GetScriptURL(nsString& aURL) const;
|
||||
|
||||
void
|
||||
DispatchStateChange(ServiceWorkerState aState)
|
||||
{
|
||||
aURL = mURL;
|
||||
SetState(aState);
|
||||
DOMEventTargetHelper::DispatchTrustedEvent(NS_LITERAL_STRING("statechange"));
|
||||
}
|
||||
|
||||
void
|
||||
DispatchStateChange()
|
||||
{
|
||||
DOMEventTargetHelper::DispatchTrustedEvent(NS_LITERAL_STRING("statechange"));
|
||||
}
|
||||
QueueStateChangeEvent(ServiceWorkerState aState);
|
||||
|
||||
#ifdef XP_WIN
|
||||
#undef PostMessage
|
||||
@@ -74,14 +77,15 @@ public:
|
||||
GetWorkerPrivate() const;
|
||||
|
||||
private:
|
||||
// This class can only be created from the RuntimeService.
|
||||
ServiceWorker(nsPIDOMWindow* aWindow, SharedWorker* aSharedWorker);
|
||||
// This class can only be created from the ServiceWorkerManager.
|
||||
ServiceWorker(nsPIDOMWindow* aWindow, ServiceWorkerInfo* aInfo,
|
||||
SharedWorker* aSharedWorker);
|
||||
|
||||
// This class is reference-counted and will be destroyed from Release().
|
||||
~ServiceWorker();
|
||||
|
||||
ServiceWorkerState mState;
|
||||
nsString mURL;
|
||||
const nsRefPtr<ServiceWorkerInfo> mInfo;
|
||||
|
||||
// To allow ServiceWorkers to potentially drop the backing DOMEventTargetHelper and
|
||||
// re-instantiate it later, they simply own a SharedWorker member that
|
||||
|
||||
@@ -73,7 +73,7 @@ ServiceWorkerContainer::WrapObject(JSContext* aCx)
|
||||
|
||||
already_AddRefed<Promise>
|
||||
ServiceWorkerContainer::Register(const nsAString& aScriptURL,
|
||||
const RegistrationOptionList& aOptions,
|
||||
const RegistrationOptions& aOptions,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
nsCOMPtr<nsISupports> promise;
|
||||
@@ -84,7 +84,38 @@ ServiceWorkerContainer::Register(const nsAString& aScriptURL,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
aRv = swm->Register(GetOwner(), aOptions.mScope, aScriptURL, getter_AddRefs(promise));
|
||||
nsCOMPtr<nsPIDOMWindow> window = GetOwner();
|
||||
MOZ_ASSERT(window);
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIURI> scriptURI;
|
||||
rv = NS_NewURI(getter_AddRefs(scriptURI), aScriptURL, nullptr,
|
||||
window->GetDocBaseURI());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
aRv.ThrowTypeError(MSG_INVALID_URL, &aScriptURL);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// In ServiceWorkerContainer.register() the scope argument is parsed against
|
||||
// different base URLs depending on whether it was passed or not.
|
||||
nsCOMPtr<nsIURI> scopeURI;
|
||||
|
||||
// Step 4. If none passed, parse against script's URL
|
||||
if (!aOptions.mScope.WasPassed()) {
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(scopeURI), NS_LITERAL_CSTRING("./"),
|
||||
nullptr, scriptURI);
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(rv));
|
||||
} else {
|
||||
// Step 5. Parse against entry settings object's base URL.
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(scopeURI), aOptions.mScope.Value(),
|
||||
nullptr, window->GetDocBaseURI());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
aRv.ThrowTypeError(MSG_INVALID_URL, &aOptions.mScope.Value());
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
aRv = swm->Register(window, scopeURI, scriptURI, getter_AddRefs(promise));
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class Promise;
|
||||
struct RegistrationOptionList;
|
||||
struct RegistrationOptions;
|
||||
|
||||
namespace workers {
|
||||
class ServiceWorker;
|
||||
@@ -40,7 +40,7 @@ public:
|
||||
|
||||
already_AddRefed<Promise>
|
||||
Register(const nsAString& aScriptURL,
|
||||
const RegistrationOptionList& aOptions,
|
||||
const RegistrationOptions& aOptions,
|
||||
ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<workers::ServiceWorker>
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
#include "mozilla/dom/WorkerScope.h"
|
||||
#include "mozilla/dom/workers/bindings/ServiceWorker.h"
|
||||
|
||||
#include "WorkerPrivate.h"
|
||||
|
||||
using namespace mozilla::dom;
|
||||
|
||||
BEGIN_WORKERS_NAMESPACE
|
||||
@@ -102,7 +104,7 @@ public:
|
||||
}
|
||||
|
||||
NS_IMETHOD
|
||||
Run()
|
||||
Run()
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
@@ -115,6 +117,14 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
mChannel->SynthesizeStatus(mInternalResponse->GetStatus(), mInternalResponse->GetStatusText());
|
||||
|
||||
nsAutoTArray<InternalHeaders::Entry, 5> entries;
|
||||
mInternalResponse->Headers()->GetEntries(entries);
|
||||
for (uint32_t i = 0; i < entries.Length(); ++i) {
|
||||
mChannel->SynthesizeHeader(entries[i].mName, entries[i].mValue);
|
||||
}
|
||||
|
||||
rv = mChannel->FinishSynthesizedResponse();
|
||||
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Failed to finish synthesized response");
|
||||
return rv;
|
||||
@@ -203,36 +213,50 @@ RespondWithHandler::ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValu
|
||||
return;
|
||||
}
|
||||
|
||||
// FIXME(nsm) Bug 1136200 deal with opaque and no-cors (fetch spec 4.2.2.2).
|
||||
if (response->Type() == ResponseType::Error) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(response->BodyUsed())) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<InternalResponse> ir = response->GetInternalResponse();
|
||||
if (NS_WARN_IF(!ir)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsAutoPtr<RespondWithClosure> closure(new RespondWithClosure(mInterceptedChannel, ir));
|
||||
nsCOMPtr<nsIInputStream> body;
|
||||
response->GetBody(getter_AddRefs(body));
|
||||
if (NS_WARN_IF(!body) || NS_WARN_IF(response->BodyUsed())) {
|
||||
return;
|
||||
}
|
||||
response->SetBodyUsed();
|
||||
// Errors and redirects may not have a body.
|
||||
if (body) {
|
||||
response->SetBodyUsed();
|
||||
|
||||
nsCOMPtr<nsIOutputStream> responseBody;
|
||||
rv = mInterceptedChannel->GetResponseBody(getter_AddRefs(responseBody));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsAutoPtr<RespondWithClosure> closure(new RespondWithClosure(mInterceptedChannel, ir));
|
||||
|
||||
nsCOMPtr<nsIEventTarget> stsThread = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
|
||||
if (NS_WARN_IF(!stsThread)) {
|
||||
return;
|
||||
}
|
||||
rv = NS_AsyncCopy(body, responseBody, stsThread, NS_ASYNCCOPY_VIA_READSEGMENTS, 4096,
|
||||
RespondWithCopyComplete, closure.forget());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
nsCOMPtr<nsIOutputStream> responseBody;
|
||||
rv = mInterceptedChannel->GetResponseBody(getter_AddRefs(responseBody));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIEventTarget> stsThread = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
|
||||
if (NS_WARN_IF(!stsThread)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// XXXnsm, Fix for Bug 1141332 means that if we decide to make this
|
||||
// streaming at some point, we'll need a different solution to that bug.
|
||||
rv = NS_AsyncCopy(body, responseBody, stsThread, NS_ASYNCCOPY_VIA_READSEGMENTS, 4096,
|
||||
RespondWithCopyComplete, closure.forget());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
RespondWithCopyComplete(closure.forget(), NS_OK);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!closure);
|
||||
autoCancel.Reset();
|
||||
}
|
||||
|
||||
@@ -264,6 +288,26 @@ FetchEvent::RespondWith(Promise& aPromise, ErrorResult& aRv)
|
||||
aPromise.AppendNativeHandler(handler);
|
||||
}
|
||||
|
||||
void
|
||||
FetchEvent::RespondWith(Response& aResponse, ErrorResult& aRv)
|
||||
{
|
||||
if (mWaitToRespond) {
|
||||
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
WorkerPrivate* worker = GetCurrentThreadWorkerPrivate();
|
||||
MOZ_ASSERT(worker);
|
||||
worker->AssertIsOnWorkerThread();
|
||||
nsRefPtr<Promise> promise = Promise::Create(worker->GlobalScope(), aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
promise->MaybeResolve(&aResponse);
|
||||
|
||||
RespondWith(*promise, aRv);
|
||||
}
|
||||
|
||||
already_AddRefed<ServiceWorkerClient>
|
||||
FetchEvent::GetClient()
|
||||
{
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "mozilla/dom/FetchEventBinding.h"
|
||||
#include "mozilla/dom/InstallEventBinding.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/dom/Response.h"
|
||||
#include "nsProxyRelease.h"
|
||||
|
||||
class nsIInterceptedChannel;
|
||||
@@ -83,6 +84,9 @@ public:
|
||||
void
|
||||
RespondWith(Promise& aPromise, ErrorResult& aRv);
|
||||
|
||||
void
|
||||
RespondWith(Response& aResponse, ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<Promise>
|
||||
ForwardTo(const nsAString& aUrl);
|
||||
|
||||
|
||||
@@ -422,7 +422,7 @@ public:
|
||||
const nsMainThreadPtrHandle<nsISupports> aJob)
|
||||
: WorkerRunnable(aWorkerPrivate, WorkerThreadUnchangedBusyCount)
|
||||
, mJob(aJob)
|
||||
{
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
}
|
||||
|
||||
@@ -442,6 +442,40 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
namespace {
|
||||
nsresult
|
||||
GetRequiredScopeStringPrefix(const nsACString& aScriptSpec, nsACString& aPrefix)
|
||||
{
|
||||
nsCOMPtr<nsIURI> scriptURI;
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(scriptURI), aScriptSpec,
|
||||
nullptr, nullptr);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = scriptURI->GetPrePath(aPrefix);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURL> scriptURL(do_QueryInterface(scriptURI));
|
||||
if (NS_WARN_IF(!scriptURL)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsAutoCString dir;
|
||||
rv = scriptURL->GetDirectory(dir);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
aPrefix.Append(dir);
|
||||
return NS_OK;
|
||||
}
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
|
||||
class ServiceWorkerRegisterJob final : public ServiceWorkerJob,
|
||||
public nsIStreamLoaderObserver
|
||||
{
|
||||
@@ -563,14 +597,29 @@ public:
|
||||
NS_WARNING("Byte wise check is disabled, just using new one");
|
||||
nsRefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||
|
||||
// FIXME: Bug 1130101 - Read max scope from Service-Worker-Allowed header.
|
||||
nsAutoCString allowedPrefix;
|
||||
rv = GetRequiredScopeStringPrefix(mRegistration->mScriptSpec, allowedPrefix);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
Fail(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (!StringBeginsWith(mRegistration->mScope, allowedPrefix)) {
|
||||
NS_WARNING("By default a service worker's scope is restricted to at or below it's script's location.");
|
||||
Fail(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
}
|
||||
|
||||
// We have to create a ServiceWorker here simply to ensure there are no
|
||||
// errors. Ideally we should just pass this worker on to ContinueInstall.
|
||||
MOZ_ASSERT(!swm->mSetOfScopesBeingUpdated.Contains(mRegistration->mScope));
|
||||
swm->mSetOfScopesBeingUpdated.Put(mRegistration->mScope, true);
|
||||
nsRefPtr<ServiceWorkerInfo> dummyInfo =
|
||||
new ServiceWorkerInfo(mRegistration, mRegistration->mScriptSpec);
|
||||
nsRefPtr<ServiceWorker> serviceWorker;
|
||||
rv = swm->CreateServiceWorker(mRegistration->mPrincipal,
|
||||
mRegistration->mScriptSpec,
|
||||
mRegistration->mScope,
|
||||
dummyInfo,
|
||||
getter_AddRefs(serviceWorker));
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
@@ -591,7 +640,7 @@ public:
|
||||
if (NS_WARN_IF(!ok)) {
|
||||
swm->mSetOfScopesBeingUpdated.Remove(mRegistration->mScope);
|
||||
Fail(NS_ERROR_DOM_ABORT_ERR);
|
||||
return rv;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@@ -639,8 +688,7 @@ public:
|
||||
nsRefPtr<ServiceWorker> serviceWorker;
|
||||
nsresult rv =
|
||||
swm->CreateServiceWorker(mRegistration->mPrincipal,
|
||||
mRegistration->mInstallingWorker->ScriptSpec(),
|
||||
mRegistration->mScope,
|
||||
mRegistration->mInstallingWorker,
|
||||
getter_AddRefs(serviceWorker));
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
@@ -776,13 +824,8 @@ private:
|
||||
mRegistration->mWaitingWorker->UpdateState(ServiceWorkerState::Redundant);
|
||||
}
|
||||
|
||||
// Although the spec first sets waiting worker and then updates its state,
|
||||
// our ServiceWorkerInfo does not hold a list of associated ServiceWorker
|
||||
// objects in content JS. This means if we want to fire an event on
|
||||
// ServiceWorkerRegistration.installing, we need to do it first, before
|
||||
// swapping it with waiting worker.
|
||||
mRegistration->mInstallingWorker->UpdateState(ServiceWorkerState::Installed);
|
||||
mRegistration->mWaitingWorker = mRegistration->mInstallingWorker.forget();
|
||||
mRegistration->mWaitingWorker->UpdateState(ServiceWorkerState::Installed);
|
||||
swm->InvalidateServiceWorkerRegistrationWorker(mRegistration,
|
||||
WhichServiceWorker::INSTALLING_WORKER | WhichServiceWorker::WAITING_WORKER);
|
||||
|
||||
@@ -818,8 +861,8 @@ ContinueInstallTask::ContinueAfterWorkerEvent(bool aSuccess, bool aActivateImmed
|
||||
// automatically reject the Promise.
|
||||
NS_IMETHODIMP
|
||||
ServiceWorkerManager::Register(nsIDOMWindow* aWindow,
|
||||
const nsAString& aScope,
|
||||
const nsAString& aScriptURL,
|
||||
nsIURI* aScopeURI,
|
||||
nsIURI* aScriptURI,
|
||||
nsISupports** aPromise)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
@@ -889,41 +932,29 @@ ServiceWorkerManager::Register(nsIDOMWindow* aWindow,
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> scriptURI;
|
||||
rv = NS_NewURI(getter_AddRefs(scriptURI), aScriptURL, nullptr, documentURI);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Data URLs are not allowed.
|
||||
nsCOMPtr<nsIPrincipal> documentPrincipal = doc->NodePrincipal();
|
||||
|
||||
rv = documentPrincipal->CheckMayLoad(scriptURI, true /* report */,
|
||||
rv = documentPrincipal->CheckMayLoad(aScriptURI, true /* report */,
|
||||
false /* allowIfInheritsPrincipal */);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> scopeURI;
|
||||
rv = NS_NewURI(getter_AddRefs(scopeURI), aScope, nullptr, documentURI);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
}
|
||||
|
||||
rv = documentPrincipal->CheckMayLoad(scopeURI, true /* report */,
|
||||
rv = documentPrincipal->CheckMayLoad(aScopeURI, true /* report */,
|
||||
false /* allowIfInheritsPrinciple */);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
}
|
||||
|
||||
nsCString cleanedScope;
|
||||
rv = scopeURI->GetSpecIgnoringRef(cleanedScope);
|
||||
rv = aScopeURI->GetSpecIgnoringRef(cleanedScope);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsAutoCString spec;
|
||||
rv = scriptURI->GetSpec(spec);
|
||||
rv = aScriptURI->GetSpec(spec);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
@@ -1129,7 +1160,6 @@ ServiceWorkerRegistrationInfo::Activate()
|
||||
// FIXME(nsm): Unlink appcache if there is one.
|
||||
|
||||
swm->CheckPendingReadyPromises();
|
||||
swm->StoreRegistration(mPrincipal, this);
|
||||
|
||||
// "Queue a task to fire a simple event named controllerchange..."
|
||||
nsCOMPtr<nsIRunnable> controllerChangeRunnable =
|
||||
@@ -1142,8 +1172,7 @@ ServiceWorkerRegistrationInfo::Activate()
|
||||
nsRefPtr<ServiceWorker> serviceWorker;
|
||||
nsresult rv =
|
||||
swm->CreateServiceWorker(mPrincipal,
|
||||
mActiveWorker->ScriptSpec(),
|
||||
mScope,
|
||||
mActiveWorker,
|
||||
getter_AddRefs(serviceWorker));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
nsCOMPtr<nsIRunnable> r =
|
||||
@@ -1265,7 +1294,7 @@ ServiceWorkerManager::GetRegistrations(nsIDOMWindow* aWindow,
|
||||
return result.ErrorCode();
|
||||
}
|
||||
|
||||
nsRefPtr<nsIRunnable> runnable =
|
||||
nsCOMPtr<nsIRunnable> runnable =
|
||||
new GetRegistrationsRunnable(window, promise);
|
||||
promise.forget(aPromise);
|
||||
return NS_DispatchToCurrentThread(runnable);
|
||||
@@ -1366,7 +1395,7 @@ ServiceWorkerManager::GetRegistration(nsIDOMWindow* aWindow,
|
||||
return result.ErrorCode();
|
||||
}
|
||||
|
||||
nsRefPtr<nsIRunnable> runnable =
|
||||
nsCOMPtr<nsIRunnable> runnable =
|
||||
new GetRegistrationRunnable(window, promise, aDocumentURL);
|
||||
promise.forget(aPromise);
|
||||
return NS_DispatchToCurrentThread(runnable);
|
||||
@@ -1432,7 +1461,7 @@ ServiceWorkerManager::GetReadyPromise(nsIDOMWindow* aWindow,
|
||||
return result.ErrorCode();
|
||||
}
|
||||
|
||||
nsRefPtr<nsIRunnable> runnable =
|
||||
nsCOMPtr<nsIRunnable> runnable =
|
||||
new GetReadyPromiseRunnable(window, promise);
|
||||
promise.forget(aPromise);
|
||||
return NS_DispatchToCurrentThread(runnable);
|
||||
@@ -1692,60 +1721,24 @@ ServiceWorkerRegistrationInfo::FinishActivate(bool aSuccess)
|
||||
|
||||
if (aSuccess) {
|
||||
mActiveWorker->UpdateState(ServiceWorkerState::Activated);
|
||||
nsRefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||
swm->StoreRegistration(mPrincipal, this);
|
||||
} else {
|
||||
mActiveWorker->UpdateState(ServiceWorkerState::Redundant);
|
||||
mActiveWorker = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ServiceWorkerRegistrationInfo::QueueStateChangeEvent(ServiceWorkerInfo* aInfo,
|
||||
ServiceWorkerState aState) const
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(aInfo);
|
||||
MOZ_ASSERT(aInfo == mInstallingWorker ||
|
||||
aInfo == mWaitingWorker ||
|
||||
aInfo == mActiveWorker);
|
||||
|
||||
nsRefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||
WhichServiceWorker whichOne;
|
||||
if (aInfo == mInstallingWorker) {
|
||||
whichOne = WhichServiceWorker::INSTALLING_WORKER;
|
||||
} else if (aInfo == mWaitingWorker) {
|
||||
whichOne = WhichServiceWorker::WAITING_WORKER;
|
||||
} else if (aInfo == mActiveWorker) {
|
||||
whichOne = WhichServiceWorker::ACTIVE_WORKER;
|
||||
} else {
|
||||
MOZ_CRASH("Hit unexpected case");
|
||||
}
|
||||
|
||||
// Refactor this iteration pattern across this and 2 other call-sites.
|
||||
nsTObserverArray<ServiceWorkerRegistration*>::ForwardIterator it(swm->mServiceWorkerRegistrations);
|
||||
while (it.HasMore()) {
|
||||
nsRefPtr<ServiceWorkerRegistration> target = it.GetNext();
|
||||
nsAutoString regScope;
|
||||
target->GetScope(regScope);
|
||||
MOZ_ASSERT(!regScope.IsEmpty());
|
||||
|
||||
NS_ConvertUTF16toUTF8 utf8Scope(regScope);
|
||||
if (utf8Scope.Equals(mScope)) {
|
||||
target->QueueStateChangeEvent(whichOne, aState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ServiceWorkerManager::CreateServiceWorkerForWindow(nsPIDOMWindow* aWindow,
|
||||
const nsACString& aScriptSpec,
|
||||
const nsACString& aScope,
|
||||
ServiceWorkerInfo* aInfo,
|
||||
ServiceWorker** aServiceWorker)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(aWindow);
|
||||
|
||||
RuntimeService* rs = RuntimeService::GetOrCreateService();
|
||||
nsRefPtr<ServiceWorker> serviceWorker;
|
||||
nsRefPtr<SharedWorker> sharedWorker;
|
||||
|
||||
AutoJSAPI jsapi;
|
||||
jsapi.Init(aWindow);
|
||||
@@ -1754,15 +1747,18 @@ ServiceWorkerManager::CreateServiceWorkerForWindow(nsPIDOMWindow* aWindow,
|
||||
nsCOMPtr<nsIGlobalObject> sgo = do_QueryInterface(aWindow);
|
||||
JS::Rooted<JSObject*> jsGlobal(cx, sgo->GetGlobalJSObject());
|
||||
GlobalObject global(cx, jsGlobal);
|
||||
nsresult rv = rs->CreateServiceWorker(global,
|
||||
NS_ConvertUTF8toUTF16(aScriptSpec),
|
||||
aScope,
|
||||
getter_AddRefs(serviceWorker));
|
||||
nsresult rv = rs->CreateSharedWorkerForServiceWorker(global,
|
||||
NS_ConvertUTF8toUTF16(aInfo->ScriptSpec()),
|
||||
aInfo->Scope(),
|
||||
getter_AddRefs(sharedWorker));
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsRefPtr<ServiceWorker> serviceWorker =
|
||||
new ServiceWorker(aWindow, aInfo, sharedWorker);
|
||||
|
||||
serviceWorker.forget(aServiceWorker);
|
||||
return rv;
|
||||
}
|
||||
@@ -1785,8 +1781,12 @@ ServiceWorkerManager::LoadRegistrations(
|
||||
|
||||
registration->mScriptSpec = aRegistrations[i].scriptSpec();
|
||||
|
||||
registration->mActiveWorker =
|
||||
new ServiceWorkerInfo(registration, aRegistrations[i].currentWorkerURL());
|
||||
const nsCString& currentWorkerURL = aRegistrations[i].currentWorkerURL();
|
||||
if (!currentWorkerURL.IsEmpty()) {
|
||||
registration->mActiveWorker =
|
||||
new ServiceWorkerInfo(registration, currentWorkerURL);
|
||||
registration->mActiveWorker->SetActivateStateUncheckedWithoutEvent(ServiceWorkerState::Activated);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2059,7 +2059,7 @@ ServiceWorkerManager::GetServiceWorkerForScope(nsIDOMWindow* aWindow,
|
||||
AssertIsOnMainThread();
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aWindow);
|
||||
if (!window) {
|
||||
if (NS_WARN_IF(!window)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@@ -2086,7 +2086,7 @@ ServiceWorkerManager::GetServiceWorkerForScope(nsIDOMWindow* aWindow,
|
||||
////////////////////////////////////////////
|
||||
|
||||
nsRefPtr<ServiceWorkerRegistrationInfo> registration = GetRegistration(scope);
|
||||
if (!registration) {
|
||||
if (NS_WARN_IF(!registration)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@@ -2101,14 +2101,13 @@ ServiceWorkerManager::GetServiceWorkerForScope(nsIDOMWindow* aWindow,
|
||||
MOZ_CRASH("Invalid worker type");
|
||||
}
|
||||
|
||||
if (!info) {
|
||||
if (NS_WARN_IF(!info)) {
|
||||
return NS_ERROR_DOM_NOT_FOUND_ERR;
|
||||
}
|
||||
|
||||
nsRefPtr<ServiceWorker> serviceWorker;
|
||||
rv = CreateServiceWorkerForWindow(window,
|
||||
info->ScriptSpec(),
|
||||
registration->mScope,
|
||||
info,
|
||||
getter_AddRefs(serviceWorker));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
@@ -2133,11 +2132,13 @@ public:
|
||||
FetchEventRunnable(WorkerPrivate* aWorkerPrivate,
|
||||
nsMainThreadPtrHandle<nsIInterceptedChannel>& aChannel,
|
||||
nsMainThreadPtrHandle<ServiceWorker>& aServiceWorker,
|
||||
nsAutoPtr<ServiceWorkerClientInfo>& aClientInfo)
|
||||
nsAutoPtr<ServiceWorkerClientInfo>& aClientInfo,
|
||||
bool aIsReload)
|
||||
: WorkerRunnable(aWorkerPrivate, WorkerThreadModifyBusyCount)
|
||||
, mInterceptedChannel(aChannel)
|
||||
, mServiceWorker(aServiceWorker)
|
||||
, mClientInfo(aClientInfo)
|
||||
, mIsReload(aIsReload)
|
||||
{
|
||||
MOZ_ASSERT(aWorkerPrivate);
|
||||
}
|
||||
@@ -2176,9 +2177,6 @@ public:
|
||||
rv = channel->GetLoadFlags(&loadFlags);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
//TODO(jdm): we should probably include reload-ness in the loadinfo or as a separate load flag
|
||||
mIsReload = false;
|
||||
|
||||
rv = httpChannel->VisitRequestHeaders(this);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
@@ -2278,7 +2276,8 @@ private:
|
||||
NS_IMPL_ISUPPORTS_INHERITED(FetchEventRunnable, WorkerRunnable, nsIHttpHeaderVisitor)
|
||||
|
||||
NS_IMETHODIMP
|
||||
ServiceWorkerManager::DispatchFetchEvent(nsIDocument* aDoc, nsIInterceptedChannel* aChannel)
|
||||
ServiceWorkerManager::DispatchFetchEvent(nsIDocument* aDoc, nsIInterceptedChannel* aChannel,
|
||||
bool aIsReload)
|
||||
{
|
||||
MOZ_ASSERT(aChannel);
|
||||
nsCOMPtr<nsISupports> serviceWorker;
|
||||
@@ -2310,8 +2309,7 @@ ServiceWorkerManager::DispatchFetchEvent(nsIDocument* aDoc, nsIInterceptedChanne
|
||||
|
||||
nsRefPtr<ServiceWorker> sw;
|
||||
rv = CreateServiceWorker(registration->mPrincipal,
|
||||
registration->mActiveWorker->ScriptSpec(),
|
||||
registration->mScope,
|
||||
registration->mActiveWorker,
|
||||
getter_AddRefs(sw));
|
||||
serviceWorker = sw.forget();
|
||||
}
|
||||
@@ -2329,7 +2327,7 @@ ServiceWorkerManager::DispatchFetchEvent(nsIDocument* aDoc, nsIInterceptedChanne
|
||||
|
||||
// clientInfo is null if we don't have a controlled document
|
||||
nsRefPtr<FetchEventRunnable> event =
|
||||
new FetchEventRunnable(sw->GetWorkerPrivate(), handle, serviceWorkerHandle, clientInfo);
|
||||
new FetchEventRunnable(sw->GetWorkerPrivate(), handle, serviceWorkerHandle, clientInfo, aIsReload);
|
||||
rv = event->Init();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
@@ -2406,8 +2404,7 @@ ServiceWorkerManager::GetDocumentController(nsIDOMWindow* aWindow, nsISupports**
|
||||
|
||||
nsRefPtr<ServiceWorker> serviceWorker;
|
||||
rv = CreateServiceWorkerForWindow(window,
|
||||
registration->mActiveWorker->ScriptSpec(),
|
||||
registration->mScope,
|
||||
registration->mActiveWorker,
|
||||
getter_AddRefs(serviceWorker));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
@@ -2449,15 +2446,15 @@ ServiceWorkerManager::GetActive(nsIDOMWindow* aWindow,
|
||||
|
||||
NS_IMETHODIMP
|
||||
ServiceWorkerManager::CreateServiceWorker(nsIPrincipal* aPrincipal,
|
||||
const nsACString& aScriptSpec,
|
||||
const nsACString& aScope,
|
||||
ServiceWorkerInfo* aInfo,
|
||||
ServiceWorker** aServiceWorker)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(aPrincipal);
|
||||
|
||||
WorkerPrivate::LoadInfo info;
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(info.mBaseURI), aScriptSpec, nullptr, nullptr);
|
||||
WorkerLoadInfo info;
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(info.mBaseURI), aInfo->ScriptSpec(),
|
||||
nullptr, nullptr);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
@@ -2479,7 +2476,6 @@ ServiceWorkerManager::CreateServiceWorker(nsIPrincipal* aPrincipal,
|
||||
// them here.
|
||||
WorkerPrivate::OverrideLoadInfoLoadGroup(info);
|
||||
|
||||
nsRefPtr<ServiceWorker> serviceWorker;
|
||||
RuntimeService* rs = RuntimeService::GetOrCreateService();
|
||||
if (!rs) {
|
||||
return NS_ERROR_FAILURE;
|
||||
@@ -2487,15 +2483,19 @@ ServiceWorkerManager::CreateServiceWorker(nsIPrincipal* aPrincipal,
|
||||
|
||||
AutoJSAPI jsapi;
|
||||
jsapi.Init();
|
||||
rv = rs->CreateServiceWorkerFromLoadInfo(jsapi.cx(), &info,
|
||||
NS_ConvertUTF8toUTF16(aScriptSpec),
|
||||
aScope,
|
||||
getter_AddRefs(serviceWorker));
|
||||
nsRefPtr<SharedWorker> sharedWorker;
|
||||
rv = rs->CreateSharedWorkerForServiceWorkerFromLoadInfo(jsapi.cx(), &info,
|
||||
NS_ConvertUTF8toUTF16(aInfo->ScriptSpec()),
|
||||
aInfo->Scope(),
|
||||
getter_AddRefs(sharedWorker));
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsRefPtr<ServiceWorker> serviceWorker =
|
||||
new ServiceWorker(nullptr, aInfo, sharedWorker);
|
||||
|
||||
serviceWorker.forget(aServiceWorker);
|
||||
return NS_OK;
|
||||
}
|
||||
@@ -2681,4 +2681,86 @@ ServiceWorkerManager::MaybeRemoveRegistration(ServiceWorkerRegistrationInfo* aRe
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ServiceWorkerManager::RemoveRegistration(ServiceWorkerRegistrationInfo* aRegistration)
|
||||
{
|
||||
MOZ_ASSERT(aRegistration);
|
||||
MOZ_ASSERT(!aRegistration->IsControllingDocuments());
|
||||
MOZ_ASSERT(mServiceWorkerRegistrationInfos.Contains(aRegistration->mScope));
|
||||
ServiceWorkerManager::RemoveScope(mOrderedScopes, aRegistration->mScope);
|
||||
|
||||
// Hold a ref since the hashtable may be the last ref.
|
||||
nsRefPtr<ServiceWorkerRegistrationInfo> reg;
|
||||
mServiceWorkerRegistrationInfos.Remove(aRegistration->mScope,
|
||||
getter_AddRefs(reg));
|
||||
MOZ_ASSERT(reg);
|
||||
|
||||
// All callers should be either from a job in which case the actor is
|
||||
// available, or from MaybeStopControlling(), in which case, this will only be
|
||||
// called if a valid registration is found. If a valid registration exists,
|
||||
// it means the actor is available since the original map of registrations is
|
||||
// populated by it, and any new registrations wait until the actor is
|
||||
// available before proceeding (See ServiceWorkerRegisterJob::Start).
|
||||
MOZ_ASSERT(mActor);
|
||||
|
||||
PrincipalInfo principalInfo;
|
||||
if (NS_WARN_IF(NS_FAILED(PrincipalToPrincipalInfo(reg->mPrincipal,
|
||||
&principalInfo)))) {
|
||||
//XXXnsm I can't think of any other reason a stored principal would fail to
|
||||
//convert.
|
||||
NS_WARNING("Unable to unregister serviceworker due to possible OOM");
|
||||
return;
|
||||
}
|
||||
mActor->SendUnregisterServiceWorker(principalInfo, NS_ConvertUTF8toUTF16(reg->mScope));
|
||||
}
|
||||
|
||||
void
|
||||
ServiceWorkerInfo::AppendWorker(ServiceWorker* aWorker)
|
||||
{
|
||||
MOZ_ASSERT(aWorker);
|
||||
#ifdef DEBUG
|
||||
nsAutoString workerURL;
|
||||
aWorker->GetScriptURL(workerURL);
|
||||
MOZ_ASSERT(workerURL.Equals(NS_ConvertUTF8toUTF16(mScriptSpec)));
|
||||
#endif
|
||||
MOZ_ASSERT(!mInstances.Contains(aWorker));
|
||||
|
||||
mInstances.AppendElement(aWorker);
|
||||
aWorker->SetState(State());
|
||||
}
|
||||
|
||||
void
|
||||
ServiceWorkerInfo::RemoveWorker(ServiceWorker* aWorker)
|
||||
{
|
||||
MOZ_ASSERT(aWorker);
|
||||
#ifdef DEBUG
|
||||
nsAutoString workerURL;
|
||||
aWorker->GetScriptURL(workerURL);
|
||||
MOZ_ASSERT(workerURL.Equals(NS_ConvertUTF8toUTF16(mScriptSpec)));
|
||||
#endif
|
||||
MOZ_ASSERT(mInstances.Contains(aWorker));
|
||||
|
||||
mInstances.RemoveElement(aWorker);
|
||||
}
|
||||
|
||||
void
|
||||
ServiceWorkerInfo::UpdateState(ServiceWorkerState aState)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
// Any state can directly transition to redundant, but everything else is
|
||||
// ordered.
|
||||
if (aState != ServiceWorkerState::Redundant) {
|
||||
MOZ_ASSERT_IF(mState == ServiceWorkerState::EndGuard_, aState == ServiceWorkerState::Installing);
|
||||
MOZ_ASSERT_IF(mState == ServiceWorkerState::Installing, aState == ServiceWorkerState::Installed);
|
||||
MOZ_ASSERT_IF(mState == ServiceWorkerState::Installed, aState == ServiceWorkerState::Activating);
|
||||
MOZ_ASSERT_IF(mState == ServiceWorkerState::Activating, aState == ServiceWorkerState::Activated);
|
||||
}
|
||||
// Activated can only go to redundant.
|
||||
MOZ_ASSERT_IF(mState == ServiceWorkerState::Activated, aState == ServiceWorkerState::Redundant);
|
||||
#endif
|
||||
mState = aState;
|
||||
for (uint32_t i = 0; i < mInstances.Length(); ++i) {
|
||||
mInstances[i]->QueueStateChangeEvent(mState);
|
||||
}
|
||||
}
|
||||
END_WORKERS_NAMESPACE
|
||||
|
||||
@@ -202,9 +202,6 @@ public:
|
||||
void
|
||||
FinishActivate(bool aSuccess);
|
||||
|
||||
void
|
||||
QueueStateChangeEvent(ServiceWorkerInfo* aInfo,
|
||||
ServiceWorkerState aState) const;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -219,6 +216,11 @@ private:
|
||||
const ServiceWorkerRegistrationInfo* mRegistration;
|
||||
nsCString mScriptSpec;
|
||||
ServiceWorkerState mState;
|
||||
// We hold rawptrs since the ServiceWorker constructor and destructor ensure
|
||||
// addition and removal.
|
||||
// There is a high chance of there being at least one ServiceWorker
|
||||
// associated with this all the time.
|
||||
nsAutoTArray<ServiceWorker*, 1> mInstances;
|
||||
|
||||
~ServiceWorkerInfo()
|
||||
{ }
|
||||
@@ -232,6 +234,12 @@ public:
|
||||
return mScriptSpec;
|
||||
}
|
||||
|
||||
const nsCString&
|
||||
Scope() const
|
||||
{
|
||||
return mRegistration->mScope;
|
||||
}
|
||||
|
||||
void SetScriptSpec(const nsCString& aSpec)
|
||||
{
|
||||
MOZ_ASSERT(!aSpec.IsEmpty());
|
||||
@@ -254,23 +262,20 @@ public:
|
||||
}
|
||||
|
||||
void
|
||||
UpdateState(ServiceWorkerState aState)
|
||||
UpdateState(ServiceWorkerState aState);
|
||||
|
||||
// Only used to set initial state when loading from disk!
|
||||
void
|
||||
SetActivateStateUncheckedWithoutEvent(ServiceWorkerState aState)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
// Any state can directly transition to redundant, but everything else is
|
||||
// ordered.
|
||||
if (aState != ServiceWorkerState::Redundant) {
|
||||
MOZ_ASSERT_IF(mState == ServiceWorkerState::EndGuard_, aState == ServiceWorkerState::Installing);
|
||||
MOZ_ASSERT_IF(mState == ServiceWorkerState::Installing, aState == ServiceWorkerState::Installed);
|
||||
MOZ_ASSERT_IF(mState == ServiceWorkerState::Installed, aState == ServiceWorkerState::Activating);
|
||||
MOZ_ASSERT_IF(mState == ServiceWorkerState::Activating, aState == ServiceWorkerState::Activated);
|
||||
}
|
||||
// Activated can only go to redundant.
|
||||
MOZ_ASSERT_IF(mState == ServiceWorkerState::Activated, aState == ServiceWorkerState::Redundant);
|
||||
#endif
|
||||
mState = aState;
|
||||
mRegistration->QueueStateChangeEvent(this, mState);
|
||||
}
|
||||
|
||||
void
|
||||
AppendWorker(ServiceWorker* aWorker);
|
||||
|
||||
void
|
||||
RemoveWorker(ServiceWorker* aWorker);
|
||||
};
|
||||
|
||||
#define NS_SERVICEWORKERMANAGER_IMPL_IID \
|
||||
@@ -346,14 +351,7 @@ public:
|
||||
CreateNewRegistration(const nsCString& aScope, nsIPrincipal* aPrincipal);
|
||||
|
||||
void
|
||||
RemoveRegistration(ServiceWorkerRegistrationInfo* aRegistration)
|
||||
{
|
||||
MOZ_ASSERT(aRegistration);
|
||||
MOZ_ASSERT(!aRegistration->IsControllingDocuments());
|
||||
MOZ_ASSERT(mServiceWorkerRegistrationInfos.Contains(aRegistration->mScope));
|
||||
ServiceWorkerManager::RemoveScope(mOrderedScopes, aRegistration->mScope);
|
||||
mServiceWorkerRegistrationInfos.Remove(aRegistration->mScope);
|
||||
}
|
||||
RemoveRegistration(ServiceWorkerRegistrationInfo* aRegistration);
|
||||
|
||||
ServiceWorkerJobQueue*
|
||||
GetOrCreateJobQueue(const nsCString& aScope)
|
||||
@@ -405,14 +403,12 @@ private:
|
||||
|
||||
NS_IMETHOD
|
||||
CreateServiceWorkerForWindow(nsPIDOMWindow* aWindow,
|
||||
const nsACString& aScriptSpec,
|
||||
const nsACString& aScope,
|
||||
ServiceWorkerInfo* aInfo,
|
||||
ServiceWorker** aServiceWorker);
|
||||
|
||||
NS_IMETHOD
|
||||
CreateServiceWorker(nsIPrincipal* aPrincipal,
|
||||
const nsACString& aScriptSpec,
|
||||
const nsACString& aScope,
|
||||
ServiceWorkerInfo* aInfo,
|
||||
ServiceWorker** aServiceWorker);
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
||||
@@ -265,28 +265,6 @@ ServiceWorkerRegistration::InvalidateWorkerReference(WhichServiceWorker aWhichOn
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ServiceWorkerRegistration::QueueStateChangeEvent(WhichServiceWorker aWhichOne,
|
||||
ServiceWorkerState aState) const
|
||||
{
|
||||
nsRefPtr<ServiceWorker> worker;
|
||||
if (aWhichOne == WhichServiceWorker::INSTALLING_WORKER) {
|
||||
worker = mInstallingWorker;
|
||||
} else if (aWhichOne == WhichServiceWorker::WAITING_WORKER) {
|
||||
worker = mWaitingWorker;
|
||||
} else if (aWhichOne == WhichServiceWorker::ACTIVE_WORKER) {
|
||||
worker = mActiveWorker;
|
||||
} else {
|
||||
MOZ_CRASH("Invalid case");
|
||||
}
|
||||
|
||||
if (worker) {
|
||||
worker->SetState(aState);
|
||||
nsCOMPtr<nsIRunnable> r = NS_NewRunnableMethod(worker, &ServiceWorker::DispatchStateChange);
|
||||
NS_DispatchToMainThread(r);
|
||||
}
|
||||
}
|
||||
|
||||
// XXXnsm, maybe this can be optimized to only add when a event handler is
|
||||
// registered.
|
||||
void
|
||||
|
||||
@@ -59,9 +59,6 @@ public:
|
||||
void
|
||||
InvalidateWorkerReference(WhichServiceWorker aWhichOnes);
|
||||
|
||||
void
|
||||
QueueStateChangeEvent(WhichServiceWorker aWhichOne, ServiceWorkerState aState) const;
|
||||
|
||||
// DOMEventTargethelper
|
||||
virtual void DisconnectFromOwner() override;
|
||||
|
||||
|
||||
+232
-177
@@ -1143,6 +1143,9 @@ class MessageEventRunnable final : public WorkerRunnable
|
||||
uint64_t mMessagePortSerial;
|
||||
bool mToMessagePort;
|
||||
|
||||
// This is only used for messages dispatched to a service worker.
|
||||
nsAutoPtr<ServiceWorkerClientInfo> mEventSource;
|
||||
|
||||
public:
|
||||
MessageEventRunnable(WorkerPrivate* aWorkerPrivate,
|
||||
TargetAndBusyBehavior aBehavior,
|
||||
@@ -1157,6 +1160,12 @@ public:
|
||||
mClonedObjects.SwapElements(aClonedObjects);
|
||||
}
|
||||
|
||||
void
|
||||
SetMessageSource(ServiceWorkerClientInfo* aSource)
|
||||
{
|
||||
mEventSource = aSource;
|
||||
}
|
||||
|
||||
bool
|
||||
DispatchDOMEvent(JSContext* aCx, WorkerPrivate* aWorkerPrivate,
|
||||
DOMEventTargetHelper* aTarget, bool aIsMainThread)
|
||||
@@ -1182,6 +1191,12 @@ public:
|
||||
EmptyString(),
|
||||
EmptyString(),
|
||||
nullptr);
|
||||
if (mEventSource) {
|
||||
nsRefPtr<ServiceWorkerClient> client =
|
||||
new ServiceWorkerWindowClient(aTarget, *mEventSource);
|
||||
event->SetSource(client);
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
xpc::Throw(aCx, rv);
|
||||
return false;
|
||||
@@ -2091,9 +2106,7 @@ NS_IMPL_ISUPPORTS_INHERITED0(TopLevelWorkerFinishedRunnable, nsRunnable)
|
||||
|
||||
NS_IMPL_ISUPPORTS(TimerThreadEventTarget, nsIEventTarget)
|
||||
|
||||
template <class Derived>
|
||||
WorkerPrivateParent<Derived>::
|
||||
LoadInfo::LoadInfo()
|
||||
WorkerLoadInfo::WorkerLoadInfo()
|
||||
: mWindowID(UINT64_MAX)
|
||||
, mFromWindow(false)
|
||||
, mEvalAllowed(false)
|
||||
@@ -2104,15 +2117,114 @@ LoadInfo::LoadInfo()
|
||||
, mIsInCertifiedApp(false)
|
||||
, mIndexedDBAllowed(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR(WorkerPrivateParent<Derived>::LoadInfo);
|
||||
MOZ_COUNT_CTOR(WorkerLoadInfo);
|
||||
}
|
||||
|
||||
WorkerLoadInfo::~WorkerLoadInfo()
|
||||
{
|
||||
MOZ_COUNT_DTOR(WorkerLoadInfo);
|
||||
}
|
||||
|
||||
void
|
||||
WorkerLoadInfo::StealFrom(WorkerLoadInfo& aOther)
|
||||
{
|
||||
MOZ_ASSERT(!mBaseURI);
|
||||
aOther.mBaseURI.swap(mBaseURI);
|
||||
|
||||
MOZ_ASSERT(!mResolvedScriptURI);
|
||||
aOther.mResolvedScriptURI.swap(mResolvedScriptURI);
|
||||
|
||||
MOZ_ASSERT(!mPrincipal);
|
||||
aOther.mPrincipal.swap(mPrincipal);
|
||||
|
||||
MOZ_ASSERT(!mScriptContext);
|
||||
aOther.mScriptContext.swap(mScriptContext);
|
||||
|
||||
MOZ_ASSERT(!mWindow);
|
||||
aOther.mWindow.swap(mWindow);
|
||||
|
||||
MOZ_ASSERT(!mCSP);
|
||||
aOther.mCSP.swap(mCSP);
|
||||
|
||||
MOZ_ASSERT(!mChannel);
|
||||
aOther.mChannel.swap(mChannel);
|
||||
|
||||
MOZ_ASSERT(!mLoadGroup);
|
||||
aOther.mLoadGroup.swap(mLoadGroup);
|
||||
|
||||
MOZ_ASSERT(!mInterfaceRequestor);
|
||||
aOther.mInterfaceRequestor.swap(mInterfaceRequestor);
|
||||
|
||||
MOZ_ASSERT(!mPrincipalInfo);
|
||||
mPrincipalInfo = aOther.mPrincipalInfo.forget();
|
||||
|
||||
mDomain = aOther.mDomain;
|
||||
mWindowID = aOther.mWindowID;
|
||||
mFromWindow = aOther.mFromWindow;
|
||||
mEvalAllowed = aOther.mEvalAllowed;
|
||||
mReportCSPViolations = aOther.mReportCSPViolations;
|
||||
mXHRParamsAllowed = aOther.mXHRParamsAllowed;
|
||||
mPrincipalIsSystem = aOther.mPrincipalIsSystem;
|
||||
mIsInPrivilegedApp = aOther.mIsInPrivilegedApp;
|
||||
mIsInCertifiedApp = aOther.mIsInCertifiedApp;
|
||||
mIndexedDBAllowed = aOther.mIndexedDBAllowed;
|
||||
}
|
||||
|
||||
template <class Derived>
|
||||
WorkerPrivateParent<Derived>::
|
||||
LoadInfo::~LoadInfo()
|
||||
class WorkerPrivateParent<Derived>::EventTarget MOZ_FINAL
|
||||
: public nsIEventTarget
|
||||
{
|
||||
MOZ_COUNT_DTOR(WorkerPrivateParent<Derived>::LoadInfo);
|
||||
}
|
||||
// This mutex protects mWorkerPrivate and must be acquired *before* the
|
||||
// WorkerPrivate's mutex whenever they must both be held.
|
||||
mozilla::Mutex mMutex;
|
||||
WorkerPrivate* mWorkerPrivate;
|
||||
nsIEventTarget* mWeakNestedEventTarget;
|
||||
nsCOMPtr<nsIEventTarget> mNestedEventTarget;
|
||||
|
||||
public:
|
||||
explicit EventTarget(WorkerPrivate* aWorkerPrivate)
|
||||
: mMutex("WorkerPrivateParent::EventTarget::mMutex"),
|
||||
mWorkerPrivate(aWorkerPrivate), mWeakNestedEventTarget(nullptr)
|
||||
{
|
||||
MOZ_ASSERT(aWorkerPrivate);
|
||||
}
|
||||
|
||||
EventTarget(WorkerPrivate* aWorkerPrivate, nsIEventTarget* aNestedEventTarget)
|
||||
: mMutex("WorkerPrivateParent::EventTarget::mMutex"),
|
||||
mWorkerPrivate(aWorkerPrivate), mWeakNestedEventTarget(aNestedEventTarget),
|
||||
mNestedEventTarget(aNestedEventTarget)
|
||||
{
|
||||
MOZ_ASSERT(aWorkerPrivate);
|
||||
MOZ_ASSERT(aNestedEventTarget);
|
||||
}
|
||||
|
||||
void
|
||||
Disable()
|
||||
{
|
||||
nsCOMPtr<nsIEventTarget> nestedEventTarget;
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
|
||||
MOZ_ASSERT(mWorkerPrivate);
|
||||
mWorkerPrivate = nullptr;
|
||||
mNestedEventTarget.swap(nestedEventTarget);
|
||||
}
|
||||
}
|
||||
|
||||
nsIEventTarget*
|
||||
GetWeakNestedEventTarget() const
|
||||
{
|
||||
MOZ_ASSERT(mWeakNestedEventTarget);
|
||||
return mWeakNestedEventTarget;
|
||||
}
|
||||
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSIEVENTTARGET
|
||||
|
||||
private:
|
||||
~EventTarget()
|
||||
{ }
|
||||
};
|
||||
|
||||
template <class Derived>
|
||||
class WorkerPrivateParent<Derived>::SynchronizeAndResumeRunnable final
|
||||
@@ -2170,184 +2282,110 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
template <class Derived>
|
||||
class WorkerPrivateParent<Derived>::InterfaceRequestor final
|
||||
: public nsIInterfaceRequestor
|
||||
WorkerLoadInfo::
|
||||
InterfaceRequestor::InterfaceRequestor(nsIPrincipal* aPrincipal,
|
||||
nsILoadGroup* aLoadGroup)
|
||||
{
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
public:
|
||||
InterfaceRequestor(nsIPrincipal* aPrincipal, nsILoadGroup* aLoadGroup)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aPrincipal);
|
||||
|
||||
// Look for an existing LoadContext. This is optional and it's ok if
|
||||
// we don't find one.
|
||||
nsCOMPtr<nsILoadContext> baseContext;
|
||||
if (aLoadGroup) {
|
||||
nsCOMPtr<nsIInterfaceRequestor> callbacks;
|
||||
aLoadGroup->GetNotificationCallbacks(getter_AddRefs(callbacks));
|
||||
if (callbacks) {
|
||||
callbacks->GetInterface(NS_GET_IID(nsILoadContext),
|
||||
getter_AddRefs(baseContext));
|
||||
}
|
||||
}
|
||||
|
||||
mLoadContext = new LoadContext(aPrincipal, baseContext);
|
||||
}
|
||||
|
||||
void
|
||||
MaybeAddTabChild(nsILoadGroup* aLoadGroup)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (!aLoadGroup) {
|
||||
return;
|
||||
}
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aPrincipal);
|
||||
|
||||
// Look for an existing LoadContext. This is optional and it's ok if
|
||||
// we don't find one.
|
||||
nsCOMPtr<nsILoadContext> baseContext;
|
||||
if (aLoadGroup) {
|
||||
nsCOMPtr<nsIInterfaceRequestor> callbacks;
|
||||
aLoadGroup->GetNotificationCallbacks(getter_AddRefs(callbacks));
|
||||
if (!callbacks) {
|
||||
return;
|
||||
if (callbacks) {
|
||||
callbacks->GetInterface(NS_GET_IID(nsILoadContext),
|
||||
getter_AddRefs(baseContext));
|
||||
}
|
||||
|
||||
nsCOMPtr<nsITabChild> tabChild;
|
||||
callbacks->GetInterface(NS_GET_IID(nsITabChild), getter_AddRefs(tabChild));
|
||||
if (!tabChild) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Use weak references to the tab child. Holding a strong reference will
|
||||
// not prevent an ActorDestroy() from being called on the TabChild.
|
||||
// Therefore, we should let the TabChild destroy itself as soon as possible.
|
||||
mTabChildList.AppendElement(do_GetWeakReference(tabChild));
|
||||
}
|
||||
|
||||
NS_IMETHOD
|
||||
GetInterface(const nsIID& aIID, void** aSink) override
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mLoadContext);
|
||||
mLoadContext = new LoadContext(aPrincipal, baseContext);
|
||||
}
|
||||
|
||||
if (aIID.Equals(NS_GET_IID(nsILoadContext))) {
|
||||
nsCOMPtr<nsILoadContext> ref = mLoadContext;
|
||||
ref.forget(aSink);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// If we still have an active nsITabChild, then return it. Its possible,
|
||||
// though, that all of the TabChild objects have been destroyed. In that
|
||||
// case we return NS_NOINTERFACE.
|
||||
if(aIID.Equals(NS_GET_IID(nsITabChild))) {
|
||||
nsCOMPtr<nsITabChild> tabChild = GetAnyLiveTabChild();
|
||||
if (!tabChild) {
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
tabChild.forget(aSink);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
|
||||
private:
|
||||
~InterfaceRequestor() { }
|
||||
|
||||
already_AddRefed<nsITabChild>
|
||||
GetAnyLiveTabChild()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
// Search our list of known TabChild objects for one that still exists.
|
||||
while (!mTabChildList.IsEmpty()) {
|
||||
nsCOMPtr<nsITabChild> tabChild =
|
||||
do_QueryReferent(mTabChildList.LastElement());
|
||||
|
||||
// Does this tab child still exist? If so, return it. We are done.
|
||||
if (tabChild) {
|
||||
return tabChild.forget();
|
||||
}
|
||||
|
||||
// Otherwise remove the stale weak reference and check the next one
|
||||
mTabChildList.RemoveElementAt(mTabChildList.Length() - 1);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsILoadContext> mLoadContext;
|
||||
|
||||
// Array of weak references to nsITabChild. We do not want to keep TabChild
|
||||
// actors alive for long after their ActorDestroy() methods are called.
|
||||
nsTArray<nsWeakPtr> mTabChildList;
|
||||
};
|
||||
|
||||
template <class Derived>
|
||||
NS_IMPL_ADDREF(WorkerPrivateParent<Derived>::InterfaceRequestor)
|
||||
|
||||
template <class Derived>
|
||||
NS_IMPL_RELEASE(WorkerPrivateParent<Derived>::InterfaceRequestor)
|
||||
|
||||
template <class Derived>
|
||||
NS_IMPL_QUERY_INTERFACE(WorkerPrivateParent<Derived>::InterfaceRequestor,
|
||||
nsIInterfaceRequestor)
|
||||
|
||||
template <class Derived>
|
||||
class WorkerPrivateParent<Derived>::EventTarget final
|
||||
: public nsIEventTarget
|
||||
void
|
||||
WorkerLoadInfo::
|
||||
InterfaceRequestor::MaybeAddTabChild(nsILoadGroup* aLoadGroup)
|
||||
{
|
||||
// This mutex protects mWorkerPrivate and must be acquired *before* the
|
||||
// WorkerPrivate's mutex whenever they must both be held.
|
||||
mozilla::Mutex mMutex;
|
||||
WorkerPrivate* mWorkerPrivate;
|
||||
nsIEventTarget* mWeakNestedEventTarget;
|
||||
nsCOMPtr<nsIEventTarget> mNestedEventTarget;
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
public:
|
||||
explicit EventTarget(WorkerPrivate* aWorkerPrivate)
|
||||
: mMutex("WorkerPrivateParent::EventTarget::mMutex"),
|
||||
mWorkerPrivate(aWorkerPrivate), mWeakNestedEventTarget(nullptr)
|
||||
{
|
||||
MOZ_ASSERT(aWorkerPrivate);
|
||||
if (!aLoadGroup) {
|
||||
return;
|
||||
}
|
||||
|
||||
EventTarget(WorkerPrivate* aWorkerPrivate, nsIEventTarget* aNestedEventTarget)
|
||||
: mMutex("WorkerPrivateParent::EventTarget::mMutex"),
|
||||
mWorkerPrivate(aWorkerPrivate), mWeakNestedEventTarget(aNestedEventTarget),
|
||||
mNestedEventTarget(aNestedEventTarget)
|
||||
{
|
||||
MOZ_ASSERT(aWorkerPrivate);
|
||||
MOZ_ASSERT(aNestedEventTarget);
|
||||
nsCOMPtr<nsIInterfaceRequestor> callbacks;
|
||||
aLoadGroup->GetNotificationCallbacks(getter_AddRefs(callbacks));
|
||||
if (!callbacks) {
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
Disable()
|
||||
{
|
||||
nsCOMPtr<nsIEventTarget> nestedEventTarget;
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
nsCOMPtr<nsITabChild> tabChild;
|
||||
callbacks->GetInterface(NS_GET_IID(nsITabChild), getter_AddRefs(tabChild));
|
||||
if (!tabChild) {
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mWorkerPrivate);
|
||||
mWorkerPrivate = nullptr;
|
||||
mNestedEventTarget.swap(nestedEventTarget);
|
||||
// Use weak references to the tab child. Holding a strong reference will
|
||||
// not prevent an ActorDestroy() from being called on the TabChild.
|
||||
// Therefore, we should let the TabChild destroy itself as soon as possible.
|
||||
mTabChildList.AppendElement(do_GetWeakReference(tabChild));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WorkerLoadInfo::
|
||||
InterfaceRequestor::GetInterface(const nsIID& aIID, void** aSink)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mLoadContext);
|
||||
|
||||
if (aIID.Equals(NS_GET_IID(nsILoadContext))) {
|
||||
nsCOMPtr<nsILoadContext> ref = mLoadContext;
|
||||
ref.forget(aSink);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// If we still have an active nsITabChild, then return it. Its possible,
|
||||
// though, that all of the TabChild objects have been destroyed. In that
|
||||
// case we return NS_NOINTERFACE.
|
||||
if (aIID.Equals(NS_GET_IID(nsITabChild))) {
|
||||
nsCOMPtr<nsITabChild> tabChild = GetAnyLiveTabChild();
|
||||
if (!tabChild) {
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
tabChild.forget(aSink);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIEventTarget*
|
||||
GetWeakNestedEventTarget() const
|
||||
{
|
||||
MOZ_ASSERT(mWeakNestedEventTarget);
|
||||
return mWeakNestedEventTarget;
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
|
||||
already_AddRefed<nsITabChild>
|
||||
WorkerLoadInfo::
|
||||
InterfaceRequestor::GetAnyLiveTabChild()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
// Search our list of known TabChild objects for one that still exists.
|
||||
while (!mTabChildList.IsEmpty()) {
|
||||
nsCOMPtr<nsITabChild> tabChild =
|
||||
do_QueryReferent(mTabChildList.LastElement());
|
||||
|
||||
// Does this tab child still exist? If so, return it. We are done.
|
||||
if (tabChild) {
|
||||
return tabChild.forget();
|
||||
}
|
||||
|
||||
// Otherwise remove the stale weak reference and check the next one
|
||||
mTabChildList.RemoveElementAt(mTabChildList.Length() - 1);
|
||||
}
|
||||
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSIEVENTTARGET
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
~EventTarget()
|
||||
{ }
|
||||
};
|
||||
NS_IMPL_ADDREF(WorkerLoadInfo::InterfaceRequestor)
|
||||
NS_IMPL_RELEASE(WorkerLoadInfo::InterfaceRequestor)
|
||||
NS_IMPL_QUERY_INTERFACE(WorkerLoadInfo::InterfaceRequestor, nsIInterfaceRequestor)
|
||||
|
||||
struct WorkerPrivate::TimeoutInfo
|
||||
{
|
||||
@@ -2551,7 +2589,7 @@ WorkerPrivateParent<Derived>::WorkerPrivateParent(
|
||||
bool aIsChromeWorker,
|
||||
WorkerType aWorkerType,
|
||||
const nsACString& aSharedWorkerName,
|
||||
LoadInfo& aLoadInfo)
|
||||
WorkerLoadInfo& aLoadInfo)
|
||||
: mMutex("WorkerPrivateParent Mutex"),
|
||||
mCondVar(mMutex, "WorkerPrivateParent CondVar"),
|
||||
mMemoryReportCondVar(mMutex, "WorkerPrivateParent Memory Report CondVar"),
|
||||
@@ -3193,9 +3231,10 @@ void
|
||||
WorkerPrivateParent<Derived>::PostMessageInternal(
|
||||
JSContext* aCx,
|
||||
JS::Handle<JS::Value> aMessage,
|
||||
const Optional<Sequence<JS::Value> >& aTransferable,
|
||||
const Optional<Sequence<JS::Value>>& aTransferable,
|
||||
bool aToMessagePort,
|
||||
uint64_t aMessagePortSerial,
|
||||
ServiceWorkerClientInfo* aClientInfo,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
AssertIsOnParentThread();
|
||||
@@ -3259,11 +3298,26 @@ WorkerPrivateParent<Derived>::PostMessageInternal(
|
||||
WorkerRunnable::WorkerThreadModifyBusyCount,
|
||||
Move(buffer), clonedObjects, aToMessagePort,
|
||||
aMessagePortSerial);
|
||||
runnable->SetMessageSource(aClientInfo);
|
||||
|
||||
if (!runnable->Dispatch(aCx)) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
template <class Derived>
|
||||
void
|
||||
WorkerPrivateParent<Derived>::PostMessageToServiceWorker(
|
||||
JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
||||
const Optional<Sequence<JS::Value>>& aTransferable,
|
||||
nsAutoPtr<ServiceWorkerClientInfo>& aClientInfo,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
PostMessageInternal(aCx, aMessage, aTransferable, false, 0,
|
||||
aClientInfo.forget(), aRv);
|
||||
}
|
||||
|
||||
template <class Derived>
|
||||
void
|
||||
WorkerPrivateParent<Derived>::PostMessageToMessagePort(
|
||||
@@ -3276,7 +3330,7 @@ WorkerPrivateParent<Derived>::PostMessageToMessagePort(
|
||||
AssertIsOnMainThread();
|
||||
|
||||
PostMessageInternal(aCx, aMessage, aTransferable, true, aMessagePortSerial,
|
||||
aRv);
|
||||
nullptr, aRv);
|
||||
}
|
||||
|
||||
template <class Derived>
|
||||
@@ -4264,7 +4318,7 @@ WorkerPrivate::WorkerPrivate(JSContext* aCx,
|
||||
const nsAString& aScriptURL,
|
||||
bool aIsChromeWorker, WorkerType aWorkerType,
|
||||
const nsACString& aSharedWorkerName,
|
||||
LoadInfo& aLoadInfo)
|
||||
WorkerLoadInfo& aLoadInfo)
|
||||
: WorkerPrivateParent<WorkerPrivate>(aCx, aParent, aScriptURL,
|
||||
aIsChromeWorker, aWorkerType,
|
||||
aSharedWorkerName, aLoadInfo)
|
||||
@@ -4366,7 +4420,7 @@ WorkerPrivate::Constructor(const GlobalObject& aGlobal,
|
||||
const nsAString& aScriptURL,
|
||||
bool aIsChromeWorker, WorkerType aWorkerType,
|
||||
const nsACString& aSharedWorkerName,
|
||||
LoadInfo* aLoadInfo, ErrorResult& aRv)
|
||||
WorkerLoadInfo* aLoadInfo, ErrorResult& aRv)
|
||||
{
|
||||
JSContext* cx = aGlobal.Context();
|
||||
return Constructor(cx, aScriptURL, aIsChromeWorker, aWorkerType,
|
||||
@@ -4379,7 +4433,7 @@ WorkerPrivate::Constructor(JSContext* aCx,
|
||||
const nsAString& aScriptURL,
|
||||
bool aIsChromeWorker, WorkerType aWorkerType,
|
||||
const nsACString& aSharedWorkerName,
|
||||
LoadInfo* aLoadInfo, ErrorResult& aRv)
|
||||
WorkerLoadInfo* aLoadInfo, ErrorResult& aRv)
|
||||
{
|
||||
WorkerPrivate* parent = NS_IsMainThread() ?
|
||||
nullptr :
|
||||
@@ -4395,7 +4449,7 @@ WorkerPrivate::Constructor(JSContext* aCx,
|
||||
MOZ_ASSERT_IF(aWorkerType == WorkerTypeDedicated,
|
||||
aSharedWorkerName.IsEmpty());
|
||||
|
||||
Maybe<LoadInfo> stackLoadInfo;
|
||||
Maybe<WorkerLoadInfo> stackLoadInfo;
|
||||
if (!aLoadInfo) {
|
||||
stackLoadInfo.emplace();
|
||||
|
||||
@@ -4458,7 +4512,7 @@ WorkerPrivate::GetLoadInfo(JSContext* aCx, nsPIDOMWindow* aWindow,
|
||||
WorkerPrivate* aParent, const nsAString& aScriptURL,
|
||||
bool aIsChromeWorker,
|
||||
LoadGroupBehavior aLoadGroupBehavior,
|
||||
LoadInfo* aLoadInfo)
|
||||
WorkerLoadInfo* aLoadInfo)
|
||||
{
|
||||
using namespace mozilla::dom::workers::scriptloader;
|
||||
using mozilla::dom::indexedDB::IDBFactory;
|
||||
@@ -4470,7 +4524,7 @@ WorkerPrivate::GetLoadInfo(JSContext* aCx, nsPIDOMWindow* aWindow,
|
||||
AssertIsOnMainThread();
|
||||
}
|
||||
|
||||
LoadInfo loadInfo;
|
||||
WorkerLoadInfo loadInfo;
|
||||
nsresult rv;
|
||||
|
||||
if (aParent) {
|
||||
@@ -4714,12 +4768,13 @@ WorkerPrivate::GetLoadInfo(JSContext* aCx, nsPIDOMWindow* aWindow,
|
||||
|
||||
// static
|
||||
void
|
||||
WorkerPrivate::OverrideLoadInfoLoadGroup(LoadInfo& aLoadInfo)
|
||||
WorkerPrivate::OverrideLoadInfoLoadGroup(WorkerLoadInfo& aLoadInfo)
|
||||
{
|
||||
MOZ_ASSERT(!aLoadInfo.mInterfaceRequestor);
|
||||
|
||||
aLoadInfo.mInterfaceRequestor = new InterfaceRequestor(aLoadInfo.mPrincipal,
|
||||
aLoadInfo.mLoadGroup);
|
||||
aLoadInfo.mInterfaceRequestor =
|
||||
new WorkerLoadInfo::InterfaceRequestor(aLoadInfo.mPrincipal,
|
||||
aLoadInfo.mLoadGroup);
|
||||
aLoadInfo.mInterfaceRequestor->MaybeAddTabChild(aLoadInfo.mLoadGroup);
|
||||
|
||||
nsCOMPtr<nsILoadGroup> loadGroup =
|
||||
|
||||
+17
-104
@@ -61,6 +61,7 @@ BEGIN_WORKERS_NAMESPACE
|
||||
class AutoSyncLoopHolder;
|
||||
class MessagePort;
|
||||
class SharedWorker;
|
||||
class ServiceWorkerClientInfo;
|
||||
class WorkerControlRunnable;
|
||||
class WorkerDebugger;
|
||||
class WorkerDebuggerGlobalScope;
|
||||
@@ -69,15 +70,6 @@ class WorkerPrivate;
|
||||
class WorkerRunnable;
|
||||
class WorkerThread;
|
||||
|
||||
// If you change this, the corresponding list in nsIWorkerDebugger.idl needs to
|
||||
// be updated too.
|
||||
enum WorkerType
|
||||
{
|
||||
WorkerTypeDedicated,
|
||||
WorkerTypeShared,
|
||||
WorkerTypeService
|
||||
};
|
||||
|
||||
// SharedMutex is a small wrapper around an (internal) reference-counted Mutex
|
||||
// object. It exists to avoid changing a lot of code to use Mutex* instead of
|
||||
// Mutex&.
|
||||
@@ -133,7 +125,6 @@ class WorkerPrivateParent : public DOMEventTargetHelper
|
||||
class SynchronizeAndResumeRunnable;
|
||||
|
||||
protected:
|
||||
class InterfaceRequestor;
|
||||
class EventTarget;
|
||||
friend class EventTarget;
|
||||
|
||||
@@ -153,84 +144,6 @@ public:
|
||||
nsString mOrigin;
|
||||
};
|
||||
|
||||
struct LoadInfo
|
||||
{
|
||||
// All of these should be released in ForgetMainThreadObjects.
|
||||
nsCOMPtr<nsIURI> mBaseURI;
|
||||
nsCOMPtr<nsIURI> mResolvedScriptURI;
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
nsCOMPtr<nsIScriptContext> mScriptContext;
|
||||
nsCOMPtr<nsPIDOMWindow> mWindow;
|
||||
nsCOMPtr<nsIContentSecurityPolicy> mCSP;
|
||||
nsCOMPtr<nsIChannel> mChannel;
|
||||
nsCOMPtr<nsILoadGroup> mLoadGroup;
|
||||
|
||||
// Only set if we have a custom overriden load group
|
||||
nsRefPtr<InterfaceRequestor> mInterfaceRequestor;
|
||||
|
||||
nsAutoPtr<PrincipalInfo> mPrincipalInfo;
|
||||
nsCString mDomain;
|
||||
|
||||
uint64_t mWindowID;
|
||||
|
||||
bool mFromWindow;
|
||||
bool mEvalAllowed;
|
||||
bool mReportCSPViolations;
|
||||
bool mXHRParamsAllowed;
|
||||
bool mPrincipalIsSystem;
|
||||
bool mIsInPrivilegedApp;
|
||||
bool mIsInCertifiedApp;
|
||||
bool mIndexedDBAllowed;
|
||||
|
||||
LoadInfo();
|
||||
~LoadInfo();
|
||||
|
||||
void
|
||||
StealFrom(LoadInfo& aOther)
|
||||
{
|
||||
MOZ_ASSERT(!mBaseURI);
|
||||
aOther.mBaseURI.swap(mBaseURI);
|
||||
|
||||
MOZ_ASSERT(!mResolvedScriptURI);
|
||||
aOther.mResolvedScriptURI.swap(mResolvedScriptURI);
|
||||
|
||||
MOZ_ASSERT(!mPrincipal);
|
||||
aOther.mPrincipal.swap(mPrincipal);
|
||||
|
||||
MOZ_ASSERT(!mScriptContext);
|
||||
aOther.mScriptContext.swap(mScriptContext);
|
||||
|
||||
MOZ_ASSERT(!mWindow);
|
||||
aOther.mWindow.swap(mWindow);
|
||||
|
||||
MOZ_ASSERT(!mCSP);
|
||||
aOther.mCSP.swap(mCSP);
|
||||
|
||||
MOZ_ASSERT(!mChannel);
|
||||
aOther.mChannel.swap(mChannel);
|
||||
|
||||
MOZ_ASSERT(!mLoadGroup);
|
||||
aOther.mLoadGroup.swap(mLoadGroup);
|
||||
|
||||
MOZ_ASSERT(!mInterfaceRequestor);
|
||||
aOther.mInterfaceRequestor.swap(mInterfaceRequestor);
|
||||
|
||||
MOZ_ASSERT(!mPrincipalInfo);
|
||||
mPrincipalInfo = aOther.mPrincipalInfo.forget();
|
||||
|
||||
mDomain = aOther.mDomain;
|
||||
mWindowID = aOther.mWindowID;
|
||||
mFromWindow = aOther.mFromWindow;
|
||||
mEvalAllowed = aOther.mEvalAllowed;
|
||||
mReportCSPViolations = aOther.mReportCSPViolations;
|
||||
mXHRParamsAllowed = aOther.mXHRParamsAllowed;
|
||||
mPrincipalIsSystem = aOther.mPrincipalIsSystem;
|
||||
mIsInPrivilegedApp = aOther.mIsInPrivilegedApp;
|
||||
mIsInCertifiedApp = aOther.mIsInCertifiedApp;
|
||||
mIndexedDBAllowed = aOther.mIndexedDBAllowed;
|
||||
}
|
||||
};
|
||||
|
||||
protected:
|
||||
typedef mozilla::ErrorResult ErrorResult;
|
||||
|
||||
@@ -249,7 +162,7 @@ private:
|
||||
LocationInfo mLocationInfo;
|
||||
// The lifetime of these objects within LoadInfo is managed explicitly;
|
||||
// they do not need to be cycle collected.
|
||||
LoadInfo mLoadInfo;
|
||||
WorkerLoadInfo mLoadInfo;
|
||||
|
||||
// Only used for top level workers.
|
||||
nsTArray<nsCOMPtr<nsIRunnable>> mQueuedRunnables;
|
||||
@@ -285,7 +198,7 @@ protected:
|
||||
const nsAString& aScriptURL, bool aIsChromeWorker,
|
||||
WorkerType aWorkerType,
|
||||
const nsACString& aSharedWorkerName,
|
||||
LoadInfo& aLoadInfo);
|
||||
WorkerLoadInfo& aLoadInfo);
|
||||
|
||||
~WorkerPrivateParent();
|
||||
|
||||
@@ -309,8 +222,9 @@ private:
|
||||
|
||||
void
|
||||
PostMessageInternal(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
||||
const Optional<Sequence<JS::Value> >& aTransferable,
|
||||
const Optional<Sequence<JS::Value>>& aTransferable,
|
||||
bool aToMessagePort, uint64_t aMessagePortSerial,
|
||||
ServiceWorkerClientInfo* aClientInfo,
|
||||
ErrorResult& aRv);
|
||||
|
||||
nsresult
|
||||
@@ -412,9 +326,15 @@ public:
|
||||
const Optional<Sequence<JS::Value> >& aTransferable,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
PostMessageInternal(aCx, aMessage, aTransferable, false, 0, aRv);
|
||||
PostMessageInternal(aCx, aMessage, aTransferable, false, 0, nullptr, aRv);
|
||||
}
|
||||
|
||||
void
|
||||
PostMessageToServiceWorker(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
||||
const Optional<Sequence<JS::Value>>& aTransferable,
|
||||
nsAutoPtr<ServiceWorkerClientInfo>& aClientInfo,
|
||||
ErrorResult& aRv);
|
||||
|
||||
void
|
||||
PostMessageToMessagePort(JSContext* aCx,
|
||||
uint64_t aMessagePortSerial,
|
||||
@@ -926,12 +846,12 @@ public:
|
||||
Constructor(const GlobalObject& aGlobal, const nsAString& aScriptURL,
|
||||
bool aIsChromeWorker, WorkerType aWorkerType,
|
||||
const nsACString& aSharedWorkerName,
|
||||
LoadInfo* aLoadInfo, ErrorResult& aRv);
|
||||
WorkerLoadInfo* aLoadInfo, ErrorResult& aRv);
|
||||
|
||||
static already_AddRefed<WorkerPrivate>
|
||||
Constructor(JSContext* aCx, const nsAString& aScriptURL, bool aIsChromeWorker,
|
||||
WorkerType aWorkerType, const nsACString& aSharedWorkerName,
|
||||
LoadInfo* aLoadInfo, ErrorResult& aRv);
|
||||
WorkerLoadInfo* aLoadInfo, ErrorResult& aRv);
|
||||
|
||||
static bool
|
||||
WorkerAvailable(JSContext* /* unused */, JSObject* /* unused */);
|
||||
@@ -945,10 +865,10 @@ public:
|
||||
static nsresult
|
||||
GetLoadInfo(JSContext* aCx, nsPIDOMWindow* aWindow, WorkerPrivate* aParent,
|
||||
const nsAString& aScriptURL, bool aIsChromeWorker,
|
||||
LoadGroupBehavior aLoadGroupBehavior, LoadInfo* aLoadInfo);
|
||||
LoadGroupBehavior aLoadGroupBehavior, WorkerLoadInfo* aLoadInfo);
|
||||
|
||||
static void
|
||||
OverrideLoadInfoLoadGroup(LoadInfo& aLoadInfo);
|
||||
OverrideLoadInfoLoadGroup(WorkerLoadInfo& aLoadInfo);
|
||||
|
||||
WorkerDebugger*
|
||||
Debugger() const
|
||||
@@ -1185,13 +1105,6 @@ public:
|
||||
return mPreferences[WORKERPREF_DUMP];
|
||||
}
|
||||
|
||||
bool
|
||||
DOMFetchEnabled() const
|
||||
{
|
||||
AssertIsOnWorkerThread();
|
||||
return mPreferences[WORKERPREF_DOM_FETCH];
|
||||
}
|
||||
|
||||
bool
|
||||
DOMCachesEnabled() const
|
||||
{
|
||||
@@ -1255,7 +1168,7 @@ private:
|
||||
WorkerPrivate(JSContext* aCx, WorkerPrivate* aParent,
|
||||
const nsAString& aScriptURL, bool aIsChromeWorker,
|
||||
WorkerType aWorkerType, const nsACString& aSharedWorkerName,
|
||||
LoadInfo& aLoadInfo);
|
||||
WorkerLoadInfo& aLoadInfo);
|
||||
|
||||
void
|
||||
ClearMainEventQueue(WorkerRanOrNot aRanOrNot);
|
||||
|
||||
+87
-2
@@ -14,6 +14,11 @@
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsDebug.h"
|
||||
#include "nsString.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
#include "nsILoadContext.h"
|
||||
#include "nsIWeakReferenceUtils.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
|
||||
#define BEGIN_WORKERS_NAMESPACE \
|
||||
namespace mozilla { namespace dom { namespace workers {
|
||||
@@ -24,9 +29,32 @@
|
||||
|
||||
#define WORKERS_SHUTDOWN_TOPIC "web-workers-shutdown"
|
||||
|
||||
class nsIGlobalObject;
|
||||
class nsIContentSecurityPolicy;
|
||||
class nsIScriptContext;
|
||||
class nsIGlobalObject;
|
||||
class nsPIDOMWindow;
|
||||
class nsIPrincipal;
|
||||
class nsILoadGroup;
|
||||
class nsITabChild;
|
||||
class nsIChannel;
|
||||
class nsIURI;
|
||||
|
||||
namespace mozilla {
|
||||
namespace ipc {
|
||||
class PrincipalInfo;
|
||||
}
|
||||
|
||||
namespace dom {
|
||||
// If you change this, the corresponding list in nsIWorkerDebugger.idl needs to
|
||||
// be updated too.
|
||||
enum WorkerType
|
||||
{
|
||||
WorkerTypeDedicated,
|
||||
WorkerTypeShared,
|
||||
WorkerTypeService
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
BEGIN_WORKERS_NAMESPACE
|
||||
|
||||
@@ -166,11 +194,68 @@ struct JSSettings
|
||||
enum WorkerPreference
|
||||
{
|
||||
WORKERPREF_DUMP = 0, // browser.dom.window.dump.enabled
|
||||
WORKERPREF_DOM_FETCH,// dom.fetch.enabled
|
||||
WORKERPREF_DOM_CACHES, // dom.caches.enabled
|
||||
WORKERPREF_COUNT
|
||||
};
|
||||
|
||||
// Implemented in WorkerPrivate.cpp
|
||||
|
||||
struct WorkerLoadInfo
|
||||
{
|
||||
// All of these should be released in WorkerPrivateParent::ForgetMainThreadObjects.
|
||||
nsCOMPtr<nsIURI> mBaseURI;
|
||||
nsCOMPtr<nsIURI> mResolvedScriptURI;
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
nsCOMPtr<nsIScriptContext> mScriptContext;
|
||||
nsCOMPtr<nsPIDOMWindow> mWindow;
|
||||
nsCOMPtr<nsIContentSecurityPolicy> mCSP;
|
||||
nsCOMPtr<nsIChannel> mChannel;
|
||||
nsCOMPtr<nsILoadGroup> mLoadGroup;
|
||||
|
||||
class InterfaceRequestor MOZ_FINAL : public nsIInterfaceRequestor
|
||||
{
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
public:
|
||||
InterfaceRequestor(nsIPrincipal* aPrincipal, nsILoadGroup* aLoadGroup);
|
||||
void MaybeAddTabChild(nsILoadGroup* aLoadGroup);
|
||||
NS_IMETHOD GetInterface(const nsIID& aIID, void** aSink) MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
~InterfaceRequestor() { }
|
||||
|
||||
already_AddRefed<nsITabChild> GetAnyLiveTabChild();
|
||||
|
||||
nsCOMPtr<nsILoadContext> mLoadContext;
|
||||
|
||||
// Array of weak references to nsITabChild. We do not want to keep TabChild
|
||||
// actors alive for long after their ActorDestroy() methods are called.
|
||||
nsTArray<nsWeakPtr> mTabChildList;
|
||||
};
|
||||
|
||||
// Only set if we have a custom overriden load group
|
||||
nsRefPtr<InterfaceRequestor> mInterfaceRequestor;
|
||||
|
||||
nsAutoPtr<mozilla::ipc::PrincipalInfo> mPrincipalInfo;
|
||||
nsCString mDomain;
|
||||
|
||||
uint64_t mWindowID;
|
||||
|
||||
bool mFromWindow;
|
||||
bool mEvalAllowed;
|
||||
bool mReportCSPViolations;
|
||||
bool mXHRParamsAllowed;
|
||||
bool mPrincipalIsSystem;
|
||||
bool mIsInPrivilegedApp;
|
||||
bool mIsInCertifiedApp;
|
||||
bool mIndexedDBAllowed;
|
||||
|
||||
WorkerLoadInfo();
|
||||
~WorkerLoadInfo();
|
||||
|
||||
void StealFrom(WorkerLoadInfo& aOther);
|
||||
};
|
||||
|
||||
// All of these are implemented in RuntimeService.cpp
|
||||
|
||||
void
|
||||
|
||||
@@ -36,11 +36,7 @@
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["dom.fetch.enabled", true]
|
||||
]}, function() {
|
||||
checkEnabled();
|
||||
});
|
||||
checkEnabled();
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
@@ -36,11 +36,7 @@
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["dom.fetch.enabled", true]
|
||||
]}, function() {
|
||||
checkEnabled();
|
||||
});
|
||||
checkEnabled();
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
@@ -36,11 +36,7 @@
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["dom.fetch.enabled", true]
|
||||
]}, function() {
|
||||
runTest();
|
||||
});
|
||||
runTest();
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
function handleRequest(request, response) {
|
||||
// The string "hello" repeated 10 times followed by newline. Compressed using gzip.
|
||||
var bytes = [0x1f, 0x8b, 0x08, 0x08, 0x4d, 0xe2, 0xf9, 0x54, 0x00, 0x03, 0x68,
|
||||
0x65, 0x6c, 0x6c, 0x6f, 0x00, 0xcb, 0x48, 0xcd, 0xc9, 0xc9, 0xcf,
|
||||
0x20, 0x85, 0xe0, 0x02, 0x00, 0xf5, 0x4b, 0x38, 0xcf, 0x33, 0x00,
|
||||
0x00, 0x00];
|
||||
|
||||
response.setHeader("Content-Encoding", "gzip", false);
|
||||
response.setHeader("Content-Length", "" + bytes.length, false);
|
||||
response.setHeader("Content-Type", "text/plain", false);
|
||||
|
||||
var bos = Components.classes["@mozilla.org/binaryoutputstream;1"]
|
||||
.createInstance(Components.interfaces.nsIBinaryOutputStream);
|
||||
bos.setOutputStream(response.bodyOutputStream);
|
||||
|
||||
bos.writeByteArray(bytes, bytes.length);
|
||||
}
|
||||
@@ -27,6 +27,25 @@ fetch('synthesized.txt', function(xhr) {
|
||||
finish();
|
||||
});
|
||||
|
||||
fetch('test-respondwith-response.txt', function(xhr) {
|
||||
my_ok(xhr.status == 200, "test-respondwith-response load should be successful");
|
||||
my_ok(xhr.responseText == "test-respondwith-response response body", "load should have response");
|
||||
finish();
|
||||
});
|
||||
|
||||
fetch('synthesized-404.txt', function(xhr) {
|
||||
my_ok(xhr.status == 404, "load should 404");
|
||||
my_ok(xhr.responseText == "synthesized response body", "404 load should have synthesized response");
|
||||
finish();
|
||||
});
|
||||
|
||||
fetch('synthesized-headers.txt', function(xhr) {
|
||||
my_ok(xhr.status == 200, "load should be successful");
|
||||
my_ok(xhr.getResponseHeader("X-Custom-Greeting") === "Hello", "custom header should be set");
|
||||
my_ok(xhr.responseText == "synthesized response body", "custom header load should have synthesized response");
|
||||
finish();
|
||||
});
|
||||
|
||||
fetch('ignored.txt', function(xhr) {
|
||||
my_ok(xhr.status == 404, "load should be uninterrupted");
|
||||
finish();
|
||||
@@ -52,3 +71,35 @@ fetch('headers.txt', function(xhr) {
|
||||
my_ok(xhr.responseText == "1", "request header checks should have passed");
|
||||
finish();
|
||||
}, null, [["X-Test1", "header1"], ["X-Test2", "header2"]]);
|
||||
|
||||
var expectedUncompressedResponse = "";
|
||||
for (var i = 0; i < 10; ++i) {
|
||||
expectedUncompressedResponse += "hello";
|
||||
}
|
||||
expectedUncompressedResponse += "\n";
|
||||
|
||||
// ServiceWorker does not intercept, at which point the network request should
|
||||
// be correctly decoded.
|
||||
fetch('deliver-gzip.sjs', function(xhr) {
|
||||
my_ok(xhr.status == 200, "network gzip load should be successful");
|
||||
my_ok(xhr.responseText == expectedUncompressedResponse, "network gzip load should have synthesized response.");
|
||||
my_ok(xhr.getResponseHeader("Content-Encoding") == "gzip", "network Content-Encoding should be gzip.");
|
||||
my_ok(xhr.getResponseHeader("Content-Length") == "35", "network Content-Length should be of original gzipped file.");
|
||||
finish();
|
||||
});
|
||||
|
||||
fetch('hello.gz', function(xhr) {
|
||||
my_ok(xhr.status == 200, "gzip load should be successful");
|
||||
my_ok(xhr.responseText == expectedUncompressedResponse, "gzip load should have synthesized response.");
|
||||
my_ok(xhr.getResponseHeader("Content-Encoding") == "gzip", "Content-Encoding should be gzip.");
|
||||
my_ok(xhr.getResponseHeader("Content-Length") == "35", "Content-Length should be of original gzipped file.");
|
||||
finish();
|
||||
});
|
||||
|
||||
fetch('hello-after-extracting.gz', function(xhr) {
|
||||
my_ok(xhr.status == 200, "gzip load should be successful");
|
||||
my_ok(xhr.responseText == expectedUncompressedResponse, "gzip load should have synthesized response.");
|
||||
my_ok(xhr.getResponseHeader("Content-Encoding") == "gzip", "Content-Encoding should be gzip.");
|
||||
my_ok(xhr.getResponseHeader("Content-Length") == "35", "Content-Length should be of original gzipped file.");
|
||||
finish();
|
||||
});
|
||||
|
||||
@@ -1,86 +1,135 @@
|
||||
var seenIndex = false;
|
||||
|
||||
onfetch = function(ev) {
|
||||
if (ev.request.url.includes("synthesized.txt")) {
|
||||
var p = new Promise(function(resolve) {
|
||||
var r = new Response("synthesized response body", {});
|
||||
resolve(r);
|
||||
});
|
||||
ev.respondWith(p);
|
||||
ev.respondWith(Promise.resolve(
|
||||
new Response("synthesized response body", {})
|
||||
));
|
||||
}
|
||||
|
||||
else if (ev.request.url.contains("synthesized-404.txt")) {
|
||||
ev.respondWith(Promise.resolve(
|
||||
new Response("synthesized response body", { status: 404 })
|
||||
));
|
||||
}
|
||||
|
||||
else if (ev.request.url.contains("synthesized-headers.txt")) {
|
||||
ev.respondWith(Promise.resolve(
|
||||
new Response("synthesized response body", {
|
||||
headers: {
|
||||
"X-Custom-Greeting": "Hello"
|
||||
}
|
||||
})
|
||||
));
|
||||
}
|
||||
|
||||
else if (ev.request.url.contains("test-respondwith-response.txt")) {
|
||||
ev.respondWith(new Response("test-respondwith-response response body", {}));
|
||||
}
|
||||
|
||||
else if (ev.request.url.includes("ignored.txt")) {
|
||||
}
|
||||
|
||||
else if (ev.request.url.includes("rejected.txt")) {
|
||||
var p = new Promise(function(resolve, reject) {
|
||||
reject();
|
||||
});
|
||||
ev.respondWith(p);
|
||||
ev.respondWith(Promise.reject());
|
||||
}
|
||||
|
||||
else if (ev.request.url.includes("nonresponse.txt")) {
|
||||
var p = new Promise(function(resolve, reject) {
|
||||
resolve(5);
|
||||
});
|
||||
ev.respondWith(p);
|
||||
ev.respondWith(Promise.resolve(5));
|
||||
}
|
||||
|
||||
else if (ev.request.url.includes("nonresponse2.txt")) {
|
||||
var p = new Promise(function(resolve, reject) {
|
||||
resolve({});
|
||||
});
|
||||
ev.respondWith(p);
|
||||
ev.respondWith(Promise.resolve({}));
|
||||
}
|
||||
|
||||
else if (ev.request.url.includes("headers.txt")) {
|
||||
var p = new Promise(function(resolve, reject) {
|
||||
var ok = true;
|
||||
ok &= ev.request.headers.get("X-Test1") == "header1";
|
||||
ok &= ev.request.headers.get("X-Test2") == "header2";
|
||||
var r = new Response(ok.toString(), {});
|
||||
resolve(r);
|
||||
});
|
||||
ev.respondWith(p);
|
||||
var ok = true;
|
||||
ok &= ev.request.headers.get("X-Test1") == "header1";
|
||||
ok &= ev.request.headers.get("X-Test2") == "header2";
|
||||
ev.respondWith(Promise.resolve(
|
||||
new Response(ok.toString(), {})
|
||||
));
|
||||
}
|
||||
|
||||
else if (ev.request.url.includes("nonexistent_image.gif")) {
|
||||
var p = new Promise(function(resolve, reject) {
|
||||
resolve(new Response(atob("R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs"), {}));
|
||||
});
|
||||
ev.respondWith(p);
|
||||
resolve(new Response(atob("R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs"), {
|
||||
ev.respondWith(Promise.resolve(
|
||||
new Response(atob("R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs"), {
|
||||
headers: {
|
||||
"Content-Type": "image/gif"
|
||||
}
|
||||
})
|
||||
));
|
||||
}
|
||||
|
||||
else if (ev.request.url.includes("nonexistent_script.js")) {
|
||||
var p = new Promise(function(resolve, reject) {
|
||||
resolve(new Response("check_intercepted_script();", {}));
|
||||
});
|
||||
ev.respondWith(p);
|
||||
ev.respondWith(Promise.resolve(
|
||||
new Response("check_intercepted_script();", {})
|
||||
));
|
||||
}
|
||||
|
||||
else if (ev.request.url.includes("nonexistent_stylesheet.css")) {
|
||||
var p = new Promise(function(resolve, reject) {
|
||||
resolve(new Response("#style-test { background-color: black !important; }", {}));
|
||||
});
|
||||
ev.respondWith(p);
|
||||
ev.respondWith(Promise.resolve(
|
||||
new Response("#style-test { background-color: black !important; }", {
|
||||
headers : {
|
||||
"Content-Type": "text/css"
|
||||
}
|
||||
})
|
||||
));
|
||||
}
|
||||
|
||||
else if (ev.request.url.includes("nonexistent_page.html")) {
|
||||
var p = new Promise(function(resolve, reject) {
|
||||
resolve(new Response("<script>window.frameElement.test_result = true;</script>", {}));
|
||||
});
|
||||
ev.respondWith(p);
|
||||
ev.respondWith(Promise.resolve(
|
||||
new Response("<script>window.frameElement.test_result = true;</script>", {
|
||||
headers : {
|
||||
"Content-Type": "text/html"
|
||||
}
|
||||
})
|
||||
));
|
||||
}
|
||||
|
||||
else if (ev.request.url.includes("nonexistent_worker_script.js")) {
|
||||
var p = new Promise(function(resolve, reject) {
|
||||
resolve(new Response("postMessage('worker-intercept-success')", {}));
|
||||
});
|
||||
ev.respondWith(p);
|
||||
ev.respondWith(Promise.resolve(
|
||||
new Response("postMessage('worker-intercept-success')", {})
|
||||
));
|
||||
}
|
||||
|
||||
else if (ev.request.url.includes("nonexistent_imported_script.js")) {
|
||||
var p = new Promise(function(resolve, reject) {
|
||||
resolve(new Response("check_intercepted_script();", {}));
|
||||
});
|
||||
ev.respondWith(p);
|
||||
ev.respondWith(Promise.resolve(
|
||||
new Response("check_intercepted_script();", {})
|
||||
));
|
||||
}
|
||||
|
||||
else if (ev.request.url.contains("deliver-gzip")) {
|
||||
// Don't handle the request, this will make Necko perform a network request, at
|
||||
// which point SetApplyConversion must be re-enabled, otherwise the request
|
||||
// will fail.
|
||||
return;
|
||||
}
|
||||
|
||||
else if (ev.request.url.contains("hello.gz")) {
|
||||
ev.respondWith(fetch("fetch/deliver-gzip.sjs"));
|
||||
}
|
||||
|
||||
else if (ev.request.url.contains("hello-after-extracting.gz")) {
|
||||
ev.respondWith(fetch("fetch/deliver-gzip.sjs").then(function(res) {
|
||||
return res.text().then(function(body) {
|
||||
return new Response(body, { status: res.status, statusText: res.statusText, headers: res.headers });
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
else if (ev.request.url.contains("index.html")) {
|
||||
if (seenIndex) {
|
||||
var body = "<script>" +
|
||||
"opener.postMessage({status: 'ok', result: " + ev.isReload + "," +
|
||||
"message: 'reload status should be indicated'}, '*');" +
|
||||
"opener.postMessage({status: 'done'}, '*');" +
|
||||
"</script>";
|
||||
ev.respondWith(new Response(body, {headers: {'Content-Type': 'text/html'}}));
|
||||
} else {
|
||||
seenIndex = true;
|
||||
ev.respondWith(fetch(ev.request.url));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ support-files =
|
||||
fetch/index.html
|
||||
fetch/fetch_worker_script.js
|
||||
fetch/fetch_tests.js
|
||||
fetch/deliver-gzip.sjs
|
||||
fetch/https/index.html
|
||||
fetch/https/register.html
|
||||
fetch/https/unregister.html
|
||||
@@ -41,6 +42,8 @@ support-files =
|
||||
serviceworker_not_sharedworker.js
|
||||
match_all_client/match_all_client_id.html
|
||||
match_all_client_id_worker.js
|
||||
source_message_posting_worker.js
|
||||
scope/scope_worker.js
|
||||
|
||||
[test_unregister.html]
|
||||
skip-if = true # Bug 1133805
|
||||
@@ -59,6 +62,7 @@ skip-if = true # Bug 1133805
|
||||
skip-if = true # Bug 1133805
|
||||
[test_post_message.html]
|
||||
[test_post_message_advanced.html]
|
||||
[test_post_message_source.html]
|
||||
[test_match_all_client_properties.html]
|
||||
[test_close.html]
|
||||
[test_serviceworker_interfaces.html]
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
// This worker is used to test if calling register() without a scope argument
|
||||
// leads to scope being relative to service worker script.
|
||||
@@ -36,15 +36,6 @@
|
||||
}
|
||||
});
|
||||
|
||||
navigator.serviceWorker.getRegistration('http://mochi.test:8888/with_star/*')
|
||||
.then(function(a) {
|
||||
window.parent.postMessage({ type: "check", status: true,
|
||||
msg: "getRegistration returns a ServiceWorkerRegistration" }, "*");
|
||||
a.onupdatefound = function(e) {
|
||||
eventReceived();
|
||||
}
|
||||
});
|
||||
|
||||
navigator.serviceWorker.getRegistration('http://www.something_else.net/')
|
||||
.then(function(a) {
|
||||
window.parent.postMessage({ type: "check", status: false,
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
onmessage = function(e) {
|
||||
if (!e.source) {
|
||||
dump("ERROR: message doesn't have a source.");
|
||||
}
|
||||
|
||||
// The client should be a window client
|
||||
if (e.source instanceof WindowClient) {
|
||||
e.source.postMessage(e.data);
|
||||
} else {
|
||||
e.source.postMessage("ERROR. source is not a window client.");
|
||||
}
|
||||
};
|
||||
@@ -60,6 +60,7 @@
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["dom.serviceWorkers.exemptFromPerDomainMax", true],
|
||||
["dom.serviceWorkers.enabled", true],
|
||||
["dom.serviceWorkers.testing.enabled", true]
|
||||
]}, runTest);
|
||||
|
||||
@@ -18,18 +18,28 @@
|
||||
|
||||
function simpleRegister() {
|
||||
var p = navigator.serviceWorker.register("fetch_event_worker.js", { scope: "./fetch" });
|
||||
return p;
|
||||
return p.then(function(swr) {
|
||||
return new Promise(function(resolve) {
|
||||
swr.installing.onstatechange = resolve;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testController() {
|
||||
var p = new Promise(function(resolve, reject) {
|
||||
var reloaded = false;
|
||||
window.onmessage = function(e) {
|
||||
if (e.data.status == "ok") {
|
||||
ok(e.data.result, e.data.message);
|
||||
} else if (e.data.status == "done") {
|
||||
window.onmessage = null;
|
||||
w.close();
|
||||
resolve();
|
||||
if (reloaded) {
|
||||
window.onmessage = null;
|
||||
w.close();
|
||||
resolve();
|
||||
} else {
|
||||
w.location.reload();
|
||||
reloaded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -51,9 +61,9 @@
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["dom.serviceWorkers.exemptFromPerDomainMax", true],
|
||||
["dom.serviceWorkers.enabled", true],
|
||||
["dom.serviceWorkers.testing.enabled", true],
|
||||
["dom.fetch.enabled", true]
|
||||
]}, runTest);
|
||||
</script>
|
||||
</pre>
|
||||
|
||||
@@ -102,6 +102,7 @@
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["dom.serviceWorkers.exemptFromPerDomainMax", true],
|
||||
["dom.serviceWorkers.enabled", true],
|
||||
["dom.serviceWorkers.testing.enabled", true]
|
||||
]}, runTest);
|
||||
|
||||
@@ -177,6 +177,7 @@
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["dom.serviceWorkers.exemptFromPerDomainMax", true],
|
||||
["dom.messageChannel.enabled", true],
|
||||
["dom.serviceWorkers.enabled", true],
|
||||
["dom.serviceWorkers.testing.enabled", true]
|
||||
|
||||
@@ -67,6 +67,7 @@
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["dom.serviceWorkers.exemptFromPerDomainMax", true],
|
||||
["dom.serviceWorkers.enabled", true],
|
||||
["dom.serviceWorkers.testing.enabled", true]
|
||||
]}, runTest);
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["dom.serviceWorkers.exemptFromPerDomainMax", true],
|
||||
["dom.serviceWorkers.enabled", true]
|
||||
]}, function() {
|
||||
checkEnabled();
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["dom.serviceWorkers.exemptFromPerDomainMax", true],
|
||||
["dom.serviceWorkers.enabled", true],
|
||||
["dom.serviceWorkers.testing.enabled", true]
|
||||
]}, runTest);
|
||||
|
||||
@@ -95,6 +95,7 @@
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["dom.serviceWorkers.exemptFromPerDomainMax", true],
|
||||
["dom.serviceWorkers.enabled", true],
|
||||
["dom.serviceWorkers.testing.enabled", true]
|
||||
]}, runTest);
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Bug 1142015 - Test service worker post message source </title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
<script class="testbody" type="text/javascript">
|
||||
var magic_value = "MAGIC_VALUE_RANDOM";
|
||||
var registration;
|
||||
function start() {
|
||||
return navigator.serviceWorker.register("source_message_posting_worker.js",
|
||||
{ scope: "./nonexistent_scope/" })
|
||||
.then((swr) => registration = swr);
|
||||
}
|
||||
|
||||
function unregister() {
|
||||
return registration.unregister().then(function(result) {
|
||||
ok(result, "Unregister should return true.");
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function testPostMessage(swr) {
|
||||
var p = new Promise(function(res, rej) {
|
||||
navigator.serviceWorker.onmessage = function(e) {
|
||||
ok(e.data === magic_value, "Worker posted the correct value.");
|
||||
res();
|
||||
}
|
||||
});
|
||||
|
||||
ok(swr.installing, "Installing worker exists.");
|
||||
swr.installing.postMessage(magic_value);
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
function runTest() {
|
||||
start()
|
||||
.then(testPostMessage)
|
||||
.then(unregister)
|
||||
.catch(function(e) {
|
||||
ok(false, "Some test failed with error " + e);
|
||||
}).then(SimpleTest.finish);
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["dom.serviceWorkers.exemptFromPerDomainMax", true],
|
||||
["dom.serviceWorkers.enabled", true],
|
||||
["dom.serviceWorkers.testing.enabled", true]
|
||||
]}, runTest);
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
var scriptsAndScopes = [
|
||||
[ "worker.js", "." ],
|
||||
[ "worker.js", "./sub/dir/"],
|
||||
[ "worker.js", "./sub/dir" ],
|
||||
[ "worker.js", "./sub/dir.html" ],
|
||||
@@ -30,6 +29,22 @@
|
||||
scriptsAndScopes.forEach(function(item) {
|
||||
registerArray.push(navigator.serviceWorker.register(item[0], { scope: item[1] }));
|
||||
});
|
||||
|
||||
// Check register()'s step 4 which uses script's url with "./" as the scope if no scope is passed.
|
||||
// The other tests already check step 5.
|
||||
registerArray.push(navigator.serviceWorker.register("scope/scope_worker.js"));
|
||||
|
||||
// Check that SW cannot be registered for a scope "above" the script's location.
|
||||
registerArray.push(new Promise(function(resolve, reject) {
|
||||
navigator.serviceWorker.register("scope/scope_worker.js", { scope: "./" })
|
||||
.then(function() {
|
||||
ok(false, "registration scope has to be inside service worker script scope.");
|
||||
reject();
|
||||
}, function() {
|
||||
ok(true, "registration scope has to be inside service worker script scope.");
|
||||
resolve();
|
||||
});
|
||||
}));
|
||||
return Promise.all(registerArray);
|
||||
}
|
||||
|
||||
@@ -41,6 +56,11 @@
|
||||
return reg.unregister();
|
||||
}));
|
||||
});
|
||||
|
||||
unregisterArray.push(navigator.serviceWorker.getRegistration("scope/").then(function (reg) {
|
||||
return reg.unregister();
|
||||
}));
|
||||
|
||||
return Promise.all(unregisterArray);
|
||||
}
|
||||
|
||||
@@ -53,15 +73,25 @@
|
||||
return base + s;
|
||||
}
|
||||
|
||||
ok(getScope(p("index.html")) === p(""), "Scope should match");
|
||||
ok(getScope(p("sua.html")) === p(""), "Scope should match");
|
||||
function fail(fn) {
|
||||
try {
|
||||
getScope(p("index.html"));
|
||||
ok(false, "No registration");
|
||||
} catch(e) {
|
||||
ok(true, "No registration");
|
||||
}
|
||||
}
|
||||
|
||||
ok(getScope(p("sub.html")) === p("sub"), "Scope should match");
|
||||
ok(getScope(p("sub/dir.html")) === p("sub/dir.html"), "Scope should match");
|
||||
ok(getScope(p("sub/dir")) === p("sub/dir"), "Scope should match");
|
||||
ok(getScope(p("sub/dir/foo")) === p("sub/dir/"), "Scope should match");
|
||||
ok(getScope(p("sub/dir/afoo")) === p("sub/dir/a"), "Scope should match");
|
||||
ok(getScope(p("star*wars")) === p("star*"), "Scope should match");
|
||||
ok(getScope(p("star/a.html")) === p(""), "Scope should match");
|
||||
ok(getScope(p("scope/some_file.html")) === p("scope/"), "Scope should match");
|
||||
fail("index.html");
|
||||
fail("sua.html");
|
||||
fail("star/a.html");
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
@@ -80,6 +110,7 @@
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["dom.serviceWorkers.exemptFromPerDomainMax", true],
|
||||
["dom.serviceWorkers.enabled", true],
|
||||
["dom.serviceWorkers.testing.enabled", true]
|
||||
]}, runTest);
|
||||
|
||||
@@ -104,7 +104,6 @@
|
||||
["dom.serviceWorkers.exemptFromPerDomainMax", true],
|
||||
["dom.serviceWorkers.enabled", true],
|
||||
["dom.serviceWorkers.testing.enabled", true],
|
||||
["dom.fetch.enabled", true],
|
||||
["dom.caches.enabled", true]
|
||||
]}, runTest);
|
||||
};
|
||||
|
||||
@@ -115,7 +115,7 @@ var interfaceNamesInGlobalScope =
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"FileReaderSync",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{ name: "Headers", pref: "dom.fetch.enabled" },
|
||||
"Headers",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"IDBCursor",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
|
||||
@@ -16,8 +16,31 @@
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
function simpleRegister() {
|
||||
info("simpleRegister() just before calling register");
|
||||
return navigator.serviceWorker.register("worker.js", { scope: "unregister/" });
|
||||
return navigator.serviceWorker.register("worker.js", { scope: "unregister/" }).then(function(swr) {
|
||||
if (swr.installing) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
swr.installing.onstatechange = function(e) {
|
||||
if (swr.waiting) {
|
||||
swr.waiting.onstatechange = function(e) {
|
||||
if (swr.active) {
|
||||
resolve();
|
||||
} else if (swr.waiting && swr.waiting.state == "redundant") {
|
||||
reject("Should not go into redundant");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (swr.active) {
|
||||
resolve();
|
||||
} else {
|
||||
reject("No waiting and no active!");
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
return Promise.reject("Installing should be non-null");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function testControlled() {
|
||||
@@ -49,6 +72,11 @@
|
||||
function unregister() {
|
||||
return navigator.serviceWorker.getRegistration("unregister/")
|
||||
.then(function(reg) {
|
||||
if (!reg) {
|
||||
info("Registration already removed");
|
||||
return;
|
||||
}
|
||||
|
||||
info("getRegistration() succeeded " + reg.scope);
|
||||
return reg.unregister().then(function(v) {
|
||||
ok(v, "Unregister should resolve to true");
|
||||
@@ -99,6 +127,7 @@
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["dom.serviceWorkers.exemptFromPerDomainMax", true],
|
||||
["dom.serviceWorkers.enabled", true],
|
||||
["dom.serviceWorkers.testing.enabled", true]
|
||||
]}, runTest);
|
||||
|
||||
@@ -14,7 +14,31 @@
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
function simpleRegister() {
|
||||
return navigator.serviceWorker.register("worker_unregister.js", { scope: "unregister/" });
|
||||
return navigator.serviceWorker.register("worker_unregister.js", { scope: "unregister/" }).then(function(swr) {
|
||||
if (swr.installing) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
swr.installing.onstatechange = function(e) {
|
||||
if (swr.waiting) {
|
||||
swr.waiting.onstatechange = function(e) {
|
||||
if (swr.active) {
|
||||
resolve();
|
||||
} else if (swr.waiting && swr.waiting.state == "redundant") {
|
||||
reject("Should not go into redundant");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (swr.active) {
|
||||
resolve();
|
||||
} else {
|
||||
reject("No waiting and no active!");
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
return Promise.reject("Installing should be non-null");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function waitForMessages(sw) {
|
||||
@@ -47,6 +71,7 @@
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["dom.serviceWorkers.exemptFromPerDomainMax", true],
|
||||
["dom.serviceWorkers.enabled", true],
|
||||
["dom.serviceWorkers.testing.enabled", true]
|
||||
]}, runTest);
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["dom.serviceWorkers.exemptFromPerDomainMax", true],
|
||||
["dom.serviceWorkers.enabled", true],
|
||||
["dom.serviceWorkers.testing.enabled", true]
|
||||
]}, runTest);
|
||||
|
||||
@@ -19,22 +19,7 @@
|
||||
info("unregister/index.html should not to be launched directly!");
|
||||
}
|
||||
|
||||
SimpleTest.requestFlakyTimeout("Unfortunately we have no way to test for a page being uncontrolled except waiting for ready to not resolve");
|
||||
var tId = setTimeout(function() {
|
||||
parent.postMessage({ controlled: false }, "*");
|
||||
tId = null;
|
||||
}, 2000);
|
||||
|
||||
navigator.serviceWorker.ready.then(function() {
|
||||
if (tId == null) {
|
||||
parent.postMessage("FAIL!!!", "*");
|
||||
return;
|
||||
}
|
||||
|
||||
clearTimeout(tId);
|
||||
parent.postMessage({ controlled: true }, "*");
|
||||
});
|
||||
|
||||
parent.postMessage({ controlled: !!navigator.serviceWorker.controller }, "*");
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<body>
|
||||
<script type="text/javascript">
|
||||
|
||||
onmessage = function(e) { parent.postMessage(e.data, "*"); }
|
||||
navigator.serviceWorker.onmessage = function(e) { parent.postMessage(e.data, "*"); }
|
||||
navigator.serviceWorker.controller.postMessage("GO");
|
||||
|
||||
</script>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<body>
|
||||
<script type="text/javascript">
|
||||
|
||||
onmessage = function(e) { parent.postMessage(e.data, "*"); }
|
||||
navigator.serviceWorker.onmessage = function(e) { parent.postMessage(e.data, "*"); }
|
||||
navigator.serviceWorker.ready.then(function() {
|
||||
navigator.serviceWorker.controller.postMessage("GO");
|
||||
});
|
||||
|
||||
@@ -109,7 +109,7 @@ var interfaceNamesInGlobalScope =
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"FileReaderSync",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{ name: "Headers", pref: "dom.fetch.enabled" },
|
||||
"Headers",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"IDBCursor",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
@@ -140,6 +140,10 @@ var interfaceNamesInGlobalScope =
|
||||
"Performance",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"Promise",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"Request",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"Response",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"TextDecoder",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
|
||||
@@ -109,7 +109,7 @@ private:
|
||||
|
||||
RefPtr<AndroidNativeWindow> mNativeWindow;
|
||||
int mID;
|
||||
nsRefPtr<nsIRunnable> mFrameAvailableCallback;
|
||||
nsCOMPtr<nsIRunnable> mFrameAvailableCallback;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
+6
-4
@@ -2212,10 +2212,12 @@ DefinePropertyById(JSContext* cx, HandleObject obj, HandleId id, HandleValue val
|
||||
// it's just a plain old data property. However the JS_Define* APIs use
|
||||
// null getter and setter to mean "default to the Class getProperty and
|
||||
// setProperty ops".
|
||||
if (!getter)
|
||||
getter = obj->getClass()->getProperty;
|
||||
if (!setter)
|
||||
setter = obj->getClass()->setProperty;
|
||||
if (!(attrs & (JSPROP_GETTER | JSPROP_SETTER))) {
|
||||
if (!getter)
|
||||
getter = obj->getClass()->getProperty;
|
||||
if (!setter)
|
||||
setter = obj->getClass()->setProperty;
|
||||
}
|
||||
if (getter == JS_PropertyStub)
|
||||
getter = nullptr;
|
||||
if (setter == JS_StrictPropertyStub)
|
||||
|
||||
@@ -49,7 +49,7 @@ VsyncParent::NotifyVsync(TimeStamp aTimeStamp)
|
||||
{
|
||||
// Called on hardware vsync thread. We should post to current ipc thread.
|
||||
MOZ_ASSERT(!IsOnBackgroundThread());
|
||||
nsRefPtr<nsIRunnable> vsyncEvent =
|
||||
nsCOMPtr<nsIRunnable> vsyncEvent =
|
||||
NS_NewRunnableMethodWithArg<TimeStamp>(this,
|
||||
&VsyncParent::DispatchVsyncEvent,
|
||||
aTimeStamp);
|
||||
|
||||
@@ -383,7 +383,7 @@ PeerConnectionCtx::~PeerConnectionCtx() {
|
||||
#endif
|
||||
};
|
||||
|
||||
void PeerConnectionCtx::queueJSEPOperation(nsRefPtr<nsIRunnable> aOperation) {
|
||||
void PeerConnectionCtx::queueJSEPOperation(nsCOMPtr<nsIRunnable> aOperation) {
|
||||
mQueuedJSEPOperations.AppendElement(aOperation);
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ class PeerConnectionCtx {
|
||||
return true;
|
||||
}
|
||||
|
||||
void queueJSEPOperation(nsRefPtr<nsIRunnable> aJSEPOperation);
|
||||
void queueJSEPOperation(nsCOMPtr<nsIRunnable> aJSEPOperation);
|
||||
void onGMPReady();
|
||||
|
||||
bool gmpHasH264();
|
||||
@@ -94,7 +94,7 @@ private:
|
||||
// ready to go, since blocking on this init is just begging for deadlock.
|
||||
nsCOMPtr<mozIGoannaMediaPluginService> mGMPService;
|
||||
bool mGMPReady;
|
||||
nsTArray<nsRefPtr<nsIRunnable>> mQueuedJSEPOperations;
|
||||
nsTArray<nsCOMPtr<nsIRunnable>> mQueuedJSEPOperations;
|
||||
|
||||
static PeerConnectionCtx *gInstance;
|
||||
public:
|
||||
|
||||
@@ -396,7 +396,7 @@ PeerConnectionMedia::StartIceChecks(const JsepSession& session) {
|
||||
}
|
||||
}
|
||||
|
||||
nsRefPtr<nsIRunnable> runnable(
|
||||
nsCOMPtr<nsIRunnable> runnable(
|
||||
WrapRunnable(
|
||||
RefPtr<PeerConnectionMedia>(this),
|
||||
&PeerConnectionMedia::StartIceChecks_s,
|
||||
@@ -507,7 +507,7 @@ PeerConnectionMedia::FlushIceCtxOperationQueueIfReady()
|
||||
|
||||
void
|
||||
PeerConnectionMedia::PerformOrEnqueueIceCtxOperation(
|
||||
const nsRefPtr<nsIRunnable>& runnable)
|
||||
const nsCOMPtr<nsIRunnable>& runnable)
|
||||
{
|
||||
ASSERT_ON_THREAD(mMainThread);
|
||||
|
||||
@@ -522,7 +522,7 @@ void
|
||||
PeerConnectionMedia::GatherIfReady() {
|
||||
ASSERT_ON_THREAD(mMainThread);
|
||||
|
||||
nsRefPtr<nsIRunnable> runnable(WrapRunnable(
|
||||
nsCOMPtr<nsIRunnable> runnable(WrapRunnable(
|
||||
RefPtr<PeerConnectionMedia>(this),
|
||||
&PeerConnectionMedia::EnsureIceGathering_s));
|
||||
|
||||
|
||||
@@ -421,7 +421,7 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
|
||||
const std::vector<std::string>& aCandidateList);
|
||||
void GatherIfReady();
|
||||
void FlushIceCtxOperationQueueIfReady();
|
||||
void PerformOrEnqueueIceCtxOperation(const nsRefPtr<nsIRunnable>& runnable);
|
||||
void PerformOrEnqueueIceCtxOperation(const nsCOMPtr<nsIRunnable>& runnable);
|
||||
void EnsureIceGathering_s();
|
||||
void StartIceChecks_s(bool aIsControlling,
|
||||
bool aIsIceLite,
|
||||
@@ -499,7 +499,7 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
|
||||
// on our ICE ctx, but are not ready to do so at the moment (eg; we are
|
||||
// waiting to get a callback with our http proxy config before we start
|
||||
// gathering or start checking)
|
||||
std::vector<nsRefPtr<nsIRunnable>> mQueuedIceCtxOperations;
|
||||
std::vector<nsCOMPtr<nsIRunnable>> mQueuedIceCtxOperations;
|
||||
|
||||
// Used to cancel any ongoing proxy request.
|
||||
nsCOMPtr<nsICancelable> mProxyRequest;
|
||||
|
||||
@@ -4767,9 +4767,6 @@ pref("beacon.enabled", true);
|
||||
// Camera prefs
|
||||
pref("camera.control.face_detection.enabled", true);
|
||||
|
||||
// Fetch API.
|
||||
pref("dom.fetch.enabled", true);
|
||||
|
||||
// SW Cache API
|
||||
pref("dom.caches.enabled", false);
|
||||
|
||||
|
||||
@@ -296,6 +296,6 @@ NetworkActivityMonitor::DataInOut(Direction direction)
|
||||
void
|
||||
NetworkActivityMonitor::PostNotification(Direction direction)
|
||||
{
|
||||
nsRefPtr<nsIRunnable> ev = new NotifyNetworkActivity(direction);
|
||||
nsCOMPtr<nsIRunnable> ev = new NotifyNetworkActivity(direction);
|
||||
NS_DispatchToMainThread(ev);
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ OfflineObserver::RegisterOfflineObserver()
|
||||
if (NS_IsMainThread()) {
|
||||
RegisterOfflineObserverMainThread();
|
||||
} else {
|
||||
nsRefPtr<nsIRunnable> event =
|
||||
nsCOMPtr<nsIRunnable> event =
|
||||
NS_NewRunnableMethod(this, &OfflineObserver::RegisterOfflineObserverMainThread);
|
||||
NS_DispatchToMainThread(event);
|
||||
}
|
||||
@@ -33,7 +33,7 @@ OfflineObserver::RemoveOfflineObserver()
|
||||
if (NS_IsMainThread()) {
|
||||
RemoveOfflineObserverMainThread();
|
||||
} else {
|
||||
nsRefPtr<nsIRunnable> event =
|
||||
nsCOMPtr<nsIRunnable> event =
|
||||
NS_NewRunnableMethod(this, &OfflineObserver::RemoveOfflineObserverMainThread);
|
||||
NS_DispatchToMainThread(event);
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ Tickler::~Tickler()
|
||||
|
||||
// Shutting down a thread can spin the event loop - which is a surprising
|
||||
// thing to do from a dtor. Running it on its own event is safer.
|
||||
nsRefPtr<nsIRunnable> event = new TicklerThreadDestructor(mThread);
|
||||
nsCOMPtr<nsIRunnable> event = new TicklerThreadDestructor(mThread);
|
||||
if (NS_FAILED(NS_DispatchToCurrentThread(event))) {
|
||||
mThread->Shutdown();
|
||||
}
|
||||
|
||||
@@ -182,7 +182,7 @@ nsAsyncRedirectVerifyHelper::ExplicitCallback(nsresult result)
|
||||
mWaitingForRedirectCallback = false;
|
||||
|
||||
// Now, dispatch the callback on the event-target which called Init()
|
||||
nsRefPtr<nsIRunnable> event =
|
||||
nsCOMPtr<nsIRunnable> event =
|
||||
new nsAsyncVerifyRedirectCallbackEvent(callback, result);
|
||||
if (!event) {
|
||||
NS_WARNING("nsAsyncRedirectVerifyHelper::ExplicitCallback() "
|
||||
|
||||
@@ -16,7 +16,7 @@ interface nsIURI;
|
||||
* which do not implement nsIChannel.
|
||||
*/
|
||||
|
||||
[scriptable, uuid(155378c1-ebb2-4492-917f-85483430d5f5)]
|
||||
[scriptable, uuid(2fc1170c-4f9d-4c9e-8e5d-2d351dbe03f2)]
|
||||
interface nsIInterceptedChannel : nsISupports
|
||||
{
|
||||
/**
|
||||
@@ -25,6 +25,12 @@ interface nsIInterceptedChannel : nsISupports
|
||||
*/
|
||||
void resetInterception();
|
||||
|
||||
/**
|
||||
* Set the status and reason for the forthcoming synthesized response.
|
||||
* Multiple calls overwrite existing values.
|
||||
*/
|
||||
void synthesizeStatus(in uint16_t status, in ACString reason);
|
||||
|
||||
/**
|
||||
* Attach a header name/value pair to the forthcoming synthesized response.
|
||||
* Overwrites any existing header value.
|
||||
|
||||
+1
-1
@@ -536,7 +536,7 @@ nsCacheEntryDescriptor::AsyncDoom(nsICacheListener *listener)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsRefPtr<nsIRunnable> event = new nsAsyncDoomEvent(this, listener);
|
||||
nsCOMPtr<nsIRunnable> event = new nsAsyncDoomEvent(this, listener);
|
||||
return nsCacheService::DispatchToCacheIOThread(event);
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user