Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use blocking elements #327

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
76 changes: 24 additions & 52 deletions app-drawer/app-drawer.html
Original file line number Diff line number Diff line change
Expand Up @@ -254,10 +254,6 @@

_boundEscKeydownHandler: null,

_firstTabStop: null,

_lastTabStop: null,

attached: function() {
// Only transition the drawer after its first render (e.g. app-drawer-layout
// may need to set the initial opened state which should not be transitioned).
Expand All @@ -273,8 +269,6 @@
this.$.scrim.addEventListener('transitionend', this._transitionend.bind(this));
this.$.contentContainer.addEventListener('transitionend', this._transitionend.bind(this));

this.addEventListener('keydown', this._tabKeydownHandler.bind(this))

// Only listen for horizontal track so you can vertically scroll inside the drawer.
this.listen(this, 'track', '_track');
this.setScrollDirection('y');
Expand All @@ -285,6 +279,9 @@

detached: function() {
document.removeEventListener('keydown', this._boundEscKeydownHandler);
if (document.$blockingElements) {
document.$blockingElements.remove(this);
}
},

/**
Expand Down Expand Up @@ -566,6 +563,9 @@
} else {
document.removeEventListener('keydown', this._boundEscKeydownHandler);
document.body.style.overflow = '';
if (document.$blockingElements) {
document.$blockingElements.remove(this);
}
}

// Don't fire the event on initial load.
Expand All @@ -579,29 +579,8 @@
if (this.noFocusTrap) {
return;
}

// NOTE: Unless we use /deep/ (which we shouldn't since it's deprecated), this will
// not select focusable elements inside shadow roots.
var focusableElementsSelector = [
'a[href]:not([tabindex="-1"])',
'area[href]:not([tabindex="-1"])',
'input:not([disabled]):not([tabindex="-1"])',
'select:not([disabled]):not([tabindex="-1"])',
'textarea:not([disabled]):not([tabindex="-1"])',
'button:not([disabled]):not([tabindex="-1"])',
'iframe:not([tabindex="-1"])',
'[tabindex]:not([tabindex="-1"])',
'[contentEditable=true]:not([tabindex="-1"])'
].join(',');
var focusableElements = Polymer.dom(this).querySelectorAll(focusableElementsSelector);

if (focusableElements.length > 0) {
this._firstTabStop = focusableElements[0];
this._lastTabStop = focusableElements[focusableElements.length - 1];
} else {
// Reset saved tab stops when there are no focusable elements in the drawer.
this._firstTabStop = null;
this._lastTabStop = null;
if (document.$blockingElements) {
document.$blockingElements.push(this);
}

// Focus on app-drawer if it has non-zero tabindex. Otherwise, focus the first focusable
Expand All @@ -610,29 +589,22 @@
var tabindex = this.getAttribute('tabindex');
if (tabindex && parseInt(tabindex, 10) > -1) {
this.focus();
} else if (this._firstTabStop) {
this._firstTabStop.focus();
}
},

_tabKeydownHandler: function(event) {
if (this.noFocusTrap) {
return;
}

var TAB_KEYCODE = 9;
if (this._drawerState === this._DRAWER_STATE.OPENED && event.keyCode === TAB_KEYCODE) {
if (event.shiftKey) {
if (this._firstTabStop && Polymer.dom(event).localTarget === this._firstTabStop) {
event.preventDefault();
this._lastTabStop.focus();
}
} else {
if (this._lastTabStop && Polymer.dom(event).localTarget === this._lastTabStop) {
event.preventDefault();
this._firstTabStop.focus();
}
}
} else {
// NOTE: Unless we use /deep/ (which we shouldn't since it's deprecated), this will
// not select focusable elements inside shadow roots.
var selector = [
'a[href]:not([tabindex="-1"])',
'area[href]:not([tabindex="-1"])',
'input:not([disabled]):not([tabindex="-1"])',
'select:not([disabled]):not([tabindex="-1"])',
'textarea:not([disabled]):not([tabindex="-1"])',
'button:not([disabled]):not([tabindex="-1"])',
'iframe:not([tabindex="-1"])',
'[tabindex]:not([tabindex="-1"])',
'[contentEditable=true]:not([tabindex="-1"])'
].join(',');
var firstTabStop = Polymer.dom(this).querySelectorAll(selector)[0];
firstTabStop && firstTabStop.focus();
}
},

Expand Down
2 changes: 2 additions & 0 deletions app-drawer/demo/right-drawer.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
<title>app-drawer demo</title>

<script src="../../../webcomponentsjs/webcomponents-lite.js"></script>
<script src="../../../blockingElements/blocking-elements.js"></script>
<script src="../../../inert/inert.js"></script>

<link rel="import" href="../../../font-roboto/roboto.html">
<link rel="import" href="../../../iron-icons/iron-icons.html">
Expand Down
36 changes: 9 additions & 27 deletions app-drawer/test/app-drawer.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@
<script src="../../../webcomponentsjs/webcomponents-lite.js"></script>
<script src="../../../web-component-tester/browser.js"></script>
<script src="../../../test-fixture/test-fixture-mocha.js"></script>

<script src="../../../blockingElements/blocking-elements.js"></script>
<script src="../../../inert/inert.js"></script>

<link rel="import" href="../../../polymer/polymer.html">
<link rel="import" href="../../../test-fixture/test-fixture.html">
<link rel="import" href="../app-drawer.html">
Expand Down Expand Up @@ -69,7 +73,7 @@
function fireKeydownEvent(target, keyCode, shiftKey) {
var e = new CustomEvent('keydown', {
bubbles: true,
cancelable: true
cancelable: true
});
e.keyCode = keyCode;
e.shiftKey = !!shiftKey;
Expand Down Expand Up @@ -285,7 +289,7 @@
assert.isFalse(drawer.opened);
assert.equal(listenerSpy.callCount, 4,
'should fire after swiping even if opened state unchanged');

drawer.fire('track', { state: 'start' });
drawer.fire('track', { state: 'track', dx: 200, ddx: 200 });
drawer.fire('track', { state: 'end', dx: 200, ddx: 0 });
Expand Down Expand Up @@ -337,7 +341,7 @@

assert.isFalse(drawer.opened);
assert.equal(listenerSpy.callCount, 3, 'should fire after flinging');

drawer.fire('track', { state: 'start' });
drawer.fire('track', { state: 'track', dx: 200, ddx: 200 });
drawer.fire('track', { state: 'end', dx: 200, ddx: 0 });
Expand Down Expand Up @@ -653,36 +657,14 @@
var root = Polymer.dom(focusDrawer.root);
var drawer = root.querySelector('app-drawer');
var input = Polymer.dom(drawer).querySelector('input');
var div = Polymer.dom(drawer).querySelector('div[tabindex]');
var inputFocusSpy = sinon.spy(input, 'focus');
var divFocusSpy = sinon.spy(div, 'focus');

Polymer.RenderStatus.afterNextRender(drawer, function() {
drawer.transitionDuration = 0;
drawer.opened = true;

assert.isTrue(inputFocusSpy.called);

var e = fireKeydownEvent(input, 9);

assert.isFalse(e.defaultPrevented, 'should not prevent default');

input.focus();
inputFocusSpy.reset();
e = fireKeydownEvent(input, 9, true /* shiftKey */);

