Skip to content

Commit

Permalink
Detect all valid selection-capable input types
Browse files Browse the repository at this point in the history
  • Loading branch information
acusti committed Nov 19, 2017
1 parent 39a9589 commit 82443f7
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 28 deletions.
65 changes: 39 additions & 26 deletions packages/react-dom/src/__tests__/ReactInputSelection-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,37 +36,50 @@ describe('ReactInputSelection', () => {
expect(ReactInputSelection.hasSelectionCapabilities(textarea)).toBe(true);
});

it('returns true for text inputs', () => {
var inputText = document.createElement('input');
it('returns true for inputs that can support text selection ranges', () => {
[
'date',
'datetime-local',
'email',
'month',
'number',
'password',
'search',
'tel',
'text',
'time',
'url',
'week',
].forEach(type => {
const input = document.createElement('input');
input.type = type;
expect(ReactInputSelection.hasSelectionCapabilities(input)).toBe(true);
});

var inputReadOnly = document.createElement('input');
inputReadOnly.readOnly = 'true';
var inputNumber = document.createElement('input');
inputNumber.type = 'number';
var inputEmail = document.createElement('input');
inputEmail.type = 'email';
var inputPassword = document.createElement('input');
inputPassword.type = 'password';
var inputHidden = document.createElement('input');
inputHidden.type = 'hidden';

expect(ReactInputSelection.hasSelectionCapabilities(inputText)).toBe(
true,
);
expect(ReactInputSelection.hasSelectionCapabilities(inputReadOnly)).toBe(
true,
);
expect(ReactInputSelection.hasSelectionCapabilities(inputNumber)).toBe(
false,
);
expect(ReactInputSelection.hasSelectionCapabilities(inputEmail)).toBe(
false,
);
expect(ReactInputSelection.hasSelectionCapabilities(inputPassword)).toBe(
false,
);
expect(ReactInputSelection.hasSelectionCapabilities(inputHidden)).toBe(
false,
);
});

it('returns false for non-text-selectable inputs', () => {
[
'button',
'checkbox',
'color',
'file',
'hidden',
'image',
'radio',
'range',
'reset',
'submit',
].forEach(type => {
const input = document.createElement('input');
input.type = type;
expect(ReactInputSelection.hasSelectionCapabilities(input)).toBe(false);
});
});

it('returns true for contentEditable elements', () => {
Expand Down
17 changes: 15 additions & 2 deletions packages/react-dom/src/client/ReactInputSelection.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,12 +113,25 @@ function focusNodePreservingScroll(element) {
* assume buttons have range selections allowed).
* Input selection module for React.
*/

const selectionCapableTypes = [
'date',
'datetime-local',
'email',
'month',
'number',
'password',
'search',
'tel',
'text',
'time',
'url',
'week',
];
export function hasSelectionCapabilities(elem) {
const nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
return (
nodeName &&
((nodeName === 'input' && elem.type === 'text') ||
((nodeName === 'input' && selectionCapableTypes.includes(elem.type)) ||
nodeName === 'textarea' ||
elem.contentEditable === 'true')
);
Expand Down

0 comments on commit 82443f7

Please sign in to comment.