gecko/dom/workers/ServiceWorkerClient.cpp
Nathan Froyd e4e2da55c9 Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat
The bulk of this commit was generated with a script, executed at the top
level of a typical source code checkout.  The only non-machine-generated
part was modifying MFBT's moz.build to reflect the new naming.

CLOSED TREE makes big refactorings like this a piece of cake.

 # The main substitution.
find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \
    xargs perl -p -i -e '
 s/nsRefPtr\.h/RefPtr\.h/g; # handle includes
 s/nsRefPtr ?</RefPtr</g;   # handle declarations and variables
'

 # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h.
perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h

 # Handle nsRefPtr.h itself, a couple places that define constructors
 # from nsRefPtr, and code generators specially.  We do this here, rather
 # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename
 # things like nsRefPtrHashtable.
perl -p -i -e 's/nsRefPtr/RefPtr/g' \
     mfbt/nsRefPtr.h \
     xpcom/glue/nsCOMPtr.h \
     xpcom/base/OwningNonNull.h \
     ipc/ipdl/ipdl/lower.py \
     ipc/ipdl/ipdl/builtin.py \
     dom/bindings/Codegen.py \
     python/lldbutils/lldbutils/utils.py

 # In our indiscriminate substitution above, we renamed
 # nsRefPtrGetterAddRefs, the class behind getter_AddRefs.  Fix that up.
find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \
    xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g'

if [ -d .git ]; then
    git mv mfbt/nsRefPtr.h mfbt/RefPtr.h
else
    hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h
fi
2015-10-18 01:24:48 -04:00

211 lines
6.0 KiB
C++

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include "ServiceWorkerClient.h"
#include "ServiceWorkerContainer.h"
#include "mozilla/dom/MessageEvent.h"
#include "mozilla/dom/Navigator.h"
#include "mozilla/dom/ServiceWorkerMessageEvent.h"
#include "mozilla/dom/ServiceWorkerMessageEventBinding.h"
#include "nsGlobalWindow.h"
#include "nsIDocument.h"
#include "WorkerPrivate.h"
using namespace mozilla;
using namespace mozilla::dom;
using namespace mozilla::dom::workers;
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(ServiceWorkerClient, mOwner)
NS_IMPL_CYCLE_COLLECTING_ADDREF(ServiceWorkerClient)
NS_IMPL_CYCLE_COLLECTING_RELEASE(ServiceWorkerClient)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ServiceWorkerClient)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
ServiceWorkerClientInfo::ServiceWorkerClientInfo(nsIDocument* aDoc)
: mWindowId(0)
{
MOZ_ASSERT(aDoc);
nsresult rv = aDoc->GetId(mClientId);
if (NS_FAILED(rv)) {
NS_WARNING("Failed to get the UUID of the document.");
}
RefPtr<nsGlobalWindow> innerWindow = static_cast<nsGlobalWindow*>(aDoc->GetInnerWindow());
if (innerWindow) {
// XXXcatalinb: The inner window can be null if the document is navigating
// and was detached.
mWindowId = innerWindow->WindowID();
}
aDoc->GetURL(mUrl);
mVisibilityState = aDoc->VisibilityState();
ErrorResult result;
mFocused = aDoc->HasFocus(result);
if (result.Failed()) {
NS_WARNING("Failed to get focus information.");
}
RefPtr<nsGlobalWindow> outerWindow = static_cast<nsGlobalWindow*>(aDoc->GetWindow());
MOZ_ASSERT(outerWindow);
if (!outerWindow->IsTopLevelWindow()) {
mFrameType = FrameType::Nested;
} else if (outerWindow->HadOriginalOpener()) {
mFrameType = FrameType::Auxiliary;
} else {
mFrameType = FrameType::Top_level;
}
}
JSObject*
ServiceWorkerClient::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
{
return ClientBinding::Wrap(aCx, this, aGivenProto);
}
namespace {
class ServiceWorkerClientPostMessageRunnable final
: public nsRunnable
, public StructuredCloneHolder
{
uint64_t mWindowId;
public:
explicit ServiceWorkerClientPostMessageRunnable(uint64_t aWindowId)
: StructuredCloneHolder(CloningSupported, TransferringSupported,
SameProcessDifferentThread)
, mWindowId(aWindowId)
{}
NS_IMETHOD
Run()
{
AssertIsOnMainThread();
nsGlobalWindow* window = nsGlobalWindow::GetInnerWindowWithId(mWindowId);
if (!window) {
return NS_ERROR_FAILURE;
}
ErrorResult result;
dom::Navigator* navigator = window->GetNavigator(result);
if (NS_WARN_IF(result.Failed())) {
return result.StealNSResult();
}
RefPtr<ServiceWorkerContainer> container = navigator->ServiceWorker();
AutoJSAPI jsapi;
if (NS_WARN_IF(!jsapi.Init(window))) {
return NS_ERROR_FAILURE;
}
JSContext* cx = jsapi.cx();
return DispatchDOMEvent(cx, container);
}
private:
NS_IMETHOD
DispatchDOMEvent(JSContext* aCx, ServiceWorkerContainer* aTargetContainer)
{
AssertIsOnMainThread();
JS::Rooted<JS::Value> messageData(aCx);
ErrorResult rv;
Read(aTargetContainer->GetParentObject(), aCx, &messageData, rv);
if (NS_WARN_IF(rv.Failed())) {
xpc::Throw(aCx, rv.StealNSResult());
return NS_ERROR_FAILURE;
}
RootedDictionary<ServiceWorkerMessageEventInit> init(aCx);
init.mData = messageData;
init.mOrigin.Construct(EmptyString());
init.mLastEventId.Construct(EmptyString());
init.mPorts.Construct();
init.mPorts.Value().SetNull();
RefPtr<ServiceWorker> serviceWorker = aTargetContainer->GetController();
init.mSource.Construct();
if (serviceWorker) {
init.mSource.Value().SetValue().SetAsServiceWorker() = serviceWorker;
} else {
init.mSource.Value().SetNull();
}
RefPtr<ServiceWorkerMessageEvent> event =
ServiceWorkerMessageEvent::Constructor(aTargetContainer,
NS_LITERAL_STRING("message"), init, rv);
nsTArray<RefPtr<MessagePort>> ports = TakeTransferredPorts();
RefPtr<MessagePortList> portList =
new MessagePortList(static_cast<dom::Event*>(event.get()),
ports);
event->SetPorts(portList);
event->SetTrusted(true);
bool status = false;
aTargetContainer->DispatchEvent(static_cast<dom::Event*>(event.get()),
&status);
if (!status) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
};
} // namespace
void
ServiceWorkerClient::PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
const Optional<Sequence<JS::Value>>& aTransferable,
ErrorResult& aRv)
{
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
MOZ_ASSERT(workerPrivate);
workerPrivate->AssertIsOnWorkerThread();
JS::Rooted<JS::Value> transferable(aCx, JS::UndefinedValue());
if (aTransferable.WasPassed()) {
const Sequence<JS::Value>& realTransferable = aTransferable.Value();
JS::HandleValueArray elements =
JS::HandleValueArray::fromMarkedLocation(realTransferable.Length(),
realTransferable.Elements());
JSObject* array = JS_NewArrayObject(aCx, elements);
if (!array) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return;
}
transferable.setObject(*array);
}
RefPtr<ServiceWorkerClientPostMessageRunnable> runnable =
new ServiceWorkerClientPostMessageRunnable(mWindowId);
runnable->Write(aCx, aMessage, transferable, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
aRv = NS_DispatchToMainThread(runnable);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
}