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

fix(select): Fix enhanced select issue where it does not stay open on long press #4173 #4590

Merged
merged 6 commits into from
Apr 15, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 3 additions & 10 deletions packages/mdc-select/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,6 @@ import {MDCSelectHelperText, MDCSelectHelperTextFactory} from './helper-text/ind
import {MDCSelectIcon, MDCSelectIconFactory} from './icon/index';
import {MDCSelectEventDetail, MDCSelectFoundationMap} from './types';

type PointerEventType = 'mousedown' | 'touchstart';

const POINTER_EVENTS: PointerEventType[] = ['mousedown', 'touchstart'];
const VALIDATION_ATTR_WHITELIST = ['required', 'aria-required'];

export class MDCSelect extends MDCComponent<MDCSelectFoundation> implements MDCRippleCapableSurface {
Expand Down Expand Up @@ -71,7 +68,7 @@ export class MDCSelect extends MDCComponent<MDCSelectFoundation> implements MDCR
private handleChange_!: SpecificEventListener<'change'>; // assigned in initialize()
private handleFocus_!: SpecificEventListener<'focus'>; // assigned in initialize()
private handleBlur_!: SpecificEventListener<'blur'>; // assigned in initialize()
private handleClick_!: SpecificEventListener<PointerEventType>; // assigned in initialize()
private handleClick_!: SpecificEventListener<'click'>; // assigned in initialize()
private handleKeydown_!: SpecificEventListener<'keydown'>; // assigned in initialize()
private handleMenuOpened_!: EventListener; // assigned in initialize()
private handleMenuClosed_!: EventListener; // assigned in initialize()
Expand Down Expand Up @@ -179,9 +176,7 @@ export class MDCSelect extends MDCComponent<MDCSelectFoundation> implements MDCR
this.targetElement_.addEventListener('focus', this.handleFocus_);
this.targetElement_.addEventListener('blur', this.handleBlur_);

POINTER_EVENTS.forEach((evtType) => {
this.targetElement_.addEventListener(evtType, this.handleClick_ as EventListener);
});
this.targetElement_.addEventListener('click', this.handleClick_ as EventListener);

if (this.menuElement_) {
this.selectedText_!.addEventListener('keydown', this.handleKeydown_);
Expand Down Expand Up @@ -215,9 +210,7 @@ export class MDCSelect extends MDCComponent<MDCSelectFoundation> implements MDCR
this.targetElement_.removeEventListener('focus', this.handleFocus_);
this.targetElement_.removeEventListener('blur', this.handleBlur_);
this.targetElement_.removeEventListener('keydown', this.handleKeydown_);
POINTER_EVENTS.forEach((evtType) => {
this.targetElement_.removeEventListener(evtType, this.handleClick_ as EventListener);
});
this.targetElement_.removeEventListener('click', this.handleClick_ as EventListener);

if (this.menu_) {
this.menu_.unlisten(menuSurfaceConstants.strings.CLOSED_EVENT, this.handleMenuClosed_);
Expand Down
44 changes: 15 additions & 29 deletions test/unit/mdc-select/mdc-select-enhanced.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -984,43 +984,29 @@ test(`#destroy removes the listener for the ${MDCMenuFoundation.strings.SELECTED
document.body.removeChild(fixture);
});

test('#destroy removes the mousedown listener', () => {
const {bottomLine, component, fixture} = setupTest();
const event = document.createEvent('MouseEvent');
test('#destroy removes the click listener', () => {
const {component, selectedText} = setupTest();
const clientX = 200;
const clientY = 200;

component.foundation_.handleClick = td.func();
component.destroy();
// IE11 mousedown event.
event.initMouseEvent('mousedown', true, true, window, 0, 0, 0, clientX, clientY, false, false, false, false, 0, null);
fixture.querySelector('.mdc-select__selected-text').dispatchEvent(event);

td.verify(bottomLine.setRippleCenter(200), {times: 0});
domEvents.emit(selectedText, 'click', {clientX});
td.verify(component.foundation_.handleClick(200), {times: 0});
});

test('mousedown on the select sets the line ripple origin', () => {
const {bottomLine, fixture} = setupTest();
const event = document.createEvent('MouseEvent');
test('click on the selectedText calls foundation.handleClick()', () => {
const {component, selectedText} = setupTest();
const clientX = 200;
const clientY = 200;
// IE11 mousedown event.
event.initMouseEvent('mousedown', true, true, window, 0, 0, 0, clientX, clientY, false, false, false, false, 0, null);
fixture.querySelector('.mdc-select__selected-text').dispatchEvent(event);

td.verify(bottomLine.setRippleCenter(200), {times: 1});
component.foundation_.handleClick = td.func();
domEvents.emit(selectedText, 'click', {clientX});
td.verify(component.foundation_.handleClick(200), {times: 1});
});

test('mousedown on the select does nothing if the it does not have a lineRipple', () => {
const hasOutline = true;
const {bottomLine, fixture} = setupTest(hasOutline);
const event = document.createEvent('MouseEvent');
test('click on the selectedText focuses on the selectedText element', () => {
const {selectedText} = setupTest();
const clientX = 200;
const clientY = 200;
// IE11 mousedown event.
event.initMouseEvent('mousedown', true, true, window, 0, 0, 0, clientX, clientY, false, false, false, false, 0, null);
fixture.querySelector('.mdc-select__selected-text').dispatchEvent(event);

td.verify(bottomLine.setRippleCenter(200), {times: 0});
selectedText.focus = td.func();
domEvents.emit(selectedText, 'click', {clientX});
td.verify(selectedText.focus(), {times: 1});
});

test('menu surface opened event causes the first element (if not element is selected) to be focused', () => {
Expand Down
41 changes: 10 additions & 31 deletions test/unit/mdc-select/mdc-select.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -577,43 +577,22 @@ test('#destroy removes the blur handler', () => {
td.verify(component.foundation_.handleBlur(), {times: 0});
});

test('mousedown on the select sets the line ripple origin', () => {
const {bottomLine, fixture} = setupTest();
const event = document.createEvent('MouseEvent');
test('click on the select calls foundation.handleClick()', () => {
const {component, nativeControl} = setupTest();
const clientX = 200;
const clientY = 200;
// IE11 mousedown event.
event.initMouseEvent('mousedown', true, true, window, 0, 0, 0, clientX, clientY, false, false, false, false, 0, null);
fixture.querySelector('select').dispatchEvent(event);

td.verify(bottomLine.setRippleCenter(200), {times: 1});
component.foundation_.handleClick = td.func();
domEvents.emit(nativeControl, 'click', {clientX});
td.verify(component.foundation_.handleClick(200), {times: 1});
});

test('mousedown on the select does nothing if the it does not have a lineRipple', () => {
const hasOutline = true;
const {bottomLine, fixture} = setupTest(hasOutline);
const event = document.createEvent('MouseEvent');
const clientX = 200;
const clientY = 200;
// IE11 mousedown event.
event.initMouseEvent('mousedown', true, true, window, 0, 0, 0, clientX, clientY, false, false, false, false, 0, null);
fixture.querySelector('select').dispatchEvent(event);

td.verify(bottomLine.setRippleCenter(200), {times: 0});
});

test('#destroy removes the mousedown listener', () => {
const {bottomLine, component, fixture} = setupTest();
const event = document.createEvent('MouseEvent');
test('#destroy removes the click listener', () => {
const {component, nativeControl} = setupTest();
const clientX = 200;
const clientY = 200;

component.foundation_.handleClick = td.func();
component.destroy();
// IE11 mousedown event.
event.initMouseEvent('mousedown', true, true, window, 0, 0, 0, clientX, clientY, false, false, false, false, 0, null);
fixture.querySelector('select').dispatchEvent(event);

td.verify(bottomLine.setRippleCenter(200), {times: 0});
domEvents.emit(nativeControl, 'click', {clientX});
td.verify(component.foundation_.handleClick(200), {times: 0});
});

test('keydown is not added to the native select when initialized', () => {
Expand Down