From be910ab9f0ba066f4db603d03e790389fe15b9f1 Mon Sep 17 00:00:00 2001 From: Jordan Majd Date: Sat, 5 Sep 2015 06:08:26 -0600 Subject: [PATCH 1/3] fix(md-chips): appendChip disallows identical objects md-chips' appendChip disallows appending an identical string or an exact object (duplicate object) more than once. It now disallows identical objects from being appended. fixes angular/material#4466 --- src/components/chips/chips.spec.js | 24 ++++++++++++++++++++++ src/components/chips/js/chipsController.js | 20 +++++++++++------- 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/src/components/chips/chips.spec.js b/src/components/chips/chips.spec.js index 1e519f4208e..3a1761baf06 100644 --- a/src/components/chips/chips.spec.js +++ b/src/components/chips/chips.spec.js @@ -218,6 +218,30 @@ describe('', function() { expect(scope.appendChip.calls.mostRecent().args[0]).toBe('Apple'); }); + it('should disallow identical object chips', function() { + var element = buildChips(CHIP_APPEND_TEMPLATE); + var ctrl = element.controller('mdChips'); + + ctrl.items = [{name: 'Apple', uppername: 'APPLE'}]; + + var chipObj = function(chip) { + return { + name: chip, + uppername: chip.toUpperCase() + }; + }; + scope.appendChip = jasmine.createSpy('appendChip').and.callFake(chipObj); + + element.scope().$apply(function() { + ctrl.chipBuffer = 'Apple'; + simulateInputEnterKey(ctrl); + }); + + expect(ctrl.items.length).toBe(1); + expect(scope.appendChip).toHaveBeenCalled(); + expect(scope.appendChip.calls.mostRecent().args[0]).toBe('Apple'); + }); + it('should prevent the default when backspace is pressed', inject(function($mdConstant) { var element = buildChips(BASIC_CHIP_TEMPLATE); var ctrl = element.controller('mdChips'); diff --git a/src/components/chips/js/chipsController.js b/src/components/chips/js/chipsController.js index e43efff4da2..46be8106346 100644 --- a/src/components/chips/js/chipsController.js +++ b/src/components/chips/js/chipsController.js @@ -192,13 +192,19 @@ MdChipsCtrl.prototype.getAdjacentChipIndex = function(index) { * call out to the md-on-append method, if provided * @param newChip */ -MdChipsCtrl.prototype.appendChip = function(newChip) { - if (this.useOnAppend && this.onAppend) { - newChip = this.onAppend({'$chip': newChip}); - } - if (this.items.indexOf(newChip) + 1) return; - this.items.push(newChip); -}; + MdChipsCtrl.prototype.appendChip = function(newChip) { + if (this.useOnAppend && this.onAppend) { + newChip = this.onAppend({'$chip': newChip}); + } + if(typeof newChip === 'object'){ + var identical = this.items.filter(function(item){ + return angular.equals(newChip, item); + }); + if(identical.length > 0) return; + } + if (this.items.indexOf(newChip) + 1) return; + this.items.push(newChip); + }; /** * Sets whether to use the md-on-append expression. This expression is From 46be703585fa9d2e0ed680e9cbd53a6d8ed1cfa3 Mon Sep 17 00:00:00 2001 From: Jordan Majd Date: Wed, 9 Sep 2015 18:13:47 -0600 Subject: [PATCH 2/3] perf(md-chips): appendChips object check loop optimized md-chips' appendChip uses a filter to loop through items to search for an identical object to chip. This is inefficient since it will keep searching even after it finds a match. Now mdchips appendChip uses a some loop, which stops execution as soon as a match is found. --- src/components/chips/js/chipsController.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/chips/js/chipsController.js b/src/components/chips/js/chipsController.js index 46be8106346..ca3766d8da1 100644 --- a/src/components/chips/js/chipsController.js +++ b/src/components/chips/js/chipsController.js @@ -197,10 +197,10 @@ MdChipsCtrl.prototype.getAdjacentChipIndex = function(index) { newChip = this.onAppend({'$chip': newChip}); } if(typeof newChip === 'object'){ - var identical = this.items.filter(function(item){ + var identical = this.items.some(function(item){ return angular.equals(newChip, item); }); - if(identical.length > 0) return; + if(identical) return; } if (this.items.indexOf(newChip) + 1) return; this.items.push(newChip); From 62a0542d5593f9d25b4e39270d67fb8042bbd2d3 Mon Sep 17 00:00:00 2001 From: Jordan Majd Date: Thu, 10 Sep 2015 13:00:17 -0600 Subject: [PATCH 3/3] style(md-chips): adds comments and whitespace to appendChip md-chips appendChip now is styled with comments and whitespaces to enhance readability. --- src/components/chips/js/chipsController.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/components/chips/js/chipsController.js b/src/components/chips/js/chipsController.js index ca3766d8da1..7543f8e7f74 100644 --- a/src/components/chips/js/chipsController.js +++ b/src/components/chips/js/chipsController.js @@ -193,16 +193,24 @@ MdChipsCtrl.prototype.getAdjacentChipIndex = function(index) { * @param newChip */ MdChipsCtrl.prototype.appendChip = function(newChip) { + + // If useOnAppend and onAppend function is provided call it. if (this.useOnAppend && this.onAppend) { newChip = this.onAppend({'$chip': newChip}); } - if(typeof newChip === 'object'){ + + // If items contains identical object to newChip do not append + if(angular.isObject(newChip)){ var identical = this.items.some(function(item){ return angular.equals(newChip, item); }); if(identical) return; } + + // If items contains newChip do not append if (this.items.indexOf(newChip) + 1) return; + + //add newChip to items this.items.push(newChip); };