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 125 126 127 128 129 130 131 132 133 134 135 136
|
// Copyright 2012 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 "content/renderer/web_ui_extension.h"
#include "base/memory/scoped_ptr.h"
#include "base/values.h"
#include "content/common/view_messages.h"
#include "content/public/common/bindings_policy.h"
#include "content/public/common/url_constants.h"
#include "content/public/renderer/render_thread.h"
#include "content/public/renderer/render_view.h"
#include "content/public/renderer/v8_value_converter.h"
#include "content/renderer/chrome_object_extensions_utils.h"
#include "content/renderer/web_ui_extension_data.h"
#include "gin/arguments.h"
#include "gin/function_template.h"
#include "third_party/WebKit/public/web/WebDocument.h"
#include "third_party/WebKit/public/web/WebKit.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h"
#include "third_party/WebKit/public/web/WebView.h"
#include "url/gurl.h"
#include "v8/include/v8.h"
namespace content {
namespace {
bool ShouldRespondToRequest(
blink::WebFrame** frame_ptr,
RenderView** render_view_ptr) {
blink::WebFrame* frame = blink::WebLocalFrame::frameForCurrentContext();
if (!frame || !frame->view())
return false;
RenderView* render_view = RenderView::FromWebView(frame->view());
if (!render_view)
return false;
GURL frame_url = frame->document().url();
bool webui_enabled =
(render_view->GetEnabledBindings() & BINDINGS_POLICY_WEB_UI) &&
(frame_url.SchemeIs(kChromeUIScheme) ||
frame_url.SchemeIs(url::kDataScheme));
if (!webui_enabled)
return false;
*frame_ptr = frame;
*render_view_ptr = render_view;
return true;
}
} // namespace
// Exposes two methods:
// - chrome.send: Used to send messages to the browser. Requires the message
// name as the first argument and can have an optional second argument that
// should be an array.
// - chrome.getVariableValue: Returns value for the input variable name if such
// a value was set by the browser. Else will return an empty string.
void WebUIExtension::Install(blink::WebFrame* frame) {
v8::Isolate* isolate = blink::mainThreadIsolate();
v8::HandleScope handle_scope(isolate);
v8::Handle<v8::Context> context = frame->mainWorldScriptContext();
if (context.IsEmpty())
return;
v8::Context::Scope context_scope(context);
v8::Handle<v8::Object> chrome = GetOrCreateChromeObject(isolate,
context->Global());
chrome->Set(gin::StringToSymbol(isolate, "send"),
gin::CreateFunctionTemplate(
isolate, base::Bind(&WebUIExtension::Send))->GetFunction());
chrome->Set(gin::StringToSymbol(isolate, "getVariableValue"),
gin::CreateFunctionTemplate(
isolate, base::Bind(&WebUIExtension::GetVariableValue))
->GetFunction());
}
// static
void WebUIExtension::Send(gin::Arguments* args) {
blink::WebFrame* frame;
RenderView* render_view;
if (!ShouldRespondToRequest(&frame, &render_view))
return;
std::string message;
if (!args->GetNext(&message)) {
args->ThrowError();
return;
}
// If they've provided an optional message parameter, convert that into a
// Value to send to the browser process.
scoped_ptr<base::ListValue> content;
if (args->PeekNext().IsEmpty() || args->PeekNext()->IsUndefined()) {
content.reset(new base::ListValue());
} else {
v8::Handle<v8::Object> obj;
if (!args->GetNext(&obj)) {
args->ThrowError();
return;
}
scoped_ptr<V8ValueConverter> converter(V8ValueConverter::create());
base::Value* value =
converter->FromV8Value(obj, frame->mainWorldScriptContext());
base::ListValue* list = NULL;
value->GetAsList(&list);
DCHECK(list);
content.reset(list);
}
// Send the message up to the browser.
render_view->Send(new ViewHostMsg_WebUISend(render_view->GetRoutingID(),
frame->document().url(),
message,
*content));
}
// static
std::string WebUIExtension::GetVariableValue(const std::string& name) {
blink::WebFrame* frame;
RenderView* render_view;
if (!ShouldRespondToRequest(&frame, &render_view))
return std::string();
return WebUIExtensionData::Get(render_view)->GetValue(name);
}
} // namespace content
|