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/renderer/extensions/dispatcher.h" 8 #include "content/public/renderer/render_view.h" 9 #include "content/public/renderer/render_view_observer.h" 10 #include "extensions/common/extension_api.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(blink::WebFrame* frame) OVERRIDE { 30 CallbackAndDie(true); 31 } 32 33 virtual void DidFailProvisionalLoad( 34 blink::WebFrame* frame, 35 const blink::WebURLError& error) OVERRIDE { 36 CallbackAndDie(false); 37 } 38 39 private: 40 void CallbackAndDie(bool succeeded) { 41 v8::Isolate* isolate = context_->isolate(); 42 v8::HandleScope handle_scope(isolate); 43 v8::Handle<v8::Value> args[] = { v8::Boolean::New(isolate, succeeded) }; 44 context_->CallFunction(callback_.NewHandle(isolate), 1, args); 45 delete this; 46 } 47 48 ChromeV8Context* context_; 49 ScopedPersistent<v8::Function> callback_; 50 DISALLOW_COPY_AND_ASSIGN(LoadWatcher); 51 }; 52 } // namespace 53 54 55 RenderViewObserverNatives::RenderViewObserverNatives(Dispatcher* dispatcher, 56 ChromeV8Context* context) 57 : ChromeV8Extension(dispatcher, context) { 58 RouteFunction("OnDocumentElementCreated", 59 base::Bind(&RenderViewObserverNatives::OnDocumentElementCreated, 60 base::Unretained(this))); 61 } 62 63 void RenderViewObserverNatives::OnDocumentElementCreated( 64 const v8::FunctionCallbackInfo<v8::Value>& args) { 65 CHECK(args.Length() == 2); 66 CHECK(args[0]->IsInt32()); 67 CHECK(args[1]->IsFunction()); 68 69 int view_id = args[0]->Int32Value(); 70 71 content::RenderView* view = content::RenderView::FromRoutingID(view_id); 72 if (!view) { 73 LOG(WARNING) << "No render view found to register LoadWatcher."; 74 return; 75 } 76 77 new LoadWatcher(context(), view, args[1].As<v8::Function>()); 78 79 args.GetReturnValue().Set(true); 80 } 81 82 } // namespace extensions 83