diff --git a/iron-list.html b/iron-list.html
index d96a4e1f..76fb1860 100644
--- a/iron-list.html
+++ b/iron-list.html
@@ -1862,13 +1862,16 @@
_keydownHandler: function(e) {
switch (e.keyCode) {
case /* ARROW_DOWN */ 40:
- e.preventDefault();
+ if (this._focusedVirtualIndex < this._virtualCount - 1)
+ e.preventDefault();
this._focusPhysicalItem(this._focusedVirtualIndex + (this.grid ? this._itemsPerRow : 1));
break;
case /* ARROW_RIGHT */ 39:
if (this.grid) this._focusPhysicalItem(this._focusedVirtualIndex + (this._isRTL ? -1 : 1));
break;
case /* ARROW_UP */ 38:
+ if (this._focusedVirtualIndex > 0)
+ e.preventDefault();
this._focusPhysicalItem(this._focusedVirtualIndex - (this.grid ? this._itemsPerRow : 1));
break;
case /* ARROW_LEFT */ 37:
diff --git a/test/focus.html b/test/focus.html
index 16012ff0..3fb0347c 100644
--- a/test/focus.html
+++ b/test/focus.html
@@ -252,6 +252,62 @@
});
});
+ test('up arrow when first item has focus, defaultPrevented is false', function(done) {
+ list.items = buildDataSet(2);
+ flush(function() {
+ getNthItemFromList(list, 0).focus();
+ var handler = e => {
+ document.removeEventListener('keydown', handler);
+ assert.isFalse(e.defaultPrevented);
+ done();
+ };
+ document.addEventListener('keydown', handler);
+ MockInteractions.pressAndReleaseKeyOn(list, 38); // up
+ });
+ });
+
+ test('down arrow when last item has focus, defaultPrevented is false', function(done) {
+ list.items = buildDataSet(2);
+ flush(function() {
+ getNthItemFromList(list, 1).focus();
+ var handler = e => {
+ document.removeEventListener('keydown', handler);
+ assert.isFalse(e.defaultPrevented);
+ done();
+ };
+ document.addEventListener('keydown', handler);
+ MockInteractions.pressAndReleaseKeyOn(list, 40); // down
+ });
+ });
+
+ test('up arrow when second item has focus, defaultPrevented is true', function(done) {
+ list.items = buildDataSet(2);
+ flush(function() {
+ getNthItemFromList(list, 1).focus();
+ var handler = e => {
+ document.removeEventListener('keydown', handler);
+ assert.isTrue(e.defaultPrevented);
+ done();
+ };
+ document.addEventListener('keydown', handler);
+ MockInteractions.pressAndReleaseKeyOn(list, 38); // up
+ });
+ });
+
+ test('down arrow when second to last item has focus, defaultPrevented is true', function(done) {
+ list.items = buildDataSet(2);
+ flush(function() {
+ getNthItemFromList(list, 0).focus();
+ var handler = e => {
+ document.removeEventListener('keydown', handler);
+ assert.isTrue(e.defaultPrevented);
+ done();
+ };
+ document.addEventListener('keydown', handler);
+ MockInteractions.pressAndReleaseKeyOn(list, 40); // down
+ });
+ });
+
test('first click recognized in long lists (#411)', function(done) {
list.items = buildDataSet(100);