| Index: components/plugins/renderer/plugin_placeholder.cc
|
| diff --git a/components/plugins/renderer/plugin_placeholder.cc b/components/plugins/renderer/plugin_placeholder.cc
|
| index aa82135446bb68a8b2c8b0a2faf53188aa3249aa..d82117e419b3d1b26028b40de9ba48ee675255bc 100644
|
| --- a/components/plugins/renderer/plugin_placeholder.cc
|
| +++ b/components/plugins/renderer/plugin_placeholder.cc
|
| @@ -34,11 +34,52 @@ using blink::WebPluginContainer;
|
| using blink::WebPluginParams;
|
| using blink::WebScriptSource;
|
| using blink::WebURLRequest;
|
| -using webkit_glue::CppArgumentList;
|
| -using webkit_glue::CppVariant;
|
|
|
| namespace plugins {
|
|
|
| +namespace {
|
| +
|
| +// This class is supposed to be stored in an v8::External. It holds a
|
| +// base::Closure and will delete itself as soon as the v8::External is garbage
|
| +// collected.
|
| +class V8ClosureWrapper {
|
| + public:
|
| + explicit V8ClosureWrapper(const base::Closure& closure) : closure_(closure) {}
|
| +
|
| + void SetExternal(v8::Isolate* isolate, v8::Handle<v8::External> external) {
|
| + DCHECK(external_.IsEmpty());
|
| + external_.Reset(isolate, external);
|
| + external_.SetWeak(this, &V8ClosureWrapper::WeakCallback);
|
| + }
|
| +
|
| + void Run() {
|
| + closure_.Run();
|
| + }
|
| +
|
| + private:
|
| + static void WeakCallback(
|
| + const v8::WeakCallbackData<v8::External, V8ClosureWrapper>& data) {
|
| + V8ClosureWrapper* info = data.GetParameter();
|
| + info->external_.Reset();
|
| + delete info;
|
| + }
|
| +
|
| + ~V8ClosureWrapper() {}
|
| +
|
| + base::Closure closure_;
|
| + v8::Persistent<v8::External> external_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(V8ClosureWrapper);
|
| +};
|
| +
|
| +void RunV8ClosureWrapper(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| + V8ClosureWrapper* wrapper = reinterpret_cast<V8ClosureWrapper*>(
|
| + v8::External::Cast(*args.Data())->Value());
|
| + wrapper->Run();
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| PluginPlaceholder::PluginPlaceholder(content::RenderView* render_view,
|
| WebFrame* frame,
|
| const WebPluginParams& params,
|
| @@ -54,21 +95,56 @@ PluginPlaceholder::PluginPlaceholder(content::RenderView* render_view,
|
| is_blocked_for_prerendering_(false),
|
| allow_loading_(false),
|
| hidden_(false),
|
| - finished_loading_(false) {}
|
| + finished_loading_(false),
|
| + weak_factory_(this) {
|
| + RegisterCallback(
|
| + "load",
|
| + base::Bind(&PluginPlaceholder::LoadCallback, weak_factory_.GetWeakPtr()));
|
| + RegisterCallback(
|
| + "hide",
|
| + base::Bind(&PluginPlaceholder::HideCallback, weak_factory_.GetWeakPtr()));
|
| + RegisterCallback("didFinishLoading",
|
| + base::Bind(&PluginPlaceholder::DidFinishLoadingCallback,
|
| + weak_factory_.GetWeakPtr()));
|
| +}
|
|
|
| PluginPlaceholder::~PluginPlaceholder() {}
|
|
|
| +void PluginPlaceholder::RegisterCallback(const std::string& callback_name,
|
| + const base::Closure& callback) {
|
| + DCHECK(callbacks_.find(callback_name) == callbacks_.end());
|
| + callbacks_[callback_name] = callback;
|
| +}
|
| +
|
| void PluginPlaceholder::BindWebFrame(WebFrame* frame) {
|
| - BindToJavascript(frame, "plugin");
|
| - BindCallback(
|
| - "load",
|
| - base::Bind(&PluginPlaceholder::LoadCallback, base::Unretained(this)));
|
| - BindCallback(
|
| - "hide",
|
| - base::Bind(&PluginPlaceholder::HideCallback, base::Unretained(this)));
|
| - BindCallback("didFinishLoading",
|
| - base::Bind(&PluginPlaceholder::DidFinishLoadingCallback,
|
| - base::Unretained(this)));
|
| + v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
| + 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::FunctionTemplate> plugin_template =
|
| + v8::FunctionTemplate::New();
|
| + v8::Handle<v8::Template> prototype = plugin_template->PrototypeTemplate();
|
| +
|
| + for (std::map<std::string, base::Closure>::const_iterator callback =
|
| + callbacks_.begin();
|
| + callback != callbacks_.end();
|
| + ++callback) {
|
| + V8ClosureWrapper* wrapper = new V8ClosureWrapper(callback->second);
|
| + v8::Handle<v8::External> wrapper_holder = v8::External::New(wrapper);
|
| + wrapper->SetExternal(isolate, wrapper_holder);
|
| + prototype->Set(
|
| + v8::String::New(callback->first.c_str()),
|
| + v8::FunctionTemplate::New(RunV8ClosureWrapper, wrapper_holder));
|
| + }
|
| +
|
| + v8::Handle<v8::Object> global = context->Global();
|
| + global->Set(v8::String::New("plugin"),
|
| + plugin_template->GetFunction()->NewInstance());
|
| }
|
|
|
| void PluginPlaceholder::ReplacePlugin(WebPlugin* new_plugin) {
|
| @@ -206,20 +282,17 @@ void PluginPlaceholder::LoadPlugin() {
|
| ReplacePlugin(plugin);
|
| }
|
|
|
| -void PluginPlaceholder::LoadCallback(const CppArgumentList& args,
|
| - CppVariant* result) {
|
| +void PluginPlaceholder::LoadCallback() {
|
| RenderThread::Get()->RecordUserMetrics("Plugin_Load_Click");
|
| LoadPlugin();
|
| }
|
|
|
| -void PluginPlaceholder::HideCallback(const CppArgumentList& args,
|
| - CppVariant* result) {
|
| +void PluginPlaceholder::HideCallback() {
|
| RenderThread::Get()->RecordUserMetrics("Plugin_Hide_Click");
|
| HidePlugin();
|
| }
|
|
|
| -void PluginPlaceholder::DidFinishLoadingCallback(const CppArgumentList& args,
|
| - CppVariant* result) {
|
| +void PluginPlaceholder::DidFinishLoadingCallback() {
|
| finished_loading_ = true;
|
| if (message_.length() > 0)
|
| UpdateMessage();
|
|
|