Skip to content

Commit

Permalink
Refactor inert to explicitly disable fields
Browse files Browse the repository at this point in the history
  • Loading branch information
aduth committed Jul 24, 2017
1 parent 7ad484f commit f452481
Showing 1 changed file with 12 additions and 80 deletions.
92 changes: 12 additions & 80 deletions components/inert/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,93 +3,25 @@
*/
import { Component } from 'element';

const focusable = [
'INPUT',
'SELECT',
'TEXTAREA',
'BUTTON',
'OBJECT',
];

function isFocusable( node ) {
if ( node.tabIndex < 0 ) {
return false;
} else if ( -1 !== focusable.indexOf( node.nodeName ) ) {
return ! node.disabled;
} else if ( 'A' === node.nodeName || 'AREA' === node.nodeName ) {
return node.hasAttribute( 'href' );
}

return node.tabIndex >= 0;
}

function getNextFocusable( node, siblingDirection ) {
let parent = node.parentNode;

let childDirection;
if ( 'nextSibling' === siblingDirection ) {
childDirection = 'firstChild';
} else {
childDirection = 'lastChild';
}

do {
while ( node[ siblingDirection ] ) {
if ( isFocusable( node[ siblingDirection ] ) ) {
return node[ siblingDirection ];
}

node = node[ siblingDirection ];
}

node = parent[ siblingDirection ];
if ( node ) {
while ( node[ childDirection ] ) {
node = node[ childDirection ];
}
} else {
node = parent;
}

if ( isFocusable( node ) ) {
return node;
}

parent = node.parentNode;
} while ( parent );
}

class Inert extends Component {
constructor() {
super( ...arguments );

this.onKeyPress = this.onKeyPress.bind( this );
}

componentDidMount() {
document.addEventListener( 'keydown', this.onKeyPress );
this.disableFields();
}

componentWillUnmount() {
document.removeEventListener( 'keydown', this.onKeyPress );
componentDidUpdate() {
this.disableFields();
}

onKeyPress( event ) {
if ( event.which !== 9 ) {
return;
}

const testDirection = event.shiftKey ? 'nextSibling' : 'previousSibling';
if ( event.target !== getNextFocusable( this.node, testDirection ) ) {
return;
}
disableFields() {
const focusables = this.node.querySelectorAll( 'input,select,textarea,button,object,a,area' );
Array.prototype.forEach.call( focusables, ( node ) => {
node.tabIndex = -1;
} );

const nextDirection = event.shiftKey ? 'previousSibling' : 'nextSibling';
const nextFocusable = getNextFocusable( this.node, nextDirection );
if ( nextFocusable ) {
nextFocusable.focus();
event.preventDefault();
}
const editables = this.node.querySelectorAll( '[contenteditable]' );
Array.prototype.forEach.call( editables, ( node ) => {
node.removeAttribute( 'contenteditable' );
} );
}

render() {
Expand Down

0 comments on commit f452481

Please sign in to comment.