1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
|
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/renderer/dom_automation_controller.h"
#include "base/json/json_string_value_serializer.h"
#include "base/strings/string_util.h"
#include "content/public/renderer/render_frame.h"
#include "content/renderer/v8_value_converter_impl.h"
#include "gin/handle.h"
#include "gin/object_template_builder.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "third_party/blink/public/platform/scheduler/web_agent_group_scheduler.h"
#include "third_party/blink/public/web/web_local_frame.h"
#include "v8/include/v8-context.h"
namespace content {
gin::WrapperInfo DomAutomationController::kWrapperInfo = {
gin::kEmbedderNativeGin};
// static
void DomAutomationController::Install(RenderFrame* render_frame,
blink::WebLocalFrame* frame) {
v8::Isolate* isolate =
render_frame->GetWebFrame()->GetAgentGroupScheduler()->Isolate();
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = frame->MainWorldScriptContext();
if (context.IsEmpty())
return;
v8::Context::Scope context_scope(context);
gin::Handle<DomAutomationController> controller =
gin::CreateHandle(isolate, new DomAutomationController(render_frame));
if (controller.IsEmpty())
return;
v8::Local<v8::Object> global = context->Global();
global
->Set(context, gin::StringToV8(isolate, "domAutomationController"),
controller.ToV8())
.Check();
}
DomAutomationController::DomAutomationController(RenderFrame* render_frame)
: RenderFrameObserver(render_frame) {}
DomAutomationController::~DomAutomationController() {}
gin::ObjectTemplateBuilder DomAutomationController::GetObjectTemplateBuilder(
v8::Isolate* isolate) {
return gin::Wrappable<DomAutomationController>::GetObjectTemplateBuilder(
isolate)
.SetMethod("send", &DomAutomationController::SendMsg);
}
void DomAutomationController::OnDestruct() {}
void DomAutomationController::DidCreateScriptContext(
v8::Local<v8::Context> context,
int32_t world_id) {
// Add the domAutomationController to isolated worlds as well.
v8::Isolate* isolate =
render_frame()->GetWebFrame()->GetAgentGroupScheduler()->Isolate();
v8::HandleScope handle_scope(isolate);
if (context.IsEmpty())
return;
v8::Context::Scope context_scope(context);
// Resuse this object instead of creating others.
gin::Handle<DomAutomationController> controller =
gin::CreateHandle(isolate, this);
if (controller.IsEmpty())
return;
v8::Local<v8::Object> global = context->Global();
global
->Set(context, gin::StringToV8(isolate, "domAutomationController"),
controller.ToV8())
.Check();
}
bool DomAutomationController::SendMsg(const gin::Arguments& args) {
if (!render_frame())
return false;
std::string json;
JSONStringValueSerializer serializer(&json);
std::unique_ptr<base::Value> value;
// Warning: note that JSON officially requires the root-level object to be
// an object (e.g. {foo:3}) or an array, while here we're serializing
// strings, bools, etc. to "JSON". This only works because (a) the JSON
// writer is lenient, and (b) on the receiving side we wrap the JSON string
// in square brackets, converting it to an array, then parsing it and
// grabbing the 0th element to get the value out.
if (!args.PeekNext().IsEmpty()) {
V8ValueConverterImpl conv;
value =
conv.FromV8Value(args.PeekNext(), args.isolate()->GetCurrentContext());
} else {
NOTREACHED() << "No arguments passed to domAutomationController.send";
}
if (!value || !serializer.Serialize(*value))
return false;
GetDomAutomationControllerHost()->DomOperationResponse(json);
return true;
}
const mojo::AssociatedRemote<mojom::DomAutomationControllerHost>&
DomAutomationController::GetDomAutomationControllerHost() {
if (!dom_automation_controller_host_) {
render_frame()->GetRemoteAssociatedInterfaces()->GetInterface(
&dom_automation_controller_host_);
}
return dom_automation_controller_host_;
}
} // namespace content
|