Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 /** | 5 /** |
| 6 * @fileoverview User pod row implementation. | 6 * @fileoverview User pod row implementation. |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 cr.define('login', function() { | 9 cr.define('login', function() { |
| 10 /** | 10 /** |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 85 /** | 85 /** |
| 86 * Tab order for user pods. Update these when adding new controls. | 86 * Tab order for user pods. Update these when adding new controls. |
| 87 * @enum {number} | 87 * @enum {number} |
| 88 * @const | 88 * @const |
| 89 */ | 89 */ |
| 90 var UserPodTabOrder = { | 90 var UserPodTabOrder = { |
| 91 POD_INPUT: 1, // Password input field, Action box menu button, and | 91 POD_INPUT: 1, // Password input field, Action box menu button, and |
| 92 // the pod itself. | 92 // the pod itself. |
| 93 POD_CUSTOM_ICON: 2, // Pod custom icon next to password input field. | 93 POD_CUSTOM_ICON: 2, // Pod custom icon next to password input field. |
| 94 HEADER_BAR: 3, // Buttons on the header bar (Shutdown, Add User). | 94 HEADER_BAR: 3, // Buttons on the header bar (Shutdown, Add User). |
| 95 PAD_MENU_ITEM: 4 // User pad menu items (Remove this user). | 95 POD_MENU_ITEM: 4 // User pad menu items (User info, Remove user). |
| 96 }; | 96 }; |
| 97 | 97 |
| 98 /** | 98 /** |
| 99 * Supported authentication types. Keep in sync with the enum in | 99 * Supported authentication types. Keep in sync with the enum in |
| 100 * chrome/browser/signin/screenlock_bridge.h | 100 * chrome/browser/signin/screenlock_bridge.h |
| 101 * @enum {number} | 101 * @enum {number} |
| 102 * @const | 102 * @const |
| 103 */ | 103 */ |
| 104 var AUTH_TYPE = { | 104 var AUTH_TYPE = { |
| 105 OFFLINE_PASSWORD: 0, | 105 OFFLINE_PASSWORD: 0, |
| (...skipping 606 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 712 this.addEventListener('click', this.handleClickOnPod_.bind(this)); | 712 this.addEventListener('click', this.handleClickOnPod_.bind(this)); |
| 713 this.addEventListener('mousedown', this.handlePodMouseDown_.bind(this)); | 713 this.addEventListener('mousedown', this.handlePodMouseDown_.bind(this)); |
| 714 | 714 |
| 715 this.actionBoxAreaElement.addEventListener('mousedown', | 715 this.actionBoxAreaElement.addEventListener('mousedown', |
| 716 stopEventPropagation); | 716 stopEventPropagation); |
| 717 this.actionBoxAreaElement.addEventListener('click', | 717 this.actionBoxAreaElement.addEventListener('click', |
| 718 this.handleActionAreaButtonClick_.bind(this)); | 718 this.handleActionAreaButtonClick_.bind(this)); |
| 719 this.actionBoxAreaElement.addEventListener('keydown', | 719 this.actionBoxAreaElement.addEventListener('keydown', |
| 720 this.handleActionAreaButtonKeyDown_.bind(this)); | 720 this.handleActionAreaButtonKeyDown_.bind(this)); |
| 721 | 721 |
| 722 this.actionBoxMenuTitleElement.addEventListener('keydown', | |
| 723 this.handleMenuTitleElementKeyDown_.bind(this)); | |
| 724 this.actionBoxMenuTitleElement.addEventListener('blur', | |
| 725 this.handleMenuTitleElementBlur_.bind(this)); | |
| 726 | |
| 722 this.actionBoxMenuRemoveElement.addEventListener('click', | 727 this.actionBoxMenuRemoveElement.addEventListener('click', |
| 723 this.handleRemoveCommandClick_.bind(this)); | 728 this.handleRemoveCommandClick_.bind(this)); |
| 724 this.actionBoxMenuRemoveElement.addEventListener('keydown', | 729 this.actionBoxMenuRemoveElement.addEventListener('keydown', |
| 725 this.handleRemoveCommandKeyDown_.bind(this)); | 730 this.handleRemoveCommandKeyDown_.bind(this)); |
| 726 this.actionBoxMenuRemoveElement.addEventListener('blur', | 731 this.actionBoxMenuRemoveElement.addEventListener('blur', |
| 727 this.handleRemoveCommandBlur_.bind(this)); | 732 this.handleRemoveCommandBlur_.bind(this)); |
| 728 this.actionBoxRemoveUserWarningButtonElement.addEventListener( | 733 this.actionBoxRemoveUserWarningButtonElement.addEventListener('click', |
| 729 'click', | |
| 730 this.handleRemoveUserConfirmationClick_.bind(this)); | 734 this.handleRemoveUserConfirmationClick_.bind(this)); |
| 731 this.actionBoxRemoveUserWarningButtonElement.addEventListener( | 735 this.actionBoxRemoveUserWarningButtonElement.addEventListener('keydown', |
| 732 'keydown', | 736 this.handleRemoveUserConfirmationKeyDown_.bind(this)); |
| 733 this.handleRemoveUserConfirmationKeyDown_.bind(this)); | |
| 734 | 737 |
| 735 var pinKeyboard = $('pin-keyboard'); | 738 var pinKeyboard = $('pin-keyboard'); |
| 736 // The pin keyboard is not present on the md user manager. | 739 // The pin keyboard is not present on the md user manager. |
| 737 if (pinKeyboard) { | 740 if (pinKeyboard) { |
| 738 pinKeyboard.addEventListener('submit', | 741 pinKeyboard.addEventListener('submit', |
| 739 this.handlePinSubmitted_.bind(this)); | 742 this.handlePinSubmitted_.bind(this)); |
| 740 } | 743 } |
| 741 | 744 |
| 742 var customIcon = this.customIconElement; | 745 var customIcon = this.customIconElement; |
| 743 customIcon.parentNode.replaceChild(new UserPodCustomIcon(), customIcon); | 746 customIcon.parentNode.replaceChild(new UserPodCustomIcon(), customIcon); |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 925 /** | 928 /** |
| 926 * Gets user type bubble like multi-profiles policy restriction message. | 929 * Gets user type bubble like multi-profiles policy restriction message. |
| 927 * @type {!HTMLDivElement} | 930 * @type {!HTMLDivElement} |
| 928 */ | 931 */ |
| 929 get userTypeBubbleElement() { | 932 get userTypeBubbleElement() { |
| 930 return this.querySelector('.user-type-bubble'); | 933 return this.querySelector('.user-type-bubble'); |
| 931 }, | 934 }, |
| 932 | 935 |
| 933 /** | 936 /** |
| 934 * Gets action box menu. | 937 * Gets action box menu. |
| 935 * @type {!HTMLInputElement} | 938 * @type {!HTMLDivElement} |
|
Greg Levin
2016/06/09 13:44:45
No idea if these comment tags should be fixed like
| |
| 936 */ | 939 */ |
| 937 get actionBoxMenu() { | 940 get actionBoxMenu() { |
| 938 return this.querySelector('.action-box-menu'); | 941 return this.querySelector('.action-box-menu'); |
| 939 }, | 942 }, |
| 940 | 943 |
| 941 /** | 944 /** |
| 945 * Gets action box menu title (user name and email). | |
| 946 * @type {!HTMLDivElement} | |
| 947 */ | |
| 948 get actionBoxMenuTitleElement() { | |
| 949 return this.querySelector('.action-box-menu-title'); | |
| 950 }, | |
| 951 | |
| 952 /** | |
| 942 * Gets action box menu title, user name item. | 953 * Gets action box menu title, user name item. |
| 943 * @type {!HTMLInputElement} | 954 * @type {!HTMLSpanElement} |
| 944 */ | 955 */ |
| 945 get actionBoxMenuTitleNameElement() { | 956 get actionBoxMenuTitleNameElement() { |
| 946 return this.querySelector('.action-box-menu-title-name'); | 957 return this.querySelector('.action-box-menu-title-name'); |
| 947 }, | 958 }, |
| 948 | 959 |
| 949 /** | 960 /** |
| 950 * Gets action box menu title, user email item. | 961 * Gets action box menu title, user email item. |
| 951 * @type {!HTMLInputElement} | 962 * @type {!HTMLSpanElement} |
| 952 */ | 963 */ |
| 953 get actionBoxMenuTitleEmailElement() { | 964 get actionBoxMenuTitleEmailElement() { |
| 954 return this.querySelector('.action-box-menu-title-email'); | 965 return this.querySelector('.action-box-menu-title-email'); |
| 955 }, | 966 }, |
| 956 | 967 |
| 957 /** | 968 /** |
| 958 * Gets action box menu, remove user command item. | 969 * Gets action box menu, remove user command item. |
| 959 * @type {!HTMLInputElement} | 970 * @type {!HTMLInputElement} |
| 960 */ | 971 */ |
| 961 get actionBoxMenuCommandElement() { | 972 get actionBoxMenuCommandElement() { |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1145 if (!this.parentNode.isFocused(this)) { | 1156 if (!this.parentNode.isFocused(this)) { |
| 1146 this.parentNode.focusPod(undefined, true); | 1157 this.parentNode.focusPod(undefined, true); |
| 1147 this.actionBoxAreaElement.focus(); | 1158 this.actionBoxAreaElement.focus(); |
| 1148 } | 1159 } |
| 1149 | 1160 |
| 1150 // Hide user-type-bubble. | 1161 // Hide user-type-bubble. |
| 1151 this.userTypeBubbleElement.classList.remove('bubble-shown'); | 1162 this.userTypeBubbleElement.classList.remove('bubble-shown'); |
| 1152 | 1163 |
| 1153 this.actionBoxAreaElement.classList.add('active'); | 1164 this.actionBoxAreaElement.classList.add('active'); |
| 1154 | 1165 |
| 1166 // Invisible focus causes ChromeVox to read user name and email. | |
| 1167 this.actionBoxMenuTitleElement.tabIndex = UserPodTabOrder.POD_MENU_ITEM; | |
| 1168 this.actionBoxMenuTitleElement.focus(); | |
|
Greg Levin
2016/06/09 13:44:45
I tried using aria-activedescendant to get CV to r
| |
| 1169 | |
| 1155 // If the user pod is on either edge of the screen, then the menu | 1170 // If the user pod is on either edge of the screen, then the menu |
| 1156 // could be displayed partially ofscreen. | 1171 // could be displayed partially ofscreen. |
| 1157 this.actionBoxMenu.classList.remove('left-edge-offset'); | 1172 this.actionBoxMenu.classList.remove('left-edge-offset'); |
| 1158 this.actionBoxMenu.classList.remove('right-edge-offset'); | 1173 this.actionBoxMenu.classList.remove('right-edge-offset'); |
| 1159 | 1174 |
| 1160 var offsetLeft = | 1175 var offsetLeft = |
| 1161 cr.ui.login.DisplayManager.getOffset(this.actionBoxMenu).left; | 1176 cr.ui.login.DisplayManager.getOffset(this.actionBoxMenu).left; |
| 1162 var menuWidth = this.actionBoxMenu.offsetWidth; | 1177 var menuWidth = this.actionBoxMenu.offsetWidth; |
| 1163 if (offsetLeft < 0) | 1178 if (offsetLeft < 0) |
| 1164 this.actionBoxMenu.classList.add('left-edge-offset'); | 1179 this.actionBoxMenu.classList.add('left-edge-offset'); |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1386 case 'Enter': | 1401 case 'Enter': |
| 1387 case 'U+0020': // Space | 1402 case 'U+0020': // Space |
| 1388 if (this.parentNode.focusedPod_ && !this.isActionBoxMenuActive) | 1403 if (this.parentNode.focusedPod_ && !this.isActionBoxMenuActive) |
| 1389 this.isActionBoxMenuActive = true; | 1404 this.isActionBoxMenuActive = true; |
| 1390 e.stopPropagation(); | 1405 e.stopPropagation(); |
| 1391 break; | 1406 break; |
| 1392 case 'Up': | 1407 case 'Up': |
| 1393 case 'Down': | 1408 case 'Down': |
| 1394 if (this.isActionBoxMenuActive) { | 1409 if (this.isActionBoxMenuActive) { |
| 1395 this.actionBoxMenuRemoveElement.tabIndex = | 1410 this.actionBoxMenuRemoveElement.tabIndex = |
| 1396 UserPodTabOrder.PAD_MENU_ITEM; | 1411 UserPodTabOrder.POD_MENU_ITEM; |
| 1397 this.actionBoxMenuRemoveElement.focus(); | 1412 this.actionBoxMenuRemoveElement.focus(); |
| 1398 } | 1413 } |
| 1399 e.stopPropagation(); | 1414 e.stopPropagation(); |
| 1400 break; | 1415 break; |
| 1416 // Ignore these two, so ChromeVox hotkeys don't close the menu before | |
| 1417 // they can navigate through it. | |
| 1418 case 'Shift': | |
| 1419 case 'Win': | |
| 1420 break; | |
| 1401 case 'U+001B': // Esc | 1421 case 'U+001B': // Esc |
| 1402 this.isActionBoxMenuActive = false; | 1422 this.isActionBoxMenuActive = false; |
| 1403 e.stopPropagation(); | 1423 e.stopPropagation(); |
| 1404 break; | 1424 break; |
| 1405 case 'U+0009': // Tab | 1425 case 'U+0009': // Tab |
| 1406 if (!this.parentNode.alwaysFocusSinglePod) | 1426 if (!this.parentNode.alwaysFocusSinglePod) |
| 1407 this.parentNode.focusPod(); | 1427 this.parentNode.focusPod(); |
| 1408 default: | 1428 default: |
| 1409 this.isActionBoxMenuActive = false; | 1429 this.isActionBoxMenuActive = false; |
| 1410 break; | 1430 break; |
| 1411 } | 1431 } |
| 1412 }, | 1432 }, |
| 1413 | 1433 |
| 1414 /** | 1434 /** |
| 1435 * Handles a keydown event on menu title. | |
| 1436 * @param {Event} e KeyDown event. | |
| 1437 */ | |
| 1438 handleMenuTitleElementKeyDown_: function(e) { | |
| 1439 if (this.disabled) | |
| 1440 return; | |
| 1441 | |
| 1442 if (e.keyIdentifier != 'U+0009' /* TAB */) { | |
| 1443 this.handleActionAreaButtonKeyDown_(e); | |
| 1444 return; | |
| 1445 } | |
| 1446 | |
| 1447 if (e.shiftKey == false) { | |
| 1448 if (this.actionBoxMenuRemoveElement.hidden) { | |
| 1449 this.isActionBoxMenuActive = false; | |
| 1450 } else { | |
| 1451 this.actionBoxMenuRemoveElement.tabIndex = | |
| 1452 UserPodTabOrder.POD_MENU_ITEM; | |
| 1453 this.actionBoxMenuRemoveElement.focus(); | |
| 1454 e.preventDefault(); | |
| 1455 } | |
| 1456 } else { | |
| 1457 this.isActionBoxMenuActive = false; | |
| 1458 this.focusInput(); | |
| 1459 e.preventDefault(); | |
| 1460 } | |
| 1461 }, | |
| 1462 | |
| 1463 /** | |
| 1464 * Handles a blur event on menu title. | |
| 1465 * @param {Event} e Blur event. | |
| 1466 */ | |
| 1467 handleMenuTitleElementBlur_: function(e) { | |
| 1468 if (this.disabled) | |
| 1469 return; | |
| 1470 this.actionBoxMenuTitleElement.tabIndex = -1; | |
| 1471 }, | |
| 1472 | |
| 1473 /** | |
| 1415 * Handles a click event on remove user command. | 1474 * Handles a click event on remove user command. |
| 1416 * @param {Event} e Click event. | 1475 * @param {Event} e Click event. |
| 1417 */ | 1476 */ |
| 1418 handleRemoveCommandClick_: function(e) { | 1477 handleRemoveCommandClick_: function(e) { |
| 1419 if (this.user.legacySupervisedUser || this.user.isDesktopUser) { | 1478 if (this.user.legacySupervisedUser || this.user.isDesktopUser) { |
| 1420 this.showRemoveWarning_(); | 1479 this.showRemoveWarning_(); |
| 1421 return; | 1480 return; |
| 1422 } | 1481 } |
| 1423 if (this.isActionBoxMenuActive) | 1482 if (this.isActionBoxMenuActive) |
| 1424 chrome.send('removeUser', [this.user.username]); | 1483 chrome.send('removeUser', [this.user.username]); |
| (...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1640 this.showRemoveWarning_(); | 1699 this.showRemoveWarning_(); |
| 1641 } else { | 1700 } else { |
| 1642 this.removeUser(this.user); | 1701 this.removeUser(this.user); |
| 1643 } | 1702 } |
| 1644 e.stopPropagation(); | 1703 e.stopPropagation(); |
| 1645 break; | 1704 break; |
| 1646 case 'Up': | 1705 case 'Up': |
| 1647 case 'Down': | 1706 case 'Down': |
| 1648 e.stopPropagation(); | 1707 e.stopPropagation(); |
| 1649 break; | 1708 break; |
| 1709 // Ignore these two, so ChromeVox hotkeys don't close the menu before | |
| 1710 // they can navigate through it. | |
| 1711 case 'Shift': | |
| 1712 case 'Win': | |
| 1713 break; | |
| 1650 case 'U+001B': // Esc | 1714 case 'U+001B': // Esc |
| 1651 this.actionBoxAreaElement.focus(); | 1715 this.actionBoxAreaElement.focus(); |
| 1652 this.isActionBoxMenuActive = false; | 1716 this.isActionBoxMenuActive = false; |
| 1653 e.stopPropagation(); | 1717 e.stopPropagation(); |
| 1654 break; | 1718 break; |
| 1655 default: | 1719 default: |
| 1656 this.actionBoxAreaElement.focus(); | 1720 this.actionBoxAreaElement.focus(); |
| 1657 this.isActionBoxMenuActive = false; | 1721 this.isActionBoxMenuActive = false; |
| 1658 break; | 1722 break; |
| 1659 } | 1723 } |
| (...skipping 1700 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3360 if (pod && pod.multiProfilesPolicyApplied) { | 3424 if (pod && pod.multiProfilesPolicyApplied) { |
| 3361 pod.userTypeBubbleElement.classList.remove('bubble-shown'); | 3425 pod.userTypeBubbleElement.classList.remove('bubble-shown'); |
| 3362 } | 3426 } |
| 3363 } | 3427 } |
| 3364 }; | 3428 }; |
| 3365 | 3429 |
| 3366 return { | 3430 return { |
| 3367 PodRow: PodRow | 3431 PodRow: PodRow |
| 3368 }; | 3432 }; |
| 3369 }); | 3433 }); |
| OLD | NEW |