| OLD | NEW |
| (Empty) |
| 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 SKY_ENGINE_BINDINGS_CORE_V8_SCRIPTPROMISEPROPERTY_H_ | |
| 6 #define SKY_ENGINE_BINDINGS_CORE_V8_SCRIPTPROMISEPROPERTY_H_ | |
| 7 | |
| 8 #include "sky/engine/bindings/core/v8/ScriptPromise.h" | |
| 9 #include "sky/engine/bindings/core/v8/ScriptPromisePropertyBase.h" | |
| 10 #include "sky/engine/bindings/core/v8/V8Binding.h" | |
| 11 #include "sky/engine/wtf/Noncopyable.h" | |
| 12 #include "sky/engine/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 private: | |
| 72 virtual v8::Handle<v8::Object> holder(v8::Handle<v8::Object> creationContext
, v8::Isolate*) override; | |
| 73 virtual v8::Handle<v8::Value> resolvedValue(v8::Handle<v8::Object> creationC
ontext, v8::Isolate*) override; | |
| 74 virtual v8::Handle<v8::Value> rejectedValue(v8::Handle<v8::Object> creationC
ontext, v8::Isolate*) override; | |
| 75 | |
| 76 HolderType m_holder; | |
| 77 ResolvedType m_resolved; | |
| 78 RejectedType m_rejected; | |
| 79 }; | |
| 80 | |
| 81 template<typename HolderType, typename ResolvedType, typename RejectedType> | |
| 82 template<typename PassHolderType> | |
| 83 ScriptPromiseProperty<HolderType, ResolvedType, RejectedType>::ScriptPromiseProp
erty(ExecutionContext* executionContext, PassHolderType holder, Name name) | |
| 84 : ScriptPromisePropertyBase(executionContext, name) | |
| 85 , m_holder(holder) | |
| 86 { | |
| 87 } | |
| 88 | |
| 89 template<typename HolderType, typename ResolvedType, typename RejectedType> | |
| 90 template<typename PassResolvedType> | |
| 91 void ScriptPromiseProperty<HolderType, ResolvedType, RejectedType>::resolve(Pass
ResolvedType value) | |
| 92 { | |
| 93 if (state() != Pending) { | |
| 94 ASSERT_NOT_REACHED(); | |
| 95 return; | |
| 96 } | |
| 97 if (!executionContext() || executionContext()->activeDOMObjectsAreStopped()) | |
| 98 return; | |
| 99 m_resolved = value; | |
| 100 resolveOrReject(Resolved); | |
| 101 } | |
| 102 | |
| 103 template<typename HolderType, typename ResolvedType, typename RejectedType> | |
| 104 template<typename PassRejectedType> | |
| 105 void ScriptPromiseProperty<HolderType, ResolvedType, RejectedType>::reject(PassR
ejectedType value) | |
| 106 { | |
| 107 if (state() != Pending) { | |
| 108 ASSERT_NOT_REACHED(); | |
| 109 return; | |
| 110 } | |
| 111 if (!executionContext() || executionContext()->activeDOMObjectsAreStopped()) | |
| 112 return; | |
| 113 m_rejected = value; | |
| 114 resolveOrReject(Rejected); | |
| 115 } | |
| 116 | |
| 117 template<typename HolderType, typename ResolvedType, typename RejectedType> | |
| 118 v8::Handle<v8::Object> ScriptPromiseProperty<HolderType, ResolvedType, RejectedT
ype>::holder(v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) | |
| 119 { | |
| 120 v8::Handle<v8::Value> value = V8ValueTraits<HolderType>::toV8Value(m_holder,
creationContext, isolate); | |
| 121 return value.As<v8::Object>(); | |
| 122 } | |
| 123 | |
| 124 template<typename HolderType, typename ResolvedType, typename RejectedType> | |
| 125 v8::Handle<v8::Value> ScriptPromiseProperty<HolderType, ResolvedType, RejectedTy
pe>::resolvedValue(v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) | |
| 126 { | |
| 127 ASSERT(state() == Resolved); | |
| 128 return V8ValueTraits<ResolvedType>::toV8Value(m_resolved, creationContext, i
solate); | |
| 129 } | |
| 130 | |
| 131 template<typename HolderType, typename ResolvedType, typename RejectedType> | |
| 132 v8::Handle<v8::Value> ScriptPromiseProperty<HolderType, ResolvedType, RejectedTy
pe>::rejectedValue(v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) | |
| 133 { | |
| 134 ASSERT(state() == Rejected); | |
| 135 return V8ValueTraits<RejectedType>::toV8Value(m_rejected, creationContext, i
solate); | |
| 136 } | |
| 137 | |
| 138 template<typename HolderType, typename ResolvedType, typename RejectedType> | |
| 139 void ScriptPromiseProperty<HolderType, ResolvedType, RejectedType>::reset() | |
| 140 { | |
| 141 resetBase(); | |
| 142 m_resolved = ResolvedType(); | |
| 143 m_rejected = RejectedType(); | |
| 144 } | |
| 145 | |
| 146 } // namespace blink | |
| 147 | |
| 148 #endif // SKY_ENGINE_BINDINGS_CORE_V8_SCRIPTPROMISEPROPERTY_H_ | |
| OLD | NEW |