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.
5 #include "components/dom_distiller/ios/distiller_page_ios.h"
7 #import <UIKit/UIKit.h>
9 #include "base/json/json_reader.h"
10 #include "base/logging.h"
11 #include "base/strings/sys_string_conversions.h"
12 #include "base/values.h"
13 #include "ios/public/provider/web/web_controller_provider.h"
14 #include "ios/web/public/browser_state.h"
16 namespace dom_distiller {
18 // Helper class for observing the loading of URLs to distill.
19 class DistillerWebStateObserver : public web::WebStateObserver {
21 DistillerWebStateObserver(web::WebState* web_state,
22 DistillerPageIOS* distiller_page);
24 // WebStateObserver implementation:
26 web::PageLoadCompletionStatus load_completion_status) override;
29 DistillerPageIOS* distiller_page_; // weak, owns this object.
32 DistillerWebStateObserver::DistillerWebStateObserver(
33 web::WebState* web_state,
34 DistillerPageIOS* distiller_page)
35 : web::WebStateObserver(web_state), distiller_page_(distiller_page) {
37 DCHECK(distiller_page_);
40 void DistillerWebStateObserver::PageLoaded(
41 web::PageLoadCompletionStatus load_completion_status) {
42 distiller_page_->OnLoadURLDone(load_completion_status);
47 DistillerPageIOS::DistillerPageIOS(web::BrowserState* browser_state)
48 : browser_state_(browser_state), weak_ptr_factory_(this) {
51 DistillerPageIOS::~DistillerPageIOS() {
54 void DistillerPageIOS::DistillPageImpl(const GURL& url,
55 const std::string& script) {
56 if (!url.is_valid() || !script.length())
61 // Lazily create provider.
63 if (ios::GetWebControllerProviderFactory()) {
65 ios::GetWebControllerProviderFactory()->CreateWebControllerProvider(
67 web_state_observer_.reset(
68 new DistillerWebStateObserver(provider_->GetWebState(), this));
72 // Load page using provider.
74 provider_->LoadURL(url_);
76 OnLoadURLDone(web::PageLoadCompletionStatus::FAILURE);
79 void DistillerPageIOS::OnLoadURLDone(
80 web::PageLoadCompletionStatus load_completion_status) {
81 // Don't attempt to distill if the page load failed or if there is no
83 if (load_completion_status == web::PageLoadCompletionStatus::FAILURE ||
85 HandleJavaScriptResultString(@"");
90 base::WeakPtr<DistillerPageIOS> weak_this = weak_ptr_factory_.GetWeakPtr();
91 provider_->InjectScript(script_, ^(NSString* string, NSError* error) {
92 DistillerPageIOS* distiller_page = weak_this.get();
94 distiller_page->HandleJavaScriptResultString(string);
98 void DistillerPageIOS::HandleJavaScriptResultString(NSString* result) {
99 scoped_ptr<base::Value> resultValue(base::Value::CreateNullValue());
101 scoped_ptr<base::Value> dictionaryValue(
102 base::JSONReader::Read(base::SysNSStringToUTF8(result)));
103 if (dictionaryValue &&
104 dictionaryValue->IsType(base::Value::TYPE_DICTIONARY)) {
105 resultValue = dictionaryValue.Pass();
108 OnDistillationDone(url_, resultValue.get());
111 } // namespace dom_distiller