cleaning up (1)
This commit is contained in:
63
bower_components/observe-js/examples/circles.html
vendored
Normal file
63
bower_components/observe-js/examples/circles.html
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
<!--
|
||||
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
|
||||
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
||||
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
||||
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
||||
Code distributed by Google as part of the polymer project is also
|
||||
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
||||
-->
|
||||
|
||||
<script src="../change_summary.js"></script>
|
||||
<script src="constrain.js"></script>
|
||||
<script src="persist.js"></script>
|
||||
<script src="mdv-object-observe/include.js"></script>
|
||||
|
||||
<h1>Circles</h1>
|
||||
<div data-controller="CircleController">
|
||||
<template iterate>
|
||||
<div style="border: 1px solid black; margin: 8px">
|
||||
<table>
|
||||
<tr><td>radius:</td><td><input type="number" value="{{ radius }}"></td></tr>
|
||||
<tr><td>area:</td><td><input type="number" value="{{ area }}"></td></tr>
|
||||
<tr><td>circumference:</td><td><input type="number" value="{{ circumference }}"></td></tr>
|
||||
</table>
|
||||
<button data-action="click:delete">Delete</button>
|
||||
</div>
|
||||
</template>
|
||||
<button data-action="click:add">New</button>
|
||||
</div>
|
||||
<script>
|
||||
|
||||
function Circle(radius) {
|
||||
// circumference = 2*PI*radius
|
||||
constrain(this, {
|
||||
radius: function() { return this.circumference / (2*Math.PI); },
|
||||
circumference: function() { return 2 * Math.PI * this.radius; }
|
||||
});
|
||||
|
||||
// area = PI*r^2'
|
||||
constrain(this, {
|
||||
area: function() { return Math.PI * Math.pow(this.radius, 2); },
|
||||
radius: function() { return Math.sqrt(this.area / Math.PI); }
|
||||
});
|
||||
|
||||
if (radius)
|
||||
this.radius = radius;
|
||||
}
|
||||
|
||||
function CircleController(elm) {
|
||||
this.circles = elm.model = persistDB.retrieve(Circle);
|
||||
}
|
||||
|
||||
CircleController.prototype = {
|
||||
delete: function(circle) {
|
||||
var index = this.circles.indexOf(circle);
|
||||
this.circles.splice(index, 1);
|
||||
},
|
||||
|
||||
add: function() {
|
||||
this.circles.push(new Circle());
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
29
bower_components/observe-js/examples/constrain.html
vendored
Normal file
29
bower_components/observe-js/examples/constrain.html
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
<!--
|
||||
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
|
||||
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
||||
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
||||
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
||||
Code distributed by Google as part of the polymer project is also
|
||||
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
||||
-->
|
||||
|
||||
<h1>The world's simplest constraint-solver</h1>
|
||||
<script src="constrain.js"></script>
|
||||
<script>
|
||||
function Circle(radius) {
|
||||
// circumference = 2*PI*radius
|
||||
constrain(this, {
|
||||
radius: function() { return this.circumference / (2*Math.PI); },
|
||||
circumference: function() { return 2 * Math.PI * this.radius; }
|
||||
});
|
||||
|
||||
// area = PI*r^2'
|
||||
constrain(this, {
|
||||
area: function() { return Math.PI * Math.pow(this.radius, 2); },
|
||||
radius: function() { return Math.sqrt(this.area / Math.PI); }
|
||||
});
|
||||
|
||||
if (radius)
|
||||
this.radius = radius;
|
||||
}
|
||||
</script>
|
||||
403
bower_components/observe-js/examples/constrain.js
vendored
Normal file
403
bower_components/observe-js/examples/constrain.js
vendored
Normal file
@@ -0,0 +1,403 @@
|
||||
/*
|
||||
* Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
|
||||
* This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
||||
* The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
||||
* The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
||||
* Code distributed by Google as part of the polymer project is also
|
||||
* subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
||||
*/
|
||||
|
||||
(function(global) {
|
||||
|
||||
/* This is a very simple version of the QuickPlan algorithm for solving
|
||||
* mutli-variable contraints. (http://www.cs.utk.edu/~bvz/quickplan.html)
|
||||
* The implementation varies from the standard described approach in a few ways:
|
||||
*
|
||||
* -There is no notion of constraint heirarchy. Here, all constraints are
|
||||
* considered REQUIRED.
|
||||
*
|
||||
* -There is no "improvement" phase where rejected constraints are added back
|
||||
* in an attempt to find a "better solution"
|
||||
*
|
||||
* -In place of the above two, a heuristic is used to pick the "weakest"
|
||||
* free constraint to remove. A function, "stayFunc" is passed to the
|
||||
* Variable class and is expected to return a priority value for the variable
|
||||
* 0 being highest and 1, 2, 3, etc... being lower.
|
||||
*
|
||||
* I suspect these variations result in there being no guarentee of choosing the
|
||||
* optimal solution, but it does seem to work well for the examples I've tested.
|
||||
* Note also that the DeltaBlue planner can be used in a similar pattern,
|
||||
* but it only supports single variable assignment.
|
||||
*
|
||||
* Note also that this is hacky and thrown together. Don't expect it to work
|
||||
* much at all =-).
|
||||
*/
|
||||
|
||||
function Map() {
|
||||
this.map_ = new global.Map;
|
||||
this.keys_ = [];
|
||||
}
|
||||
|
||||
Map.prototype = {
|
||||
get: function(key) {
|
||||
return this.map_.get(key);
|
||||
},
|
||||
|
||||
set: function(key, value) {
|
||||
if (!this.map_.has(key))
|
||||
this.keys_.push(key);
|
||||
return this.map_.set(key, value);
|
||||
},
|
||||
|
||||
has: function(key) {
|
||||
return this.map_.has(key);
|
||||
},
|
||||
|
||||
delete: function(key) {
|
||||
this.keys_.splice(this.keys_.indexOf(key), 1);
|
||||
this.map_.delete(key);
|
||||
},
|
||||
|
||||
keys: function() {
|
||||
return this.keys_.slice();
|
||||
}
|
||||
}
|
||||
|
||||
function Variable(property, stayFunc) {
|
||||
this.property = property;
|
||||
this.stayFunc = stayFunc || function() {
|
||||
//console.log("Warning: using default stay func");
|
||||
return 0;
|
||||
};
|
||||
this.methods = [];
|
||||
};
|
||||
|
||||
Variable.prototype = {
|
||||
addMethod: function(method) {
|
||||
this.methods.push(method);
|
||||
},
|
||||
|
||||
removeMethod: function(method) {
|
||||
this.methods.splice(this.methods.indexOf(method), 1);
|
||||
},
|
||||
|
||||
isFree: function() {
|
||||
return this.methods.length <= 1;
|
||||
},
|
||||
|
||||
get stayPriority() {
|
||||
return this.stayFunc(this.property);
|
||||
}
|
||||
}
|
||||
|
||||
function Method(opts) {
|
||||
opts = opts || {};
|
||||
this.name = opts.name || 'function() { ... }';
|
||||
this.outputs = opts.outputs || [];
|
||||
this.f = opts.f || function() {
|
||||
console.log('Warning: using default execution function');
|
||||
};
|
||||
};
|
||||
|
||||
Method.prototype = {
|
||||
planned_: false,
|
||||
variables_: [],
|
||||
|
||||
set planned(planned) {
|
||||
this.planned_ = planned;
|
||||
|
||||
if (this.planned_) {
|
||||
if (this.variables_) {
|
||||
// Remove this method from all variables.
|
||||
this.variables_.forEach(function(variable) {
|
||||
variable.removeMethod(this);
|
||||
}, this);
|
||||
}
|
||||
|
||||
this.variables_ = null;
|
||||
} else {
|
||||
this.variables_ = null;
|
||||
|
||||
// Get & add this method to all variables.
|
||||
if (this.constraint && this.constraint.planner) {
|
||||
this.variables_ = this.outputs.map(function(output) {
|
||||
var variable = this.constraint.planner.getVariable(output);
|
||||
variable.addMethod(this);
|
||||
return variable;
|
||||
}, this);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
get planned() {
|
||||
return this.planned_;
|
||||
},
|
||||
|
||||
isFree: function() {
|
||||
// Return true only if all variables are free.
|
||||
var variables = this.variables_;
|
||||
for (var i = variables.length - 1; i >= 0; i--) {
|
||||
if (!variables[i].isFree())
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
weakerOf: function(other) {
|
||||
if (!other) {
|
||||
return this;
|
||||
}
|
||||
|
||||
// Prefer a method that assigns to fewer variables.
|
||||
if (this.variables_.length != other.variables_.length) {
|
||||
return this.variables_.length < other.variables_.length ? this : other;
|
||||
}
|
||||
|
||||
// Note: A weaker stay priority is a higher number.
|
||||
return this.getStayPriority() >= other.getStayPriority() ? this : other;
|
||||
},
|
||||
|
||||
getStayPriority: function() {
|
||||
// This returns the strongest (lowest) stay priority of this method's
|
||||
// output variables.
|
||||
return retval = this.variables_.reduce(function(min, variable) {
|
||||
return Math.min(min, variable.stayPriority);
|
||||
}, Infinity);
|
||||
},
|
||||
|
||||
execute: function() {
|
||||
console.log(JSON.stringify(this.outputs) + ' <= ' + this.name);
|
||||
this.f();
|
||||
}
|
||||
};
|
||||
|
||||
function Constraint(methods, when) {
|
||||
this.methods = methods;
|
||||
this.when = when;
|
||||
};
|
||||
|
||||
Constraint.prototype = {
|
||||
executionMethod_: null,
|
||||
|
||||
set executionMethod(executionMethod) {
|
||||
this.executionMethod_ = executionMethod;
|
||||
var planned = !!this.executionMethod_;
|
||||
|
||||
this.methods.forEach(function(method) {
|
||||
method.constraint = this;
|
||||
method.planned = planned;
|
||||
}, this);
|
||||
},
|
||||
|
||||
get executionMethod() {
|
||||
return this.executionMethod_;
|
||||
},
|
||||
|
||||
getWeakestFreeMethod: function() {
|
||||
var methods = this.methods;
|
||||
var weakest = null;
|
||||
for (var i = 0; i < methods.length; i++) {
|
||||
var method = methods[i];
|
||||
if (method.isFree())
|
||||
weakest = method.weakerOf(weakest);
|
||||
}
|
||||
return weakest;
|
||||
},
|
||||
|
||||
execute: function() {
|
||||
this.executionMethod.execute();
|
||||
}
|
||||
};
|
||||
|
||||
function Planner(object) {
|
||||
this.object = object;
|
||||
this.properties = {};
|
||||
this.priority = []
|
||||
var self = this;
|
||||
|
||||
this.stayFunc = function(property) {
|
||||
if (self.object[property] === undefined)
|
||||
return Infinity;
|
||||
var index = self.priority.indexOf(property);
|
||||
return index >= 0 ? index : Infinity;
|
||||
}
|
||||
|
||||
Object.observe(this.object, internalCallback);
|
||||
};
|
||||
|
||||
Planner.prototype = {
|
||||
plan_: null,
|
||||
|
||||
deliverChanged: function(changeRecords) {
|
||||
var needsResolve = false;
|
||||
|
||||
changeRecords.forEach(function(change) {
|
||||
var property = change.name;
|
||||
if (!(property in this.properties))
|
||||
return;
|
||||
|
||||
var index = this.priority.indexOf(property);
|
||||
if (index >= 0)
|
||||
this.priority.splice(this.priority.indexOf(property), 1);
|
||||
|
||||
this.priority.unshift(property);
|
||||
needsResolve = true;
|
||||
}, this);
|
||||
|
||||
if (!needsResolve)
|
||||
return;
|
||||
|
||||
console.log('Resolving: ' + Object.getPrototypeOf(changeRecords[0].object).constructor.name);
|
||||
|
||||
Object.unobserve(this.object, internalCallback);
|
||||
this.execute();
|
||||
console.log('...Done: ' + JSON.stringify(this.object));
|
||||
Object.observe(this.object, internalCallback);
|
||||
},
|
||||
|
||||
addConstraint: function(methods) {
|
||||
methods.forEach(function(method) {
|
||||
method.outputs.forEach(function(output) {
|
||||
this.properties[output] = true;
|
||||
}, this);
|
||||
}, this);
|
||||
|
||||
var constraint = new Constraint(methods);
|
||||
|
||||
this.constraints = this.constraints || [];
|
||||
if (this.constraints.indexOf(constraint) < 0) {
|
||||
this.plan_ = null;
|
||||
this.constraints.push(constraint);
|
||||
}
|
||||
return constraint;
|
||||
},
|
||||
|
||||
removeConstraint: function(constraint) {
|
||||
var index = this.constraints.indexOf(constraint);
|
||||
if (index >= 0) {
|
||||
this.plan_ = null;
|
||||
var removed = this.constraints.splice(index, 1)[0];
|
||||
}
|
||||
return constraint;
|
||||
},
|
||||
|
||||
getVariable: function(property) {
|
||||
var index = this.properties_.indexOf(property);
|
||||
if (index >= 0) {
|
||||
return this.variables_[index];
|
||||
}
|
||||
|
||||
this.properties_.push(property);
|
||||
var variable = new Variable(property, this.stayFunc);
|
||||
this.variables_.push(variable);
|
||||
return variable;
|
||||
},
|
||||
|
||||
get plan() {
|
||||
if (this.plan_) {
|
||||
return this.plan_;
|
||||
}
|
||||
|
||||
this.plan_ = [];
|
||||
this.properties_ = [];
|
||||
this.variables_ = [];
|
||||
|
||||
var unplanned = this.constraints.filter(function(constraint) {
|
||||
// Note: setting executionMethod must take place after setting planner.
|
||||
if (constraint.when && !constraint.when()) {
|
||||
// Conditional and currenty disabled => not in use.
|
||||
constraint.planner = null;
|
||||
constraint.executionMethod = null;
|
||||
return false;
|
||||
} else {
|
||||
// In use.
|
||||
constraint.planner = this;
|
||||
constraint.executionMethod = null;
|
||||
return true;
|
||||
}
|
||||
}, this);
|
||||
|
||||
while (unplanned.length > 0) {
|
||||
var method = this.chooseNextMethod(unplanned);
|
||||
if (!method) {
|
||||
throw "Cycle detected";
|
||||
}
|
||||
|
||||
var nextConstraint = method.constraint;
|
||||
unplanned.splice(unplanned.indexOf(nextConstraint), 1);
|
||||
this.plan_.unshift(nextConstraint);
|
||||
nextConstraint.executionMethod = method;
|
||||
}
|
||||
|
||||
return this.plan_;
|
||||
},
|
||||
|
||||
chooseNextMethod: function(constraints) {
|
||||
var weakest = null;
|
||||
for (var i = 0; i < constraints.length; i++) {
|
||||
var current = constraints[i].getWeakestFreeMethod();
|
||||
weakest = current ? current.weakerOf(weakest) : weakest;
|
||||
}
|
||||
return weakest;
|
||||
},
|
||||
|
||||
run: function() {
|
||||
this.execute();
|
||||
},
|
||||
|
||||
execute: function() {
|
||||
this.plan_ = null;
|
||||
this.executing = true;
|
||||
this.plan.forEach(function(constraint) {
|
||||
constraint.execute();
|
||||
});
|
||||
this.executing = false;
|
||||
}
|
||||
}
|
||||
|
||||
var planners = new WeakMap;
|
||||
|
||||
function internalCallback(changeRecords) {
|
||||
var changeMap = new Map;
|
||||
|
||||
changeRecords.forEach(function(change) {
|
||||
if (!planners.has(change.object))
|
||||
return;
|
||||
|
||||
var changes = changeMap.get(change.object);
|
||||
if (!changes) {
|
||||
changeMap.set(change.object, [change]);
|
||||
return;
|
||||
}
|
||||
|
||||
changes.push(change);
|
||||
});
|
||||
|
||||
changeMap.keys().forEach(function(object) {
|
||||
planners.get(object).deliverChanged(changeMap.get(object));
|
||||
});
|
||||
}
|
||||
|
||||
// Register callback to assign delivery order.
|
||||
var register = {};
|
||||
Object.observe(register, internalCallback);
|
||||
Object.unobserve(register, internalCallback);
|
||||
|
||||
global.constrain = function(obj, methodFunctions) {
|
||||
var planner = planners.get(obj);
|
||||
if (!planner) {
|
||||
planner = new Planner(obj);
|
||||
planners.set(obj, planner);
|
||||
}
|
||||
|
||||
planner.addConstraint(Object.keys(methodFunctions).map(function(property) {
|
||||
var func = methodFunctions[property];
|
||||
|
||||
return new Method({
|
||||
name: func.toString(),
|
||||
outputs: [ property ],
|
||||
f: function() { obj[property] = func.apply(obj); }
|
||||
});
|
||||
}));
|
||||
}
|
||||
})(this);
|
||||
13
bower_components/observe-js/examples/persist.html
vendored
Normal file
13
bower_components/observe-js/examples/persist.html
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
<!--
|
||||
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
|
||||
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
||||
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
||||
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
||||
Code distributed by Google as part of the polymer project is also
|
||||
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
||||
-->
|
||||
|
||||
<h1>The worlds simplest persistence system</h1>
|
||||
|
||||
<script src="../change_summary.js"></script>
|
||||
<script src="persist.js"></script>
|
||||
246
bower_components/observe-js/examples/persist.js
vendored
Normal file
246
bower_components/observe-js/examples/persist.js
vendored
Normal file
@@ -0,0 +1,246 @@
|
||||
/*
|
||||
* Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
|
||||
* This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
||||
* The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
||||
* The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
||||
* Code distributed by Google as part of the polymer project is also
|
||||
* subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
||||
*/
|
||||
|
||||
(function(global) {
|
||||
|
||||
function Set() {
|
||||
this.set_ = new global.Set;
|
||||
this.keys_ = [];
|
||||
}
|
||||
|
||||
Set.prototype = {
|
||||
add: function(key) {
|
||||
if (!this.set_.has(key))
|
||||
this.keys_.push(key);
|
||||
return this.set_.add(key);
|
||||
},
|
||||
|
||||
has: function(key) {
|
||||
return this.set_.has(key);
|
||||
},
|
||||
|
||||
delete: function(key) {
|
||||
this.keys_.splice(this.keys_.indexOf(key), 1);
|
||||
this.set_.delete(key);
|
||||
},
|
||||
|
||||
keys: function() {
|
||||
return this.keys_.slice();
|
||||
}
|
||||
}
|
||||
|
||||
var dbName = 'PersistObserved';
|
||||
var version;
|
||||
var db;
|
||||
var storeNames = {};
|
||||
|
||||
function constructorName(objOrFunction) {
|
||||
if (typeof objOrFunction == 'function')
|
||||
return objOrFunction.name;
|
||||
else
|
||||
return Object.getPrototypeOf(objOrFunction).constructor.name;
|
||||
}
|
||||
|
||||
function getKeyPath(constructor) {
|
||||
return constructor.keyPath || 'id';
|
||||
}
|
||||
|
||||
function onerror(e) {
|
||||
console.log('Error: ' + e);
|
||||
};
|
||||
|
||||
var postOpen = [];
|
||||
|
||||
function openDB() {
|
||||
var request = webkitIndexedDB.open(dbName);
|
||||
|
||||
request.onerror = onerror;
|
||||
request.onsuccess = function(e) {
|
||||
db = e.target.result;
|
||||
version = db.version || 0;
|
||||
for (var i = 0; i < db.objectStoreNames.length; i++)
|
||||
storeNames[db.objectStoreNames.item(i)] = true;
|
||||
|
||||
postOpen.forEach(function(action) {
|
||||
action();
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function handleChanged(changeRecords) {
|
||||
changeRecords.forEach(function(change) {
|
||||
persist(change.object);
|
||||
});
|
||||
}
|
||||
|
||||
var observer = new ChangeSummary(function(summaries) {
|
||||
storeChanges = {};
|
||||
|
||||
function getChange(obj) {
|
||||
var change = storeChanges[constructorName(obj)];
|
||||
if (change)
|
||||
return change;
|
||||
|
||||
change = {
|
||||
keyPath: getKeyPath(obj),
|
||||
needsAdd: new Set,
|
||||
needsSave: new Set,
|
||||
needsDelete: new Set
|
||||
};
|
||||
|
||||
storeChanges[storeName] = change;
|
||||
return change;
|
||||
}
|
||||
|
||||
summaries.forEach(function(summary) {
|
||||
if (!Array.isArray(summary.object)) {
|
||||
getChange(summary.object).needsSave.add(summary.object);
|
||||
return;
|
||||
}
|
||||
|
||||
summary.arraySplices.forEach(function(splice) {
|
||||
for (var i = 0; i < splice.removed.length; i++) {
|
||||
var obj = splice.removed[i];
|
||||
var change = getChange(obj);
|
||||
if (change.needsAdd.has(obj))
|
||||
change.needsAdd.delete(obj);
|
||||
else
|
||||
change.needsDelete.add(obj);
|
||||
}
|
||||
|
||||
for (var i = splice.index; i < splice.index + splice.addedCount; i++) {
|
||||
var obj = summary.object[i];
|
||||
var change = getChange(obj);
|
||||
if (change.needsDelete.has(obj))
|
||||
change.needsDelete.delete(obj);
|
||||
else
|
||||
change.needsAdd.add(obj);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
var storeNames = Object.keys(storeChanges);
|
||||
|
||||
console.log('Persisting: ' + JSON.stringify(storeNames));
|
||||
var trans = db.transaction(storeNames, "readwrite");
|
||||
trans.onerror = onerror;
|
||||
trans.oncomplete = function() {
|
||||
console.log('...complete');
|
||||
}
|
||||
storeNames.forEach(function(storeName) {
|
||||
|
||||
var change = storeChanges[storeName];
|
||||
var store = trans.objectStore(storeName);
|
||||
|
||||
change.needsDelete.keys().forEach(function(obj) {
|
||||
var request = store.delete(obj[change.keyPath]);
|
||||
request.onerror = onerror;
|
||||
request.onsuccess = function(e) {
|
||||
console.log(' deleted: ' + JSON.stringify(obj));
|
||||
delete obj[keyPath];
|
||||
observer.unobserve(obj);
|
||||
if (change.needsSave.has(obj))
|
||||
change.needsSave.delete(obj);
|
||||
};
|
||||
});
|
||||
|
||||
change.needsSave.keys().forEach(function(obj) {
|
||||
var request = store.put(obj);
|
||||
request.onerror = onerror;
|
||||
request.onsuccess = function(e) {
|
||||
console.log(' saved: ' + JSON.stringify(obj));
|
||||
};
|
||||
});
|
||||
|
||||
change.needsAdd.keys().forEach(function(obj) {
|
||||
obj[keyPath] = ++maxIds[storeName];
|
||||
var request = store.put(obj);
|
||||
request.onerror = onerror;
|
||||
request.onsuccess = function(e) {
|
||||
console.log(' created: ' + JSON.stringify(obj));
|
||||
observer.observe(obj);
|
||||
};
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
var maxIds = {};
|
||||
|
||||
global.persistDB = {};
|
||||
|
||||
global.persistDB.retrieve = function(constructor) {
|
||||
var results = [];
|
||||
var instance = new constructor();
|
||||
|
||||
keyPath = constructor.keyPath || 'id';
|
||||
storeName = constructor.name;
|
||||
maxIds[storeName] = maxIds[storeName] || 0;
|
||||
|
||||
function doRetrieve() {
|
||||
console.log("Retrieving: " + storeName);
|
||||
|
||||
var trans = db.transaction([storeName]);
|
||||
var store = trans.objectStore(storeName);
|
||||
|
||||
var keyRange = webkitIDBKeyRange.lowerBound(0);
|
||||
var request = store.openCursor(keyRange);
|
||||
|
||||
request.onerror = onerror;
|
||||
|
||||
request.onsuccess = function(e) {
|
||||
var result = e.target.result;
|
||||
if (!!result == false) {
|
||||
observer.observePropertySet(results);
|
||||
console.log('...complete');
|
||||
return;
|
||||
}
|
||||
|
||||
var object = result.value;
|
||||
maxIds[storeName] = Math.max(maxIds[storeName], object[keyPath]);
|
||||
|
||||
object.__proto__ = instance;
|
||||
constructor.apply(object);
|
||||
results.push(object);
|
||||
observer.observe(object);
|
||||
|
||||
console.log(' => ' + JSON.stringify(object));
|
||||
result.continue();
|
||||
};
|
||||
}
|
||||
|
||||
function createStore() {
|
||||
console.log('Creating store: ' + storeName);
|
||||
version++;
|
||||
var request = db.setVersion(version);
|
||||
request.onerror = onerror;
|
||||
|
||||
request.onsuccess = function(e) {
|
||||
var store = db.createObjectStore(storeName, { keyPath: keyPath });
|
||||
storeNames[storeName] = true;
|
||||
e.target.transaction.oncomplete = doRetrieve;
|
||||
};
|
||||
}
|
||||
|
||||
var action = function() {
|
||||
if (storeName in storeNames)
|
||||
doRetrieve()
|
||||
else
|
||||
createStore();
|
||||
}
|
||||
|
||||
if (db)
|
||||
action();
|
||||
else
|
||||
postOpen.push(action);
|
||||
|
||||
return results;
|
||||
};
|
||||
|
||||
openDB();
|
||||
})(this);
|
||||
Reference in New Issue
Block a user