Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / bindings / core / v8 / ScriptPromiseProperty.h
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef ScriptPromiseProperty_h
6 #define ScriptPromiseProperty_h
7
8 #include "bindings/core/v8/ScriptPromise.h"
9 #include "bindings/core/v8/ScriptPromisePropertyBase.h"
10 #include "bindings/core/v8/V8Binding.h"
11 #include "wtf/Noncopyable.h"
12 #include "wtf/PassRefPtr.h"
13
14 namespace blink {
15
16 class ExecutionContext;
17
18 // ScriptPromiseProperty is a helper for implementing a DOM method or
19 // attribute whose value is a Promise, and the same Promise must be
20 // returned each time.
21 //
22 // ScriptPromiseProperty does not keep Promises or worlds alive to
23 // deliver Promise resolution/rejection to them; the Promise
24 // resolution/rejections are delivered if the holder's wrapper is
25 // alive. This is achieved by keeping a weak reference from
26 // ScriptPromiseProperty to the holder's wrapper, and references in
27 // hidden values from the wrapper to the promise and resolver
28 // (coincidentally the Resolver and Promise may be the same object,
29 // but that is an implementation detail of v8.)
30 //
31 //                                             ----> Resolver
32 //                                            /
33 // ScriptPromiseProperty - - -> Holder Wrapper ----> Promise
34 //
35 // To avoid exposing the action of the garbage collector to script,
36 // you should keep the wrapper alive as long as a promise may be
37 // settled.
38 //
39 // To avoid clobbering hidden values, a holder should only have one
40 // ScriptPromiseProperty object for a given name at a time. See reset.
41 template<typename HolderType, typename ResolvedType, typename RejectedType>
42 class ScriptPromiseProperty : public ScriptPromisePropertyBase {
43     WTF_MAKE_NONCOPYABLE(ScriptPromiseProperty);
44 public:
45     // Creates a ScriptPromiseProperty that will create Promises in
46     // the specified ExecutionContext for a property of 'holder'
47     // (typically ScriptPromiseProperty should be a member of the
48     // property holder).
49     //
50     // When implementing a ScriptPromiseProperty add the property name
51     // to ScriptPromiseProperties.h and pass
52     // ScriptPromiseProperty::Foo to create. The name must be unique
53     // per kind of holder.
54     template<typename PassHolderType>
55     ScriptPromiseProperty(ExecutionContext*, PassHolderType, Name);
56
57     virtual ~ScriptPromiseProperty() { }
58
59     template<typename PassResolvedType>
60     void resolve(PassResolvedType);
61
62     template<typename PassRejectedType>
63     void reject(PassRejectedType);
64
65     // Resets this property by unregistering the Promise property from the
66     // holder wrapper. Resets the internal state to Pending and clears the
67     // resolved and the rejected values.
68     // This method keeps the holder object and the property name.
69     void reset();
70
71     virtual void trace(Visitor*) OVERRIDE;
72
73 private:
74     virtual v8::Handle<v8::Object> holder(v8::Handle<v8::Object> creationContext, v8::Isolate*) OVERRIDE;
75     virtual v8::Handle<v8::Value> resolvedValue(v8::Handle<v8::Object> creationContext, v8::Isolate*) OVERRIDE;
76     virtual v8::Handle<v8::Value> rejectedValue(v8::Handle<v8::Object> creationContext, v8::Isolate*) OVERRIDE;
77
78     HolderType m_holder;
79     ResolvedType m_resolved;
80     RejectedType m_rejected;
81 };
82
83 template<typename HolderType, typename ResolvedType, typename RejectedType>
84 template<typename PassHolderType>
85 ScriptPromiseProperty<HolderType, ResolvedType, RejectedType>::ScriptPromiseProperty(ExecutionContext* executionContext, PassHolderType holder, Name name)
86     : ScriptPromisePropertyBase(executionContext, name)
87     , m_holder(holder)
88 {
89 }
90
91 template<typename HolderType, typename ResolvedType, typename RejectedType>
92 template<typename PassResolvedType>
93 void ScriptPromiseProperty<HolderType, ResolvedType, RejectedType>::resolve(PassResolvedType value)
94 {
95     if (state() != Pending) {
96         ASSERT_NOT_REACHED();
97         return;
98     }
99     if (!executionContext() || executionContext()->activeDOMObjectsAreStopped())
100         return;
101     m_resolved = value;
102     resolveOrReject(Resolved);
103 }
104
105 template<typename HolderType, typename ResolvedType, typename RejectedType>
106 template<typename PassRejectedType>
107 void ScriptPromiseProperty<HolderType, ResolvedType, RejectedType>::reject(PassRejectedType value)
108 {
109     if (state() != Pending) {
110         ASSERT_NOT_REACHED();
111         return;
112     }
113     if (!executionContext() || executionContext()->activeDOMObjectsAreStopped())
114         return;
115     m_rejected = value;
116     resolveOrReject(Rejected);
117 }
118
119 template<typename HolderType, typename ResolvedType, typename RejectedType>
120 v8::Handle<v8::Object> ScriptPromiseProperty<HolderType, ResolvedType, RejectedType>::holder(v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
121 {
122     v8::Handle<v8::Value> value = V8ValueTraits<HolderType>::toV8Value(m_holder, creationContext, isolate);
123     return value.As<v8::Object>();
124 }
125
126 template<typename HolderType, typename ResolvedType, typename RejectedType>
127 v8::Handle<v8::Value> ScriptPromiseProperty<HolderType, ResolvedType, RejectedType>::resolvedValue(v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
128 {
129     ASSERT(state() == Resolved);
130     return V8ValueTraits<ResolvedType>::toV8Value(m_resolved, creationContext, isolate);
131 }
132
133 template<typename HolderType, typename ResolvedType, typename RejectedType>
134 v8::Handle<v8::Value> ScriptPromiseProperty<HolderType, ResolvedType, RejectedType>::rejectedValue(v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
135 {
136     ASSERT(state() == Rejected);
137     return V8ValueTraits<RejectedType>::toV8Value(m_rejected, creationContext, isolate);
138 }
139
140 template<typename HolderType, typename ResolvedType, typename RejectedType>
141 void ScriptPromiseProperty<HolderType, ResolvedType, RejectedType>::reset()
142 {
143     resetBase();
144     m_resolved = ResolvedType();
145     m_rejected = RejectedType();
146 }
147
148 template<typename HolderType, typename ResolvedType, typename RejectedType>
149 void ScriptPromiseProperty<HolderType, ResolvedType, RejectedType>::trace(Visitor* visitor)
150 {
151     TraceIfNeeded<HolderType>::trace(visitor, &m_holder);
152     TraceIfNeeded<ResolvedType>::trace(visitor, &m_resolved);
153     TraceIfNeeded<RejectedType>::trace(visitor, &m_rejected);
154     ScriptPromisePropertyBase::trace(visitor);
155 }
156
157 } // namespace blink
158
159 #endif // ScriptPromiseProperty_h