Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(659)

Side by Side Diff: ios/chrome/browser/reading_list/reading_list_distiller_page.mm

Issue 2635193003: IOS Reading distillation: Handle Google AMP iFrame. (Closed)
Patch Set: add missing comments Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ios/chrome/browser/reading_list/reading_list_distiller_page.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ios/chrome/browser/reading_list/reading_list_distiller_page.h" 5 #include "ios/chrome/browser/reading_list/reading_list_distiller_page.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/mac/foundation_util.h"
9 #include "base/strings/utf_string_conversions.h"
8 #include "base/threading/thread_task_runner_handle.h" 10 #include "base/threading/thread_task_runner_handle.h"
9 #include "components/favicon/ios/web_favicon_driver.h" 11 #include "components/favicon/ios/web_favicon_driver.h"
12 #include "components/google/core/browser/google_util.h"
10 #include "ios/chrome/browser/reading_list/favicon_web_state_dispatcher_impl.h" 13 #include "ios/chrome/browser/reading_list/favicon_web_state_dispatcher_impl.h"
14 #import "ios/web/public/navigation_item.h"
15 #import "ios/web/public/navigation_manager.h"
16 #include "ios/web/public/ssl_status.h"
17 #import "ios/web/public/web_state/js/crw_js_injection_receiver.h"
11 #import "ios/web/public/web_state/web_state.h" 18 #import "ios/web/public/web_state/web_state.h"
19 #import "net/base/mac/url_conversions.h"
20 #include "net/cert/cert_status_flags.h"
21 #include "url/url_constants.h"
12 22
13 namespace { 23 namespace {
14 // The delay between the page load and the distillation in seconds. 24 // The delay between the page load and the distillation in seconds.
15 const int64_t kDistillationDelayInSeconds = 2; 25 const int64_t kDistillationDelayInSeconds = 2;
26 const char* kGetIframeURLJavaScript =
27 "document.getElementsByTagName('iframe')[0].src;";
16 } // namespace 28 } // namespace
17 29
18 namespace reading_list { 30 namespace reading_list {
19 31
20 ReadingListDistillerPage::ReadingListDistillerPage( 32 ReadingListDistillerPage::ReadingListDistillerPage(
21 web::BrowserState* browser_state, 33 web::BrowserState* browser_state,
22 FaviconWebStateDispatcher* web_state_dispatcher) 34 FaviconWebStateDispatcher* web_state_dispatcher)
23 : dom_distiller::DistillerPageIOS(browser_state), 35 : dom_distiller::DistillerPageIOS(browser_state),
24 web_state_dispatcher_(web_state_dispatcher), 36 web_state_dispatcher_(web_state_dispatcher),
25 weak_ptr_factory_(this) {} 37 weak_ptr_factory_(this) {}
(...skipping 22 matching lines...) Expand all
48 const base::Value* value) { 60 const base::Value* value) {
49 std::unique_ptr<web::WebState> old_web_state = DetachWebState(); 61 std::unique_ptr<web::WebState> old_web_state = DetachWebState();
50 if (old_web_state) { 62 if (old_web_state) {
51 web_state_dispatcher_->ReturnWebState(std::move(old_web_state)); 63 web_state_dispatcher_->ReturnWebState(std::move(old_web_state));
52 } 64 }
53 DistillerPageIOS::OnDistillationDone(page_url, value); 65 DistillerPageIOS::OnDistillationDone(page_url, value);
54 } 66 }
55 67
56 void ReadingListDistillerPage::OnLoadURLDone( 68 void ReadingListDistillerPage::OnLoadURLDone(
57 web::PageLoadCompletionStatus load_completion_status) { 69 web::PageLoadCompletionStatus load_completion_status) {
58 if (load_completion_status == web::PageLoadCompletionStatus::FAILURE) { 70 if (load_completion_status != web::PageLoadCompletionStatus::SUCCESS) {
noyau (Ping after 24h) 2017/01/18 16:19:37 Can you explain this change a bit?
Olivier 2017/01/18 17:04:25 At the moment, there is only two values, SUCCESS a
59 DistillerPageIOS::OnLoadURLDone(load_completion_status); 71 DistillerPageIOS::OnLoadURLDone(load_completion_status);
60 return; 72 return;
61 } 73 }
74 if (IsGoogleCachedAMPPage()) {
75 // Workaround for Google AMP pages.
76 HandleGoogleCachedAMPPage();
77 } else {
78 WaitForPageLoadCompletion();
79 }
80 }
81
82 void ReadingListDistillerPage::WaitForPageLoadCompletion() {
62 base::WeakPtr<ReadingListDistillerPage> weak_this = 83 base::WeakPtr<ReadingListDistillerPage> weak_this =
63 weak_ptr_factory_.GetWeakPtr(); 84 weak_ptr_factory_.GetWeakPtr();
64 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( 85 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
65 FROM_HERE, base::Bind(&ReadingListDistillerPage::DelayedOnLoadURLDone, 86 FROM_HERE,
66 weak_this, load_completion_status), 87 base::Bind(&ReadingListDistillerPage::DelayedOnLoadURLDone, weak_this),
67 base::TimeDelta::FromSeconds(kDistillationDelayInSeconds)); 88 base::TimeDelta::FromSeconds(kDistillationDelayInSeconds));
68 } 89 }
69 90
70 void ReadingListDistillerPage::DelayedOnLoadURLDone( 91 void ReadingListDistillerPage::DelayedOnLoadURLDone() {
71 web::PageLoadCompletionStatus load_completion_status) { 92 DistillerPageIOS::OnLoadURLDone(web::PageLoadCompletionStatus::SUCCESS);
72 DistillerPageIOS::OnLoadURLDone(load_completion_status);
73 } 93 }
94
95 bool ReadingListDistillerPage::IsGoogleCachedAMPPage() {
96 // All google AMP pages have URL in the form "https://google_domain/amp/..."
97 // and a valid certificate.
98 // This method checks that this is strictly the case.
99 const GURL& url = CurrentWebState()->GetLastCommittedURL();
100 if (!url.is_valid() || !url.SchemeIs(url::kHttpsScheme)) {
101 return false;
102 }
103 if (!google_util::IsGoogleDomainUrl(
104 url, google_util::DISALLOW_SUBDOMAIN,
105 google_util::DISALLOW_NON_STANDARD_PORTS) ||
106 !url.path().compare(0, 4, "amp/")) {
107 return false;
108 }
109 const web::SSLStatus& ssl_status = CurrentWebState()
110 ->GetNavigationManager()
111 ->GetLastCommittedItem()
112 ->GetSSL();
113 if (!ssl_status.certificate ||
114 (net::IsCertStatusError(ssl_status.cert_status) &&
115 !net::IsCertStatusMinorError(ssl_status.cert_status))) {
116 return false;
117 }
118
119 return true;
120 }
121
122 void ReadingListDistillerPage::HandleGoogleCachedAMPPage() {
123 base::WeakPtr<ReadingListDistillerPage> weak_this =
124 weak_ptr_factory_.GetWeakPtr();
125 [CurrentWebState()->GetJSInjectionReceiver()
126 executeJavaScript:@(kGetIframeURLJavaScript)
127 completionHandler:^(id result, NSError* error) {
128 if (weak_this &&
129 !weak_this->HandleGoogleCachedAMPPageJavaScriptResult(result,
130 error)) {
131 // If there is an error on navigation, continue normal distillation.
132 weak_this->WaitForPageLoadCompletion();
noyau (Ping after 24h) 2017/01/18 16:19:37 When I see a weak_this I always wonder if it could
Olivier 2017/01/18 17:04:25 Both this block and the code destroying this objec
133 }
134 // If there is no error, the navigation completion will trigger a new
135 // |OnLoadURLDone| call that will resume the distillation.
136 }];
137 }
138
139 bool ReadingListDistillerPage::HandleGoogleCachedAMPPageJavaScriptResult(
140 id result,
141 NSError* error) {
142 if (error) {
143 return false;
144 }
145 NSString* result_string = base::mac::ObjCCast<NSString>(result);
146 NSURL* new_url = [NSURL URLWithString:result_string];
147 if (!new_url) {
148 return false;
149 }
150 bool is_cdn_ampproject =
151 [[new_url host] isEqualToString:@"cdn.ampproject.org"];
152 bool is_cdn_ampproject_subdomain =
153 [[new_url host] hasSuffix:@".cdn.ampproject.org"];
154
155 if (!is_cdn_ampproject && !is_cdn_ampproject_subdomain) {
156 return false;
157 }
158 GURL new_gurl = net::GURLWithNSURL(new_url);
159 if (!new_gurl.is_valid()) {
160 return false;
161 }
162 web::NavigationManager::WebLoadParams params(new_gurl);
163 CurrentWebState()->GetNavigationManager()->LoadURLWithParams(params);
164 return true;
165 }
166
74 } // namespace reading_list 167 } // namespace reading_list
OLDNEW
« no previous file with comments | « ios/chrome/browser/reading_list/reading_list_distiller_page.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698