Browse Source

Improvements to observed array extension methods

- mutateFilter() is now remove(fn)
- replace() now also takes a function argument
- tests for above
- fix unit tests for IE9
Evan You 12 years ago
parent
commit
19d15ecf8d
5 changed files with 106 additions and 27 deletions
  1. 2 2
      examples/todomvc/js/app.js
  2. 1 1
      src/compiler.js
  3. 35 10
      src/observer.js
  4. 2 0
      test/unit/specs/directives.js
  5. 66 14
      test/unit/specs/observer.js

+ 2 - 2
examples/todomvc/js/app.js

@@ -72,8 +72,8 @@ var app = new Seed({
         },
 
         removeCompleted: function () {
-            this.todos.mutateFilter(function (todo) {
-                return !todo.completed
+            this.todos.remove(function (todo) {
+                return todo.completed
             })
             todoStorage.save()
         },

+ 1 - 1
src/compiler.js

@@ -221,7 +221,7 @@ CompilerProto.compile = function (node, root) {
         var repeatExp,
             componentId,
             partialId,
-            customElementFn = utils.elements[node.tagName.toLowerCase()]
+            customElementFn = compiler.getOption('elements', node.tagName.toLowerCase())
 
         // It is important that we access these attributes
         // procedurally because the order matters.

+ 35 - 10
src/observer.js

@@ -38,19 +38,44 @@ methods.forEach(function (method) {
 // Augment it with several convenience methods
 var extensions = {
     remove: function (index) {
-        if (typeof index !== 'number') index = this.indexOf(index)
-        return this.splice(index, 1)[0]
+        if (typeof index === 'function') {
+            var i = this.length,
+                removed = []
+            while (i--) {
+                if (index(this[i])) {
+                    removed.push(this.splice(i, 1)[0])
+                }
+            }
+            return removed.reverse()
+        } else {
+            if (typeof index !== 'number') {
+                index = this.indexOf(index)
+            }
+            if (index > -1) {
+                return this.splice(index, 1)[0]
+            }
+        }
     },
     replace: function (index, data) {
-        if (typeof index !== 'number') index = this.indexOf(index)
-        if (this[index] !== undefined) return this.splice(index, 1, data)[0]
-    },
-    mutateFilter: function (fn) {
-        var i = this.length
-        while (i--) {
-            if (!fn(this[i])) this.splice(i, 1)
+        if (typeof index === 'function') {
+            var i = this.length,
+                replaced = [],
+                replacer
+            while (i--) {
+                replacer = index(this[i])
+                if (replacer !== undefined) {
+                    replaced.push(this.splice(i, 1, replacer)[0])
+                }
+            }
+            return replaced.reverse()
+        } else {
+            if (typeof index !== 'number') {
+                index = this.indexOf(index)
+            }
+            if (index > -1) {
+                return this.splice(index, 1, data)[0]
+            }
         }
-        return this
     }
 }
 

+ 2 - 0
test/unit/specs/directives.js

@@ -389,10 +389,12 @@ describe('UNIT: Directives', function () {
                     triggered = true
                 }}
                 dir.el.value = 'foo'
+                document.body.appendChild(dir.el)
                 dir.el.dispatchEvent(mockHTMLEvent('input'))
                 // timeout becuase the update is async
                 setTimeout(function () {
                     assert.ok(triggered)
+                    document.body.removeChild(dir.el)
                     done()
                 }, 1)
             })

+ 66 - 14
test/unit/specs/observer.js

@@ -263,44 +263,96 @@ describe('UNIT: Observer', function () {
         })
 
         describe('Augmentations', function () {
+
+            it('remove (index)', function () {
+                var emitted = false,
+                    index = ~~(Math.random() * arr.length),
+                    expected = arr[index] = { a: 1 }
+                ob.once('mutate', function (key, array, mutation) {
+                    emitted = true
+                    assert.strictEqual(mutation.method, 'splice')
+                    assert.strictEqual(mutation.args.length, 2)
+                    assert.strictEqual(mutation.args[0], index)
+                })
+                var r = arr.remove(index)
+                assert.ok(emitted)
+                assert.strictEqual(r, expected)
+            })
             
-            it('remove', function () {
+            it('remove (object)', function () {
                 var emitted = false,
-                    expected = arr[0] = { a: 1 }
+                    index = ~~(Math.random() * arr.length),
+                    expected = arr[index] = { a: 1 }
                 ob.once('mutate', function (key, array, mutation) {
                     emitted = true
                     assert.strictEqual(mutation.method, 'splice')
                     assert.strictEqual(mutation.args.length, 2)
+                    assert.strictEqual(mutation.args[0], index)
                 })
                 var r = arr.remove(expected)
                 assert.ok(emitted)
                 assert.strictEqual(r, expected)
             })
 
-            it('replace', function () {
+            it('remove (function)', function () {
+                var expected = [1001, 1002]
+                arr.push.apply(arr, expected)
+                var filter = function (e) {
+                        return e > 1000
+                    },
+                    copy = arr.filter(function (e) {
+                        return e <= 1000
+                    })
+                var removed = arr.remove(filter)
+                assert.deepEqual(arr, copy)
+                assert.deepEqual(expected, removed)
+            })
+
+            it('replace (index)', function () {
+                var emitted = false,
+                    index = ~~(Math.random() * arr.length),
+                    expected = arr[index] = { a: 1 },
+                    arg = 34567
+                ob.once('mutate', function (key, array, mutation) {
+                    emitted = true
+                    assert.strictEqual(mutation.method, 'splice')
+                    assert.strictEqual(mutation.args.length, 3)
+                    assert.strictEqual(mutation.args[0], index)
+                })
+                var r = arr.replace(index, arg)
+                assert.ok(emitted)
+                assert.strictEqual(r, expected)
+                assert.strictEqual(arr[index], arg)
+            })
+
+            it('replace (object)', function () {
                 var emitted = false,
-                    expected = arr[0] = { a: 1 },
+                    index = ~~(Math.random() * arr.length),
+                    expected = arr[index] = { a: 1 },
                     arg = 45678
                 ob.once('mutate', function (key, array, mutation) {
                     emitted = true
                     assert.strictEqual(mutation.method, 'splice')
                     assert.strictEqual(mutation.args.length, 3)
+                    assert.strictEqual(mutation.args[0], index)
                 })
                 var r = arr.replace(expected, arg)
                 assert.ok(emitted)
                 assert.strictEqual(r, expected)
-                assert.strictEqual(arr[0], arg)
+                assert.strictEqual(arr[index], arg)
             })
 
-            it('mutateFilter', function () {
-                var filter = function (e) {
-                        return e > 1000
-                    },
-                    copy = arr.slice().filter(filter)
-                arr.mutateFilter(filter)
-                for (var i = 0; i < copy.length; i++) {
-                    assert.strictEqual(arr[i], copy[i])
-                }
+            it('replace (function)', function () {
+                arr[0] = 1
+                arr[1] = 2
+                arr[2] = 3
+                var expected = [2, 3, 3],
+                    expectRet = [1, 2]
+                var replaced = arr.replace(function (e) {
+                    if (e < 3) return e + 1
+                })
+                assert.deepEqual(arr, expected)
+                assert.deepEqual(replaced, expectRet)
             })
 
         })