summaryrefslogtreecommitdiffstats
path: root/ui/login
diff options
context:
space:
mode:
authortbarzic@chromium.org <tbarzic@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-08-15 04:40:54 +0000
committertbarzic@chromium.org <tbarzic@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-08-15 04:42:10 +0000
commitc950a9b113c7bf10364cee6257f7976414e844af (patch)
tree344553c549adce05ec46ebdb05a95479e92bcc4c /ui/login
parent659274e254140b6b832f58415da0a9f5485d6994 (diff)
downloadchromium_src-c950a9b113c7bf10364cee6257f7976414e844af.zip
chromium_src-c950a9b113c7bf10364cee6257f7976414e844af.tar.gz
chromium_src-c950a9b113c7bf10364cee6257f7976414e844af.tar.bz2
Hook up new easyUnlockPrivate API function for updating lock screen
This will replace screenlockPrivate methods for updating screenlock icon, auth type, and message. The cl starts migration of the Easy Unlocking logic from Chrome app to native code. The new easyUnlockPrivate function should be removed once the migration is complete (probably in M39). It moves resources used on screen lock from Easy Unlock app to Chrome, and simplifies generating icon URL to be used in the screenlock web ui. Adds support for setting icon tooltip and animating the icon directly in screenlock web ui (instead of calling showCustomIcon for each animation frame, which can produce somewhat laggy animation). BUG=393792,397366,397360,385719, 402106 Review URL: https://codereview.chromium.org/446743003 Cr-Commit-Position: refs/heads/master@{#289784} git-svn-id: svn://svn.chromium.org/chrome/trunk/src@289784 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/login')
-rw-r--r--ui/login/account_picker/screen_account_picker.js18
-rw-r--r--ui/login/account_picker/user_pod_row.css13
-rw-r--r--ui/login/account_picker/user_pod_row.js386
-rw-r--r--ui/login/account_picker/user_pod_template.html2
4 files changed, 372 insertions, 47 deletions
diff --git a/ui/login/account_picker/screen_account_picker.js b/ui/login/account_picker/screen_account_picker.js
index d4af56b..69e922a 100644
--- a/ui/login/account_picker/screen_account_picker.js
+++ b/ui/login/account_picker/screen_account_picker.js
@@ -29,7 +29,6 @@ login.createScreen('AccountPickerScreen', 'account-picker', function() {
'showUserPodCustomIcon',
'hideUserPodCustomIcon',
'setAuthType',
- 'showEasyUnlockBubble',
'setPublicSessionDisplayName',
'setPublicSessionLocales',
'setPublicSessionKeyboardLayouts',
@@ -279,8 +278,14 @@ login.createScreen('AccountPickerScreen', 'account-picker', function() {
* Shows a custom icon in the user pod of |username|. This function
* is used by the chrome.screenlockPrivate API.
* @param {string} username Username of pod to add button
- * @param {{scale1x: string, scale2x: string}} icon Dictionary of URLs of
- * the custom icon's representations for 1x and 2x scale factors.
+ * @param {!{resourceUrl: (string | undefined),
+ * data: ({scale1x: string, scale2x: string} | undefined),
+ * size: ({width: number, height: number} | undefined),
+ * animation: ({resourceWidth: number, frameLength: number} |
+ * undefined),
+ * opacity: (number | undefined),
+ * tooltip: ({text: string, autoshow: boolean} | undefined)}} icon
+ * The icon parameters.
*/
showUserPodCustomIcon: function(username, icon) {
$('pod-row').showUserPodCustomIcon(username, icon);
@@ -308,13 +313,6 @@ login.createScreen('AccountPickerScreen', 'account-picker', function() {
},
/**
- * Shows a tooltip bubble explaining Easy Unlock.
- */
- showEasyUnlockBubble: function() {
- $('pod-row').showEasyUnlockBubble();
- },
-
- /**
* Updates the display name shown on a public session pod.
* @param {string} userID The user ID of the public session
* @param {string} displayName The new display name
diff --git a/ui/login/account_picker/user_pod_row.css b/ui/login/account_picker/user_pod_row.css
index 5927b25..01a3b7a 100644
--- a/ui/login/account_picker/user_pod_row.css
+++ b/ui/login/account_picker/user_pod_row.css
@@ -219,10 +219,19 @@ html[dir=rtl] .main-pane {
}
.custom-icon {
+ -webkit-margin-end: 0;
+ -webkit-margin-start: auto;
background-position: center;
background-repeat: no-repeat;
flex: none;
+}
+
+.custom-icon-container {
+ display: flex;
+ flex: none;
+ flex-direction: column;
height: 40px;
+ justify-content: center;
width: 40px;
}
@@ -423,10 +432,6 @@ html[dir=rtl] .user-type-bubble {
margin-bottom: 14px;
}
-.easy-unlock-button-content {
- width: 145px;
-}
-
/**** Public account user pod rules *******************************************/
.pod.public-account.expanded {
diff --git a/ui/login/account_picker/user_pod_row.js b/ui/login/account_picker/user_pod_row.js
index 194a3c6..39b5c7d 100644
--- a/ui/login/account_picker/user_pod_row.js
+++ b/ui/login/account_picker/user_pod_row.js
@@ -55,6 +55,7 @@ cr.define('login', function() {
var DESKTOP_POD_HEIGHT = 226;
var POD_ROW_PADDING = 10;
var DESKTOP_ROW_PADDING = 15;
+ var CUSTOM_ICON_CONTAINER_SIZE = 40;
/**
* Minimal padding between user pod and virtual keyboard.
@@ -159,6 +160,330 @@ cr.define('login', function() {
}
/**
+ * Creates an element for custom icon shown in a user pod next to the input
+ * field.
+ * @constructor
+ * @extends {HTMLDivElement}
+ */
+ var UserPodCustomIcon = cr.ui.define(function() {
+ var node = document.createElement('div');
+ node.classList.add('custom-icon-container');
+ node.hidden = true;
+
+ // Create the actual icon element and add it as a child to the container.
+ var iconNode = document.createElement('div');
+ iconNode.classList.add('custom-icon');
+ node.appendChild(iconNode);
+ return node;
+ });
+
+ UserPodCustomIcon.prototype = {
+ __proto__: HTMLDivElement.prototype,
+
+ /**
+ * The icon height.
+ * @type {number}
+ * @private
+ */
+ height_: 0,
+
+ /**
+ * The icon width.
+ * @type {number}
+ * @private
+ */
+ width_: 0,
+
+ /**
+ * Tooltip to be shown when the user hovers over the icon. The icon
+ * properties may be set so the tooltip is shown automatically when the icon
+ * is updated. The tooltip is shown in a bubble attached to the icon
+ * element.
+ * @type {string}
+ * @private
+ */
+ tooltip_: '',
+
+ /**
+ * Whether the tooltip is shown and the user is hovering over the icon.
+ * @type {boolean}
+ * @private
+ */
+ tooltipActive_: false,
+
+ /**
+ * Whether the icon has been shown as a result of |autoshow| parameter begin
+ * set rather than user hovering over the icon.
+ * If this is set, the tooltip will not be removed when the mouse leaves the
+ * icon.
+ * @type {boolean}
+ * @private
+ */
+ tooltipAutoshown_: false,
+
+ /**
+ * A reference to the timeout for showing tooltip after mouse enters the
+ * icon.
+ * @type {?number}
+ * @private
+ */
+ showTooltipTimeout_: null,
+
+ /**
+ * If animation is set, the current horizontal background offset for the
+ * icon resource.
+ * @type {number}
+ * @private
+ */
+ lastAnimationOffset_: 0,
+
+ /**
+ * The reference to interval for progressing the animation.
+ * @type {?number}
+ * @private
+ */
+ animationInterval_: null,
+
+ /**
+ * The width of the resource that contains representations for different
+ * animation stages.
+ * @type {number}
+ * @private
+ */
+ animationResourceSize_: 0,
+
+ /** @override */
+ decorate: function() {
+ this.iconElement.addEventListener('mouseover',
+ this.showTooltipSoon_.bind(this));
+ this.iconElement.addEventListener('mouseout',
+ this.hideTooltip_.bind(this, false));
+ this.iconElement.addEventListener('mousedown',
+ this.hideTooltip_.bind(this, false));
+ },
+
+ /**
+ * Getter for the icon element's div.
+ * @return {HTMLDivElement}
+ */
+ get iconElement() {
+ return this.querySelector('.custom-icon');
+ },
+
+ /**
+ * Set the icon's background image as image set with different
+ * representations for available screen scale factors.
+ * @param {!{scale1x: string, scale2x: string}} icon The icon
+ * representations.
+ */
+ setIconAsImageSet: function(icon) {
+ this.iconElement.style.backgroundImage =
+ '-webkit-image-set(' +
+ 'url(' + icon.scale1x + ') 1x,' +
+ 'url(' + icon.scale2x + ') 2x)';
+ },
+
+ /**
+ * Sets the icon background image to a chrome://theme URL.
+ * @param {!string} iconUrl The icon's background image URL.
+ */
+ setIconAsResourceUrl: function(iconUrl) {
+ this.iconElement.style.backgroundImage =
+ '-webkit-image-set(' +
+ 'url(' + iconUrl + '@1x) 1x,' +
+ 'url(' + iconUrl + '@2x) 2x)';
+ },
+
+ /**
+ * Shows the icon.
+ */
+ show: function() {
+ this.hidden = false;
+ },
+
+ /**
+ * Hides the icon. Makes sure the tooltip is hidden and animation reset.
+ */
+ hide: function() {
+ this.hideTooltip_(true);
+ this.setAnimation(null);
+ this.hidden = true;
+ },
+
+ /**
+ * Sets the icon size element size.
+ * @param {!{width: number, height: number}} size The icon size.
+ */
+ setSize: function(size) {
+ this.height_ = size.height < CUSTOM_ICON_CONTAINER_SIZE ?
+ size.height : CUSTOM_ICON_COTAINER_SIZE;
+ this.iconElement.style.height = this.height_ + 'px';
+
+ this.width_ = size.width < CUSTOM_ICON_CONTAINER_SIZE ?
+ size.width : CUSTOM_ICON_COTAINER_SIZE;
+ this.iconElement.style.width = this.width_ + 'px';
+ this.style.width = this.width_ + 'px';
+ },
+
+ /**
+ * Sets the icon opacity.
+ * @param {number} opacity The icon opacity in [0-100] scale.
+ */
+ setOpacity: function(opacity) {
+ if (opacity > 100) {
+ this.style.opacity = 1;
+ } else if (opacity < 0) {
+ this.style.opacity = 0;
+ } else {
+ this.style.opacity = opacity / 100;
+ }
+ },
+
+ /**
+ * Updates the icon tooltip. If {@code autoshow} parameter is set the
+ * tooltip is immediatelly shown. If tooltip text is not set, the method
+ * ensures the tooltip gets hidden. If tooltip is shown prior to this call,
+ * it remains shown, but the tooltip text is updated.
+ * @param {!{text: string, autoshow: boolean}} tooltip The tooltip
+ * parameters.
+ */
+ setTooltip: function(tooltip) {
+ if (this.tooltip_ == tooltip.text && !tooltip.autoshow)
+ return;
+ this.tooltip_ = tooltip.text;
+
+ // If tooltip is already shown, just update the text.
+ if (tooltip.text && this.tooltipActive_ && !$('bubble').hidden) {
+ // If both previous and the new tooltip are supposed to be shown
+ // automatically, keep the autoshown flag.
+ var markAutoshown = this.tooltipAutoshown_ && tooltip.autoshow;
+ this.hideTooltip_(true);
+ this.showTooltip_();
+ this.tooltipAutoshown_ = markAutoshown;
+ return;
+ }
+
+ // If autoshow flag is set, make sure the tooltip gets shown.
+ if (tooltip.text && tooltip.autoshow) {
+ this.hideTooltip_(true);
+ this.showTooltip_();
+ this.tooltipAutoshown_ = true;
+ // Reset the tooltip active flag, which gets set in |showTooltip_|.
+ this.tooltipActive_ = false;
+ return;
+ }
+
+ this.hideTooltip_(true);
+
+ if (this.tooltip_)
+ this.iconElement.setAttribute('aria-lablel', this.tooltip_);
+ },
+
+ /**
+ * Sets the icon animation parameter and starts the animation.
+ * The animation is set using the resource containing all animation frames
+ * concatenated horizontally. The animator offsets the background image in
+ * regural intervals.
+ * @param {?{resourceWidth: number, frameLengthMs: number}} animation
+ * |resourceWidth|: Total width for the resource containing the
+ * animation frames.
+ * |frameLengthMs|: Time interval for which a single animation frame is
+ * shown.
+ */
+ setAnimation: function(animation) {
+ if (this.animationInterval_)
+ clearInterval(this.animationInterval_);
+ this.iconElement.style.backgroundPosition = 'center';
+ if (!animation)
+ return;
+ this.lastAnimationOffset_ = 0;
+ this.animationResourceSize_ = animation.resourceWidth;
+ this.animationInterval_ = setInterval(this.progressAnimation_.bind(this),
+ animation.frameLengthMs);
+ },
+
+ /**
+ * Called when mouse enters the icon. It sets timeout for showing the
+ * tooltip.
+ * @private
+ */
+ showTooltipSoon_: function() {
+ if (this.showTooltipTimeout_ || this.tooltipActive_)
+ return;
+ this.showTooltipTimeout_ =
+ setTimeout(this.showTooltip_.bind(this), 1000);
+ },
+
+ /**
+ * Shows the current tooltip, if one is set.
+ * @private
+ */
+ showTooltip_: function() {
+ if (this.hidden || !this.tooltip_ || this.tooltipActive_)
+ return;
+
+ // If autoshown bubble got hidden, clear the autoshown flag.
+ if ($('bubble').hidden && this.tooltipAutoshown_)
+ this.tooltipAutoshown_ = false;
+
+ // Show the tooltip bubble.
+ var bubbleContent = document.createElement('div');
+ bubbleContent.textContent = this.tooltip_;
+
+ /** @const */ var BUBBLE_OFFSET = CUSTOM_ICON_CONTAINER_SIZE / 2;
+ /** @const */ var BUBBLE_PADDING = 8;
+ $('bubble').showContentForElement(this,
+ cr.ui.Bubble.Attachment.RIGHT,
+ bubbleContent,
+ BUBBLE_OFFSET,
+ BUBBLE_PADDING);
+ this.ensureTooltipTimeoutCleared_();
+ this.tooltipActive_ = true;
+ },
+
+ /**
+ * Hides the tooltip. If the current tooltip was automatically shown, it
+ * will be hidden only if |force| is set.
+ * @param {boolean} Whether the tooltip should be hidden if it got shown
+ * because autoshow flag was set.
+ * @private
+ */
+ hideTooltip_: function(force) {
+ this.tooltipActive_ = false;
+ this.ensureTooltipTimeoutCleared_();
+ if (!force && this.tooltipAutoshown_)
+ return;
+ $('bubble').hideForElement(this);
+ this.tooltipAutoshown_ = false;
+ this.iconElement.removeAttribute('aria-label');
+ },
+
+ /**
+ * Clears timaout for showing the tooltip if it's set.
+ * @private
+ */
+ ensureTooltipTimeoutCleared_: function() {
+ if (this.showTooltipTimeout_) {
+ clearTimeout(this.showTooltipTimeout_);
+ this.showTooltipTimeout_ = null;
+ }
+ },
+
+ /**
+ * Horizontally offsets the animated icon's background for a single icon
+ * size width.
+ * @private
+ */
+ progressAnimation_: function() {
+ this.lastAnimationOffset_ += this.width_;
+ if (this.lastAnimationOffset_ >= this.animationResourceSize_)
+ this.lastAnimationOffset_ = 0;
+ this.iconElement.style.backgroundPosition =
+ '-' + this.lastAnimationOffset_ + 'px center';
+ }
+ };
+
+ /**
* Unique salt added to user image URLs to prevent caching. Dictionary with
* user names as keys.
* @type {Object}
@@ -198,6 +523,9 @@ cr.define('login', function() {
this.actionBoxRemoveUserWarningButtonElement.addEventListener(
'keydown',
this.handleRemoveUserConfirmationKeyDown_.bind(this));
+
+ var customIcon = this.customIconElement;
+ customIcon.parentNode.replaceChild(new UserPodCustomIcon(), customIcon);
},
/**
@@ -445,7 +773,7 @@ cr.define('login', function() {
* @type {!HTMLDivElement}
*/
get customIconElement() {
- return this.querySelector('.custom-icon');
+ return this.querySelector('.custom-icon-container');
},
/**
@@ -1843,8 +2171,14 @@ cr.define('login', function() {
/**
* Shows a custom icon on a user pod besides the input field.
* @param {string} username Username of pod to add button
- * @param {{scale1x: string, scale2x: string}} icon Dictionary of URLs of
- * the custom icon's representations for 1x and 2x scale factors.
+ * @param {!{resourceUrl: (string | undefined),
+ * data: ({scale1x: string, scale2x: string} | undefined),
+ * size: ({width: number, height: number} | undefined),
+ * animation: ({resourceWidth: number, frameLength: number} |
+ * undefined),
+ * opacity: (number | undefined),
+ * tooltip: ({text: string, autoshow: boolean} | undefined)}} icon
+ * The icon parameters.
*/
showUserPodCustomIcon: function(username, icon) {
var pod = this.getPodWithUsername_(username);
@@ -1854,11 +2188,22 @@ cr.define('login', function() {
return;
}
- pod.customIconElement.hidden = false;
- pod.customIconElement.style.backgroundImage =
- '-webkit-image-set(' +
- 'url(' + icon.scale1x + ') 1x,' +
- 'url(' + icon.scale2x + ') 2x)';
+ if (icon.resourceUrl) {
+ pod.customIconElement.setIconAsResourceUrl(icon.resourceUrl);
+ } else if (icon.data) {
+ pod.customIconElement.setIconAsImageSet(icon.data);
+ } else {
+ return;
+ }
+
+ pod.customIconElement.setSize(icon.size || {width: 0, height: 0});
+ pod.customIconElement.setAnimation(icon.animation || null);
+ pod.customIconElement.setOpacity(icon.opacity || 100);
+ pod.customIconElement.show();
+ // This has to be called after |show| in case the tooltip should be shown
+ // immediatelly.
+ pod.customIconElement.setTooltip(
+ icon.tooltip || {text: '', autoshow: false});
},
/**
@@ -1873,7 +2218,7 @@ cr.define('login', function() {
return;
}
- pod.customIconElement.hidden = true;
+ pod.customIconElement.hide();
},
/**
@@ -1894,29 +2239,6 @@ cr.define('login', function() {
},
/**
- * Shows a tooltip bubble explaining Easy Unlock for the focused pod.
- */
- showEasyUnlockBubble: function() {
- if (!this.focusedPod_) {
- console.error('No focused pod to show Easy Unlock bubble.');
- return;
- }
-
- var bubbleContent = document.createElement('div');
- bubbleContent.classList.add('easy-unlock-button-content');
- bubbleContent.textContent = loadTimeData.getString('easyUnlockTooltip');
-
- var attachElement = this.focusedPod_.customIconElement;
- /** @const */ var BUBBLE_OFFSET = 20;
- /** @const */ var BUBBLE_PADDING = 8;
- $('bubble').showContentForElement(attachElement,
- cr.ui.Bubble.Attachment.RIGHT,
- bubbleContent,
- BUBBLE_OFFSET,
- BUBBLE_PADDING);
- },
-
- /**
* Updates the display name shown on a public session pod.
* @param {string} userID The user ID of the public session
* @param {string} displayName The new display name
diff --git a/ui/login/account_picker/user_pod_template.html b/ui/login/account_picker/user_pod_template.html
index b61f42a..555c56c 100644
--- a/ui/login/account_picker/user_pod_template.html
+++ b/ui/login/account_picker/user_pod_template.html
@@ -28,7 +28,7 @@
</div>
<!-- User Click Authentication -->
<div class="password-label"></div>
- <div class="custom-icon" hidden></div>
+ <div class="custom-icon-container" hidden></div>
<div class="signin-button-container">
<button class="signin-button" i18n-content="signinButton"></button>
</div>