Home | History | Annotate | Download | only in extensions
      1 // Copyright (c) 2012 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 #ifndef CHROME_RENDERER_EXTENSIONS_USER_SCRIPT_SCHEDULER_H_
      6 #define CHROME_RENDERER_EXTENSIONS_USER_SCRIPT_SCHEDULER_H_
      7 
      8 #include <map>
      9 #include <queue>
     10 
     11 #include "base/memory/linked_ptr.h"
     12 #include "base/memory/weak_ptr.h"
     13 #include "extensions/common/user_script.h"
     14 
     15 class RenderView;
     16 struct ExtensionMsg_ExecuteCode_Params;
     17 
     18 namespace WebKit {
     19 class WebFrame;
     20 }
     21 
     22 namespace extensions {
     23 class Dispatcher;
     24 
     25 // Implements support for injecting scripts at different times in the document
     26 // loading process. The different possible time are described in
     27 // UserScript::RunLocation.
     28 //
     29 // Currently, determining idleness is simple: it is whichever of the following
     30 // happens first:
     31 //
     32 // a) When the initial DOM for a page is complete + kUserScriptIdleTimeout,
     33 // b) or when the page has completely loaded including all subresources.
     34 //
     35 // The intent of this mechanism is to prevent user scripts from slowing down
     36 // fast pages (run after load), while still allowing them to run relatively
     37 // timely for pages with lots of slow subresources.
     38 //
     39 // NOTE: this class does not inherit from RenderViewObserver on purpose.  The
     40 // reason is that this object is per frame, and a frame can move across
     41 // RenderViews thanks to adoptNode.  So we have each RenderView's
     42 // ExtensionHelper proxy these calls to the renderer process' Dispatcher,
     43 // which contains the mapping from WebFrame to us.
     44 class UserScriptScheduler {
     45  public:
     46   UserScriptScheduler(WebKit::WebFrame* frame, Dispatcher* dispatcher);
     47   ~UserScriptScheduler();
     48 
     49   void ExecuteCode(const ExtensionMsg_ExecuteCode_Params& params);
     50   void DidCreateDocumentElement();
     51   void DidFinishDocumentLoad();
     52   void DidFinishLoad();
     53   void DidStartProvisionalLoad();
     54 
     55  private:
     56   typedef
     57     std::queue<linked_ptr<ExtensionMsg_ExecuteCode_Params> >
     58     ExecutionQueue;
     59 
     60   // Run user scripts, except if they've already run for this frame, or the
     61   // frame has been destroyed.
     62   void MaybeRun();
     63 
     64   // Backend for the IPC Message ExecuteCode in addition to being used
     65   // internally.
     66   void ExecuteCodeImpl(const ExtensionMsg_ExecuteCode_Params& params);
     67 
     68   // Get all child frames of parent_frame, returned by frames_vector.
     69   bool GetAllChildFrames(WebKit::WebFrame* parent_frame,
     70                          std::vector<WebKit::WebFrame*>* frames_vector) const;
     71 
     72   // Call to signify thet the idle timeout has expired.
     73   void IdleTimeout();
     74 
     75   base::WeakPtrFactory<UserScriptScheduler> weak_factory_;
     76 
     77   // The Frame we will run scripts in.
     78   WebKit::WebFrame* frame_;
     79 
     80   // The current location in the document loading process.
     81   // Will be UserScript::UNDEFINED if it is before any scripts should be run.
     82   UserScript::RunLocation current_location_;
     83 
     84   // Whether we have already run the idle scripts.
     85   bool has_run_idle_;
     86 
     87   // This is only used if we're for the main frame.
     88   std::map<UserScript::RunLocation, ExecutionQueue> pending_execution_map_;
     89 
     90   Dispatcher* dispatcher_;
     91 };
     92 
     93 }  // namespace extensions
     94 
     95 #endif  // CHROME_RENDERER_EXTENSIONS_USER_SCRIPT_SCHEDULER_H_
     96