Skip to content

Commit

Permalink
Fixes #118: Prevent selectCallback from being called multiple times…
Browse files Browse the repository at this point in the history
… when changing selection if multi === false.
  • Loading branch information
bicknellr committed Jul 7, 2017
1 parent bcb18b5 commit 54534d9
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 3 deletions.
42 changes: 39 additions & 3 deletions iron-selection.html
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,10 @@
if (this.multi) {
this.toggle(item);
} else if (this.get() !== item) {
this.setItemSelected(this.get(), false);
this.setItemSelected(item, true);
this._mutateAtomic(function() {
this.setItemSelected(this.get(), false);
this.setItemSelected(item, true);
}, this);
}
},

Expand All @@ -112,8 +114,42 @@
*/
toggle: function(item) {
this.setItemSelected(item, !this.isSelected(item));
}
},

/**
* Runs an arbitrary function (`fn`) but postpones calls normally made to
* `selectCallback` until the function has returned. Additionally, when the
* postponed calls to `selectCallback` are made, only one call will be made
* per item and this call will be provided the *final* selection state of
* that item (after `fn`).
*
* @param {!Function} fn The function to run.
* @param {?Object} thisArg `fn` will be called with `thisArg` as its context.
*/
_mutateAtomic: function(fn, thisArg) {
// TODO(bicknellr): Use Map when IE10 gets dropped.
var items = [];
var finalValues = [];

// Patch `selectCallback` with a function that records results to a map.
var originalSelectCallback = this.selectCallback;
this.selectCallback = function(item, isSelected) {
var index = items.indexOf(item);
if (index < 0) {
index = items.length;
items.push(item);
}
finalValues[index] = isSelected;
};

fn.call(thisArg);

// Restore `selectCallback` and call it with all end results from the map.
this.selectCallback = originalSelectCallback;
for (var i = 0; i < items.length; i++) {
this.selectCallback(items[i], finalValues[i]);
}
}
};

</script>
19 changes: 19 additions & 0 deletions test/basic.html
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,25 @@
assert.equal(selectedEventCounter, 1);
});

test('`selectedItem` does not move through undefined between item changes', function() {
var selectedEventCounter = 0;
s2.addEventListener('selected-item-changed', function(e) {
console.log(e.detail.value);
if (e.detail.value === undefined) debugger;
selectedEventCounter++;
});

s2.selectNext();
s2.selectPrevious();
s2.selectNext();
assert.equal(selectedEventCounter, 3);

s2.selectPrevious();
s2.selectNext();
s2.selectPrevious();
assert.equal(selectedEventCounter, 6);
});

test('set selected to old value', function() {
// setup listener for iron-select event
var selectedEventCounter = 0;
Expand Down

0 comments on commit 54534d9

Please sign in to comment.