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