Commit 679eb85f authored by bauerb's avatar bauerb Committed by Commit bot

Update supervised user interstitial pages.

BUG=698235

Review-Url: https://codereview.chromium.org/2739473006
Cr-Commit-Position: refs/heads/master@{#456074}
parent ce0e6322
......@@ -267,6 +267,7 @@ void SupervisedUserInterstitial::CommandReceived(const std::string& command) {
std::string message = l10n_util::GetStringFUTF8(
IDS_BLOCK_INTERSTITIAL_DEFAULT_FEEDBACK_TEXT, reason);
#if defined(OS_ANDROID)
DCHECK(profile_->IsChild());
ReportChildAccountFeedback(web_contents_, message, url_);
#else
chrome::ShowFeedbackPage(chrome::FindBrowserWithWebContents(web_contents_),
......
......@@ -15,10 +15,12 @@
#include "chrome/browser/safe_browsing/ui_manager.h"
#include "chrome/browser/ssl/bad_clock_blocking_page.h"
#include "chrome/browser/ssl/ssl_blocking_page.h"
#include "chrome/browser/supervised_user/supervised_user_interstitial.h"
#include "chrome/common/features.h"
#include "chrome/common/url_constants.h"
#include "components/grit/components_resources.h"
#include "components/security_interstitials/core/ssl_error_ui.h"
#include "components/supervised_user_error_page/supervised_user_error_page.h"
#include "content/public/browser/interstitial_page_delegate.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
......@@ -65,7 +67,7 @@ scoped_refptr<net::X509Certificate> CreateFakeCert() {
// not used in displaying any real interstitials.
class InterstitialHTMLSource : public content::URLDataSource {
public:
InterstitialHTMLSource() {}
explicit InterstitialHTMLSource(Profile* profile) : profile_(profile) {}
~InterstitialHTMLSource() override {}
// content::URLDataSource:
......@@ -80,6 +82,8 @@ class InterstitialHTMLSource : public content::URLDataSource {
const content::URLDataSource::GotDataCallback& callback) override;
private:
Profile* profile_;
DISALLOW_COPY_AND_ASSIGN(InterstitialHTMLSource);
};
......@@ -308,7 +312,7 @@ CaptivePortalBlockingPage* CreateCaptivePortalBlockingPage(
InterstitialUI::InterstitialUI(content::WebUI* web_ui)
: WebUIController(web_ui) {
Profile* profile = Profile::FromWebUI(web_ui);
content::URLDataSource::Add(profile, new InterstitialHTMLSource());
content::URLDataSource::Add(profile, new InterstitialHTMLSource(profile));
}
InterstitialUI::~InterstitialUI() {
......@@ -365,7 +369,12 @@ void InterstitialHTMLSource::StartDataRequest(
}
#endif
std::string html;
if (interstitial_delegate.get()) {
if (base::StartsWith(path, "supervised_user", base::CompareCase::SENSITIVE)) {
html = SupervisedUserInterstitial::GetHTMLContents(
profile_, profile_->IsChild()
? supervised_user_error_page::ASYNC_CHECKER
: supervised_user_error_page::MANUAL);
} else if (interstitial_delegate.get()) {
html = interstitial_delegate.get()->GetHTMLContents();
} else {
html = ResourceBundle::GetSharedInstance()
......
/* Copyright 2014 The Chromium Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file. */
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file. */
body {
background-color: rgb(247, 247, 247);
font-size: 10pt;
margin: 150px 60px 0 30px;
background-color: #f7f7f7;
color: #646464;
}
#main-frame-blocked {
margin: auto;
max-width: 600px;
min-width: 200px;
a {
color: #585858;
}
h1 {
font-size: 1.8em;
font-weight: normal;
margin: 5px 0 25px 0;
button {
border: 0;
border-radius: 2px;
box-sizing: border-box;
color: #fff;
cursor: pointer;
float: right;
font-size: .875em;
margin: 0;
padding: 10px 24px;
transition: box-shadow 200ms cubic-bezier(0.4, 0, 0.2, 1);
user-select: none;
}
#block-page-message {
color: rgb(97,97,97);
font-size: 0.667em;
margin-top: 16px;
[dir='rtl'] button {
float: left;
}
.avatar-img {
-webkit-user-select: none;
border: 3px solid rgb(251, 251, 251);
border-radius: 50%;
content: -webkit-image-set(
url(default_100_percent/logo_avatar_circle_blue_color.png) 1x,
url(default_200_percent/logo_avatar_circle_blue_color.png) 2x);
margin-bottom: 5px;
margin-right: 15px;
margin-top: 5px;
max-width: 45px;
position: relative;
.primary-button {
background: rgb(66, 133, 244);
}
#feedback {
margin-top: 50px;
.primary-button:active {
background: rgb(50, 102, 213);
outline: 0;
}
#feedback-link {
color: rgb(66, 133, 244);
button:hover {
box-shadow: 0 1px 3px rgba(0, 0, 0, .50);
}
#request-access-button {
background-color: rgb(66, 133, 244);
color: rgb(255, 255, 255);
cursor: pointer;
font-size: 12px;
font-weight: bold;
min-width: 88px;
padding: 10px 15px;
transition: box-shadow 200ms cubic-bezier(0.4, 0, 0.2, 1);
transition-delay: 200ms;
#details {
color: #696969;
margin: 45px 0 50px;
}
#request-access-button:hover {
background-color: rgb(30, 136, 229);
#details p:not(:first-of-type) {
margin-top: 20px;
}
#request-access-button:active {
background-color: rgb(25,118,210);
box-shadow: 0 8px 17px 0 rgba(0, 0, 0, 0.2);
transition-delay: 0s;
#details-header {
font-weight: bold;
}
#details-button-container {
color: rgb(97,97,97);
cursor: pointer;
box-shadow: inherit;
}
.details-button {
background: inherit;
border: 0;
float: none;
margin: 0;
padding: 10px 0;
text-transform: uppercase;
}
.details-button:hover {
box-shadow: inherit;
text-decoration: underline;
}
h1 {
color: #333;
font-size: 1.6em;
font-weight: normal;
line-height: 1.25em;
margin-bottom: 16px;
}
h2 {
font-size: 1.2em;
font-weight: normal;
}
html {
-webkit-text-size-adjust: 100%;
font-size: 125%;
}
.icon {
background-repeat: no-repeat;
background-size: 100%;
height: 72px;
margin: 0 0 40px;
width: 72px;
}
.main-frame-blocked {
box-sizing: border-box;
font-size: 1em;
line-height: 1.6em;
margin: 100px auto 0;
max-width: 600px;
width: 100%;
}
#main-message > p:not([hidden]) {
display: inline;
font-size: 12px;
}
#button-container {
align-items: baseline;
display: flex;
justify-content: space-between;
margin-top: 60px;
.button-container {
margin-top: 51px;
}
#details {
color: rgb(97,97,97);
font-size: 14px;
.button-container::after {
clear: both;
content: '';
display: table;
width: 100%;
}
#details-header {
font-weight: bold;
.small-link {
color: #696969;
font-size: .875em;
}
.avatar-img {
border: 3px solid rgb(251, 251, 251);
border-radius: 50%;
content: -webkit-image-set(
url(default_100_percent/logo_avatar_circle_blue_color.png) 1x,
url(default_200_percent/logo_avatar_circle_blue_color.png) 2x);
margin-bottom: 5px;
margin-right: 15px;
margin-top: 5px;
max-width: 45px;
position: relative;
user-select: none;
}
#feedback {
margin-top: 50px;
}
.custodian-information {
......@@ -108,46 +162,356 @@ h1 {
padding: 1px 0;
}
@media (max-width: 600px) {
#button-container {
display: flex;
flex-flow: column;
justify-content: flex-start;
order: 2;
@media (max-width: 700px) {
.main-frame-blocked {
padding: 0 10%;
}
}
@media (max-height: 600px) {
#feedback {
margin-top: 35px;
}
}
@media (max-width: 420px) {
button,
[dir='rtl'] button,
.small-link {
float: none;
font-size: .825em;
font-weight: 400;
margin: 0;
text-transform: uppercase;
width: 100%;
}
#details-button-container {
font-weight: bold;
margin: auto;
order: 2;
padding: 0 15px;
#details {
margin: 20px 0 20px 0;
}
#details p:not(:first-of-type) {
margin-top: 10px;
}
.details-button {
margin-top: 20px;
text-align: center;
width: 100%;
}
#request-access-button {
margin-bottom: 30px;
order: 1;
text-align: center;
.main-frame-blocked {
padding: 0 5%;
}
.button-container {
margin-top: 30px;
}
}
/**
* Mobile specific styling.
* Navigation buttons are anchored to the bottom of the screen.
* Details message replaces the top content in its own scrollable area.
*/
@media (max-width: 420px) and (max-height: 736px) and (orientation: portrait) {
.details-button {
border: 0;
margin: 8px 0 0;
}
.secondary-button {
-webkit-margin-end: 0;
margin-top: 16px;
}
}
/* Fixed nav. */
@media (min-width: 240px) and (max-width: 420px) and
(min-height: 401px) and (max-height: 736px) and (orientation:portrait),
(min-width: 421px) and (max-width: 736px) and (min-height: 240px) and
(max-height: 420px) and (orientation:landscape) {
body .button-container {
background: #f7f7f7;
bottom: 0;
box-shadow: 0 -22px 40px rgb(247, 247, 247);
left: 0;
margin: 0;
max-width: 736px;
padding-left: 24px;
padding-right: 24px;
position: fixed;
z-index: 2;
}
.main-frame-blocked {
max-width: 736px;
}
#details,
#information-container {
padding-bottom: 40px;
}
}
@media (max-width: 420px) and (max-height: 736px) and (orientation: portrait),
(max-width: 736px) and (max-height: 420px) and (orientation: landscape) {
body {
margin: 0 auto;
}
button,
[dir='rtl'] button,
button.small-link {
font-family: Roboto-Regular,Helvetica;
font-size: .933em;
font-weight: 600;
margin: 6px 0;
text-transform: uppercase;
transform: translatez(0);
}
.button-container {
box-sizing: border-box;
padding-bottom: 8px;
width: 100%;
}
#details {
margin: auto;
order: 1;
box-sizing: border-box;
height: auto;
margin: 0;
opacity: 1;
padding-top: 40px;
transition: opacity 250ms cubic-bezier(0.4, 0, 0.2, 1);
}
#details[hidden],
#information-container[hidden] {
display: block;
height: 0;
opacity: 0;
overflow: hidden;
transition: none;
}
.details-button {
padding-bottom: 16px;
padding-top: 16px;
}
h1 {
font-size: 1.5em;
margin-bottom: 8px;
}
.icon {
margin-bottom: 12px;
}
.hidden-on-mobile {
display: none;
.main-frame-blocked {
box-sizing: border-box;
margin: 24px auto 12px;
padding: 0 24px;
position: relative;
}
#main-frame-blocked {
.main-frame-blocked p {
font-size: .95em;
line-height: 1.61em;
margin-top: 8px;
}
#information-container {
margin: 0;
transition: opacity 100ms cubic-bezier(0.4, 0, 0.2, 1);
}
.small-link {
border: 0;
}
}
@media (min-height: 400px) and (orientation:portrait) {
.main-frame-blocked {
margin-bottom: 145px;
}
}
@media (min-height: 299px) and (orientation:portrait) {
.button-container {
padding-bottom: 16px;
}
}
@media (min-height: 405px) and (max-height: 736px) and
(max-width: 420px) and (orientation:portrait) {
.icon {
margin-bottom: 24px;
}
.main-frame-blocked {
margin-top: 64px;
}
}
@media (min-height: 480px) and (max-width: 420px) and
(max-height: 736px) and (orientation: portrait),
(min-height: 338px) and (max-height: 420px) and (max-width: 736px) and
(orientation: landscape) {
.icon {
margin-bottom: 24px;
}
.button-container {
padding-bottom: 24px;
}
}
@media (min-height: 500px) and (max-width: 414px) and (orientation: portrait) {
.main-frame-blocked {
margin-top: 96px;
}
}
/* Phablet sizing */
@media (min-width: 375px) and (min-height: 641px) and (max-height: 736px) and
(max-width: 414px) and (orientation: portrait) {
button,
[dir='rtl'] button,
.small-link {
font-size: 1em;
padding-bottom: 12px;
padding-top: 12px;
}
body:not(.offline) .icon {
height: 80px;
width: 80px;
}
.details-button {
margin-top: 28px;
}
h1 {
font-size: 1.7em;
}
.icon {
margin-bottom: 28px;
}
.main-frame-blocked {
padding: 28px;
}
.main-frame-blocked p {
font-size: 1.05em;
}
.button-container {
padding: 28px;
}
}
@media (min-width: 420px) and (max-width: 736px) and
(min-height: 240px) and (max-height: 298px) and
(orientation:landscape) {
body:not(.offline) .icon {
height: 50px;
width: 50px;
}
.icon {
padding-top: 0;
}
.main-frame-blocked {
margin-top: 16px;
}
.button-container {
padding: 0 24px 8px;
}
}
@media (min-width: 420px) and (max-width: 736px) and
(min-height: 240px) and (max-height: 420px) and
(orientation:landscape) {
.details-button {
margin: 0;
}
.main-frame-blocked {
margin-bottom: 70px;
}
.button-container {
margin-top: 0;
}
}
/* Phablet landscape */
@media (min-width: 680px) and (max-height: 414px) {
.main-frame-blocked {
margin: 24px auto;
}
.button-container {
margin: 16px auto 0;
}
}
@media (max-height: 240px) and (orientation: landscape),
(max-height: 480px) and (orientation: portrait),
(max-width: 419px) and (max-height: 323px) {
body:not(.offline) .icon {
height: 56px;
width: 56px;
}
.icon {
margin-bottom: 16px;
}
}
/* Small mobile screens. No fixed nav. */
@media (max-height: 400px) and (orientation: portrait),
(max-height: 239px) and (orientation: landscape),
(max-width: 419px) and (max-height: 399px) {
.main-frame-blocked {
display: flex;
flex-flow: column;
flex-direction: column;
margin-bottom: 0;
}
#feedback {
margin-top: 35px;
#details {
flex: 1 1 auto;
order: 0;
}
#information-container {
flex: 1 1 auto;
order: 0;
}
.button-container {
flex: 0 1 auto;
margin-top: 8px;
order: 1;
padding-left: 0;
padding-right: 0;
position: relative;
width: 100%;
}
}
@media (max-width: 239px) and (orientation: portrait) {
.button-container {
padding-left: 0;
padding-right: 0;
}
}
<!doctype html>
<html i18n-values="dir:textdirection;lang:language">
<head>
<meta name="viewport" content="width=device-width">
<meta charset="utf-8">
<meta name="viewport"
content="initial-scale=1, minimum-scale=1, width=device-width">
<title i18n-content="blockPageTitle"></title>
<link rel="stylesheet" href="../../../ui/webui/resources/css/widgets.css">
<link rel="stylesheet" href="supervised_user_block_interstitial.css">
<script src="../../../ui/webui/resources/js/cr.js"></script>
<script src="../../../ui/webui/resources/js/util.js"></script>
<script src="supervised_user_block_interstitial.js"></script>
</head>
<body>
<div id="main-frame-blocked">
<div class="main-frame-blocked">
<div id="information-container">
<h1>
<div id="block-page-header" i18n-content="blockPageHeader"></div>
<div id="block-page-message" i18n-content="blockPageMessage"></div>
<div id="request-failed-message" i18n-content="requestFailedMessage"
hidden></div>
<div id="request-sent-message" i18n-content="requestSentMessage" hidden>
</div>
</h1>
<div class="icon" id="icon"></div>
<div id="main-message">
<h1 id="block-page-header" i18n-content="blockPageHeader"></h1>
<p id="block-page-message" i18n-content="blockPageMessage"></p>
<h1 id="request-failed-message" i18n-content="requestFailedMessage"
hidden></h1>
<h1 id="request-sent-message" i18n-content="requestSentMessage" hidden></h1>
</div>
<div id="custodians-information" hidden>
<div id="custodian-information" class="custodian-information">
<img id="custodian-avatar-img" class="avatar-img">
......@@ -39,19 +38,14 @@
</div>
</div>
</div>
<div id="button-container">
<div class="button-container">
<button id="request-access-button" class="primary-button" i18n-content="requestAccessButton">
</button>
<div id="details-button-container">
<a id="show-details-link" i18n-content="showDetailsLink"
hidden class="button">
</a>
<a id="hide-details-link" i18n-content="hideDetailsLink"
hidden class="button"></a>
<a id="back-button" i18n-content="backButton"
hidden class="button"></a>
<button id="show-details-link" class="details-button small-link" i18n-content="showDetailsLink" hidden></button>
<button id="hide-details-link" class="details-button small-link" i18n-content="hideDetailsLink" hidden></button>
<button id="back-button" class="details-button small-link" i18n-content="backButton" hidden></button>
</div>
<div id="request-access-button" class="button"
i18n-content="requestAccessButton">
</div>
</div>
<div id="details" hidden>
<p id="details-header" i18n-content="blockReasonHeader"></p>
......
......@@ -2,6 +2,40 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
var mobileNav = false;
var showDetails = false;
/**
* For small screen mobile the navigation buttons are moved
* below the advanced text.
*/
function onResize() {
var mediaQuery = '(min-width: 240px) and (max-width: 420px) and ' +
'(max-height: 736px) and (min-height: 401px) and ' +
'(orientation: portrait), (max-width: 736px) and ' +
'(max-height: 420px) and (min-height: 240px) and ' +
'(min-width: 421px) and (orientation: landscape)';
// Check for change in nav status.
if (mobileNav != window.matchMedia(mediaQuery).matches) {
mobileNav = !mobileNav;
updateDetails();
}
}
function updateDetails() {
$('information-container').hidden = mobileNav && showDetails;
$('details').hidden = !showDetails;
}
function setupMobileNav() {
window.addEventListener('resize', onResize);
onResize();
}
document.addEventListener('DOMContentLoaded', setupMobileNav);
function sendCommand(cmd) {
window.domAutomationController.setAutomationId(1);
window.domAutomationController.send(cmd);
......@@ -57,18 +91,16 @@ function initialize() {
sendCommand('back');
};
$('show-details-link').onclick = function(event) {
$('details').hidden = false;
showDetails = true;
$('show-details-link').hidden = true;
$('hide-details-link').hidden = false;
$('information-container').classList.add('hidden-on-mobile');
$('request-access-button').classList.add('hidden-on-mobile');
updateDetails();
};
$('hide-details-link').onclick = function(event) {
$('details').hidden = true;
showDetails = false;
$('show-details-link').hidden = false;
$('hide-details-link').hidden = true;
$('information-container').classList.remove('hidden-on-mobile');
$('request-access-button').classList.remove('hidden-on-mobile');
updateDetails();
};
if (window.domAutomationController &&
loadTimeData.getBoolean('showFeedbackLink')) {
......@@ -88,17 +120,20 @@ function setRequestStatus(isSuccessful) {
console.log('setRequestStatus(' + isSuccessful +')');
$('block-page-header').hidden = true;
$('block-page-message').hidden = true;
$('hide-details-link').hidden = true;
showDetails = false;
updateDetails();
if (isSuccessful) {
$('request-failed-message').hidden = true;
$('request-sent-message').hidden = false;
$('show-details-link').hidden = true;
$('hide-details-link').hidden = true;
$('details').hidden = true;
$('back-button').hidden = !window.domAutomationController;
$('request-access-button').hidden = true;
$('show-details-link').hidden = true;
} else {
$('request-failed-message').hidden = false;
$('request-access-button').hidden = false;
$('show-details-link').hidden = false;
}
}
......
......@@ -23,11 +23,9 @@ namespace {
static const int kAvatarSize1x = 45;
static const int kAvatarSize2x = 90;
#if defined(GOOGLE_CHROME_BUILD)
bool ReasonIsAutomatic(FilteringBehaviorReason reason) {
return reason == ASYNC_CHECKER || reason == BLACKLIST;
}
#endif
std::string BuildAvatarImageUrl(const std::string& url, int size) {
std::string result = url;
......@@ -124,10 +122,9 @@ std::string BuildHtml(bool allow_access_requests,
reason, is_child_account, second_custodian.empty())));
strings.SetString("blockReasonHeader", l10n_util::GetStringUTF16(
IDS_SUPERVISED_USER_BLOCK_HEADER));
bool show_feedback = false;
#if defined(GOOGLE_CHROME_BUILD)
show_feedback = is_child_account && ReasonIsAutomatic(reason);
#endif
bool show_feedback = ReasonIsAutomatic(reason);
DCHECK(is_child_account || !show_feedback);
strings.SetBoolean("showFeedbackLink", show_feedback);
strings.SetString("feedbackLink", l10n_util::GetStringUTF16(
IDS_BLOCK_INTERSTITIAL_SEND_FEEDBACK));
......
......@@ -40,8 +40,7 @@ BlockMessageIDTestParameter block_message_id_test_params[] = {
{DEFAULT, false, true, IDS_SUPERVISED_USER_BLOCK_MESSAGE_DEFAULT},
{DEFAULT, true, true, IDS_CHILD_BLOCK_MESSAGE_DEFAULT_SINGLE_PARENT},
{DEFAULT, true, false, IDS_CHILD_BLOCK_MESSAGE_DEFAULT_MULTI_PARENT},
{ASYNC_CHECKER, false, false, IDS_SUPERVISED_USER_BLOCK_MESSAGE_SAFE_SITES},
{ASYNC_CHECKER, false, true, IDS_SUPERVISED_USER_BLOCK_MESSAGE_SAFE_SITES},
// SafeSites is not enabled for supervised users.
{ASYNC_CHECKER, true, true, IDS_SUPERVISED_USER_BLOCK_MESSAGE_SAFE_SITES},
{ASYNC_CHECKER, true, false, IDS_SUPERVISED_USER_BLOCK_MESSAGE_SAFE_SITES},
{MANUAL, false, false, IDS_SUPERVISED_USER_BLOCK_MESSAGE_MANUAL},
......@@ -93,13 +92,12 @@ TEST_P(SupervisedUserErrorPageTest_BuildHtml, BuildHtml) {
EXPECT_THAT(result, testing::HasSubstr(param.second_custodian));
EXPECT_THAT(result, testing::HasSubstr(param.second_custodian_email));
}
#if defined(GOOGLE_CHROME_BUILD)
if (param.is_child_account &&
(param.reason == ASYNC_CHECKER || param.reason == BLACKLIST))
if (param.reason == ASYNC_CHECKER || param.reason == BLACKLIST) {
EXPECT_THAT(result, testing::HasSubstr("\"showFeedbackLink\":true"));
else
#endif
} else {
EXPECT_THAT(result, testing::HasSubstr("\"showFeedbackLink\":false"));
}
// Messages containing parameters aren't tested since they get modified before
// they are added to the result.
if (param.allow_access_requests) {
......@@ -201,7 +199,7 @@ BuildHtmlTestParameter build_html_test_parameter[] = {
{true, "url1", "url2", "custodian", "custodian_email", "custodian2",
"custodian2_email", false, DEFAULT, true},
{true, "url1", "url2", "custodian", "custodian_email", "custodian2",
"custodian2_email", false, ASYNC_CHECKER, true},
"custodian2_email", true, ASYNC_CHECKER, true},
};
INSTANTIATE_TEST_CASE_P(GetBlockMessageIDParameterized,
......
......@@ -44,7 +44,7 @@
We could not reach your parents at the moment. Please try again.
</message>
<message name="IDS_BLOCK_INTERSTITIAL_SEND_FEEDBACK" desc="The text for a link to submit feedback about a blocked site.">
Was this unexpected? <ph name="BEGIN_LINK">&lt;a is="action-link" id="feedback-link"&gt;</ph>Let us know<ph name="END_LINK">&lt;/a&gt;</ph>
Was this unexpected? <ph name="BEGIN_LINK">&lt;a href="#" id="feedback-link"&gt;</ph>Let us know<ph name="END_LINK">&lt;/a&gt;</ph>
</message>
<message name="IDS_BLOCK_INTERSTITIAL_SHOW_DETAILS" desc="The text for the link to show details about the interstitial.">
Details
......
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