Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(9)

Side by Side Diff: chrome/renderer/extensions/bindings_utils.cc

Issue 147033: Refactor extension bindings to share code, avoid exposing hidden variables (Closed)
Patch Set: at head Created 11 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/renderer/extensions/bindings_utils.h" 5 #include "chrome/renderer/extensions/bindings_utils.h"
6 6
7 #include "base/string_util.h" 7 #include "base/string_util.h"
8 #include "chrome/renderer/render_view.h" 8 #include "chrome/renderer/render_view.h"
9 #include "webkit/glue/webframe.h" 9 #include "webkit/glue/webframe.h"
10 10
11 namespace bindings_utils {
12
13 const char* kChromeHidden = "chromeHidden";
14
15 struct SingletonData {
16 ContextList contexts;
17 PendingRequestMap pending_requests;
18 };
19
20 // ExtensionBase
21
22 v8::Handle<v8::FunctionTemplate>
23 ExtensionBase::GetNativeFunction(v8::Handle<v8::String> name) {
24 if (name->Equals(v8::String::New("GetChromeHidden"))) {
25 return v8::FunctionTemplate::New(GetChromeHidden);
26 }
27
28 return v8::Handle<v8::FunctionTemplate>();
29 }
30
31 v8::Handle<v8::Value> ExtensionBase::GetChromeHidden(
32 const v8::Arguments& args) {
33 v8::Local<v8::Context> context = v8::Context::GetCurrent();
34 v8::Local<v8::Object> global = context->Global();
35 v8::Local<v8::Value> hidden = global->GetHiddenValue(
36 v8::String::New(kChromeHidden));
37
38 if (hidden.IsEmpty() || hidden->IsUndefined()) {
39 hidden = v8::Object::New();
40 global->SetHiddenValue(v8::String::New(kChromeHidden), hidden);
41 }
42
43 DCHECK(hidden->IsObject());
44 return hidden;
45 }
46
47 v8::Handle<v8::Value> ExtensionBase::StartRequest(
48 const v8::Arguments& args) {
49 // Get the current RenderView so that we can send a routed IPC message from
50 // the correct source.
51 RenderView* renderview = bindings_utils::GetRenderViewForCurrentContext();
52 if (!renderview)
53 return v8::Undefined();
54
55 if (args.Length() != 3 || !args[0]->IsString() || !args[1]->IsInt32() ||
56 !args[2]->IsBoolean())
57 return v8::Undefined();
58
59 std::string name = *v8::String::AsciiValue(args.Data());
60 std::string json_args = *v8::String::Utf8Value(args[0]);
61 int request_id = args[1]->Int32Value();
62 bool has_callback = args[2]->BooleanValue();
63
64 v8::Persistent<v8::Context> current_context =
65 v8::Persistent<v8::Context>::New(v8::Context::GetCurrent());
66 DCHECK(!current_context.IsEmpty());
67 GetPendingRequestMap()[request_id].reset(new PendingRequest(
68 current_context, *v8::String::AsciiValue(args.Data())));
69
70 renderview->SendExtensionRequest(name, json_args, request_id, has_callback);
71
72 return v8::Undefined();
73 }
74
75 ContextList& GetContexts() {
76 return Singleton<SingletonData>::get()->contexts;
77 }
78
79 ContextList GetContextsForExtension(const std::string& extension_id) {
80 ContextList& all_contexts = GetContexts();
81 ContextList contexts;
82
83 for (ContextList::iterator it = all_contexts.begin();
84 it != all_contexts.end(); ++it) {
85 if ((*it)->extension_id == extension_id)
86 contexts.push_back(*it);
87 }
88
89 return contexts;
90 }
91
92 ContextList::iterator FindContext(v8::Handle<v8::Context> context) {
93 ContextList& all_contexts = GetContexts();
94
95 ContextList::iterator it = all_contexts.begin();
96 for (; it != all_contexts.end(); ++it) {
97 if ((*it)->context == context)
98 break;
99 }
100
101 return it;
102 }
103
104 PendingRequestMap& GetPendingRequestMap() {
105 return Singleton<SingletonData>::get()->pending_requests;
106 }
107
11 RenderView* GetRenderViewForCurrentContext() { 108 RenderView* GetRenderViewForCurrentContext() {
12 WebFrame* webframe = WebFrame::RetrieveFrameForCurrentContext(); 109 WebFrame* webframe = WebFrame::RetrieveFrameForCurrentContext();
13 DCHECK(webframe) << "RetrieveCurrentFrame called when not in a V8 context."; 110 DCHECK(webframe) << "RetrieveCurrentFrame called when not in a V8 context.";
14 if (!webframe) 111 if (!webframe)
15 return NULL; 112 return NULL;
16 113
17 WebView* webview = webframe->GetView(); 114 WebView* webview = webframe->GetView();
18 if (!webview) 115 if (!webview)
19 return NULL; // can happen during closing 116 return NULL; // can happen during closing
20 117
21 RenderView* renderview = static_cast<RenderView*>(webview->GetDelegate()); 118 RenderView* renderview = static_cast<RenderView*>(webview->GetDelegate());
22 DCHECK(renderview) << "Encountered a WebView without a WebViewDelegate"; 119 DCHECK(renderview) << "Encountered a WebView without a WebViewDelegate";
23 return renderview; 120 return renderview;
24 } 121 }
25 122
26 void CallFunctionInContext(v8::Handle<v8::Context> context, 123 void CallFunctionInContext(v8::Handle<v8::Context> context,
27 const std::string& function_name, int argc, 124 const std::string& function_name, int argc,
28 v8::Handle<v8::Value>* argv) { 125 v8::Handle<v8::Value>* argv) {
29 v8::Context::Scope context_scope(context); 126 v8::Context::Scope context_scope(context);
30 127
31 // Look up the function name, which may be a sub-property like 128 // Look up the function name, which may be a sub-property like
32 // "chrome.handleResponse_" in the global variable. 129 // "Port.dispatchOnMessage" in the hidden global variable.
33 v8::Local<v8::Value> value = context->Global(); 130 v8::Local<v8::Value> value =
131 context->Global()->GetHiddenValue(v8::String::New(kChromeHidden));
34 std::vector<std::string> components; 132 std::vector<std::string> components;
35 SplitStringDontTrim(function_name, '.', &components); 133 SplitStringDontTrim(function_name, '.', &components);
36 for (size_t i = 0; i < components.size(); ++i) { 134 for (size_t i = 0; i < components.size(); ++i) {
37 if (value->IsObject()) 135 if (!value.IsEmpty() && value->IsObject())
38 value = value->ToObject()->Get(v8::String::New(components[i].c_str())); 136 value = value->ToObject()->Get(v8::String::New(components[i].c_str()));
39 } 137 }
40 if (!value->IsFunction()) 138 if (value.IsEmpty() || !value->IsFunction()) {
139 NOTREACHED();
41 return; 140 return;
141 }
42 142
43 v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast(value); 143 v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast(value);
44 if (!function.IsEmpty()) 144 if (!function.IsEmpty())
45 function->Call(v8::Object::New(), argc, argv); 145 function->Call(v8::Object::New(), argc, argv);
46 } 146 }
147
148 } // namespace bindings_utils
OLDNEW
« no previous file with comments | « chrome/renderer/extensions/bindings_utils.h ('k') | chrome/renderer/extensions/event_bindings.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698