Index: Source/bindings/core/v8/ScriptPromiseProperty.h |
diff --git a/Source/bindings/core/v8/ScriptPromiseProperty.h b/Source/bindings/core/v8/ScriptPromiseProperty.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..e5902f010b1edea11b8979405415fda9622d14ff |
--- /dev/null |
+++ b/Source/bindings/core/v8/ScriptPromiseProperty.h |
@@ -0,0 +1,146 @@ |
+// 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. |
+ |
+#ifndef ScriptPromiseProperty_h |
+#define ScriptPromiseProperty_h |
+ |
+#include "bindings/core/v8/ScriptPromise.h" |
+#include "bindings/core/v8/ScriptPromisePropertyBase.h" |
+#include "bindings/core/v8/V8Binding.h" |
+#include "wtf/Noncopyable.h" |
+#include "wtf/PassRefPtr.h" |
+ |
+namespace WebCore { |
+ |
+class ExecutionContext; |
+ |
+// ScriptPromiseProperty is a helper for implementing a DOM method or |
+// attribute whose value is a Promise, and the same Promise must be |
+// returned each time. |
+// |
+// ScriptPromiseProperty does not keep Promises or worlds alive to |
+// deliver Promise resolution/rejection to them; the Promise |
+// resolution/rejections are delivered if the holder's wrapper is |
+// alive. This is achieved by keeping a weak reference from |
+// ScriptPromiseProperty to the holder's wrapper, and references in |
+// hidden values between the wrapper, promise and resolver |
+// (coincidentally the Resolver and Promise may be the same object, |
+// but that is an implementation detail of v8.) |
+// |
+// -----> Resolver |
+// / |
+// ScriptPromiseProperty - - -> Holder Wrapper <------. |
+// \ | |
+// -----> Promise |
+// |
+// To avoid exposing the action of the garbage collector to script, |
+// you should keep the wrapper alive as long as a promise may be |
+// settled. |
+// |
+// ScriptPromiseProperty only supports the main world. |
+// FIXME: Implement support for isolated worlds. |
+template<typename HolderType, typename ResolvedType, typename RejectedType> |
+class ScriptPromiseProperty : public ScriptPromisePropertyBase { |
+ WTF_MAKE_NONCOPYABLE(ScriptPromiseProperty); |
+public: |
+ // Creates a ScriptPromiseProperty that will create Promises in |
+ // the specified ExecutionContext for a property of 'holder' |
+ // (typically ScriptPromiseProperty should be a member of the |
+ // property holder). |
+ // |
+ // When implementing a ScriptPromiseProperty add the property name |
+ // to ScriptPromiseProperties.h and pass |
+ // ScriptPromiseProperty::Foo to create. The name must be unique |
+ // per kind of holder. |
+ template<typename PassHolderType> |
+ static PassRefPtrWillBeRawPtr<ScriptPromiseProperty<HolderType, ResolvedType, RejectedType> > create(ExecutionContext*, PassHolderType, Name); |
+ |
+ virtual ~ScriptPromiseProperty() { } |
+ |
+ template<typename PassResolvedType> |
+ void resolve(PassResolvedType); |
+ |
+ template<typename PassRejectedType> |
+ void reject(PassRejectedType); |
+ |
+private: |
+ template<typename PassHolderType> |
+ ScriptPromiseProperty(ExecutionContext*, PassHolderType, Name); |
+ |
+ virtual v8::Handle<v8::Object> holder(v8::Handle<v8::Object> creationContext, v8::Isolate*) OVERRIDE; |
+ virtual v8::Handle<v8::Value> resolvedValue(v8::Handle<v8::Object> creationContext, v8::Isolate*) OVERRIDE; |
+ virtual v8::Handle<v8::Value> rejectedValue(v8::Handle<v8::Object> creationContext, v8::Isolate*) OVERRIDE; |
+ |
+ HolderType m_holder; |
+ ResolvedType m_resolved; |
+ RejectedType m_rejected; |
+}; |
+ |
+template<typename HolderType, typename ResolvedType, typename RejectedType> |
+template<typename PassHolderType> |
+PassRefPtrWillBeRawPtr<ScriptPromiseProperty<HolderType, ResolvedType, RejectedType> > ScriptPromiseProperty<HolderType, ResolvedType, RejectedType>::create(ExecutionContext* executionContext, PassHolderType holder, Name name) |
+{ |
+ return adoptRef(new ScriptPromiseProperty<HolderType, ResolvedType, RejectedType>(executionContext, holder, name)); |
+} |
+ |
+template<typename HolderType, typename ResolvedType, typename RejectedType> |
+template<typename PassHolderType> |
+ScriptPromiseProperty<HolderType, ResolvedType, RejectedType>::ScriptPromiseProperty(ExecutionContext* executionContext, PassHolderType holder, Name name) |
+ : ScriptPromisePropertyBase(executionContext, name) |
+ , m_holder(holder) |
+{ |
+} |
+ |
+template<typename HolderType, typename ResolvedType, typename RejectedType> |
+template<typename PassResolvedType> |
+void ScriptPromiseProperty<HolderType, ResolvedType, RejectedType>::resolve(PassResolvedType value) |
+{ |
+ if (state() != Pending) { |
+ ASSERT_NOT_REACHED(); |
+ return; |
+ } |
+ if (!executionContext()) |
+ return; |
+ m_resolved = value; |
+ resolveOrReject(Resolved); |
+} |
+ |
+template<typename HolderType, typename ResolvedType, typename RejectedType> |
+template<typename PassRejectedType> |
+void ScriptPromiseProperty<HolderType, ResolvedType, RejectedType>::reject(PassRejectedType value) |
+{ |
+ if (state() != Pending) { |
+ ASSERT_NOT_REACHED(); |
+ return; |
+ } |
+ if (!executionContext()) |
+ return; |
+ m_rejected = value; |
+ resolveOrReject(Rejected); |
+} |
+ |
+template<typename HolderType, typename ResolvedType, typename RejectedType> |
+v8::Handle<v8::Object> ScriptPromiseProperty<HolderType, ResolvedType, RejectedType>::holder(v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) |
+{ |
+ v8::Handle<v8::Value> value = V8ValueTraits<HolderType>::toV8Value(m_holder, creationContext, isolate); |
+ return value.As<v8::Object>(); |
+} |
+ |
+template<typename HolderType, typename ResolvedType, typename RejectedType> |
+v8::Handle<v8::Value> ScriptPromiseProperty<HolderType, ResolvedType, RejectedType>::resolvedValue(v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) |
+{ |
+ ASSERT(state() == Resolved); |
+ return V8ValueTraits<ResolvedType>::toV8Value(m_resolved, creationContext, isolate); |
+} |
+ |
+template<typename HolderType, typename ResolvedType, typename RejectedType> |
+v8::Handle<v8::Value> ScriptPromiseProperty<HolderType, ResolvedType, RejectedType>::rejectedValue(v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) |
+{ |
+ ASSERT(state() == Rejected); |
+ return V8ValueTraits<RejectedType>::toV8Value(m_rejected, creationContext, isolate); |
+} |
+ |
+} // namespace WebCore |
+ |
+#endif // ScriptPromiseProperty_h |