Index: Source/bindings/modules/v8/custom/V8ServiceWorkerMessageEventCustom.cpp |
diff --git a/Source/bindings/modules/v8/custom/V8ServiceWorkerMessageEventCustom.cpp b/Source/bindings/modules/v8/custom/V8ServiceWorkerMessageEventCustom.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..c61300a300ef2f081076aa31c280263956581a9b |
--- /dev/null |
+++ b/Source/bindings/modules/v8/custom/V8ServiceWorkerMessageEventCustom.cpp |
@@ -0,0 +1,175 @@ |
+// Copyright 2015 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 "bindings/modules/v8/V8ServiceWorkerMessageEvent.h" |
+ |
+#include "bindings/core/v8/Dictionary.h" |
+#include "bindings/core/v8/SerializedScriptValue.h" |
+#include "bindings/core/v8/SerializedScriptValueFactory.h" |
+#include "bindings/core/v8/V8Binding.h" |
+#include "bindings/core/v8/V8DOMWrapper.h" |
+#include "bindings/core/v8/V8Event.h" |
+#include "bindings/core/v8/V8HiddenValue.h" |
+#include "bindings/core/v8/V8MessagePort.h" |
+#include "bindings/modules/v8/V8ServiceWorker.h" |
+ |
+namespace blink { |
+ |
+static bool initializeServiceWorkerMessageEvent(ServiceWorkerMessageEventInit& eventInit, const Dictionary& options, ExceptionState& exceptionState, const v8::FunctionCallbackInfo<v8::Value>& info) |
+{ |
+ Dictionary::ConversionContext conversionContext(exceptionState); |
+ if (!initializeEvent(eventInit, options, exceptionState, info)) |
+ return false; |
+ |
+ if (!DictionaryHelper::convert(options, conversionContext.setConversionType("DOMString", false), "origin", eventInit.origin)) |
+ return false; |
+ if (!DictionaryHelper::convert(options, conversionContext.setConversionType("DOMString", false), "lastEventId", eventInit.lastEventId)) |
+ return false; |
+ if (!DictionaryHelper::convert(options, conversionContext.setConversionType("MessagePort[]", false), "ports", eventInit.ports)) |
+ return false; |
+ return true; |
+} |
+ |
+static void setEventSource(PassRefPtrWillBeRawPtr<ServiceWorkerMessageEvent> event, v8::Isolate* isolate, v8::Local<v8::Value> value, ExceptionState& exceptionState) |
+{ |
+ if (value.IsEmpty() || isUndefinedOrNull(value)) |
+ return; |
+ if (V8ServiceWorker::hasInstance(value, isolate)) { |
+ ServiceWorker* source = V8ServiceWorker::toImpl(v8::Local<v8::Object>::Cast(value)); |
+ event->setSource(source); |
+ return; |
+ } |
+ if (V8MessagePort::hasInstance(value, isolate)) { |
+ MessagePort* source = V8MessagePort::toImpl(v8::Local<v8::Object>::Cast(value)); |
+ event->setSource(source); |
+ return; |
+ } |
+ exceptionState.throwTypeError("The 'source' type is neither a ServiceWorker nor MessagePort"); |
+} |
+ |
+static v8::Local<v8::Value> cacheState(v8::Isolate* isolate, v8::Local<v8::Object> event, v8::Local<v8::Value> data) |
+{ |
+ V8HiddenValue::setHiddenValue(isolate, event, V8HiddenValue::data(isolate), data); |
+ return data; |
+} |
+ |
+void V8ServiceWorkerMessageEvent::constructorCustom(const v8::FunctionCallbackInfo<v8::Value>& info) |
+{ |
+ ExceptionState exceptionState(ExceptionState::ConstructionContext, "ServiceWorkerMessageEvent", info.Holder(), info.GetIsolate()); |
+ if (info.Length() < 1) { |
+ exceptionState.throwTypeError("An event name must be provided."); |
+ exceptionState.throwIfNeeded(); |
+ return; |
+ } |
+ |
+ V8StringResource<> type(info[0]); |
+ if (!type.prepare()) |
+ return; |
+ v8::Local<v8::Value> source; |
+ v8::Local<v8::Value> data; |
+ ServiceWorkerMessageEventInit eventInit; |
+ if (info.Length() >= 2) { |
+ Dictionary options(info[1], info.GetIsolate(), exceptionState); |
+ if (!initializeServiceWorkerMessageEvent(eventInit, options, exceptionState, info)) { |
+ exceptionState.throwIfNeeded(); |
+ return; |
+ } |
+ options.get("source", source); |
+ options.get("data", data); |
+ if (!data.IsEmpty()) |
+ V8HiddenValue::setHiddenValue(info.GetIsolate(), info.Holder(), v8AtomicString(info.GetIsolate(), "data"), data); |
+ } |
+ RefPtrWillBeRawPtr<ServiceWorkerMessageEvent> event = ServiceWorkerMessageEvent::create(type, eventInit); |
+ setEventSource(event, info.GetIsolate(), source, exceptionState); |
+ if (exceptionState.throwIfNeeded()) |
+ return; |
+ if (DOMWrapperWorld::current(info.GetIsolate()).isIsolatedWorld()) { |
+ if (!data.IsEmpty()) |
+ event->setSerializedData(SerializedScriptValueFactory::instance().createAndSwallowExceptions(info.GetIsolate(), data)); |
+ } |
+ |
+ v8::Local<v8::Object> wrapper = info.Holder(); |
+ event->associateWithWrapper(info.GetIsolate(), &V8ServiceWorkerMessageEvent::wrapperTypeInfo, wrapper); |
+ v8SetReturnValue(info, wrapper); |
+} |
+ |
+void V8ServiceWorkerMessageEvent::sourceAttributeGetterCustom(const v8::PropertyCallbackInfo<v8::Value>& info) |
+{ |
+ ServiceWorkerMessageEvent* event = V8ServiceWorkerMessageEvent::toImpl(info.Holder()); |
+ RefPtrWillBeRawPtr<ServiceWorker> sourceAsServiceWorker = event->sourceAsServiceWorker(); |
+ RefPtrWillBeRawPtr<MessagePort> sourceAsMessagePort = event->sourceAsMessagePort(); |
+ ASSERT(sourceAsServiceWorker && sourceAsMessagePort); |
+ if (sourceAsServiceWorker) |
+ v8SetReturnValue(info, toV8(sourceAsServiceWorker, info.Holder(), info.GetIsolate())); |
+ else if (sourceAsMessagePort) |
+ v8SetReturnValue(info, toV8(sourceAsMessagePort, info.Holder(), info.GetIsolate())); |
+ else |
+ v8SetReturnValue(info, v8::Null(info.GetIsolate())); |
+} |
+ |
+void V8ServiceWorkerMessageEvent::dataAttributeGetterCustom(const v8::PropertyCallbackInfo<v8::Value>& info) |
+{ |
+ ServiceWorkerMessageEvent* event = V8ServiceWorkerMessageEvent::toImpl(info.Holder()); |
+ |
+ v8::Local<v8::Value> result = V8HiddenValue::getHiddenValue(info.GetIsolate(), info.Holder(), V8HiddenValue::data(info.GetIsolate())); |
+ |
+ if (!result.IsEmpty()) { |
+ v8SetReturnValue(info, result); |
+ return; |
+ } |
+ |
+ if (!event->serializedData()) { |
+ // If we're in an isolated world and the event was created in the main world, |
+ // we need to find the 'data' property on the main world wrapper and clone it. |
+ v8::Local<v8::Value> mainWorldData = V8HiddenValue::getHiddenValueFromMainWorldWrapper(info.GetIsolate(), event, V8HiddenValue::data(info.GetIsolate())); |
+ if (!mainWorldData.IsEmpty()) |
+ event->setSerializedData(SerializedScriptValueFactory::instance().createAndSwallowExceptions(info.GetIsolate(), mainWorldData)); |
+ } |
+ |
+ if (event->serializedData()) { |
+ MessagePortArray ports = event->ports(); |
+ result = event->serializedData()->deserialize(info.GetIsolate(), &ports); |
+ v8SetReturnValue(info, cacheState(info.GetIsolate(), info.Holder(), result)); |
+ return; |
+ } |
+ |
+ v8SetReturnValue(info, cacheState(info.GetIsolate(), info.Holder(), v8::Null(info.GetIsolate()))); |
+} |
+ |
+void V8ServiceWorkerMessageEvent::initServiceWorkerMessageEventMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info) |
+{ |
+ ExceptionState exceptionState(ExceptionState::ExecutionContext, "initServiceWorkerMessageEvent", "ServiceWorkerMessageEvent", info.Holder(), info.GetIsolate()); |
+ ServiceWorkerMessageEvent* event = V8ServiceWorkerMessageEvent::toImpl(info.Holder()); |
+ TOSTRING_VOID(V8StringResource<>, typeArg, info[0]); |
+ bool canBubbleArg; |
+ bool cancelableArg; |
+ if (!v8Call(info[1]->BooleanValue(info.GetIsolate()->GetCurrentContext()), canBubbleArg) |
+ || !v8Call(info[2]->BooleanValue(info.GetIsolate()->GetCurrentContext()), cancelableArg)) |
+ return; |
+ v8::Local<v8::Value> dataArg = info[3]; |
+ TOSTRING_VOID(V8StringResource<>, originArg, info[4]); |
+ TOSTRING_VOID(V8StringResource<>, lastEventIdArg, info[5]); |
+ v8::Local<v8::Value> sourceArg = info[6]; |
+ setEventSource(event, info.GetIsolate(), sourceArg, exceptionState); |
+ if (exceptionState.throwIfNeeded()) |
+ return; |
+ OwnPtrWillBeRawPtr<MessagePortArray> portArray = nullptr; |
+ const int portArrayIndex = 7; |
+ if (!isUndefinedOrNull(info[portArrayIndex])) { |
+ portArray = adoptPtrWillBeNoop(new MessagePortArray); |
+ *portArray = toRefPtrWillBeMemberNativeArray<MessagePort, V8MessagePort>(info[portArrayIndex], portArrayIndex + 1, info.GetIsolate(), exceptionState); |
+ if (exceptionState.throwIfNeeded()) |
+ return; |
+ } |
+ event->initServiceWorkerMessageEvent(typeArg, canBubbleArg, cancelableArg, originArg, lastEventIdArg, portArray.release()); |
+ |
+ if (!dataArg.IsEmpty()) { |
+ V8HiddenValue::setHiddenValue(info.GetIsolate(), info.Holder(), V8HiddenValue::data(info.GetIsolate()), dataArg); |
+ if (DOMWrapperWorld::current(info.GetIsolate()).isIsolatedWorld()) |
+ event->setSerializedData(SerializedScriptValueFactory::instance().createAndSwallowExceptions(info.GetIsolate(), dataArg)); |
+ } |
+} |
+ |
+} // namespace blink |