Commit b8f5fb8b authored by Gavin Williams's avatar Gavin Williams Committed by Commit Bot

Use index to determine highlighted dropdown item

Instead of stamping 'highlighted_' HTML attribute to determine
which of one of the dropdown items should be highlighted, use an index
instead. Allows for simpler tracking of which item to highlight.

Bug: 1059607
Change-Id: I1c60419c8c38862e33434e0f2ed05523cfb74b44
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2300668Reviewed-by: default avatarRebekah Potter <rbpotter@chromium.org>
Commit-Queue: Gavin Williams <gavinwill@chromium.org>
Cr-Commit-Position: refs/heads/master@{#789486}
parent d0207826
...@@ -67,7 +67,7 @@ ...@@ -67,7 +67,7 @@
outline: none; outline: none;
} }
.list-item[highlighted_] { .list-item.highlighted {
background-color: var(--google-blue-refresh-100); background-color: var(--google-blue-refresh-100);
} }
...@@ -121,28 +121,38 @@ ...@@ -121,28 +121,38 @@
no-cancel-on-esc-key> no-cancel-on-esc-key>
<div slot="dropdown-content"> <div slot="dropdown-content">
<template is="dom-repeat" items="[[itemList]]"> <template is="dom-repeat" items="[[itemList]]">
<button id="[[item.key]]" class="list-item" on-click="onSelect_" <button id="[[item.key]]" tabindex="-1" value="[[item.key]]"
tabindex="-1" value="[[item.key]]"> on-click="onSelect_"
class$="list-item [[getHighlightedClass_(item.key,
highlightedIndex_)]]">
<printer-status-icon-cros background="white" <printer-status-icon-cros background="white"
state$="[[computePrinterState_(item.printerStatusReason)]]"> state$="[[computePrinterState_(item.printerStatusReason)]]">
</printer-status-icon-cros> </printer-status-icon-cros>
<span class="printer-display-name">[[item.displayName]]</span> <span class="printer-display-name">[[item.displayName]]</span>
</button> </button>
</template> </template>
<button class="list-item" on-click="onSelect_" tabindex="-1" <button on-click="onSelect_" tabindex="-1" value="[[pdfDestinationKey]]"
value="[[pdfDestinationKey]]" hidden$="[[pdfPrinterDisabled]]"> hidden$="[[pdfPrinterDisabled]]"
class$="list-item [[getHighlightedClass_(pdfDestinationKey,
highlightedIndex_)]]">
$i18n{printToPDF} $i18n{printToPDF}
</button> </button>
<button class="list-item" on-click="onSelect_" tabindex="-1" <button on-click="onSelect_" tabindex="-1"
value="[[driveDestinationKey]]" hidden$="[[!driveDestinationKey]]"> value="[[driveDestinationKey]]" hidden$="[[!driveDestinationKey]]"
class$="list-item [[getHighlightedClass_(driveDestinationKey,
highlightedIndex_)]]">
$i18n{printToGoogleDrive} $i18n{printToGoogleDrive}
</button> </button>
<button class="list-item" on-click="onSelect_" tabindex="-1" <button on-click="onSelect_" tabindex="-1" value="noDestinations"
value="noDestinations" hidden$="[[!noDestinations]]"> hidden$="[[!noDestinations]]"
class$="list-item [[getHighlightedClass_('noDestinations',
highlightedIndex_)]]">
$i18n{noDestinationsMessage} $i18n{noDestinationsMessage}
</button> </button>
<button class="list-item" on-click="onSelect_" tabindex="-1" <button on-click="onSelect_" tabindex="-1" value="seeMore"
value="seeMore" aria-label$="[[i18n(seeMoreDestinationsLabel)]]"> aria-label$="[[i18n(seeMoreDestinationsLabel)]]"
class$="list-item [[getHighlightedClass_('seeMore',
highlightedIndex_)]]">
$i18n{seeMore} $i18n{seeMore}
</button> </button>
</div> </div>
......
...@@ -51,6 +51,12 @@ Polymer({ ...@@ -51,6 +51,12 @@ Polymer({
destinationIcon: String, destinationIcon: String,
isCurrentDestinationCrosLocal: Boolean, isCurrentDestinationCrosLocal: Boolean,
/**
* Index of the highlighted item in the dropdown.
* @private
*/
highlightedIndex_: Number,
}, },
listeners: { listeners: {
...@@ -90,12 +96,8 @@ Polymer({ ...@@ -90,12 +96,8 @@ Polymer({
return; return;
} }
const selectedItem = this.getButtonListFromDropdown_().find( this.highlightedIndex_ = this.getButtonListFromDropdown_().findIndex(
item => item.value === this.value.key); item => item.value === this.value.key);
if (selectedItem) {
selectedItem.toggleAttribute('highlighted_', true);
}
this.$$('iron-dropdown').open(); this.$$('iron-dropdown').open();
this.opened_ = true; this.opened_ = true;
}, },
...@@ -104,37 +106,24 @@ Polymer({ ...@@ -104,37 +106,24 @@ Polymer({
closeDropdown_() { closeDropdown_() {
this.$$('iron-dropdown').close(); this.$$('iron-dropdown').close();
this.opened_ = false; this.opened_ = false;
this.highlightedIndex_ = -1;
const highlightedItem = this.findHighlightedItem_();
if (highlightedItem) {
highlightedItem.toggleAttribute('highlighted_', false);
}
}, },
/** /**
* Highlight the item the mouse is hovering over. If the user uses the
* keyboard, the highlight will shift. But once the user moves the mouse,
* the highlight should be updated based on the location of the mouse
* cursor.
* @param {!Event} event * @param {!Event} event
* @private * @private
*/ */
onMouseMove_(event) { onMouseMove_(event) {
const item = event.composedPath().find( const item = /** @type {!Element} */ (event.composedPath().find(
elm => elm.classList && elm.classList.contains('list-item')); elm => elm.classList && elm.classList.contains('list-item')));
if (!item) { if (!item) {
return; return;
} }
this.highlightedIndex_ = this.getButtonListFromDropdown_().indexOf(item);
// Highlight the item the mouse is hovering over. If the user uses the
// keyboard, the highlight will shift. But once the user moves the mouse,
// the highlight should be updated based on the location of the mouse
// cursor.
const highlightedItem = this.findHighlightedItem_();
if (item === highlightedItem) {
return;
}
if (highlightedItem) {
highlightedItem.toggleAttribute('highlighted_', false);
}
item.toggleAttribute('highlighted_', true);
}, },
/** /**
...@@ -187,7 +176,8 @@ Polymer({ ...@@ -187,7 +176,8 @@ Polymer({
break; break;
case 'Enter': { case 'Enter': {
if (dropdown.opened) { if (dropdown.opened) {
this.dropdownValueSelected_(this.findHighlightedItem_()); this.dropdownValueSelected_(
this.getButtonListFromDropdown_()[this.highlightedIndex_]);
break; break;
} }
this.openDropdown_(); this.openDropdown_();
...@@ -218,26 +208,23 @@ Polymer({ ...@@ -218,26 +208,23 @@ Polymer({
// highlighted in the dropdown. If the dropdown is closed, use the arrow key // highlighted in the dropdown. If the dropdown is closed, use the arrow key
// press to change the selected destination. // press to change the selected destination.
if (dropdown.opened) { if (dropdown.opened) {
const currentIndex = const nextIndex = this.getNextItemIndexInList_(
items.findIndex(item => item.hasAttribute('highlighted_')); eventCode, this.highlightedIndex_, items.length);
const nextIndex =
this.getNextItemIndexInList_(eventCode, currentIndex, items.length);
if (nextIndex === -1) { if (nextIndex === -1) {
return; return;
} }
items[currentIndex].toggleAttribute('highlighted_', false); this.highlightedIndex_ = nextIndex;
items[nextIndex].toggleAttribute('highlighted_', true); items[this.highlightedIndex_].focus();
items[nextIndex].focus(); return;
} else {
const currentIndex =
items.findIndex(item => item.value === this.value.key);
const nextIndex =
this.getNextItemIndexInList_(eventCode, currentIndex, items.length);
if (nextIndex === -1) {
return;
}
this.fire('dropdown-value-selected', items[nextIndex]);
} }
const currentIndex = items.findIndex(item => item.value === this.value.key);
const nextIndex =
this.getNextItemIndexInList_(eventCode, currentIndex, items.length);
if (nextIndex === -1) {
return;
}
this.fire('dropdown-value-selected', items[nextIndex]);
}, },
/** /**
...@@ -265,17 +252,6 @@ Polymer({ ...@@ -265,17 +252,6 @@ Polymer({
this.$$('#destination-dropdown').focus(); this.$$('#destination-dropdown').focus();
}, },
/**
* Finds the currently highlighted dropdown item.
* @return {Element|undefined} Currently highlighted dropdown item, or
* undefined if no item is highlighted.
* @private
*/
findHighlightedItem_() {
const items = this.getButtonListFromDropdown_();
return items.find(item => item.hasAttribute('highlighted_'));
},
/** /**
* Returns list of all the visible items in the dropdown. * Returns list of all the visible items in the dropdown.
* @return {!Array<!Element>} * @return {!Array<!Element>}
...@@ -312,4 +288,19 @@ Polymer({ ...@@ -312,4 +288,19 @@ Polymer({
this.$$('#destination-dropdown') this.$$('#destination-dropdown')
.setAttribute('tabindex', this.disabled ? '-1' : '0'); .setAttribute('tabindex', this.disabled ? '-1' : '0');
}, },
/**
* Determines if an item in the dropdown should be highlighted based on the
* current value of |highlightedIndex_|.
* @param {string} itemValue
* @return {string}
* @private
*/
getHighlightedClass_(itemValue) {
const itemToHighlight =
this.getButtonListFromDropdown_()[this.highlightedIndex_];
return itemToHighlight && itemValue === itemToHighlight.value ?
'highlighted' :
'';
},
}); });
...@@ -19,7 +19,6 @@ destination_dropdown_cros_test.suiteName = ...@@ -19,7 +19,6 @@ destination_dropdown_cros_test.suiteName =
/** @enum {string} */ /** @enum {string} */
destination_dropdown_cros_test.TestNames = { destination_dropdown_cros_test.TestNames = {
CorrectListItems: 'correct list items', CorrectListItems: 'correct list items',
ClickRemovesHighlight: 'click removes highlight',
ClickCloses: 'click closes dropdown', ClickCloses: 'click closes dropdown',
TabCloses: 'tab closes dropdown', TabCloses: 'tab closes dropdown',
HighlightedAfterUpDown: 'highlighted after keyboard press up and down', HighlightedAfterUpDown: 'highlighted after keyboard press up and down',
...@@ -86,7 +85,7 @@ suite(destination_dropdown_cros_test.suiteName, function() { ...@@ -86,7 +85,7 @@ suite(destination_dropdown_cros_test.suiteName, function() {
/** @return {?Element} */ /** @return {?Element} */
function getHighlightedElement() { function getHighlightedElement() {
return dropdown.$$('[highlighted_]'); return dropdown.$$('.highlighted');
} }
/** @return {string} */ /** @return {string} */
...@@ -134,20 +133,6 @@ suite(destination_dropdown_cros_test.suiteName, function() { ...@@ -134,20 +133,6 @@ suite(destination_dropdown_cros_test.suiteName, function() {
assertEquals('Three', itemList[2].textContent.trim()); assertEquals('Three', itemList[2].textContent.trim());
}); });
test(
assert(destination_dropdown_cros_test.TestNames.ClickRemovesHighlight),
function() {
const destinationOne = createDestination('One', DestinationOrigin.CROS);
setItemList([destinationOne]);
dropdown.value = destinationOne;
getList()[0].toggleAttribute('highlighted_', true);
assertTrue(getList()[0].hasAttribute('highlighted_'));
getList()[0].click();
assertFalse(getList()[0].hasAttribute('highlighted_'));
});
test( test(
assert(destination_dropdown_cros_test.TestNames.ClickCloses), function() { assert(destination_dropdown_cros_test.TestNames.ClickCloses), function() {
const destinationOne = createDestination('One', DestinationOrigin.CROS); const destinationOne = createDestination('One', DestinationOrigin.CROS);
......
...@@ -1142,13 +1142,6 @@ TEST_F( ...@@ -1142,13 +1142,6 @@ TEST_F(
destination_dropdown_cros_test.TestNames.CorrectListItems); destination_dropdown_cros_test.TestNames.CorrectListItems);
}); });
TEST_F(
'PrintPreviewDestinationDropdownCrosTest', 'ClickRemovesHighlight',
function() {
this.runMochaTest(
destination_dropdown_cros_test.TestNames.ClickRemovesHighlight);
});
TEST_F('PrintPreviewDestinationDropdownCrosTest', 'ClickCloses', function() { TEST_F('PrintPreviewDestinationDropdownCrosTest', 'ClickCloses', function() {
this.runMochaTest(destination_dropdown_cros_test.TestNames.ClickCloses); this.runMochaTest(destination_dropdown_cros_test.TestNames.ClickCloses);
}); });
......
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