Commit 2aa5522d authored by Dan Harrington's avatar Dan Harrington Committed by Commit Bot

Implement dino page UI for auto-fetch feature

Internal link to UX mocks: http://shortn/_x5YgxIQutq

Bug: 883486
Change-Id: If8c6026231c4d1e0da72832c834d727f125a543d
Reviewed-on: https://chromium-review.googlesource.com/c/1323902
Commit-Queue: Dan H <harringtond@google.com>
Reviewed-by: default avatarMatt Mueller <mattm@chromium.org>
Reviewed-by: default avatarCarlos Knippschild <carlosk@chromium.org>
Reviewed-by: default avatarCathy Li <chili@chromium.org>
Reviewed-by: default avatarEdward Jung <edwardjung@chromium.org>
Cr-Commit-Position: refs/heads/master@{#609370}
parent f1d8bce1
...@@ -118,7 +118,11 @@ OfflineContentOnNetErrorFeatureState GetOfflineContentOnNetErrorFeatureState() { ...@@ -118,7 +118,11 @@ OfflineContentOnNetErrorFeatureState GetOfflineContentOnNetErrorFeatureState() {
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
bool IsAutoFetchFeatureEnabled() { bool IsAutoFetchFeatureEnabled() {
return base::FeatureList::IsEnabled(features::kAutoFetchOnNetErrorPage); // This feature is incompatible with OfflineContentOnNetError, so don't allow
// both.
return GetOfflineContentOnNetErrorFeatureState() ==
OfflineContentOnNetErrorFeatureState::kDisabled &&
base::FeatureList::IsEnabled(features::kAutoFetchOnNetErrorPage);
} }
#else // OS_ANDROID #else // OS_ANDROID
bool IsAutoFetchFeatureEnabled() { bool IsAutoFetchFeatureEnabled() {
...@@ -205,6 +209,14 @@ void NetErrorHelper::LaunchDownloadsPage() { ...@@ -205,6 +209,14 @@ void NetErrorHelper::LaunchDownloadsPage() {
core_->LaunchDownloadsPage(); core_->LaunchDownloadsPage();
} }
void NetErrorHelper::SavePageForLater() {
core_->SavePageForLater();
}
void NetErrorHelper::CancelSavePage() {
core_->CancelSavePage();
}
content::RenderFrame* NetErrorHelper::GetRenderFrame() { content::RenderFrame* NetErrorHelper::GetRenderFrame() {
return render_frame(); return render_frame();
} }
......
...@@ -68,6 +68,8 @@ class NetErrorHelper ...@@ -68,6 +68,8 @@ class NetErrorHelper
void LaunchOfflineItem(const std::string& id, void LaunchOfflineItem(const std::string& id,
const std::string& name_space) override; const std::string& name_space) override;
void LaunchDownloadsPage() override; void LaunchDownloadsPage() override;
void SavePageForLater() override;
void CancelSavePage() override;
// SSLCertificateErrorPageController::Delegate implementation // SSLCertificateErrorPageController::Delegate implementation
void SendCommand( void SendCommand(
......
...@@ -1128,3 +1128,17 @@ void NetErrorHelperCore::LaunchDownloadsPage() { ...@@ -1128,3 +1128,17 @@ void NetErrorHelperCore::LaunchDownloadsPage() {
available_content_helper_.LaunchDownloadsPage(); available_content_helper_.LaunchDownloadsPage();
#endif #endif
} }
void NetErrorHelperCore::SavePageForLater() {
#if defined(OS_ANDROID)
page_auto_fetcher_helper_->TrySchedule(
/*user_requested=*/true, base::BindOnce(&Delegate::SetAutoFetchState,
base::Unretained(delegate_)));
#endif
}
void NetErrorHelperCore::CancelSavePage() {
#if defined(OS_ANDROID)
page_auto_fetcher_helper_->CancelSchedule();
#endif
}
...@@ -248,6 +248,9 @@ class NetErrorHelperCore { ...@@ -248,6 +248,9 @@ class NetErrorHelperCore {
// Shows all available offline content. // Shows all available offline content.
void LaunchDownloadsPage(); void LaunchDownloadsPage();
void CancelSavePage();
void SavePageForLater();
private: private:
struct ErrorPageInfo; struct ErrorPageInfo;
......
...@@ -102,6 +102,16 @@ void NetErrorPageController::LaunchDownloadsPage() { ...@@ -102,6 +102,16 @@ void NetErrorPageController::LaunchDownloadsPage() {
delegate_->LaunchDownloadsPage(); delegate_->LaunchDownloadsPage();
} }
void NetErrorPageController::SavePageForLater() {
if (delegate_)
delegate_->SavePageForLater();
}
void NetErrorPageController::CancelSavePage() {
if (delegate_)
delegate_->CancelSavePage();
}
NetErrorPageController::NetErrorPageController(base::WeakPtr<Delegate> delegate) NetErrorPageController::NetErrorPageController(base::WeakPtr<Delegate> delegate)
: delegate_(delegate) { : delegate_(delegate) {
} }
...@@ -129,5 +139,7 @@ gin::ObjectTemplateBuilder NetErrorPageController::GetObjectTemplateBuilder( ...@@ -129,5 +139,7 @@ gin::ObjectTemplateBuilder NetErrorPageController::GetObjectTemplateBuilder(
.SetMethod("launchOfflineItem", .SetMethod("launchOfflineItem",
&NetErrorPageController::LaunchOfflineItem) &NetErrorPageController::LaunchOfflineItem)
.SetMethod("launchDownloadsPage", .SetMethod("launchDownloadsPage",
&NetErrorPageController::LaunchDownloadsPage); &NetErrorPageController::LaunchDownloadsPage)
.SetMethod("savePageForLater", &NetErrorPageController::SavePageForLater)
.SetMethod("cancelSavePage", &NetErrorPageController::CancelSavePage);
} }
...@@ -38,6 +38,17 @@ class NetErrorPageController : public gin::Wrappable<NetErrorPageController> { ...@@ -38,6 +38,17 @@ class NetErrorPageController : public gin::Wrappable<NetErrorPageController> {
// Called to show all available offline content. // Called to show all available offline content.
virtual void LaunchDownloadsPage() = 0; virtual void LaunchDownloadsPage() = 0;
// Schedules a request to save the page later. This is different from the
// download button in that the page is only saved temporarily. This is used
// only for the auto-fetch-on-net-error-page feature.
virtual void SavePageForLater() = 0;
// Cancels the request to save the page later. This cancels a previous call
// to |SavePageForLater|, or the automatic request made when loading the
// error page. This is used only for the auto-fetch-on-net-error-page
// feature.
virtual void CancelSavePage() = 0;
protected: protected:
Delegate(); Delegate();
virtual ~Delegate(); virtual ~Delegate();
...@@ -86,6 +97,8 @@ class NetErrorPageController : public gin::Wrappable<NetErrorPageController> { ...@@ -86,6 +97,8 @@ class NetErrorPageController : public gin::Wrappable<NetErrorPageController> {
void LaunchOfflineItem(gin::Arguments* args); void LaunchOfflineItem(gin::Arguments* args);
void LaunchDownloadsPage(); void LaunchDownloadsPage();
void SavePageForLater();
void CancelSavePage();
// gin::WrappableBase // gin::WrappableBase
gin::ObjectTemplateBuilder GetObjectTemplateBuilder( gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
......
...@@ -1071,23 +1071,28 @@ void LocalizedError::GetStrings( ...@@ -1071,23 +1071,28 @@ void LocalizedError::GetStrings(
!is_incognito && failed_url.is_valid() && !is_incognito && failed_url.is_valid() &&
failed_url.SchemeIsHTTPOrHTTPS() && failed_url.SchemeIsHTTPOrHTTPS() &&
IsOfflineError(error_domain, error_code)) { IsOfflineError(error_domain, error_code)) {
error_strings->SetPath( if (!auto_fetch_feature_enabled) {
{"downloadButton", "msg"}, error_strings->SetPath({"downloadButton", "msg"},
base::Value(l10n_util::GetStringUTF16(IDS_ERRORPAGES_BUTTON_DOWNLOAD))); base::Value(l10n_util::GetStringUTF16(
error_strings->SetPath({"downloadButton", "disabledMsg"}, IDS_ERRORPAGES_BUTTON_DOWNLOAD)));
base::Value(l10n_util::GetStringUTF16( error_strings->SetPath({"downloadButton", "disabledMsg"},
IDS_ERRORPAGES_BUTTON_DOWNLOADING))); base::Value(l10n_util::GetStringUTF16(
IDS_ERRORPAGES_BUTTON_DOWNLOADING)));
} else {
error_strings->SetString("attemptAutoFetch", "true");
error_strings->SetPath({"savePageLater", "savePageMsg"},
base::Value(l10n_util::GetStringUTF16(
IDS_ERRORPAGES_SAVE_PAGE_BUTTON)));
error_strings->SetPath({"savePageLater", "cancelMsg"},
base::Value(l10n_util::GetStringUTF16(
IDS_ERRORPAGES_CANCEL_SAVE_PAGE_BUTTON)));
}
} }
error_strings->SetString( error_strings->SetString(
"closeDescriptionPopup", "closeDescriptionPopup",
l10n_util::GetStringUTF16(IDS_ERRORPAGES_SUGGESTION_CLOSE_POPUP_BUTTON)); l10n_util::GetStringUTF16(IDS_ERRORPAGES_SUGGESTION_CLOSE_POPUP_BUTTON));
if (auto_fetch_feature_enabled && IsOfflineError(error_domain, error_code) &&
!is_incognito) {
error_strings->SetString("attemptAutoFetch", "true");
}
if (IsOfflineError(error_domain, error_code) && !is_incognito) { if (IsOfflineError(error_domain, error_code) && !is_incognito) {
switch (offline_content_feature_state) { switch (offline_content_feature_state) {
case OfflineContentOnNetErrorFeatureState::kDisabled: case OfflineContentOnNetErrorFeatureState::kDisabled:
......
...@@ -48,6 +48,12 @@ ...@@ -48,6 +48,12 @@
<message name="IDS_ERRORPAGES_OFFLINE_CONTENT_SUMMARY_BUTTON" desc="Label for the button that will take the user to the downloads home, attached to the offline content summary card shown in an error page"> <message name="IDS_ERRORPAGES_OFFLINE_CONTENT_SUMMARY_BUTTON" desc="Label for the button that will take the user to the downloads home, attached to the offline content summary card shown in an error page">
Take me there now Take me there now
</message> </message>
<message name="IDS_ERRORPAGES_SAVE_PAGE_BUTTON" desc="Label for the button that will save the page for later. The saved page is not retained in Downloads, unlike with the DOWNLOAD button.">
Save page for later
</message>
<message name="IDS_ERRORPAGES_CANCEL_SAVE_PAGE_BUTTON" desc="Label for the button that will cancel the request to save the page for later. 'Cancel' is colored blue with the 'a' tag.">
Chrome will let you know when this page is ready. &lt;a&gt;Cancel&lt;/a&gt;
</message>
</if> </if>
<message name="IDS_ERRORPAGES_SUGGESTION_VISIT_GOOGLE_CACHE" desc="When a page fails to load, sometimes we viewing a version of the page cached on Google's servers."> <message name="IDS_ERRORPAGES_SUGGESTION_VISIT_GOOGLE_CACHE" desc="When a page fails to load, sometimes we viewing a version of the page cached on Google's servers.">
......
...@@ -584,6 +584,23 @@ div.offline-content-suggestion { ...@@ -584,6 +584,23 @@ div.offline-content-suggestion {
padding-top: 12px; padding-top: 12px;
} }
#cancel-save-page-button {
border: 1px solid var(--google-gray-300);
border-radius: 5px;
color: var(--google-gray-700);
padding: 16px;
text-align: center;
}
#save-page-for-later-button {
display: flex;
justify-content: center;
}
.hidden#save-page-for-later-button {
display: none;
}
/* Don't allow overflow when in a subframe. */ /* Don't allow overflow when in a subframe. */
html[subframe] body { html[subframe] body {
overflow: hidden; overflow: hidden;
......
...@@ -117,6 +117,17 @@ ...@@ -117,6 +117,17 @@
jsselect="downloadButton" jsselect="downloadButton"
jscontent="msg" jsvalues=".disabledText:disabledMsg"> jscontent="msg" jsvalues=".disabledText:disabledMsg">
</button> </button>
<div id="save-page-for-later-button" class="hidden">
<a class="link-button" onclick="savePageLaterClick()"
jsselect="savePageLater"
jscontent="savePageMsg">
</a>
</div>
<div id="cancel-save-page-button" class="hidden"
onclick="cancelSavePageClick()"
jsselect="savePageLater"
jsvalues=".innerHTML:cancelMsg">
</div>
</div> </div>
<button id="details-button" class="secondary-button text-button small-link" <button id="details-button" class="secondary-button text-button small-link"
onclick="detailsButtonClick(); toggleHelpBox()" jscontent="details" onclick="detailsButtonClick(); toggleHelpBox()" jscontent="details"
......
...@@ -159,8 +159,24 @@ var primaryControlOnLeft = true; ...@@ -159,8 +159,24 @@ var primaryControlOnLeft = true;
primaryControlOnLeft = false; primaryControlOnLeft = false;
// </if> // </if>
// TODO(crbug.com/883486): UI not yet implemented.
function setAutoFetchState(scheduled, can_schedule) { function setAutoFetchState(scheduled, can_schedule) {
document.getElementById('cancel-save-page-button')
.classList.toggle(HIDDEN_CLASS, !scheduled);
document.getElementById('save-page-for-later-button')
.classList.toggle(HIDDEN_CLASS, scheduled || !can_schedule);
}
function savePageLaterClick() {
errorPageController.savePageForLater();
// savePageForLater will eventually trigger a call to setAutoFetchState() when
// it completes.
}
function cancelSavePageClick() {
errorPageController.cancelSavePage();
// setAutoFetchState is not called in response to cancelSavePage(), so do it
// now.
setAutoFetchState(false, true);
} }
function toggleErrorInformationPopup() { function toggleErrorInformationPopup() {
...@@ -347,9 +363,12 @@ function onDocumentLoad() { ...@@ -347,9 +363,12 @@ function onDocumentLoad() {
detailsButton.classList.add('singular'); detailsButton.classList.add('singular');
} }
var attemptAutoFetch = loadTimeData.valueExists('attemptAutoFetch') &&
loadTimeData.getValue('attemptAutoFetch');
// Show control buttons. // Show control buttons.
if (reloadButtonVisible || showSavedCopyButtonVisible || if (reloadButtonVisible || showSavedCopyButtonVisible ||
downloadButtonVisible) { downloadButtonVisible || attemptAutoFetch) {
controlButtonDiv.hidden = false; controlButtonDiv.hidden = false;
// Set the secondary button state in the cases of two call to actions. // Set the secondary button state in the cases of two call to actions.
......
...@@ -10,6 +10,7 @@ body { ...@@ -10,6 +10,7 @@ body {
--google-blue-600: rgb(26, 115, 232); --google-blue-600: rgb(26, 115, 232);
--google-blue-700: rgb(25, 103, 210); --google-blue-700: rgb(25, 103, 210);
--google-gray-50: rgb(248, 249, 250); --google-gray-50: rgb(248, 249, 250);
--google-gray-300: rgb(218, 220, 224);
--google-gray-500: rgb(154, 160, 166); --google-gray-500: rgb(154, 160, 166);
--google-gray-600: rgb(128, 134, 139); --google-gray-600: rgb(128, 134, 139);
--google-gray-700: rgb(95, 99, 105); --google-gray-700: rgb(95, 99, 105);
...@@ -39,4 +40,4 @@ html { ...@@ -39,4 +40,4 @@ html {
.icon { .icon {
background-repeat: no-repeat; background-repeat: no-repeat;
background-size: 100%; background-size: 100%;
} }
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment