Chromium Code Reviews| Index: ios/chrome/browser/reading_list/reading_list_distiller_page.mm |
| diff --git a/ios/chrome/browser/reading_list/reading_list_distiller_page.mm b/ios/chrome/browser/reading_list/reading_list_distiller_page.mm |
| index 9384226ee501fa5a50e0d9b3cd893b7dd88437b5..6c3e69726062bf5c811100f4f1491e3b34dbfe21 100644 |
| --- a/ios/chrome/browser/reading_list/reading_list_distiller_page.mm |
| +++ b/ios/chrome/browser/reading_list/reading_list_distiller_page.mm |
| @@ -5,14 +5,25 @@ |
| #include "ios/chrome/browser/reading_list/reading_list_distiller_page.h" |
| #include "base/bind.h" |
| +#include "base/strings/utf_string_conversions.h" |
| #include "base/threading/thread_task_runner_handle.h" |
| #include "components/favicon/ios/web_favicon_driver.h" |
| +#include "components/google/core/browser/google_util.h" |
| #include "ios/chrome/browser/reading_list/favicon_web_state_dispatcher_impl.h" |
| +#import "ios/web/public/navigation_item.h" |
| +#import "ios/web/public/navigation_manager.h" |
| +#include "ios/web/public/ssl_status.h" |
| +#import "ios/web/public/web_state/js/crw_js_injection_receiver.h" |
| #import "ios/web/public/web_state/web_state.h" |
| +#import "net/base/mac/url_conversions.h" |
| +#include "net/cert/cert_status_flags.h" |
| +#include "url/url_constants.h" |
| namespace { |
| // The delay between the page load and the distillation in seconds. |
| const int64_t kDistillationDelayInSeconds = 2; |
| +const char* kJavaScriptNavigateToIframe = |
|
jif
2017/01/17 17:43:10
s/kJavaScriptNavigateToIframe/kGetIframeURLJavaScr
Olivier
2017/01/18 09:30:13
mmm, I obviously did not upload my cleaning PS...
|
| + "document.getElementsByTagName('iframe')[0].src;"; |
| } // namespace |
| namespace reading_list { |
| @@ -59,16 +70,98 @@ void ReadingListDistillerPage::OnLoadURLDone( |
| DistillerPageIOS::OnLoadURLDone(load_completion_status); |
| return; |
| } |
| + if (HandleGoogleCachedAMP()) { |
|
jif
2017/01/17 17:43:10
How about this:
if (IsGoogleCachedAMP()) {
// W
Olivier
2017/01/18 09:30:13
Done.
|
| + // The rest of the distillation will be handled by Google AMP workaround. |
| + // Stop distillation here. |
| + return; |
| + } |
| + WaitForPageLoadCompletion(); |
| +} |
| + |
| +void ReadingListDistillerPage::WaitForPageLoadCompletion() { |
| base::WeakPtr<ReadingListDistillerPage> weak_this = |
| weak_ptr_factory_.GetWeakPtr(); |
| base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
| - FROM_HERE, base::Bind(&ReadingListDistillerPage::DelayedOnLoadURLDone, |
| - weak_this, load_completion_status), |
| + FROM_HERE, |
| + base::Bind(&ReadingListDistillerPage::DelayedOnLoadURLDone, weak_this), |
| base::TimeDelta::FromSeconds(kDistillationDelayInSeconds)); |
| } |
| -void ReadingListDistillerPage::DelayedOnLoadURLDone( |
| - web::PageLoadCompletionStatus load_completion_status) { |
| - DistillerPageIOS::OnLoadURLDone(load_completion_status); |
| +void ReadingListDistillerPage::DelayedOnLoadURLDone() { |
| + DistillerPageIOS::OnLoadURLDone(web::PageLoadCompletionStatus::SUCCESS); |
|
jif
2017/01/17 17:43:10
There's some funny business going on here.
jif
2017/01/17 17:43:45
Ignore this comment, I forgot to remove it.
Olivier
2017/01/18 09:30:13
Acknowledged.
|
| +} |
| + |
| +bool ReadingListDistillerPage::IsGoogleCachedAMP() { |
| + // All google AMP pages have URL in the form "https://google_domain/amp/..." |
| + // and a valid certificate. |
| + // This method checks that this is strictly the case. |
| + GURL url = CurrentWebState()->GetLastCommittedURL(); |
|
jif
2017/01/17 17:43:10
const GURL &
Olivier
2017/01/18 09:30:13
Done.
|
| + if (!url.is_valid() || !url.SchemeIs(url::kHttpsScheme)) { |
| + return false; |
| + } |
| + if (!google_util::IsGoogleDomainUrl( |
| + url, google_util::DISALLOW_SUBDOMAIN, |
| + google_util::DISALLOW_NON_STANDARD_PORTS) || |
| + !url.path().compare(0, 4, "amp/")) { |
| + return false; |
| + } |
| + const web::SSLStatus& ssl_status = CurrentWebState() |
| + ->GetNavigationManager() |
| + ->GetLastCommittedItem() |
| + ->GetSSL(); |
| + if (!ssl_status.certificate || |
| + (net::IsCertStatusError(ssl_status.cert_status) && |
| + !net::IsCertStatusMinorError(ssl_status.cert_status))) { |
| + return false; |
| + } |
| + |
| + return true; |
| +} |
| + |
| +bool ReadingListDistillerPage::HandleGoogleCachedAMP() { |
| + if (!IsGoogleCachedAMP()) { |
| + return false; |
| + } |
| + base::WeakPtr<ReadingListDistillerPage> weak_this = |
| + weak_ptr_factory_.GetWeakPtr(); |
| + [CurrentWebState()->GetJSInjectionReceiver() |
| + executeJavaScript:@(kJavaScriptNavigateToIframe) |
| + completionHandler:^(id result, NSError* error) { |
| + if (!weak_this->HandleGoogleCachedAMPJavaScriptResult(result, error)) { |
|
jif
2017/01/17 17:43:10
weak_this can be null.
Olivier
2017/01/18 09:30:13
Interesting question on what to do if weak_this is
|
| + // If there is an error on navigation, continue normal distillation. |
| + weak_this->WaitForPageLoadCompletion(); |
| + } |
| + // If there is no error, the navigation completion will trigger a new |
| + // |OnLoadURLDone| call that will resume the distillation. |
| + }]; |
| + return true; |
| +} |
| + |
| +bool ReadingListDistillerPage::HandleGoogleCachedAMPJavaScriptResult( |
| + id result, |
| + NSError* error) { |
| + if (error) { |
| + return false; |
| + } |
| + NSURL* new_url = [NSURL URLWithString:result]; |
|
jif
2017/01/17 17:43:10
can you add an DCHECK that verifies that |result|
Olivier
2017/01/18 09:30:13
Added a cast.
If result is not a string (which is
|
| + if (!new_url) { |
| + return false; |
| + } |
| + bool is_cdn_ampproject = |
| + [[new_url host] isEqualToString:@"cdn.amproject.org"]; |
| + bool is_cdn_ampproject_subdomain = |
| + [[new_url host] hasSuffix:@".cdn.amproject.org"]; |
| + |
| + if (!is_cdn_ampproject && !is_cdn_ampproject_subdomain) { |
| + return false; |
| + } |
| + GURL new_gurl = net::GURLWithNSURL(new_url); |
| + if (!new_gurl.is_valid()) { |
| + return false; |
| + } |
| + web::NavigationManager::WebLoadParams params(new_gurl); |
| + CurrentWebState()->GetNavigationManager()->LoadURLWithParams(params); |
| + return true; |
| } |
| + |
| } // namespace reading_list |