[DevTools] Added public method for async execution of scripts

This methods accept callback which will be called when scripts finished execution.

R=vsevik@chromium.org
BUG=410289

Review URL: https://codereview.chromium.org/660863002

git-svn-id: svn://svn.chromium.org/blink/trunk@184279 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent ca2e0037
// 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.
#include "config.h"
#include "web/SuspendableScriptExecutor.h"
#include "bindings/core/v8/ScriptController.h"
#include "core/dom/Document.h"
#include "core/frame/LocalFrame.h"
#include "platform/UserGestureIndicator.h"
#include "public/platform/WebVector.h"
#include "public/web/WebScriptExecutionCallback.h"
namespace blink {
SuspendableScriptExecutor::SuspendableScriptExecutor(LocalFrame* frame, int worldID, const Vector<ScriptSourceCode>& sources, int extensionGroup, bool userGesture, WebScriptExecutionCallback* callback)
: ActiveDOMObject(frame->document())
, m_frame(frame)
, m_worldID(worldID)
, m_sources(sources)
, m_extensionGroup(extensionGroup)
, m_userGesture(userGesture)
, m_callback(callback)
{
}
SuspendableScriptExecutor::~SuspendableScriptExecutor()
{
}
void SuspendableScriptExecutor::run()
{
suspendIfNeeded();
ExecutionContext* context = executionContext();
ASSERT(context);
if (context && !context->activeDOMObjectsAreSuspended())
executeAndDestroySelf();
}
void SuspendableScriptExecutor::resume()
{
executeAndDestroySelf();
}
void SuspendableScriptExecutor::contextDestroyed()
{
// this method can only be called if the script was not called in run()
// and context remained suspend (method resume has never called)
ActiveDOMObject::contextDestroyed();
m_callback->completed(Vector<v8::Local<v8::Value> >());
delete this;
}
void SuspendableScriptExecutor::executeAndDestroySelf()
{
// after calling the destructor of object - object will be unsubscribed from
// resumed and contextDestroyed LifecycleObserver methods
OwnPtr<UserGestureIndicator> indicator;
if (m_userGesture)
indicator = adoptPtr(new UserGestureIndicator(DefinitelyProcessingNewUserGesture));
v8::HandleScope scope(v8::Isolate::GetCurrent());
Vector<v8::Local<v8::Value> > results;
if (m_worldID) {
m_frame->script().executeScriptInIsolatedWorld(m_worldID, m_sources, m_extensionGroup, &results);
} else {
v8::Local<v8::Value> scriptValue = m_frame->script().executeScriptInMainWorldAndReturnValue(m_sources.first());
results.append(scriptValue);
}
m_callback->completed(results);
delete this;
}
} // namespace blink
// 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 SuspendableScriptExecutor_h
#define SuspendableScriptExecutor_h
#include "core/dom/ActiveDOMObject.h"
#include "wtf/OwnPtr.h"
#include "wtf/Vector.h"
namespace blink {
class LocalFrame;
class ScriptSourceCode;
class WebScriptExecutionCallback;
class SuspendableScriptExecutor final : public ActiveDOMObject {
public:
SuspendableScriptExecutor(LocalFrame*, int worldID, const Vector<ScriptSourceCode>& sources, int extensionGroup, bool userGesture, WebScriptExecutionCallback*);
virtual ~SuspendableScriptExecutor();
// this method must be called only once
void run();
virtual void resume() override;
virtual void contextDestroyed() override;
private:
void executeAndDestroySelf();
LocalFrame* m_frame;
int m_worldID;
Vector<ScriptSourceCode> m_sources;
int m_extensionGroup;
bool m_userGesture;
WebScriptExecutionCallback* m_callback;
};
} // namespace blink
#endif // SuspendableScriptExecutor_h
......@@ -201,6 +201,7 @@
#include "web/NotificationPermissionClientImpl.h"
#include "web/PageOverlay.h"
#include "web/SharedWorkerRepositoryClientImpl.h"
#include "web/SuspendableScriptExecutor.h"
#include "web/TextFinder.h"
#include "web/WebDataSourceImpl.h"
#include "web/WebDevToolsAgentPrivate.h"
......@@ -278,6 +279,13 @@ static void frameContentAsPlainText(size_t maxChars, LocalFrame* frame, StringBu
}
}
static Vector<ScriptSourceCode> createSourcesVector(const WebScriptSource* sourcesIn, unsigned numSources)
{
Vector<ScriptSourceCode> sources;
sources.append(sourcesIn, numSources);
return sources;
}
WebPluginContainerImpl* WebLocalFrameImpl::pluginContainerFromFrame(LocalFrame* frame)
{
if (!frame)
......@@ -706,12 +714,7 @@ void WebLocalFrameImpl::executeScriptInIsolatedWorld(int worldID, const WebScrip
RELEASE_ASSERT(worldID > 0);
RELEASE_ASSERT(worldID < EmbedderWorldIdLimit);
Vector<ScriptSourceCode> sources;
for (unsigned i = 0; i < numSources; ++i) {
TextPosition position(OrdinalNumber::fromOneBasedInt(sourcesIn[i].startLine), OrdinalNumber::first());
sources.append(ScriptSourceCode(sourcesIn[i].code, sourcesIn[i].url, position));
}
Vector<ScriptSourceCode> sources = createSourcesVector(sourcesIn, numSources);
v8::HandleScope handleScope(toIsolate(frame()));
frame()->script().executeScriptInIsolatedWorld(worldID, sources, extensionGroup, 0);
}
......@@ -783,18 +786,22 @@ v8::Handle<v8::Value> WebLocalFrameImpl::executeScriptAndReturnValue(const WebSc
return frame()->script().executeScriptInMainWorldAndReturnValue(ScriptSourceCode(source.code, source.url, position));
}
void WebLocalFrameImpl::requestExecuteScriptAndReturnValue(const WebScriptSource& source, bool userGesture, WebScriptExecutionCallback* callback)
{
ASSERT(frame());
Vector<ScriptSourceCode> sources = createSourcesVector(&source, 1);
SuspendableScriptExecutor* executor = new SuspendableScriptExecutor(frame(), 0, sources, 0, userGesture, callback);
executor->run();
}
void WebLocalFrameImpl::executeScriptInIsolatedWorld(int worldID, const WebScriptSource* sourcesIn, unsigned numSources, int extensionGroup, WebVector<v8::Local<v8::Value> >* results)
{
ASSERT(frame());
RELEASE_ASSERT(worldID > 0);
RELEASE_ASSERT(worldID < EmbedderWorldIdLimit);
Vector<ScriptSourceCode> sources;
for (unsigned i = 0; i < numSources; ++i) {
TextPosition position(OrdinalNumber::fromOneBasedInt(sourcesIn[i].startLine), OrdinalNumber::first());
sources.append(ScriptSourceCode(sourcesIn[i].code, sourcesIn[i].url, position));
}
Vector<ScriptSourceCode> sources = createSourcesVector(sourcesIn, numSources);
if (results) {
Vector<v8::Local<v8::Value> > scriptResults;
......@@ -809,6 +816,17 @@ void WebLocalFrameImpl::executeScriptInIsolatedWorld(int worldID, const WebScrip
}
}
void WebLocalFrameImpl::requestExecuteScriptInIsolatedWorld(int worldID, const WebScriptSource* sourcesIn, unsigned numSources, int extensionGroup, bool userGesture, WebScriptExecutionCallback* callback)
{
ASSERT(frame());
RELEASE_ASSERT(worldID > 0);
RELEASE_ASSERT(worldID < EmbedderWorldIdLimit);
Vector<ScriptSourceCode> sources = createSourcesVector(sourcesIn, numSources);
SuspendableScriptExecutor* executor = new SuspendableScriptExecutor(frame(), worldID, sources, extensionGroup, userGesture, callback);
executor->run();
}
v8::Handle<v8::Value> WebLocalFrameImpl::callFunctionEvenIfScriptDisabled(v8::Handle<v8::Function> function, v8::Handle<v8::Value> receiver, int argc, v8::Handle<v8::Value> argv[])
{
ASSERT(frame());
......
......@@ -50,6 +50,7 @@ class GeolocationClientProxy;
class IntSize;
class KURL;
class Range;
class ScriptSourceCode;
class SharedWorkerRepositoryClientImpl;
class TextFinder;
class WebDataSourceImpl;
......@@ -57,6 +58,7 @@ class WebFrameClient;
class WebPerformance;
class WebPlugin;
class WebPluginContainerImpl;
class WebScriptExecutionCallback;
class WebView;
class WebViewImpl;
struct FrameLoadRequest;
......@@ -110,9 +112,14 @@ public:
virtual bool checkIfRunInsecureContent(const WebURL&) const override;
virtual v8::Handle<v8::Value> executeScriptAndReturnValue(
const WebScriptSource&) override;
virtual void requestExecuteScriptAndReturnValue(
const WebScriptSource&, bool userGesture, WebScriptExecutionCallback*) override;
virtual void executeScriptInIsolatedWorld(
int worldID, const WebScriptSource* sourcesIn, unsigned numSources,
int extensionGroup, WebVector<v8::Local<v8::Value> >* results) override;
virtual void requestExecuteScriptInIsolatedWorld(
int worldID, const WebScriptSource* sourceIn, unsigned numSources,
int extensionGroup, bool userGesture, WebScriptExecutionCallback*) override;
virtual v8::Handle<v8::Value> callFunctionEvenIfScriptDisabled(
v8::Handle<v8::Function>,
v8::Handle<v8::Value>,
......
// 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.
#include "config.h"
#include "public/web/WebScriptSource.h"
#include "bindings/core/v8/ScriptSourceCode.h"
#include "wtf/text/TextPosition.h"
namespace blink {
WebScriptSource::operator ScriptSourceCode() const
{
TextPosition position(OrdinalNumber::fromOneBasedInt(startLine), OrdinalNumber::first());
return ScriptSourceCode(code, url, position);
}
} // namespace blink
......@@ -98,6 +98,8 @@
'StorageClientImpl.h',
'StorageQuotaClientImpl.cpp',
'StorageQuotaClientImpl.h',
'SuspendableScriptExecutor.cpp',
'SuspendableScriptExecutor.h',
'TextFinder.cpp',
'TextFinder.h',
'UserMediaClientImpl.cpp',
......@@ -215,6 +217,7 @@
'WebScopedWindowFocusAllowedIndicator.cpp',
'WebScriptBindings.cpp',
'WebScriptController.cpp',
'WebScriptSource.cpp',
'WebScrollbarThemePainter.cpp',
'WebSearchableFormData.cpp',
'WebSecurityOrigin.cpp',
......
......@@ -299,11 +299,13 @@ public:
// Executes script in the context of the current page and returns the value
// that the script evaluated to.
// DEPRECATED: Use WebLocalFrame::requestExecuteScriptAndReturnValue.
virtual v8::Handle<v8::Value> executeScriptAndReturnValue(
const WebScriptSource&) = 0;
// worldID must be > 0 (as 0 represents the main world).
// worldID must be < EmbedderWorldIdLimit, high number used internally.
// DEPRECATED: Use WebLocalFrame::requestExecuteScriptInIsolatedWorld.
virtual void executeScriptInIsolatedWorld(
int worldID, const WebScriptSource* sourcesIn, unsigned numSources,
int extensionGroup, WebVector<v8::Local<v8::Value> >* results) = 0;
......
......@@ -9,6 +9,8 @@
namespace blink {
class WebScriptExecutionCallback;
// Interface for interacting with in process frames. This contains methods that
// require interacting with a frame's document.
// FIXME: Move lots of methods from WebFrame in here.
......@@ -67,6 +69,18 @@ public:
// Scripting --------------------------------------------------------------
// Executes script in the context of the current page and returns the value
// that the script evaluated to with callback. Script execution can be
// suspend.
virtual void requestExecuteScriptAndReturnValue(const WebScriptSource&,
bool userGesture, WebScriptExecutionCallback*) = 0;
// worldID must be > 0 (as 0 represents the main world).
// worldID must be < EmbedderWorldIdLimit, high number used internally.
virtual void requestExecuteScriptInIsolatedWorld(
int worldID, const WebScriptSource* sourceIn, unsigned numSources,
int extensionGroup, bool userGesture, WebScriptExecutionCallback*) = 0;
// ONLY FOR TESTS: Forwards to executeScriptAndReturnValue, but sets a fake
// UserGestureIndicator before execution.
virtual v8::Handle<v8::Value> executeScriptAndReturnValueForTests(const WebScriptSource&) = 0;
......
// 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 WebScriptExecutionCallback_h
#define WebScriptExecutionCallback_h
namespace v8 {
class Value;
template <class T> class Local;
}
namespace blink {
template <typename T> class WebVector;
class WebScriptExecutionCallback {
public:
virtual ~WebScriptExecutionCallback() { }
// Method to be invoked when the asynchronous script execution is complete.
// After function call all objects in vector will be collected
virtual void completed(const WebVector<v8::Local<v8::Value> >&) { }
};
} // namespace blink
#endif // WebScriptExecutionCallback_h
......@@ -36,6 +36,8 @@
namespace blink {
class ScriptSourceCode;
struct WebScriptSource {
WebString code;
WebURL url;
......@@ -47,6 +49,10 @@ struct WebScriptSource {
: code(code), url(url), startLine(1) { }
WebScriptSource(const WebString& code, const WebURL& url, int startLine)
: code(code), url(url), startLine(startLine) { }
#if BLINK_IMPLEMENTATION
operator ScriptSourceCode() const;
#endif
};
} // namespace blink
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment