Skip to content
This repository was archived by the owner on Jan 13, 2025. It is now read-only.

Commit 53f42b9

Browse files
lynnmercierwilliamernest
authored andcommitted
chore(list): Remove all references to Element from MDCListAdapter (#3398)
BREAKING CHANGE: Please update calls to MDCListFoundation.handleKeydown to pass in isRootListItem and listItemIndex, and update both MDCListFoundation.handleFocusIn, MDCListFoundation.handleFocusOut to pass in listItemIndex
1 parent 3485ae1 commit 53f42b9

File tree

5 files changed

+189
-222
lines changed

5 files changed

+189
-222
lines changed

packages/mdc-list/adapter.js

-9
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,6 @@ class MDCListAdapter {
4444
* @return {number} */
4545
getFocusedElementIndex() {}
4646

47-
/** @param {Element} node */
48-
getListItemIndex(node) {}
49-
5047
/**
5148
* @param {number} index
5249
* @param {string} attribute
@@ -78,12 +75,6 @@ class MDCListAdapter {
7875
*/
7976
focusItemAtIndex(index) {}
8077

81-
/**
82-
* Checks if the provided element is contains the mdc-list-item class.
83-
* @param {Element} ele
84-
*/
85-
isListItem(ele) {}
86-
8778
/**
8879
* Sets the tabindex to the value specified for all button/a element children of
8980
* the list item at the index specified.

packages/mdc-list/foundation.js

+11-34
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,11 @@ class MDCListFoundation extends MDCFoundation {
4747
return /** @type {!MDCListAdapter} */ ({
4848
getListItemCount: () => {},
4949
getFocusedElementIndex: () => {},
50-
getListItemIndex: () => {},
5150
setAttributeForElementIndex: () => {},
5251
removeAttributeForElementIndex: () => {},
5352
addClassForElementIndex: () => {},
5453
removeClassForElementIndex: () => {},
5554
focusItemAtIndex: () => {},
56-
isListItem: () => {},
5755
setTabIndexForListItemChildren: () => {},
5856
followHref: () => {},
5957
});
@@ -135,13 +133,9 @@ class MDCListFoundation extends MDCFoundation {
135133
/**
136134
* Focus in handler for the list items.
137135
* @param evt
136+
* @param {number} listItemIndex
138137
*/
139-
handleFocusIn(evt) {
140-
const listItem = this.getListItem_(evt.target);
141-
if (!listItem) return;
142-
143-
const listItemIndex = this.adapter_.getListItemIndex(listItem);
144-
138+
handleFocusIn(evt, listItemIndex) {
145139
if (listItemIndex >= 0) {
146140
this.adapter_.setTabIndexForListItemChildren(listItemIndex, 0);
147141
}
@@ -150,12 +144,9 @@ class MDCListFoundation extends MDCFoundation {
150144
/**
151145
* Focus out handler for the list items.
152146
* @param {Event} evt
147+
* @param {number} listItemIndex
153148
*/
154-
handleFocusOut(evt) {
155-
const listItem = this.getListItem_(evt.target);
156-
if (!listItem) return;
157-
const listItemIndex = this.adapter_.getListItemIndex(listItem);
158-
149+
handleFocusOut(evt, listItemIndex) {
159150
if (listItemIndex >= 0) {
160151
this.adapter_.setTabIndexForListItemChildren(listItemIndex, -1);
161152
}
@@ -164,8 +155,10 @@ class MDCListFoundation extends MDCFoundation {
164155
/**
165156
* Key handler for the list.
166157
* @param {Event} evt
158+
* @param {boolean} isRootListItem
159+
* @param {number} listItemIndex
167160
*/
168-
handleKeydown(evt) {
161+
handleKeydown(evt, isRootListItem, listItemIndex) {
169162
const arrowLeft = evt.key === 'ArrowLeft' || evt.keyCode === 37;
170163
const arrowUp = evt.key === 'ArrowUp' || evt.keyCode === 38;
171164
const arrowRight = evt.key === 'ArrowRight' || evt.keyCode === 39;
@@ -176,10 +169,8 @@ class MDCListFoundation extends MDCFoundation {
176169
const isSpace = evt.key === 'Space' || evt.keyCode === 32;
177170

178171
let currentIndex = this.adapter_.getFocusedElementIndex();
179-
180172
if (currentIndex === -1) {
181-
currentIndex = this.adapter_.getListItemIndex(this.getListItem_(evt.target));
182-
173+
currentIndex = listItemIndex;
183174
if (currentIndex < 0) {
184175
// If this event doesn't have a mdc-list-item ancestor from the
185176
// current list (not from a sublist), return early.
@@ -202,11 +193,11 @@ class MDCListFoundation extends MDCFoundation {
202193
} else if (this.isSingleSelectionList_ && (isEnter || isSpace)) {
203194
this.preventDefaultEvent_(evt);
204195
// Check if the space key was pressed on the list item or a child element.
205-
if (this.adapter_.isListItem(evt.target)) {
196+
if (isRootListItem) {
206197
this.setSelectedIndex(currentIndex);
207198

208-
// Explicitly activate links, since we're preventing default on Enter, and Space doesn't activate them
209-
this.adapter_.followHref(evt.target);
199+
// Explicitly activate links, since we're preventing default on Enter, and Space doesn't activate them.
200+
this.adapter_.followHref(currentIndex);
210201
}
211202
}
212203
}
@@ -282,20 +273,6 @@ class MDCListFoundation extends MDCFoundation {
282273
this.adapter_.focusItemAtIndex(lastIndex);
283274
}
284275
}
285-
286-
/**
287-
* Utility method to find the first ancestor with the mdc-list-item class.
288-
* @param {EventTarget} target
289-
* @return {?Element}
290-
* @private
291-
*/
292-
getListItem_(target) {
293-
while (!this.adapter_.isListItem(target)) {
294-
if (!target.parentElement) return null;
295-
target = target.parentElement;
296-
}
297-
return target;
298-
}
299276
}
300277

301278
export default MDCListFoundation;

packages/mdc-list/index.js

+64-8
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,10 @@ class MDCList extends MDCComponent {
5959
}
6060

6161
initialSyncWithDOM() {
62-
this.handleKeydown_ = this.foundation_.handleKeydown.bind(this.foundation_);
6362
this.handleClick_ = this.foundation_.handleClick.bind(this.foundation_);
64-
this.focusInEventListener_ = this.foundation_.handleFocusIn.bind(this.foundation_);
65-
this.focusOutEventListener_ = this.foundation_.handleFocusOut.bind(this.foundation_);
63+
this.handleKeydown_ = this.handleKeydownEvent_.bind(this);
64+
this.focusInEventListener_ = this.handleFocusInEvent_.bind(this);
65+
this.focusOutEventListener_ = this.handleFocusOutEvent_.bind(this);
6666
this.root_.addEventListener('keydown', this.handleKeydown_);
6767
this.root_.addEventListener('focusin', this.focusInEventListener_);
6868
this.root_.addEventListener('focusout', this.focusOutEventListener_);
@@ -85,6 +85,63 @@ class MDCList extends MDCComponent {
8585
.forEach((ele) => ele.setAttribute('tabindex', -1));
8686
}
8787

88+
/**
89+
* Used to figure out which list item this event is targetting. Or returns -1 if
90+
* there is no list item
91+
* @param {Event} evt
92+
* @private
93+
*/
94+
getListItemIndex_(evt) {
95+
let eventTarget = /** @type {HTMLElement} */ (evt.target);
96+
let index = -1;
97+
98+
// Find the first ancestor that is a list item or the list.
99+
while (!eventTarget.classList.contains(cssClasses.LIST_ITEM_CLASS)
100+
&& !eventTarget.classList.contains(cssClasses.ROOT)) {
101+
eventTarget = eventTarget.parentElement;
102+
}
103+
104+
// Get the index of the element if it is a list item.
105+
if (eventTarget.classList.contains(cssClasses.LIST_ITEM_CLASS)) {
106+
index = this.listElements_.indexOf(eventTarget);
107+
}
108+
109+
return index;
110+
}
111+
112+
/**
113+
* Used to figure out which element was clicked before sending the event to the foundation.
114+
* @param {Event} evt
115+
* @private
116+
*/
117+
handleFocusInEvent_(evt) {
118+
const index = this.getListItemIndex_(evt);
119+
this.foundation_.handleFocusIn(evt, index);
120+
}
121+
122+
/**
123+
* Used to figure out which element was clicked before sending the event to the foundation.
124+
* @param {Event} evt
125+
* @private
126+
*/
127+
handleFocusOutEvent_(evt) {
128+
const index = this.getListItemIndex_(evt);
129+
this.foundation_.handleFocusOut(evt, index);
130+
}
131+
132+
/**
133+
* Used to figure out which element was clicked before sending the event to the foundation.
134+
* @param {Event} evt
135+
* @private
136+
*/
137+
handleKeydownEvent_(evt) {
138+
const index = this.getListItemIndex_(evt);
139+
140+
if (index >= 0) {
141+
this.foundation_.handleKeydown(evt, evt.target.classList.contains(cssClasses.LIST_ITEM_CLASS), index);
142+
}
143+
}
144+
88145
initializeListType() {
89146
// Automatically set single selection if selected/activated classes are present.
90147
const preselectedElement =
@@ -136,7 +193,6 @@ class MDCList extends MDCComponent {
136193
return new MDCListFoundation(/** @type {!MDCListAdapter} */ (Object.assign({
137194
getListItemCount: () => this.listElements_.length,
138195
getFocusedElementIndex: () => this.listElements_.indexOf(document.activeElement),
139-
getListItemIndex: (node) => this.listElements_.indexOf(node),
140196
setAttributeForElementIndex: (index, attr, value) => {
141197
const element = this.listElements_[index];
142198
if (element) {
@@ -161,7 +217,6 @@ class MDCList extends MDCComponent {
161217
element.classList.remove(className);
162218
}
163219
},
164-
isListItem: (target) => target.classList.contains(cssClasses.LIST_ITEM_CLASS),
165220
focusItemAtIndex: (index) => {
166221
const element = this.listElements_[index];
167222
if (element) {
@@ -173,9 +228,10 @@ class MDCList extends MDCComponent {
173228
const listItemChildren = [].slice.call(element.querySelectorAll(strings.FOCUSABLE_CHILD_ELEMENTS));
174229
listItemChildren.forEach((ele) => ele.setAttribute('tabindex', tabIndexValue));
175230
},
176-
followHref: (ele) => {
177-
if (ele.href) {
178-
ele.click();
231+
followHref: (index) => {
232+
const listItem = this.listElements_[index];
233+
if (listItem && listItem.href) {
234+
listItem.click();
179235
}
180236
},
181237
})));

0 commit comments

Comments
 (0)