Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 97 | 97 |
| 98 V8V0CustomElementLifecycleCallbacks::V8V0CustomElementLifecycleCallbacks( | 98 V8V0CustomElementLifecycleCallbacks::V8V0CustomElementLifecycleCallbacks( |
| 99 ScriptState* scriptState, | 99 ScriptState* scriptState, |
| 100 v8::Local<v8::Object> prototype, | 100 v8::Local<v8::Object> prototype, |
| 101 v8::MaybeLocal<v8::Function> created, | 101 v8::MaybeLocal<v8::Function> created, |
| 102 v8::MaybeLocal<v8::Function> attached, | 102 v8::MaybeLocal<v8::Function> attached, |
| 103 v8::MaybeLocal<v8::Function> detached, | 103 v8::MaybeLocal<v8::Function> detached, |
| 104 v8::MaybeLocal<v8::Function> attributeChanged) | 104 v8::MaybeLocal<v8::Function> attributeChanged) |
| 105 : V0CustomElementLifecycleCallbacks( | 105 : V0CustomElementLifecycleCallbacks( |
| 106 flagSet(attached, detached, attributeChanged)), | 106 flagSet(attached, detached, attributeChanged)), |
| 107 ContextLifecycleObserver(scriptState->getExecutionContext()), | |
| 108 m_scriptState(scriptState), | 107 m_scriptState(scriptState), |
| 109 m_prototype(scriptState->isolate(), prototype), | 108 m_prototype(scriptState->isolate(), prototype), |
| 110 m_created(scriptState->isolate(), created), | 109 m_created(scriptState->isolate(), created), |
| 111 m_attached(scriptState->isolate(), attached), | 110 m_attached(scriptState->isolate(), attached), |
| 112 m_detached(scriptState->isolate(), detached), | 111 m_detached(scriptState->isolate(), detached), |
| 113 m_attributeChanged(scriptState->isolate(), attributeChanged) { | 112 m_attributeChanged(scriptState->isolate(), attributeChanged) { |
| 114 m_prototype.setPhantom(); | 113 m_prototype.setPhantom(); |
| 115 | 114 |
| 116 #define MAKE_WEAK(Var, _) \ | 115 #define MAKE_WEAK(Var, _) \ |
| 117 if (!m_##Var.isEmpty()) \ | 116 if (!m_##Var.isEmpty()) \ |
| 118 m_##Var.setPhantom(); | 117 m_##Var.setPhantom(); |
| 119 | 118 |
| 120 CALLBACK_LIST(MAKE_WEAK) | 119 CALLBACK_LIST(MAKE_WEAK) |
| 121 #undef MAKE_WEAK | 120 #undef MAKE_WEAK |
| 122 } | 121 } |
| 123 | 122 |
| 124 V8PerContextData* V8V0CustomElementLifecycleCallbacks::creationContextData() { | 123 V8PerContextData* V8V0CustomElementLifecycleCallbacks::creationContextData() { |
| 125 if (!getExecutionContext()) | 124 if (!m_scriptState->contextIsValid()) |
| 126 return 0; | 125 return 0; |
| 127 | 126 |
| 128 v8::Local<v8::Context> context = m_scriptState->context(); | 127 v8::Local<v8::Context> context = m_scriptState->context(); |
| 129 if (context.IsEmpty()) | 128 if (context.IsEmpty()) |
| 130 return 0; | 129 return 0; |
| 131 | 130 |
| 132 return V8PerContextData::from(context); | 131 return V8PerContextData::from(context); |
| 133 } | 132 } |
| 134 | 133 |
| 135 V8V0CustomElementLifecycleCallbacks::~V8V0CustomElementLifecycleCallbacks() {} | 134 V8V0CustomElementLifecycleCallbacks::~V8V0CustomElementLifecycleCallbacks() {} |
| 136 | 135 |
| 137 bool V8V0CustomElementLifecycleCallbacks::setBinding( | 136 bool V8V0CustomElementLifecycleCallbacks::setBinding( |
| 138 std::unique_ptr<V0CustomElementBinding> binding) { | 137 std::unique_ptr<V0CustomElementBinding> binding) { |
| 139 V8PerContextData* perContextData = creationContextData(); | 138 V8PerContextData* perContextData = creationContextData(); |
| 140 if (!perContextData) | 139 if (!perContextData) |
| 141 return false; | 140 return false; |
| 142 | 141 |
| 143 // The context is responsible for keeping the prototype | 142 // The context is responsible for keeping the prototype |
| 144 // alive. This in turn keeps callbacks alive through hidden | 143 // alive. This in turn keeps callbacks alive through hidden |
| 145 // references; see CALLBACK_LIST(SET_HIDDEN_VALUE). | 144 // references; see CALLBACK_LIST(SET_HIDDEN_VALUE). |
| 146 perContextData->addCustomElementBinding(std::move(binding)); | 145 perContextData->addCustomElementBinding(std::move(binding)); |
| 147 return true; | 146 return true; |
| 148 } | 147 } |
| 149 | 148 |
| 150 void V8V0CustomElementLifecycleCallbacks::created(Element* element) { | 149 void V8V0CustomElementLifecycleCallbacks::created(Element* element) { |
| 151 // FIXME: callbacks while paused should be queued up for execution to | 150 // FIXME: callbacks while paused should be queued up for execution to |
| 152 // continue then be delivered in order rather than delivered immediately. | 151 // continue then be delivered in order rather than delivered immediately. |
| 153 // Bug 329665 tracks similar behavior for other synchronous events. | 152 // Bug 329665 tracks similar behavior for other synchronous events. |
| 154 if (!getExecutionContext() || getExecutionContext()->isContextDestroyed()) | |
|
sof
2016/12/07 12:14:59
Can you clarify why the explicit checks here for i
haraken
2016/12/07 12:17:21
Because it's equivalent to the m_scriptState->cont
sof
2016/12/07 12:25:14
ok, if the interval between context() becoming nul
| |
| 155 return; | |
| 156 | |
| 157 if (!m_scriptState->contextIsValid()) | 153 if (!m_scriptState->contextIsValid()) |
| 158 return; | 154 return; |
| 159 | 155 |
| 160 element->setV0CustomElementState(Element::V0Upgraded); | 156 element->setV0CustomElementState(Element::V0Upgraded); |
| 161 | 157 |
| 162 ScriptState::Scope scope(m_scriptState.get()); | 158 ScriptState::Scope scope(m_scriptState.get()); |
| 163 v8::Isolate* isolate = m_scriptState->isolate(); | 159 v8::Isolate* isolate = m_scriptState->isolate(); |
| 164 v8::Local<v8::Context> context = m_scriptState->context(); | 160 v8::Local<v8::Context> context = m_scriptState->context(); |
| 165 v8::Local<v8::Value> receiverValue = | 161 v8::Local<v8::Value> receiverValue = |
| 166 toV8(element, context->Global(), isolate); | 162 toV8(element, context->Global(), isolate); |
| 167 if (receiverValue.IsEmpty()) | 163 if (receiverValue.IsEmpty()) |
| 168 return; | 164 return; |
| 169 v8::Local<v8::Object> receiver = receiverValue.As<v8::Object>(); | 165 v8::Local<v8::Object> receiver = receiverValue.As<v8::Object>(); |
| 170 | 166 |
| 171 // Swizzle the prototype of the wrapper. | 167 // Swizzle the prototype of the wrapper. |
| 172 v8::Local<v8::Object> prototype = m_prototype.newLocal(isolate); | 168 v8::Local<v8::Object> prototype = m_prototype.newLocal(isolate); |
| 173 if (prototype.IsEmpty()) | 169 if (prototype.IsEmpty()) |
| 174 return; | 170 return; |
| 175 if (!v8CallBoolean(receiver->SetPrototype(context, prototype))) | 171 if (!v8CallBoolean(receiver->SetPrototype(context, prototype))) |
| 176 return; | 172 return; |
| 177 | 173 |
| 178 v8::Local<v8::Function> callback = m_created.newLocal(isolate); | 174 v8::Local<v8::Function> callback = m_created.newLocal(isolate); |
| 179 if (callback.IsEmpty()) | 175 if (callback.IsEmpty()) |
| 180 return; | 176 return; |
| 181 | 177 |
| 182 v8::TryCatch exceptionCatcher(isolate); | 178 v8::TryCatch exceptionCatcher(isolate); |
| 183 exceptionCatcher.SetVerbose(true); | 179 exceptionCatcher.SetVerbose(true); |
| 184 V8ScriptRunner::callFunction(callback, getExecutionContext(), receiver, 0, 0, | 180 V8ScriptRunner::callFunction(callback, m_scriptState->getExecutionContext(), |
| 185 isolate); | 181 receiver, 0, 0, isolate); |
| 186 } | 182 } |
| 187 | 183 |
| 188 void V8V0CustomElementLifecycleCallbacks::attached(Element* element) { | 184 void V8V0CustomElementLifecycleCallbacks::attached(Element* element) { |
| 189 call(m_attached, element); | 185 call(m_attached, element); |
| 190 } | 186 } |
| 191 | 187 |
| 192 void V8V0CustomElementLifecycleCallbacks::detached(Element* element) { | 188 void V8V0CustomElementLifecycleCallbacks::detached(Element* element) { |
| 193 call(m_detached, element); | 189 call(m_detached, element); |
| 194 } | 190 } |
| 195 | 191 |
| 196 void V8V0CustomElementLifecycleCallbacks::attributeChanged( | 192 void V8V0CustomElementLifecycleCallbacks::attributeChanged( |
| 197 Element* element, | 193 Element* element, |
| 198 const AtomicString& name, | 194 const AtomicString& name, |
| 199 const AtomicString& oldValue, | 195 const AtomicString& oldValue, |
| 200 const AtomicString& newValue) { | 196 const AtomicString& newValue) { |
| 201 // FIXME: callbacks while paused should be queued up for execution to | 197 // FIXME: callbacks while paused should be queued up for execution to |
| 202 // continue then be delivered in order rather than delivered immediately. | 198 // continue then be delivered in order rather than delivered immediately. |
| 203 // Bug 329665 tracks similar behavior for other synchronous events. | 199 // Bug 329665 tracks similar behavior for other synchronous events. |
| 204 if (!getExecutionContext() || getExecutionContext()->isContextDestroyed()) | |
| 205 return; | |
| 206 | |
| 207 if (!m_scriptState->contextIsValid()) | 200 if (!m_scriptState->contextIsValid()) |
| 208 return; | 201 return; |
| 209 ScriptState::Scope scope(m_scriptState.get()); | 202 ScriptState::Scope scope(m_scriptState.get()); |
| 210 v8::Isolate* isolate = m_scriptState->isolate(); | 203 v8::Isolate* isolate = m_scriptState->isolate(); |
| 211 v8::Local<v8::Context> context = m_scriptState->context(); | 204 v8::Local<v8::Context> context = m_scriptState->context(); |
| 212 v8::Local<v8::Value> receiver = toV8(element, context->Global(), isolate); | 205 v8::Local<v8::Value> receiver = toV8(element, context->Global(), isolate); |
| 213 if (receiver.IsEmpty()) | 206 if (receiver.IsEmpty()) |
| 214 return; | 207 return; |
| 215 | 208 |
| 216 v8::Local<v8::Function> callback = m_attributeChanged.newLocal(isolate); | 209 v8::Local<v8::Function> callback = m_attributeChanged.newLocal(isolate); |
| 217 if (callback.IsEmpty()) | 210 if (callback.IsEmpty()) |
| 218 return; | 211 return; |
| 219 | 212 |
| 220 v8::Local<v8::Value> argv[] = { | 213 v8::Local<v8::Value> argv[] = { |
| 221 v8String(isolate, name), | 214 v8String(isolate, name), |
| 222 oldValue.isNull() ? v8::Local<v8::Value>(v8::Null(isolate)) | 215 oldValue.isNull() ? v8::Local<v8::Value>(v8::Null(isolate)) |
| 223 : v8::Local<v8::Value>(v8String(isolate, oldValue)), | 216 : v8::Local<v8::Value>(v8String(isolate, oldValue)), |
| 224 newValue.isNull() ? v8::Local<v8::Value>(v8::Null(isolate)) | 217 newValue.isNull() ? v8::Local<v8::Value>(v8::Null(isolate)) |
| 225 : v8::Local<v8::Value>(v8String(isolate, newValue))}; | 218 : v8::Local<v8::Value>(v8String(isolate, newValue))}; |
| 226 | 219 |
| 227 v8::TryCatch exceptionCatcher(isolate); | 220 v8::TryCatch exceptionCatcher(isolate); |
| 228 exceptionCatcher.SetVerbose(true); | 221 exceptionCatcher.SetVerbose(true); |
| 229 V8ScriptRunner::callFunction(callback, getExecutionContext(), receiver, | 222 V8ScriptRunner::callFunction(callback, m_scriptState->getExecutionContext(), |
| 230 WTF_ARRAY_LENGTH(argv), argv, isolate); | 223 receiver, WTF_ARRAY_LENGTH(argv), argv, isolate); |
| 231 } | 224 } |
| 232 | 225 |
| 233 void V8V0CustomElementLifecycleCallbacks::call( | 226 void V8V0CustomElementLifecycleCallbacks::call( |
| 234 const ScopedPersistent<v8::Function>& weakCallback, | 227 const ScopedPersistent<v8::Function>& weakCallback, |
| 235 Element* element) { | 228 Element* element) { |
| 236 // FIXME: callbacks while paused should be queued up for execution to | 229 // FIXME: callbacks while paused should be queued up for execution to |
| 237 // continue then be delivered in order rather than delivered immediately. | 230 // continue then be delivered in order rather than delivered immediately. |
| 238 // Bug 329665 tracks similar behavior for other synchronous events. | 231 // Bug 329665 tracks similar behavior for other synchronous events. |
| 239 if (!getExecutionContext() || getExecutionContext()->isContextDestroyed()) | |
| 240 return; | |
| 241 | |
| 242 if (!m_scriptState->contextIsValid()) | 232 if (!m_scriptState->contextIsValid()) |
| 243 return; | 233 return; |
| 244 ScriptState::Scope scope(m_scriptState.get()); | 234 ScriptState::Scope scope(m_scriptState.get()); |
| 245 v8::Isolate* isolate = m_scriptState->isolate(); | 235 v8::Isolate* isolate = m_scriptState->isolate(); |
| 246 v8::Local<v8::Context> context = m_scriptState->context(); | 236 v8::Local<v8::Context> context = m_scriptState->context(); |
| 247 v8::Local<v8::Function> callback = weakCallback.newLocal(isolate); | 237 v8::Local<v8::Function> callback = weakCallback.newLocal(isolate); |
| 248 if (callback.IsEmpty()) | 238 if (callback.IsEmpty()) |
| 249 return; | 239 return; |
| 250 | 240 |
| 251 v8::Local<v8::Value> receiver = toV8(element, context->Global(), isolate); | 241 v8::Local<v8::Value> receiver = toV8(element, context->Global(), isolate); |
| 252 if (receiver.IsEmpty()) | 242 if (receiver.IsEmpty()) |
| 253 return; | 243 return; |
| 254 | 244 |
| 255 v8::TryCatch exceptionCatcher(isolate); | 245 v8::TryCatch exceptionCatcher(isolate); |
| 256 exceptionCatcher.SetVerbose(true); | 246 exceptionCatcher.SetVerbose(true); |
| 257 V8ScriptRunner::callFunction(callback, getExecutionContext(), receiver, 0, 0, | 247 V8ScriptRunner::callFunction(callback, m_scriptState->getExecutionContext(), |
| 258 isolate); | 248 receiver, 0, 0, isolate); |
| 259 } | 249 } |
| 260 | 250 |
| 261 DEFINE_TRACE(V8V0CustomElementLifecycleCallbacks) { | 251 DEFINE_TRACE(V8V0CustomElementLifecycleCallbacks) { |
| 262 V0CustomElementLifecycleCallbacks::trace(visitor); | 252 V0CustomElementLifecycleCallbacks::trace(visitor); |
| 263 ContextLifecycleObserver::trace(visitor); | |
| 264 } | 253 } |
| 265 | 254 |
| 266 } // namespace blink | 255 } // namespace blink |
| OLD | NEW |