From 1d9df4abb5f5719d12a77d3d0d7d8ccbf3e09cc5 Mon Sep 17 00:00:00 2001 From: Kresten Krab Thorup Date: Wed, 14 Dec 2011 09:25:11 +0100 Subject: [PATCH 1/3] 'continue' and 'delete' are somehow reserved The closure compiler trips on these as method names, so we simply use array-index syntax to access these properties. --- src/adapters/indexed-db.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/adapters/indexed-db.js b/src/adapters/indexed-db.js index 8d49ef90..755da2bc 100644 --- a/src/adapters/indexed-db.js +++ b/src/adapters/indexed-db.js @@ -169,7 +169,7 @@ Lawnchair.adapter('indexed-db', (function(){ var cursor = event.target.result; if (cursor) { toReturn.push(cursor.value); - cursor.continue(); + cursor['continue'](); } else { if (cb) cb.call(self, toReturn); @@ -191,7 +191,7 @@ Lawnchair.adapter('indexed-db', (function(){ var self = this; var win = function () { if (callback) self.lambda(callback).call(self) }; - var request = this.db.transaction(["teststore"], webkitIDBTransaction.READ_WRITE).objectStore("teststore").delete(keyOrObj); + var request = this.db.transaction(["teststore"], READ_WRITE).objectStore("teststore")['delete'](keyOrObj); request.onsuccess = win; request.onerror = fail; return this; From a99108a29358c66d8a4ceb725eef678c7ad93e55 Mon Sep 17 00:00:00 2001 From: Kresten Krab Thorup Date: Wed, 14 Dec 2011 10:00:42 +0100 Subject: [PATCH 2/3] Allow adapter to implement async_each --- src/Lawnchair.js | 20 +++++++++++++++----- src/adapters/indexed-db.js | 25 ++++++++++++++++++++++++- test/lawnchair-spec.js | 2 +- 3 files changed, 40 insertions(+), 7 deletions(-) diff --git a/src/Lawnchair.js b/src/Lawnchair.js index 9a891756..38f35603 100644 --- a/src/Lawnchair.js +++ b/src/Lawnchair.js @@ -76,7 +76,10 @@ Lawnchair.adapter = function (id, obj) { , indexOf = this.prototype.indexOf // mix in the adapter for (var i in obj) { - if (indexOf(implementing, i) === -1) throw 'Invalid adapter! Nonstandard method: ' + i + if (indexOf(implementing, i) === -1) { + if (i != 'async_each') + throw 'Invalid adapter '+id+'! Nonstandard method: ' + i + } } // if we made it this far the adapter interface is valid Lawnchair.adapters.push(obj) @@ -133,17 +136,24 @@ Lawnchair.prototype = { }, // a classic iterator - each: function (callback) { + each: function (callback, done_callback) { var cb = this.lambda(callback) + var cb2 = this.lambda(done_callback) // iterate from chain if (this.__results) { for (var i = 0, l = this.__results.length; i < l; i++) cb.call(this, this.__results[i], i) + if (cb2) cb2.call(this, null, -1); } // otherwise iterate the entire collection else { - this.all(function(r) { - for (var i = 0, l = r.length; i < l; i++) cb.call(this, r[i], i) - }) + if (this.async_each) { + this.async_each(cb, cb2); + } else { + this.all(function(r) { + for (var i = 0, l = r.length; i < l; i++) cb.call(this, r[i], i); + if (cb2) cb2.call(this, null, -1); + }) + } } return this } diff --git a/src/adapters/indexed-db.js b/src/adapters/indexed-db.js index 755da2bc..57ded05e 100644 --- a/src/adapters/indexed-db.js +++ b/src/adapters/indexed-db.js @@ -154,8 +154,31 @@ Lawnchair.adapter('indexed-db', (function(){ return this; }, - all:function(callback) { + async_each: function (callback, done_callback) { if(!this.store) { + this.waiting.push(function() { + this.async_each(callback, done_callback); + }); + return; + } + var self = this; + var objectStore = this.db.transaction("teststore").objectStore("teststore"); + var index = 0; + objectStore.openCursor().onsuccess = function(event) { + var cursor = event.target.result; + if (cursor) { + if (callback) callback.call(self, cursor.value, index++); + cursor['continue'](); + } + else { + if (done_callback) done_callback.call(self, null, -1); + } + }; + return this; + }, + + all:function(callback) { + if(!this.store) { this.waiting.push(function() { this.all(callback); }); diff --git a/test/lawnchair-spec.js b/test/lawnchair-spec.js index 502963db..5c163502 100755 --- a/test/lawnchair-spec.js +++ b/test/lawnchair-spec.js @@ -109,7 +109,7 @@ test('scoped variable in shorthand callback', function() { var tmp = new Lawnchair({name:'temps', record:'tmp'}, function() { this.nuke(function() { this.save({a:1}, function() { - this.each('ok(tmp, "this.record is passed to each callback"); QUnit.start()') + this.each('ok(tmp, "this.record is passed to each callback");', 'QUnit.start()') }) }) }) From 99af9a1ba6092af14fa5cbeefba5a349940e5e4b Mon Sep 17 00:00:00 2001 From: Kresten Krab Thorup Date: Wed, 14 Dec 2011 10:01:19 +0100 Subject: [PATCH 3/3] Define in-line constants for transaction types --- src/adapters/indexed-db.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/adapters/indexed-db.js b/src/adapters/indexed-db.js index 57ded05e..a7180f55 100644 --- a/src/adapters/indexed-db.js +++ b/src/adapters/indexed-db.js @@ -13,7 +13,9 @@ Lawnchair.adapter('indexed-db', (function(){ return window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.oIndexedDB || window.msIndexedDB; }; - + var READ_ONLY = 0; + var READ_WRITE = 1; + var VERSION_CHANGE = 2; return { @@ -68,7 +70,7 @@ Lawnchair.adapter('indexed-db', (function(){ var self = this; var win = function (e) { if (callback) { obj.key = e.target.result; self.lambda(callback).call(self, obj) }}; - var trans = this.db.transaction(["teststore"], webkitIDBTransaction.READ_WRITE, 0); + var trans = this.db.transaction(["teststore"], READ_WRITE, 0); var store = trans.objectStore("teststore"); var request = obj.key ? store.put(obj, obj.key) : store.put(obj); @@ -87,7 +89,7 @@ Lawnchair.adapter('indexed-db', (function(){ var updateProgress = function(obj) { results.push(obj) - done = results.length === objs.length + done = (results.length === objs.length) } var checkProgress = setInterval(function() { @@ -233,7 +235,7 @@ Lawnchair.adapter('indexed-db', (function(){ try { this.db - .transaction(["teststore"], webkitIDBTransaction.READ_WRITE) + .transaction(["teststore"], READ_WRITE) .objectStore("teststore").clear().onsuccess = win; } catch(e) {