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

Unified Diff: ios/chrome/browser/reading_list/reading_list_distiller_page.mm

Issue 2635193003: IOS Reading distillation: Handle Google AMP iFrame. (Closed)
Patch Set: 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 side-by-side diff with in-line comments
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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
« 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