OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 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 #include "headless/lib/web_frame_impl.h" |
| 6 |
| 7 #include "headless/public/web_document.h" |
| 8 #include "third_party/WebKit/public/web/WebDocument.h" |
| 9 #include "third_party/WebKit/public/web/WebFrame.h" |
| 10 #include "third_party/WebKit/public/web/WebLocalFrame.h" |
| 11 #include "third_party/WebKit/public/web/WebScriptSource.h" |
| 12 #include "third_party/WebKit/public/web/WebScriptExecutionCallback.h" |
| 13 #include "base/values.h" |
| 14 #include "v8/include/v8.h" |
| 15 |
| 16 namespace headless { |
| 17 |
| 18 WebFrameImpl::WebFrameImpl(blink::WebLocalFrame* web_frame) |
| 19 : web_frame_(web_frame) {} |
| 20 |
| 21 WebFrameImpl::~WebFrameImpl() {} |
| 22 |
| 23 WebDocument WebFrameImpl::document() { |
| 24 return WebDocument(web_frame_->document()); |
| 25 } |
| 26 |
| 27 namespace { |
| 28 |
| 29 blink::WebScriptSource StringToWebScript(const std::string& code) { |
| 30 return blink::WebScriptSource( |
| 31 blink::WebString::fromUTF8(code.c_str(), code.size())); |
| 32 } |
| 33 |
| 34 } |
| 35 |
| 36 class WebFrameImpl::JavaScriptExecutionCallback : |
| 37 public blink::WebScriptExecutionCallback |
| 38 { |
| 39 public: |
| 40 JavaScriptExecutionCallback( |
| 41 WebFrameImpl* web_frame, |
| 42 const WebFrame::ScriptExecutionCallback callback) |
| 43 : web_frame_(web_frame) |
| 44 , callback_(callback) {} |
| 45 ~JavaScriptExecutionCallback() override {}; |
| 46 |
| 47 void completed(const blink::WebVector<v8::Local<v8::Value>>& values) { |
| 48 std::vector<scoped_ptr<base::Value>> converted_values; |
| 49 for (const auto& value : values) { |
| 50 converted_values.push_back(web_frame_->ConvertV8ValueToBase(value)); |
| 51 } |
| 52 callback_.Run(converted_values); |
| 53 } |
| 54 private: |
| 55 WebFrameImpl* web_frame_; |
| 56 ScriptExecutionCallback callback_; |
| 57 }; |
| 58 |
| 59 namespace { |
| 60 |
| 61 std::string ConvertV8StringToStd(v8::Local<v8::String> string) |
| 62 { |
| 63 std::vector<char> buffer; |
| 64 buffer.resize(string->Utf8Length()); |
| 65 string->WriteUtf8(buffer.data(), buffer.size()); |
| 66 return std::string(buffer.data(), buffer.size()); |
| 67 } |
| 68 |
| 69 } |
| 70 |
| 71 scoped_ptr<base::Value> WebFrameImpl::ConvertV8ValueToBase( |
| 72 const v8::Local<v8::Value>& value) { |
| 73 v8::Local<v8::Context> context = web_frame_->mainWorldScriptContext(); |
| 74 if (value->IsBoolean()) { |
| 75 v8::Local<v8::Boolean> boolean = value->ToBoolean(context).ToLocalChecked(); |
| 76 return make_scoped_ptr(new base::FundamentalValue(boolean->Value())); |
| 77 } else if (value->IsNumber()) { |
| 78 v8::Local<v8::Number> number = value->ToNumber(context).ToLocalChecked(); |
| 79 return make_scoped_ptr(new base::FundamentalValue(number->Value())); |
| 80 } else if (value->IsString()) { |
| 81 v8::Local<v8::String> string = value->ToString(context).ToLocalChecked(); |
| 82 return make_scoped_ptr(new base::StringValue(ConvertV8StringToStd(string))); |
| 83 } else if (value->IsArray()) { |
| 84 v8::Local<v8::Object> array = value->ToObject(context).ToLocalChecked(); |
| 85 scoped_ptr<base::ListValue> list = make_scoped_ptr( |
| 86 new base::ListValue()); |
| 87 size_t index = 0; |
| 88 |
| 89 // TODO(altimin): Handle exceptions properly. |
| 90 while (array->Has(context, index).FromJust()) { |
| 91 list->Append(ConvertV8ValueToBase(array->Get(context, index).ToLocalChecke
d())); |
| 92 ++index; |
| 93 } |
| 94 return scoped_ptr<base::Value>(std::move(list)); |
| 95 } else if (value->IsObject()) { |
| 96 v8::Local<v8::Object> object = value->ToObject(context).ToLocalChecked(); |
| 97 v8::Local<v8::Array> property_names = |
| 98 object->GetPropertyNames(context).ToLocalChecked();; |
| 99 scoped_ptr<base::DictionaryValue> dictionary = make_scoped_ptr( |
| 100 new base::DictionaryValue()); |
| 101 |
| 102 for (size_t i = 0; i < property_names->Length(); ++i) { |
| 103 v8::Local<v8::Value> property_name = |
| 104 property_names->Get(context, i).ToLocalChecked(); |
| 105 if (!property_name->IsString()) { |
| 106 continue; |
| 107 } |
| 108 v8::Local<v8::String> property_name_as_string = |
| 109 property_name->ToString(context).ToLocalChecked(); |
| 110 dictionary->Set(ConvertV8StringToStd(property_name_as_string), |
| 111 ConvertV8ValueToBase(object->Get(property_name))); |
| 112 } |
| 113 |
| 114 return scoped_ptr<base::Value>(std::move(dictionary)); |
| 115 } |
| 116 return nullptr; |
| 117 } |
| 118 |
| 119 |
| 120 void WebFrameImpl::ExecuteScript( |
| 121 const std::string& source_code) { |
| 122 web_frame_->executeScript(StringToWebScript(source_code)); |
| 123 } |
| 124 |
| 125 void WebFrameImpl::ExecuteScriptAndReturnValue( |
| 126 const std::string& source_code, |
| 127 const ScriptExecutionCallback& callback) { |
| 128 web_frame_->requestExecuteScriptAndReturnValue( |
| 129 StringToWebScript(source_code), |
| 130 /* user_gesture */ false, |
| 131 new JavaScriptExecutionCallback(this, callback)); |
| 132 } |
| 133 |
| 134 } // namespace headless |
OLD | NEW |