| OLD | NEW |
| 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/extension_process_bindings.h" | 5 #include "chrome/renderer/extensions/extension_process_bindings.h" |
| 6 | 6 |
| 7 #include "chrome/common/render_messages.h" | 7 #include "chrome/common/render_messages.h" |
| 8 #include "chrome/common/resource_bundle.h" | 8 #include "chrome/common/resource_bundle.h" |
| 9 #include "chrome/renderer/render_view.h" | 9 #include "chrome/renderer/render_view.h" |
| 10 #include "grit/renderer_resources.h" | 10 #include "grit/renderer_resources.h" |
| 11 #include "webkit/glue/webframe.h" | 11 #include "webkit/glue/webframe.h" |
| 12 | 12 |
| 13 namespace extensions_v8 { | 13 namespace extensions_v8 { |
| 14 | 14 |
| 15 const char kExtensionProcessExtensionName[] = "v8/ExtensionProcess"; | 15 const char kExtensionProcessExtensionName[] = "v8/ExtensionProcess"; |
| 16 | 16 |
| 17 class ExtensionProcessBindingsWrapper : public v8::Extension { | 17 class ExtensionProcessBindingsWrapper : public v8::Extension { |
| 18 public: | 18 public: |
| 19 ExtensionProcessBindingsWrapper() | 19 ExtensionProcessBindingsWrapper() |
| 20 : v8::Extension(kExtensionProcessExtensionName, GetSource()) {} | 20 : v8::Extension(kExtensionProcessExtensionName, GetSource()) {} |
| 21 | 21 |
| 22 static void SetFunctionNames(const std::vector<std::string>& names) { |
| 23 function_names_ = new std::set<std::string>(); |
| 24 for (size_t i = 0; i < names.size(); ++i) { |
| 25 function_names_->insert(names[i]); |
| 26 } |
| 27 } |
| 28 |
| 22 virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction( | 29 virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction( |
| 23 v8::Handle<v8::String> name) { | 30 v8::Handle<v8::String> name) { |
| 24 if (name->Equals(v8::String::New("GetNextCallbackId"))) | 31 if (name->Equals(v8::String::New("GetNextCallbackId"))) |
| 25 return v8::FunctionTemplate::New(GetNextCallbackId); | 32 return v8::FunctionTemplate::New(GetNextCallbackId); |
| 26 else if (name->Equals(v8::String::New("CreateTab"))) | 33 else if (function_names_->find(*v8::String::AsciiValue(name)) != |
| 34 function_names_->end()) |
| 27 return v8::FunctionTemplate::New(StartRequest, name); | 35 return v8::FunctionTemplate::New(StartRequest, name); |
| 28 | 36 |
| 29 return v8::Handle<v8::FunctionTemplate>(); | 37 return v8::Handle<v8::FunctionTemplate>(); |
| 30 } | 38 } |
| 31 | 39 |
| 32 private: | 40 private: |
| 33 static const char* GetSource() { | 41 static const char* GetSource() { |
| 34 // This is weird. The v8::Extension constructor expects a null-terminated | 42 // This is weird. The v8::Extension constructor expects a null-terminated |
| 35 // string which it doesn't own (all current uses are constant). The value | 43 // string which it doesn't own (all current uses are constant). The value |
| 36 // returned by GetDataResource is *not* null-terminated, and simply | 44 // returned by GetDataResource is *not* null-terminated, and simply |
| 37 // converting it to a string, then using that string's c_str() in this | 45 // converting it to a string, then using that string's c_str() in this |
| 38 // class's constructor doesn't work because the resulting string is stack- | 46 // class's constructor doesn't work because the resulting string is stack- |
| 39 // allocated. | 47 // allocated. |
| 40 if (!source_) | 48 if (!source_) |
| 41 source_ = new std::string( | 49 source_ = new std::string( |
| 42 ResourceBundle::GetSharedInstance().GetRawDataResource( | 50 ResourceBundle::GetSharedInstance().GetRawDataResource( |
| 43 IDR_EXTENSION_PROCESS_BINDINGS_JS).as_string()); | 51 IDR_EXTENSION_PROCESS_BINDINGS_JS).as_string()); |
| 44 | 52 |
| 45 return source_->c_str(); | 53 return source_->c_str(); |
| 46 } | 54 } |
| 47 | 55 |
| 48 static v8::Handle<v8::Value> GetNextCallbackId(const v8::Arguments& args) { | 56 static v8::Handle<v8::Value> GetNextCallbackId(const v8::Arguments& args) { |
| 49 static int next_callback_id = 0; | 57 static int next_callback_id = 0; |
| 50 return v8::Integer::New(next_callback_id++); | 58 return v8::Integer::New(next_callback_id++); |
| 51 } | 59 } |
| 52 | 60 |
| 53 static v8::Handle<v8::Value> StartRequest(const v8::Arguments& args) { | 61 static v8::Handle<v8::Value> StartRequest(const v8::Arguments& args) { |
| 54 WebFrame* webframe = WebFrame::RetrieveActiveFrame(); | 62 WebFrame* webframe = WebFrame::RetrieveActiveFrame(); |
| 55 DCHECK(webframe) << "There should be an active frame since we just got " | 63 DCHECK(webframe) << "There should be an active frame since we just got " |
| 56 "an API called."; | 64 "a native function called."; |
| 57 if (!webframe) return v8::Undefined(); | 65 if (!webframe) return v8::Undefined(); |
| 58 | 66 |
| 59 WebView* webview = webframe->GetView(); | 67 WebView* webview = webframe->GetView(); |
| 60 if (!webview) return v8::Undefined(); // can happen during closing | 68 if (!webview) return v8::Undefined(); // can happen during closing |
| 61 | 69 |
| 62 RenderView* renderview = static_cast<RenderView*>(webview->GetDelegate()); | 70 RenderView* renderview = static_cast<RenderView*>(webview->GetDelegate()); |
| 63 DCHECK(renderview) << "Encountered a WebView without a WebViewDelegate"; | 71 DCHECK(renderview) << "Encountered a WebView without a WebViewDelegate"; |
| 64 if (!renderview) return v8::Undefined(); | 72 if (!renderview) return v8::Undefined(); |
| 65 | 73 |
| 66 if (args.Length() != 2 || !args[0]->IsString() || !args[1]->IsInt32()) | 74 if (args.Length() != 2 || !args[0]->IsString() || !args[1]->IsInt32()) |
| 67 return v8::Undefined(); | 75 return v8::Undefined(); |
| 68 | 76 |
| 69 int callback_id = args[1]->Int32Value(); | 77 int callback_id = args[1]->Int32Value(); |
| 70 renderview->SendExtensionRequest( | 78 renderview->SendExtensionRequest( |
| 71 std::string(*v8::String::AsciiValue(args.Data())), | 79 std::string(*v8::String::AsciiValue(args.Data())), |
| 72 std::string(*v8::String::Utf8Value(args[0])), | 80 std::string(*v8::String::Utf8Value(args[0])), |
| 73 callback_id, webframe); | 81 callback_id, webframe); |
| 74 | 82 |
| 75 return v8::Undefined(); | 83 return v8::Undefined(); |
| 76 } | 84 } |
| 77 | 85 |
| 78 static std::string* source_; | 86 static std::string* source_; |
| 87 static std::set<std::string>* function_names_; |
| 79 }; | 88 }; |
| 80 | 89 |
| 81 std::string* ExtensionProcessBindingsWrapper::source_; | 90 std::string* ExtensionProcessBindingsWrapper::source_; |
| 91 std::set<std::string>* ExtensionProcessBindingsWrapper::function_names_; |
| 82 | 92 |
| 83 | 93 |
| 84 // static | 94 // static |
| 85 v8::Extension* ExtensionProcessBindings::Get() { | 95 v8::Extension* ExtensionProcessBindings::Get() { |
| 86 return new ExtensionProcessBindingsWrapper(); | 96 return new ExtensionProcessBindingsWrapper(); |
| 87 } | 97 } |
| 88 | 98 |
| 89 // static | 99 // static |
| 100 void ExtensionProcessBindings::SetFunctionNames( |
| 101 const std::vector<std::string>& names) { |
| 102 ExtensionProcessBindingsWrapper::SetFunctionNames(names); |
| 103 } |
| 104 |
| 105 // static |
| 90 void ExtensionProcessBindings::ExecuteCallbackInFrame( | 106 void ExtensionProcessBindings::ExecuteCallbackInFrame( |
| 91 WebFrame* frame, int callback_id, const std::string& response) { | 107 WebFrame* frame, int callback_id, const std::string& response) { |
| 92 std::string code = "chromium._dispatchCallback("; | 108 std::string code = "chromium._dispatchCallback("; |
| 93 code += IntToString(callback_id); | 109 code += IntToString(callback_id); |
| 94 code += ", '"; | 110 code += ", '"; |
| 95 | 111 |
| 96 size_t offset = code.length(); | 112 size_t offset = code.length(); |
| 97 code += response; | 113 code += response; |
| 98 ReplaceSubstringsAfterOffset(&code, offset, "\\", "\\\\"); | 114 ReplaceSubstringsAfterOffset(&code, offset, "\\", "\\\\"); |
| 99 ReplaceSubstringsAfterOffset(&code, offset, "'", "\\'"); | 115 ReplaceSubstringsAfterOffset(&code, offset, "'", "\\'"); |
| 100 code += "')"; | 116 code += "')"; |
| 101 | 117 |
| 102 frame->ExecuteScript(webkit_glue::WebScriptSource(code)); | 118 frame->ExecuteScript(webkit_glue::WebScriptSource(code)); |
| 103 } | 119 } |
| 104 | 120 |
| 105 } // namespace extensions_v8 | 121 } // namespace extensions_v8 |
| OLD | NEW |