Chromium Code Reviews| Index: third_party/WebKit/Source/web/SuspendableScriptExecutor.cpp |
| diff --git a/third_party/WebKit/Source/web/SuspendableScriptExecutor.cpp b/third_party/WebKit/Source/web/SuspendableScriptExecutor.cpp |
| index 20aba329814e771e03d166318aecd919a4079194..b12a1b2b31cd92ef9107383f68f1842b33b59014 100644 |
| --- a/third_party/WebKit/Source/web/SuspendableScriptExecutor.cpp |
| +++ b/third_party/WebKit/Source/web/SuspendableScriptExecutor.cpp |
| @@ -29,6 +29,7 @@ class WebScriptExecutor : public SuspendableScriptExecutor::Executor { |
| bool userGesture); |
| Vector<v8::Local<v8::Value>> execute(LocalFrame*) override; |
| + ScriptState* getScriptState() override { return nullptr; } |
| DEFINE_INLINE_VIRTUAL_TRACE() { |
| visitor->trace(m_sources); |
| @@ -84,12 +85,14 @@ class V8FunctionExecutor : public SuspendableScriptExecutor::Executor { |
| v8::Local<v8::Value> argv[]); |
| Vector<v8::Local<v8::Value>> execute(LocalFrame*) override; |
| + ScriptState* getScriptState() override { return m_scriptState.get(); } |
| private: |
| ScopedPersistent<v8::Function> m_function; |
| ScopedPersistent<v8::Value> m_receiver; |
| V8PersistentValueVector<v8::Value> m_args; |
| RefPtr<ScriptState> m_scriptState; |
| + RefPtr<UserGestureToken> m_gestureToken; |
| }; |
| V8FunctionExecutor::V8FunctionExecutor(v8::Isolate* isolate, |
| @@ -101,7 +104,8 @@ V8FunctionExecutor::V8FunctionExecutor(v8::Isolate* isolate, |
| : m_function(isolate, function), |
| m_receiver(isolate, receiver), |
| m_args(isolate), |
| - m_scriptState(scriptState) { |
| + m_scriptState(scriptState), |
| + m_gestureToken(UserGestureIndicator::currentToken()) { |
| m_args.ReserveCapacity(argc); |
| for (int i = 0; i < argc; ++i) |
| m_args.Append(argv[i]); |
| @@ -110,20 +114,21 @@ V8FunctionExecutor::V8FunctionExecutor(v8::Isolate* isolate, |
| Vector<v8::Local<v8::Value>> V8FunctionExecutor::execute(LocalFrame* frame) { |
| v8::Isolate* isolate = v8::Isolate::GetCurrent(); |
| Vector<v8::Local<v8::Value>> results; |
| - if (!m_scriptState->contextIsValid()) |
| - return results; |
| - ScriptState::Scope scope(m_scriptState.get()); |
| + DCHECK(m_scriptState->contextIsValid()); |
| v8::Local<v8::Value> singleResult; |
| Vector<v8::Local<v8::Value>> args; |
| args.reserveCapacity(m_args.Size()); |
| for (size_t i = 0; i < m_args.Size(); ++i) |
| args.append(m_args.Get(i)); |
| - if (V8ScriptRunner::callFunction(m_function.newLocal(isolate), |
| - frame->document(), |
| - m_receiver.newLocal(isolate), args.size(), |
| - args.data(), toIsolate(frame)) |
| - .ToLocal(&singleResult)) |
| - results.append(singleResult); |
| + { |
| + UserGestureIndicator gestureIndicator(m_gestureToken.release()); |
| + if (V8ScriptRunner::callFunction(m_function.newLocal(isolate), |
| + frame->document(), |
| + m_receiver.newLocal(isolate), args.size(), |
| + args.data(), toIsolate(frame)) |
| + .ToLocal(&singleResult)) |
| + results.append(singleResult); |
| + } |
| return results; |
| } |
| @@ -200,15 +205,28 @@ void SuspendableScriptExecutor::run() { |
| void SuspendableScriptExecutor::executeAndDestroySelf() { |
| v8::HandleScope scope(v8::Isolate::GetCurrent()); |
|
dcheng
2016/10/28 17:24:17
Btw, assuming we combine the two separate paths, t
Devlin
2016/10/28 20:31:37
Done.
|
| - Vector<v8::Local<v8::Value>> results = m_executor->execute(m_frame); |
| - |
| - // The script may have removed the frame, in which case contextDestroyed() |
| - // will have handled the disposal/callback. |
| - if (!m_frame->client()) |
| - return; |
| - if (m_callback) |
| - m_callback->completed(results); |
| + Vector<v8::Local<v8::Value>> results; |
| + ScriptState* scriptState = m_executor->getScriptState(); |
| + if (scriptState && scriptState->contextIsValid()) { |
| + ScriptState::Scope scriptScope(scriptState); |
|
Devlin
2016/10/27 23:33:28
This change is necessary because when the scriptSc
haraken
2016/10/28 08:45:14
What specifically do you need to keep alive?
Devlin
2016/10/28 15:00:05
The results from the script execution. They're po
haraken
2016/10/28 15:47:51
What ScriptState::Scope are you referring to?
Not
Devlin
2016/10/28 16:00:00
In this patch set, as its written, this works, bec
haraken
2016/10/28 16:18:57
Ah, now I understand what you want to do.
BTW, ca
dcheng
2016/10/28 17:24:17
Hmm. Why does WebScriptExecutor not need the Scrip
Devlin
2016/10/28 20:31:37
WebScriptExecutor uses ScriptController::executeSc
|
| + results = m_executor->execute(m_frame); |
| + |
| + // The script may have removed the frame, in which case contextDestroyed() |
| + // will have handled the disposal/callback. |
| + if (!m_frame->client()) |
| + return; |
| + if (m_callback) |
| + m_callback->completed(results); |
| + } else { |
| + results = m_executor->execute(m_frame); |
| + // The script may have removed the frame, in which case contextDestroyed() |
| + // will have handled the disposal/callback. |
| + if (!m_frame->client()) |
| + return; |
| + if (m_callback) |
| + m_callback->completed(results); |
| + } |
| dispose(); |
| } |