1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "chrome/renderer/extensions/render_view_observer_natives.h" 6 7 #include "chrome/common/extensions/api/extension_api.h" 8 #include "chrome/renderer/extensions/dispatcher.h" 9 #include "content/public/renderer/render_view.h" 10 #include "content/public/renderer/render_view_observer.h" 11 #include "third_party/WebKit/public/web/WebFrame.h" 12 #include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h" 13 14 namespace extensions { 15 16 namespace { 17 18 // Deletes itself when done. 19 class LoadWatcher : public content::RenderViewObserver { 20 public: 21 LoadWatcher(ChromeV8Context* context, 22 content::RenderView* view, 23 v8::Handle<v8::Function> cb) 24 : content::RenderViewObserver(view), 25 context_(context), 26 callback_(cb) { 27 } 28 29 virtual void DidCreateDocumentElement(WebKit::WebFrame* frame) OVERRIDE { 30 CallbackAndDie(true); 31 } 32 33 virtual void DidFailProvisionalLoad( 34 WebKit::WebFrame* frame, 35 const WebKit::WebURLError& error) OVERRIDE { 36 CallbackAndDie(false); 37 } 38 39 private: 40 void CallbackAndDie(bool succeeded) { 41 v8::HandleScope handle_scope; 42 v8::Handle<v8::Value> args[] = { v8::Boolean::New(succeeded) }; 43 context_->CallFunction(callback_.get(), 1, args); 44 delete this; 45 } 46 47 ChromeV8Context* context_; 48 ScopedPersistent<v8::Function> callback_; 49 DISALLOW_COPY_AND_ASSIGN(LoadWatcher); 50 }; 51 } // namespace 52 53 54 RenderViewObserverNatives::RenderViewObserverNatives(Dispatcher* dispatcher, 55 ChromeV8Context* context) 56 : ChromeV8Extension(dispatcher, context) { 57 RouteFunction("OnDocumentElementCreated", 58 base::Bind(&RenderViewObserverNatives::OnDocumentElementCreated, 59 base::Unretained(this))); 60 } 61 62 void RenderViewObserverNatives::OnDocumentElementCreated( 63 const v8::FunctionCallbackInfo<v8::Value>& args) { 64 CHECK(args.Length() == 2); 65 CHECK(args[0]->IsInt32()); 66 CHECK(args[1]->IsFunction()); 67 68 int view_id = args[0]->Int32Value(); 69 70 content::RenderView* view = content::RenderView::FromRoutingID(view_id); 71 if (!view) { 72 LOG(WARNING) << "No render view found to register LoadWatcher."; 73 return; 74 } 75 76 new LoadWatcher(context(), view, args[1].As<v8::Function>()); 77 78 args.GetReturnValue().Set(true); 79 } 80 81 } // namespace extensions 82