| Index: Source/modules/navigatorconnect/NavigatorConnect.cpp
|
| diff --git a/Source/modules/navigatorconnect/NavigatorConnect.cpp b/Source/modules/navigatorconnect/NavigatorConnect.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..fed929cd7cc9e9386c21720362fe329670198cd2
|
| --- /dev/null
|
| +++ b/Source/modules/navigatorconnect/NavigatorConnect.cpp
|
| @@ -0,0 +1,84 @@
|
| +// Copyright 2014 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "config.h"
|
| +#include "modules/navigatorconnect/NavigatorConnect.h"
|
| +
|
| +#include "bindings/core/v8/ScriptPromiseResolver.h"
|
| +#include "core/dom/DOMException.h"
|
| +#include "core/dom/ExceptionCode.h"
|
| +#include "core/dom/MessageChannel.h"
|
| +#include "core/dom/MessagePort.h"
|
| +#include "public/platform/Platform.h"
|
| +#include "public/platform/WebCallbacks.h"
|
| +#include "public/platform/WebNavigatorConnectProvider.h"
|
| +
|
| +namespace blink {
|
| +
|
| +namespace {
|
| +
|
| +class ConnectCallbacks : public WebCallbacks<void, void> {
|
| +public:
|
| + ConnectCallbacks(PassRefPtr<ScriptPromiseResolver> resolver, PassRefPtrWillBeRawPtr<MessagePort> port)
|
| + : m_resolver(resolver), m_port(port)
|
| + {
|
| + ASSERT(m_resolver);
|
| + }
|
| + ~ConnectCallbacks() override { }
|
| +
|
| + void onSuccess() override
|
| + {
|
| + if (!m_resolver->executionContext() || m_resolver->executionContext()->activeDOMObjectsAreStopped()) {
|
| + return;
|
| + }
|
| + m_resolver->resolve(m_port);
|
| + }
|
| +
|
| + void onError() override
|
| + {
|
| + if (!m_resolver->executionContext() || m_resolver->executionContext()->activeDOMObjectsAreStopped()) {
|
| + return;
|
| + }
|
| + m_resolver->reject(DOMException::create(AbortError));
|
| + }
|
| +
|
| +private:
|
| + RefPtr<ScriptPromiseResolver> m_resolver;
|
| + RefPtrWillBeMember<MessagePort> m_port;
|
| + WTF_MAKE_NONCOPYABLE(ConnectCallbacks);
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| +ScriptPromise NavigatorConnect::connect(ScriptState* scriptState, const String& url)
|
| +{
|
| + WebNavigatorConnectProvider* provider = Platform::current()->navigatorConnectProvider();
|
| + if (!provider)
|
| + return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(NotSupportedError));
|
| +
|
| + RefPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState);
|
| + ScriptPromise promise = resolver->promise();
|
| + // Create a new MessageChannel, but immediately disentangle port2 (extract
|
| + // the WebMessagePortChannel from the port and mark it as being transfered).
|
| + // This way we have:
|
| + // - Ownership of port1 is kept in the ConnectCallbacks and later passed to
|
| + // javascript (or released if the connection is not accepted).
|
| + // - Ownership of port2 (or more precisely the WebMessagePortChannel backing
|
| + // it) is passed to the content layer to be transfered to the service
|
| + // provider.
|
| + // - Ownership of the MessageChannel object itself will be released at the
|
| + // end of this method. This is okay as it's the ports themselves that
|
| + // represent the actual message channel. MessageChannel is only used to
|
| + // create a pair of ports.
|
| + RefPtrWillBeRawPtr<MessageChannel> channel(MessageChannel::create(scriptState->executionContext()));
|
| + OwnPtr<WebMessagePortChannel> webchannel = channel->port2()->disentangle();
|
| + provider->connect(
|
| + scriptState->executionContext()->completeURL(url),
|
| + webchannel.leakPtr(),
|
| + new ConnectCallbacks(resolver, channel->port1()));
|
| + return promise;
|
| +}
|
| +
|
| +
|
| +} // namespace blink
|
|
|