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#ifndef COMPONENTS_DOM_DISTILLER_CONTENT_DISTILLER_PAGE_WEB_CONTENTS_H_
6#define COMPONENTS_DOM_DISTILLER_CONTENT_DISTILLER_PAGE_WEB_CONTENTS_H_
7
8#include <string>
9
10#include "base/memory/scoped_ptr.h"
11#include "components/dom_distiller/core/distiller_page.h"
12#include "content/public/browser/web_contents.h"
13#include "content/public/browser/web_contents_delegate.h"
14#include "content/public/browser/web_contents_observer.h"
15#include "url/gurl.h"
16
17namespace dom_distiller {
18
19class SourcePageHandleWebContents : public SourcePageHandle {
20 public:
21  explicit SourcePageHandleWebContents(
22      scoped_ptr<content::WebContents> web_contents);
23  virtual ~SourcePageHandleWebContents();
24
25  scoped_ptr<content::WebContents> GetWebContents();
26
27 private:
28  // The WebContents this class owns.
29  scoped_ptr<content::WebContents> web_contents_;
30};
31
32class DistillerPageWebContentsFactory : public DistillerPageFactory {
33 public:
34  explicit DistillerPageWebContentsFactory(
35      content::BrowserContext* browser_context)
36      : DistillerPageFactory(), browser_context_(browser_context) {}
37  virtual ~DistillerPageWebContentsFactory() {}
38
39  virtual scoped_ptr<DistillerPage> CreateDistillerPage(
40      const gfx::Size& render_view_size) const OVERRIDE;
41  virtual scoped_ptr<DistillerPage> CreateDistillerPageWithHandle(
42      scoped_ptr<SourcePageHandle> handle) const OVERRIDE;
43
44 private:
45  content::BrowserContext* browser_context_;
46};
47
48class DistillerPageWebContents : public DistillerPage,
49                                 public content::WebContentsDelegate,
50                                 public content::WebContentsObserver {
51 public:
52  DistillerPageWebContents(
53      content::BrowserContext* browser_context,
54      const gfx::Size& render_view_size,
55      scoped_ptr<SourcePageHandleWebContents> optional_web_contents_handle);
56  virtual ~DistillerPageWebContents();
57
58  // content::WebContentsDelegate implementation.
59  virtual gfx::Size GetSizeForNewRenderView(
60      content::WebContents* web_contents) const OVERRIDE;
61
62  // content::WebContentsObserver implementation.
63  virtual void DocumentLoadedInFrame(
64      content::RenderFrameHost* render_frame_host) OVERRIDE;
65
66  virtual void DidFailLoad(content::RenderFrameHost* render_frame_host,
67                           const GURL& validated_url,
68                           int error_code,
69                           const base::string16& error_description) OVERRIDE;
70
71 protected:
72  virtual void DistillPageImpl(const GURL& url,
73                               const std::string& script) OVERRIDE;
74
75 private:
76  friend class TestDistillerPageWebContents;
77
78  enum State {
79    // The page distiller is idle.
80    IDLE,
81    // A page is currently loading.
82    LOADING_PAGE,
83    // There was an error processing the page.
84    PAGELOAD_FAILED,
85    // JavaScript is executing within the context of the page. When the
86    // JavaScript completes, the state will be returned to |IDLE|.
87    EXECUTING_JAVASCRIPT
88  };
89
90  // Creates a new WebContents, adds |this| as an observer, and loads the
91  // |url|.
92  virtual void CreateNewWebContents(const GURL& url);
93
94  // Injects and executes JavaScript in the context of a loaded page. This
95  // must only be called after the page has successfully loaded.
96  void ExecuteJavaScript();
97
98  // Called when the distillation is done or if the page load failed.
99  void OnWebContentsDistillationDone(const GURL& page_url,
100                                     const base::Value* value);
101
102  // The current state of the |DistillerPage|, initially |IDLE|.
103  State state_;
104
105  // The JavaScript to inject to extract content.
106  std::string script_;
107
108  scoped_ptr<content::WebContents> web_contents_;
109  content::BrowserContext* browser_context_;
110  gfx::Size render_view_size_;
111  DISALLOW_COPY_AND_ASSIGN(DistillerPageWebContents);
112};
113
114}  // namespace dom_distiller
115
116#endif  // COMPONENTS_DOM_DISTILLER_CONTENT_DISTILLER_PAGE_WEB_CONTENTS_H_
117