[WO-673] Remove cruft from lawnchair

This commit is contained in:
Felix Hammerl 2014-12-04 18:30:12 +01:00
parent 1979903943
commit 10c3748249
2 changed files with 80 additions and 235 deletions

View File

@ -7,126 +7,87 @@
Lawnchair.adapter('indexed-db', (function(){
function fail(e, i) { console.error('error in indexed-db adapter!', e, i); }
// update the STORE_VERSION when the schema used by this adapter changes
// (for example, if you change the STORE_NAME above)
// NB: Causes onupgradeneeded to be fired, which erases the old database!
var STORE_VERSION = 3;
var getIDB = function() {
return window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.oIndexedDB || window.msIndexedDB;
};
var getIDBTransaction = function() {
return window.IDBTransaction || window.webkitIDBTransaction ||
window.mozIDBTransaction || window.oIDBTransaction ||
window.msIDBTransaction;
};
var getIDBKeyRange = function() {
return window.IDBKeyRange || window.webkitIDBKeyRange ||
window.mozIDBKeyRange || window.oIDBKeyRange ||
window.msIDBKeyRange;
};
var getIDBDatabaseException = function() {
return window.IDBDatabaseException || window.webkitIDBDatabaseException ||
window.mozIDBDatabaseException || window.oIDBDatabaseException ||
window.msIDBDatabaseException;
};
var useAutoIncrement = function() {
// using preliminary mozilla implementation which doesn't support
// auto-generated keys. Neither do some webkit implementations.
return !!window.indexedDB;
return window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.oIndexedDB || window.msIndexedDB;
};
var getIDBTransaction = function() {
return window.IDBTransaction || window.webkitIDBTransaction || window.mozIDBTransaction || window.oIDBTransaction || window.msIDBTransaction;
};
var getIDBKeyRange = function() {
return window.IDBKeyRange || window.webkitIDBKeyRange || window.mozIDBKeyRange || window.oIDBKeyRange || window.msIDBKeyRange;
};
// see https://groups.google.com/a/chromium.org/forum/?fromgroups#!topic/chromium-html5/OhsoAQLj7kc
var READ_WRITE = (getIDBTransaction() &&
'READ_WRITE' in getIDBTransaction()) ?
getIDBTransaction().READ_WRITE : 'readwrite';
var READ_WRITE = (getIDBTransaction() && 'READ_WRITE' in getIDBTransaction()) ? getIDBTransaction().READ_WRITE : 'readwrite';
return {
valid: function() { return !!getIDB(); },
init:function(options, callback) {
this.idb = getIDB();
this.waiting = [];
this.useAutoIncrement = useAutoIncrement();
var request = this.idb.open(this.name, STORE_VERSION);
var self = this;
var cb = self.fn(self.name, callback);
if (cb && typeof cb != 'function') throw 'callback not valid';
var win = function() {
// manually clean up event handlers on request; this helps on chrome
request.onupgradeneeded = request.onsuccess = request.error = null;
if(cb) return cb.call(self, self);
};
var upgrade = function(from, to) {
// don't try to migrate dbs, just recreate
try {
self.db.deleteObjectStore('teststore'); // old adapter
} catch (e1) { /* ignore */ }
try {
self.db.deleteObjectStore(self.record);
} catch (e2) { /* ignore */ }
valid: function() {
return !!getIDB();
},
// ok, create object store.
var params = {};
if (self.useAutoIncrement) { params.autoIncrement = true; }
self.db.createObjectStore(self.record, params);
self.store = true;
};
request.onupgradeneeded = function(event) {
init: function(options, callback) {
var self = this;
var cb = self.fn(self.name, callback);
if (cb && typeof cb !== 'function') {
throw 'callback not valid';
}
// queues pending operations
self.waiting = [];
// open idb
self.idb = getIDB();
var request = self.idb.open(self.name, STORE_VERSION);
// attach callback handlers
request.onerror = fail;
request.onupgradeneeded = onupgradeneeded;
request.onsuccess = onsuccess;
// first start or indexeddb needs a version upgrade
function onupgradeneeded() {
self.db = request.result;
self.transaction = request.transaction;
upgrade(event.oldVersion, event.newVersion);
// will end up in onsuccess callback
};
request.onsuccess = function(event) {
self.db = event.target.result;
if(self.db.version != (''+STORE_VERSION)) {
// DEPRECATED API: modern implementations will fire the
// upgradeneeded event instead.
var oldVersion = self.db.version;
var setVrequest = self.db.setVersion(''+STORE_VERSION);
// onsuccess is the only place we can create Object Stores
setVrequest.onsuccess = function(event) {
var transaction = setVrequest.result;
setVrequest.onsuccess = setVrequest.onerror = null;
// can't upgrade w/o versionchange transaction.
upgrade(oldVersion, STORE_VERSION);
transaction.oncomplete = function() {
for (var i = 0; i < self.waiting.length; i++) {
self.waiting[i].call(self);
}
self.waiting = [];
win();
};
};
setVrequest.onerror = function(e) {
setVrequest.onsuccess = setVrequest.onerror = null;
console.error("Failed to create objectstore " + e);
fail(e);
};
} else {
self.store = true;
for (var i = 0; i < self.waiting.length; i++) {
self.waiting[i].call(self);
}
self.waiting = [];
win();
// NB! in case of a version conflict, we don't try to migrate,
// instead just throw away the old store and create a new one.
// this happens if somebody changed the
try {
self.db.deleteObjectStore(self.record);
} catch (e) { /* ignore */ }
// create object store.
self.db.createObjectStore(self.record, {
autoIncrement: useAutoIncrement()
});
}
// database is ready for use
function onsuccess(event) {
// remember the db instance
self.db = event.target.result;
// storage is now possible
self.store = true;
// execute all pending operations
while (self.waiting.length) {
self.waiting.shift().call(self);
}
// we're done, fire the callback
if (cb) {
cb.call(self, self);
}
}
request.onerror = function(ev) {
if (request.errorCode === getIDBDatabaseException().VERSION_ERR) {
// xxx blow it away
self.idb.deleteDatabase(self.name);
// try it again.
return self.init(options, callback);
}
console.error('Failed to open database');
};
},
save:function(obj, callback) {
@ -352,5 +313,19 @@ Lawnchair.adapter('indexed-db', (function(){
}
};
//
// Helper functions
//
function fail(e, i) {
console.error('error in indexed-db adapter!', e, i);
}
function useAutoIncrement() {
// using preliminary mozilla implementation which doesn't support
// auto-generated keys. Neither do some webkit implementations.
return !!window.indexedDB;
}
})());

View File

@ -168,133 +168,3 @@ Lawnchair.prototype = {
if (typeof module !== 'undefined' && module.exports) {
module.exports = Lawnchair;
}
// window.name code courtesy Remy Sharp: http://24ways.org/2009/breaking-out-the-edges-of-the-browser
Lawnchair.adapter('window-name', (function() {
if (typeof window==='undefined') {
window = { top: { } }; // node/optimizer compatibility
}
// edited from the original here by elsigh
// Some sites store JSON data in window.top.name, but some folks (twitter on iPad)
// put simple strings in there - we should make sure not to cause a SyntaxError.
var data = {}
try {
data = JSON.parse(window.top.name)
} catch (e) {}
return {
valid: function () {
return typeof window.top.name != 'undefined'
},
init: function (options, callback) {
data[this.name] = data[this.name] || {index:[],store:{}}
this.index = data[this.name].index
this.store = data[this.name].store
this.fn(this.name, callback).call(this, this)
return this
},
keys: function (callback) {
this.fn('keys', callback).call(this, this.index)
return this
},
save: function (obj, cb) {
// data[key] = value + ''; // force to string
// window.top.name = JSON.stringify(data);
var key = obj.key || this.uuid()
this.exists(key, function(exists) {
if (!exists) {
if (obj.key) delete obj.key
this.index.push(key)
}
this.store[key] = obj
try {
window.top.name = JSON.stringify(data) // TODO wow, this is the only diff from the memory adapter
} catch(e) {
// restore index/store to previous value before JSON exception
if (!exists) {
this.index.pop();
delete this.store[key];
}
throw e;
}
if (cb) {
obj.key = key
this.lambda(cb).call(this, obj)
}
})
return this
},
batch: function (objs, cb) {
var r = []
for (var i = 0, l = objs.length; i < l; i++) {
this.save(objs[i], function(record) {
r.push(record)
})
}
if (cb) this.lambda(cb).call(this, r)
return this
},
get: function (keyOrArray, cb) {
var r;
if (this.isArray(keyOrArray)) {
r = []
for (var i = 0, l = keyOrArray.length; i < l; i++) {
r.push(this.store[keyOrArray[i]])
}
} else {
r = this.store[keyOrArray]
if (r) r.key = keyOrArray
}
if (cb) this.lambda(cb).call(this, r)
return this
},
exists: function (key, cb) {
this.lambda(cb).call(this, !!(this.store[key]))
return this
},
all: function (cb) {
var r = []
for (var i = 0, l = this.index.length; i < l; i++) {
var obj = this.store[this.index[i]]
obj.key = this.index[i]
r.push(obj)
}
this.fn(this.name, cb).call(this, r)
return this
},
remove: function (keyOrArray, cb) {
var del = this.isArray(keyOrArray) ? keyOrArray : [keyOrArray]
for (var i = 0, l = del.length; i < l; i++) {
var key = del[i].key ? del[i].key : del[i]
var where = this.indexOf(this.index, key)
if (where < 0) continue /* key not present */
delete this.store[key]
this.index.splice(where, 1)
}
window.top.name = JSON.stringify(data)
if (cb) this.lambda(cb).call(this)
return this
},
nuke: function (cb) {
this.store = data[this.name].store = {}
this.index = data[this.name].index = []
window.top.name = JSON.stringify(data)
if (cb) this.lambda(cb).call(this)
return this
}
}
/////
})());