assert.isTrue(divFocusSpy.called);
assert.isTrue(e.defaultPrevented, 'should prevent default');

e = fireKeydownEvent(div, 9, true /* shiftKey */);

assert.isFalse(e.defaultPrevented, 'should not prevent default');

div.focus();
e = fireKeydownEvent(div, 9);

assert.isTrue(inputFocusSpy.called);
assert.isTrue(e.defaultPrevented, 'should prevent default');
assert.equal(document.$blockingElements.top, drawer, 'drawer is the top blocking element');
done();
});
});
Expand Down Expand Up @@ -712,7 +694,7 @@
var drawer = root.querySelector('app-drawer');
var input = Polymer.dom(drawer).querySelector('input');
var inputFocusSpy = sinon.spy(input, 'focus');

Polymer.RenderStatus.afterNextRender(drawer, function() {
drawer.transitionDuration = 0;
drawer.noFocusTrap = true;
Expand Down
4 changes: 3 additions & 1 deletion bower.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@
"paper-tabs": "PolymerElements/paper-tabs#^1.0.0",
"test-fixture": "PolymerElements/test-fixture#^1.0.0",
"web-component-tester": "^4.0.0",
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0",
"blockingElements": "PolymerLabs/blockingElements#issue-2",
"inert": "WICG/inert"
},
"ignore": [],
"private": true
Expand Down