| Index: headless/lib/web_frame_impl.cc
|
| diff --git a/headless/lib/web_frame_impl.cc b/headless/lib/web_frame_impl.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..48f38891b8bb01b1d1766569b71bb3ee2c2e467f
|
| --- /dev/null
|
| +++ b/headless/lib/web_frame_impl.cc
|
| @@ -0,0 +1,134 @@
|
| +// Copyright 2015 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 "headless/lib/web_frame_impl.h"
|
| +
|
| +#include "headless/public/web_document.h"
|
| +#include "third_party/WebKit/public/web/WebDocument.h"
|
| +#include "third_party/WebKit/public/web/WebFrame.h"
|
| +#include "third_party/WebKit/public/web/WebLocalFrame.h"
|
| +#include "third_party/WebKit/public/web/WebScriptSource.h"
|
| +#include "third_party/WebKit/public/web/WebScriptExecutionCallback.h"
|
| +#include "base/values.h"
|
| +#include "v8/include/v8.h"
|
| +
|
| +namespace headless {
|
| +
|
| +WebFrameImpl::WebFrameImpl(blink::WebLocalFrame* web_frame)
|
| + : web_frame_(web_frame) {}
|
| +
|
| +WebFrameImpl::~WebFrameImpl() {}
|
| +
|
| +WebDocument WebFrameImpl::document() {
|
| + return WebDocument(web_frame_->document());
|
| +}
|
| +
|
| +namespace {
|
| +
|
| +blink::WebScriptSource StringToWebScript(const std::string& code) {
|
| + return blink::WebScriptSource(
|
| + blink::WebString::fromUTF8(code.c_str(), code.size()));
|
| +}
|
| +
|
| +}
|
| +
|
| +class WebFrameImpl::JavaScriptExecutionCallback :
|
| + public blink::WebScriptExecutionCallback
|
| +{
|
| + public:
|
| + JavaScriptExecutionCallback(
|
| + WebFrameImpl* web_frame,
|
| + const WebFrame::ScriptExecutionCallback callback)
|
| + : web_frame_(web_frame)
|
| + , callback_(callback) {}
|
| + ~JavaScriptExecutionCallback() override {};
|
| +
|
| + void completed(const blink::WebVector<v8::Local<v8::Value>>& values) {
|
| + std::vector<scoped_ptr<base::Value>> converted_values;
|
| + for (const auto& value : values) {
|
| + converted_values.push_back(web_frame_->ConvertV8ValueToBase(value));
|
| + }
|
| + callback_.Run(converted_values);
|
| + }
|
| + private:
|
| + WebFrameImpl* web_frame_;
|
| + ScriptExecutionCallback callback_;
|
| +};
|
| +
|
| +namespace {
|
| +
|
| +std::string ConvertV8StringToStd(v8::Local<v8::String> string)
|
| +{
|
| + std::vector<char> buffer;
|
| + buffer.resize(string->Utf8Length());
|
| + string->WriteUtf8(buffer.data(), buffer.size());
|
| + return std::string(buffer.data(), buffer.size());
|
| +}
|
| +
|
| +}
|
| +
|
| +scoped_ptr<base::Value> WebFrameImpl::ConvertV8ValueToBase(
|
| + const v8::Local<v8::Value>& value) {
|
| + v8::Local<v8::Context> context = web_frame_->mainWorldScriptContext();
|
| + if (value->IsBoolean()) {
|
| + v8::Local<v8::Boolean> boolean = value->ToBoolean(context).ToLocalChecked();
|
| + return make_scoped_ptr(new base::FundamentalValue(boolean->Value()));
|
| + } else if (value->IsNumber()) {
|
| + v8::Local<v8::Number> number = value->ToNumber(context).ToLocalChecked();
|
| + return make_scoped_ptr(new base::FundamentalValue(number->Value()));
|
| + } else if (value->IsString()) {
|
| + v8::Local<v8::String> string = value->ToString(context).ToLocalChecked();
|
| + return make_scoped_ptr(new base::StringValue(ConvertV8StringToStd(string)));
|
| + } else if (value->IsArray()) {
|
| + v8::Local<v8::Object> array = value->ToObject(context).ToLocalChecked();
|
| + scoped_ptr<base::ListValue> list = make_scoped_ptr(
|
| + new base::ListValue());
|
| + size_t index = 0;
|
| +
|
| + // TODO(altimin): Handle exceptions properly.
|
| + while (array->Has(context, index).FromJust()) {
|
| + list->Append(ConvertV8ValueToBase(array->Get(context, index).ToLocalChecked()));
|
| + ++index;
|
| + }
|
| + return scoped_ptr<base::Value>(std::move(list));
|
| + } else if (value->IsObject()) {
|
| + v8::Local<v8::Object> object = value->ToObject(context).ToLocalChecked();
|
| + v8::Local<v8::Array> property_names =
|
| + object->GetPropertyNames(context).ToLocalChecked();;
|
| + scoped_ptr<base::DictionaryValue> dictionary = make_scoped_ptr(
|
| + new base::DictionaryValue());
|
| +
|
| + for (size_t i = 0; i < property_names->Length(); ++i) {
|
| + v8::Local<v8::Value> property_name =
|
| + property_names->Get(context, i).ToLocalChecked();
|
| + if (!property_name->IsString()) {
|
| + continue;
|
| + }
|
| + v8::Local<v8::String> property_name_as_string =
|
| + property_name->ToString(context).ToLocalChecked();
|
| + dictionary->Set(ConvertV8StringToStd(property_name_as_string),
|
| + ConvertV8ValueToBase(object->Get(property_name)));
|
| + }
|
| +
|
| + return scoped_ptr<base::Value>(std::move(dictionary));
|
| + }
|
| + return nullptr;
|
| +}
|
| +
|
| +
|
| +void WebFrameImpl::ExecuteScript(
|
| + const std::string& source_code) {
|
| + web_frame_->executeScript(StringToWebScript(source_code));
|
| +}
|
| +
|
| +void WebFrameImpl::ExecuteScriptAndReturnValue(
|
| + const std::string& source_code,
|
| + const ScriptExecutionCallback& callback) {
|
| + web_frame_->requestExecuteScriptAndReturnValue(
|
| + StringToWebScript(source_code),
|
| + /* user_gesture */ false,
|
| + new JavaScriptExecutionCallback(this, callback));
|
| +}
|
| +
|
| +} // namespace headless
|
|
|