14e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
24e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
34e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// found in the LICENSE file.
44e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
54e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#ifndef COMPONENTS_DOM_DISTILLER_CORE_DISTILLER_H_
64e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#define COMPONENTS_DOM_DISTILLER_CORE_DISTILLER_H_
74e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include <map>
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <string>
104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/callback.h"
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/containers/hash_tables.h"
13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/memory/ref_counted.h"
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/memory/scoped_vector.h"
16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/memory/weak_ptr.h"
17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "components/dom_distiller/core/article_distillation_update.h"
18a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "components/dom_distiller/core/distiller_page.h"
19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "components/dom_distiller/core/distiller_url_fetcher.h"
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/dom_distiller/core/proto/distilled_article.pb.h"
21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "net/url_request/url_request_context_getter.h"
224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "url/gurl.h"
234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace dom_distiller {
254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class DistillerImpl;
274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class Distiller {
294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public:
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  typedef base::Callback<void(scoped_ptr<DistilledArticleProto>)>
31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      DistillationFinishedCallback;
32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  typedef base::Callback<void(const ArticleDistillationUpdate&)>
33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      DistillationUpdateCallback;
34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual ~Distiller() {}
364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Distills a page, and asynchronously returns the article HTML to the
38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // supplied |finished_cb| callback. |update_cb| is invoked whenever article
39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // under distillation is updated with more data.
40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // E.g. when distilling a 2 page article, |update_cb| may be invoked each time
41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // a distilled page is added and |finished_cb| will be invoked once
42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // distillation is completed.
434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual void DistillPage(const GURL& url,
445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                           scoped_ptr<DistillerPage> distiller_page,
45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                           const DistillationFinishedCallback& finished_cb,
46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                           const DistillationUpdateCallback& update_cb) = 0;
474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)};
484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class DistillerFactory {
504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public:
51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual scoped_ptr<Distiller> CreateDistiller() = 0;
52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual ~DistillerFactory() {}
53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Factory for creating a Distiller.
56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class DistillerFactoryImpl : public DistillerFactory {
57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public:
58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DistillerFactoryImpl(
59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      scoped_ptr<DistillerURLFetcherFactory> distiller_url_fetcher_factory,
60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      const dom_distiller::proto::DomDistillerOptions& dom_distiller_options);
61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual ~DistillerFactoryImpl();
62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual scoped_ptr<Distiller> CreateDistiller() OVERRIDE;
63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) private:
65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<DistillerURLFetcherFactory> distiller_url_fetcher_factory_;
66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  dom_distiller::proto::DomDistillerOptions dom_distiller_options_;
67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Distills a article from a page and associated pages.
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class DistillerImpl : public Distiller {
71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public:
72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DistillerImpl(
73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      const DistillerURLFetcherFactory& distiller_url_fetcher_factory,
74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      const dom_distiller::proto::DomDistillerOptions& dom_distiller_options);
75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual ~DistillerImpl();
76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  virtual void DistillPage(
785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      const GURL& url,
795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      scoped_ptr<DistillerPage> distiller_page,
805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      const DistillationFinishedCallback& finished_cb,
815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      const DistillationUpdateCallback& update_cb) OVERRIDE;
82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void SetMaxNumPagesInArticle(size_t max_num_pages);
84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) private:
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // In case of multiple pages, the Distiller maintains state of multiple pages
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // as page numbers relative to the page number where distillation started.
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // E.g. if distillation starts at page 2 for a 3 page article. The relative
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // page numbers assigned to pages will be [-1,0,1].
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Class representing the state of a page under distillation.
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  struct DistilledPageData {
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DistilledPageData();
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    virtual ~DistilledPageData();
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Relative page number of the page.
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int page_num;
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ScopedVector<DistillerURLFetcher> image_fetchers_;
98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    scoped_refptr<base::RefCountedData<DistilledPageProto> >
99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        distilled_page_proto;
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   private:
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DISALLOW_COPY_AND_ASSIGN(DistilledPageData);
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  };
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void OnFetchImageDone(int page_num,
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        DistillerURLFetcher* url_fetcher,
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        const std::string& id,
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        const std::string& response);
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void OnPageDistillationFinished(
1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      int page_num,
1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      const GURL& page_url,
1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      scoped_ptr<proto::DomDistillerResult> distilled_page,
1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      bool distillation_successful);
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void FetchImage(int page_num,
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                          const std::string& image_id,
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                          const std::string& item);
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Distills the next page.
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void DistillNextPage();
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Adds the |url| to |pages_to_be_distilled| if |page_num| is a valid relative
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // page number and |url| is valid. Ignores duplicate pages and urls.
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void AddToDistillationQueue(int page_num, const GURL& url);
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Check if |page_num| is a valid relative page number, i.e. page with
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // |page_num| is either under distillation or has already completed
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // distillation.
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool IsPageNumberInUse(int page_num) const;
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool AreAllPagesFinished() const;
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Total number of pages in the article that the distiller knows of, this
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // includes pages that are pending distillation.
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  size_t TotalPageCount() const;
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Runs |finished_cb_| if all distillation callbacks and image fetches are
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // complete.
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void RunDistillerCallbackIfDone();
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Checks if page |distilled_page_data| has finished distillation, including
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // all image fetches.
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void AddPageIfDone(int page_num);
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DistilledPageData* GetPageAtIndex(size_t index) const;
147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Create an ArticleDistillationUpdate for the current distillation
149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // state.
150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const ArticleDistillationUpdate CreateDistillationUpdate() const;
151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const DistillerURLFetcherFactory& distiller_url_fetcher_factory_;
153a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  scoped_ptr<DistillerPage> distiller_page_;
154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  dom_distiller::proto::DomDistillerOptions dom_distiller_options_;
156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DistillationFinishedCallback finished_cb_;
157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DistillationUpdateCallback update_cb_;
158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Set of pages that are under distillation or have finished distillation.
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // |started_pages_index_| and |finished_pages_index_| maintains the mapping
1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // from page number to the indices in |pages_|.
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ScopedVector<DistilledPageData> pages_;
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Maps page numbers of finished pages to the indices in |pages_|.
1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::map<int, size_t> finished_pages_index_;
1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Maps page numbers of pages under distillation to the indices in |pages_|.
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // If a page is |started_pages_| that means it is still waiting for an action
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // (distillation or image fetch) to finish.
1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::hash_map<int, size_t> started_pages_index_;
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The list of pages that are still waiting for distillation to start.
1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // This is a map, to make distiller prefer distilling lower page numbers
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // first.
1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::map<int, GURL> waiting_pages_;
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Set to keep track of which urls are already seen by the distiller. Used to
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // prevent distiller from distilling the same url twice.
1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::hash_set<std::string> seen_urls_;
180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  size_t max_pages_in_article_;
182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
183a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool destruction_allowed_;
184a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
185a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::WeakPtrFactory<DistillerImpl> weak_factory_;
186a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
187f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(DistillerImpl);
1884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)};
1894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}  // namespace dom_distiller
1914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif  // COMPONENTS_DOM_DISTILLER_CORE_DISTILLER_H_
193