Home | History | Annotate | Download | only in extensions
      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