cleaning up (1)
This commit is contained in:
32
bower_components/observe-js/.bower.json
vendored
Normal file
32
bower_components/observe-js/.bower.json
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"name": "observe-js",
|
||||
"homepage": "https://github.com/Polymer/observe-js",
|
||||
"authors": [
|
||||
"The Polymer Authors"
|
||||
],
|
||||
"description": "A library for observing Arrays, Objects and PathValues",
|
||||
"main": "src/observe.js",
|
||||
"keywords": [
|
||||
"Object.observe"
|
||||
],
|
||||
"license": "BSD",
|
||||
"private": true,
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"tests"
|
||||
],
|
||||
"version": "0.5.1",
|
||||
"_release": "0.5.1",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "0.5.1",
|
||||
"commit": "d530515b4afe7d0a6b61c06f1a6c64f07bcbbf57"
|
||||
},
|
||||
"_source": "git://github.com/Polymer/observe-js.git",
|
||||
"_target": "~0.5.1",
|
||||
"_originalSource": "observe-js",
|
||||
"_direct": true
|
||||
}
|
||||
9
bower_components/observe-js/AUTHORS
vendored
Normal file
9
bower_components/observe-js/AUTHORS
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
# Names should be added to this file with this pattern:
|
||||
#
|
||||
# For individuals:
|
||||
# Name <email address>
|
||||
#
|
||||
# For organizations:
|
||||
# Organization <fnmatch pattern>
|
||||
#
|
||||
Google Inc. <*@google.com>
|
||||
203
bower_components/observe-js/README.md
vendored
Normal file
203
bower_components/observe-js/README.md
vendored
Normal file
@@ -0,0 +1,203 @@
|
||||
[](http://build.chromium.org/p/client.polymer/waterfall) [](https://github.com/igrigorik/ga-beacon)
|
||||
|
||||
## Learn the tech
|
||||
|
||||
### Why observe-js?
|
||||
|
||||
observe-js is a library for observing changes in JavaScript data. It exposes a high-level API and uses Object.observe if available, and otherwise performs dirty-checking. observe-js requires ECMAScript 5.
|
||||
|
||||
### Observable
|
||||
|
||||
observe-js implements a set of observers (PathObserver, ArrayObserver, ObjectObserver, CompoundObserver, ObserverTransform) which all implement the Observable interface:
|
||||
|
||||
```JavaScript
|
||||
{
|
||||
// Begins observation. Value changes will be reported by invoking |changeFn| with |opt_receiver| as
|
||||
// the target, if provided. Returns the initial value of the observation.
|
||||
open: function(changeFn, opt_receiver) {},
|
||||
|
||||
// Report any changes now (does nothing if there are no changes to report).
|
||||
deliver: function() {},
|
||||
|
||||
// If there are changes to report, ignore them. Returns the current value of the observation.
|
||||
discardChanges: function() {},
|
||||
|
||||
// Ends observation. Frees resources and drops references to observed objects.
|
||||
close: function() {}
|
||||
}
|
||||
```
|
||||
|
||||
### PathObserver
|
||||
|
||||
PathObserver observes a "value-at-a-path" from a given object:
|
||||
|
||||
```JavaScript
|
||||
var obj = { foo: { bar: 'baz' } };
|
||||
var observer = new PathObserver(obj, 'foo.bar');
|
||||
observer.open(function(newValue, oldValue) {
|
||||
// respond to obj.foo.bar having changed value.
|
||||
});
|
||||
```
|
||||
|
||||
PathObserver will report a change whenever the value obtained by the corresponding path expression (e.g. `obj.foo.bar`) would return a different value.
|
||||
|
||||
PathObserver also exposes a `setValue` method which attempts to update the underlying value. Setting the value does not affect notification state (in other words, a caller sets the value but does not `discardChanges`, the `changeFn` will be notified of the change).
|
||||
|
||||
```JavaScript
|
||||
observer.setValue('boo');
|
||||
assert(obj.foo.bar == 'boo');
|
||||
```
|
||||
|
||||
Notes:
|
||||
* If the path is ever unreachable, the value is considered to be `undefined`.
|
||||
* If the path is empty (e.g. `''`), it is said to be the empty path and its value is its root object.
|
||||
* PathObservation respects values on the prototype chain
|
||||
|
||||
### ArrayObserver
|
||||
|
||||
ArrayObserver observes the index-positions of an Array and reports changes as the minimal set of "splices" which would have had the same effect.
|
||||
|
||||
```JavaScript
|
||||
var arr = [0, 1, 2, 4];
|
||||
var observer = new ArrayObserver(arr);
|
||||
observer.open(function(splices) {
|
||||
// respond to changes to the elements of arr.
|
||||
splices.forEach(function(splice) {
|
||||
splice.index; // index position that the change occurred.
|
||||
splice.removed; // an array of values representing the sequence of elements which were removed
|
||||
splice.addedCount; // the number of elements which were inserted.
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
ArrayObserver also exposes a utility function: `applySplices`. The purpose of `applySplices` is to transform a copy of an old state of an array into a copy of its current state, given the current state and the splices reported from the ArrayObserver.
|
||||
|
||||
```JavaScript
|
||||
AraryObserver.applySplices = function(previous, current, splices) { }
|
||||
```
|
||||
|
||||
### ObjectObserver
|
||||
|
||||
ObjectObserver observes the set of own-properties of an object and their values.
|
||||
|
||||
```JavaScript
|
||||
var myObj = { id: 1, foo: 'bar' };
|
||||
var observer = new ObjectObserver(myObj);
|
||||
observer.open(function(added, removed, changed, getOldValueFn) {
|
||||
// respond to changes to the obj.
|
||||
Object.keys(added).forEach(function(property) {
|
||||
property; // a property which has been been added to obj
|
||||
added[property]; // its value
|
||||
});
|
||||
Object.keys(removed).forEach(function(property) {
|
||||
property; // a property which has been been removed from obj
|
||||
getOldValueFn(property); // its old value
|
||||
});
|
||||
Object.keys(changed).forEach(function(property) {
|
||||
property; // a property on obj which has changed value.
|
||||
changed[property]; // its value
|
||||
getOldValueFn(property); // its old value
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### CompoundObserver
|
||||
|
||||
CompoundObserver allows simultaneous observation of multiple paths and/or Observables. It reports any and all changes in to the provided `changeFn` callback.
|
||||
|
||||
```JavaScript
|
||||
var obj = {
|
||||
a: 1,
|
||||
b: 2,
|
||||
};
|
||||
|
||||
var otherObj = { c: 3 };
|
||||
|
||||
var observer = new CompoundObserver();
|
||||
observer.addPath(obj, 'a');
|
||||
observer.addObserver(new PathObserver(obj, 'b'));
|
||||
observer.addPath(otherObj, 'c');
|
||||
observer.open(function(newValues, oldValues) {
|
||||
// Use for-in to iterte which values have changed.
|
||||
for (var i in oldValues) {
|
||||
console.log('The ' + i + 'th value changed from: ' + newValues[i] + ' to: ' + oldValues[i]);
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
|
||||
### ObserverTransform
|
||||
|
||||
ObserverTransform is used to dynamically transform observed value(s).
|
||||
|
||||
```JavaScript
|
||||
var obj = { value: 10 };
|
||||
var observer = new PathObserver(obj, 'value');
|
||||
function getValue(value) { return value * 2 };
|
||||
function setValue(value) { return value / 2 };
|
||||
|
||||
var transform = new ObserverTransform(observer, getValue, setValue);
|
||||
|
||||
// returns 20.
|
||||
transform.open(function(newValue, oldValue) {
|
||||
console.log('new: ' + newValue + ', old: ' + oldValue);
|
||||
});
|
||||
|
||||
obj.value = 20;
|
||||
transform.deliver(); // 'new: 40, old: 20'
|
||||
transform.setValue(4); // obj.value === 2;
|
||||
```
|
||||
|
||||
ObserverTransform can also be used to reduce a set of observed values to a single value:
|
||||
|
||||
```JavaScript
|
||||
var obj = { a: 1, b: 2, c: 3 };
|
||||
var observer = new CompoundObserver();
|
||||
observer.addPath(obj, 'a');
|
||||
observer.addPath(obj, 'b');
|
||||
observer.addPath(obj, 'c');
|
||||
var transform = new ObserverTransform(observer, fuction(values) {
|
||||
var value = 0;
|
||||
for (var i = 0; i < values.length; i++)
|
||||
value += values[i]
|
||||
return value;
|
||||
});
|
||||
|
||||
// returns 6.
|
||||
transform.open(function(newValue, oldValue) {
|
||||
console.log('new: ' + newValue + ', old: ' + oldValue);
|
||||
});
|
||||
|
||||
obj.a = 2;
|
||||
obj.c = 10;
|
||||
transform.deliver(); // 'new: 14, old: 6'
|
||||
```
|
||||
|
||||
### Path objects
|
||||
|
||||
A path is an ECMAScript expression consisting only of identifiers (`myVal`), member accesses (`foo.bar`) and key lookup with literal values (`arr[0]` `obj['str-value'].bar.baz`).
|
||||
|
||||
`Path.get('foo.bar.baz')` returns a Path object which represents the path. Path objects have the following API:
|
||||
|
||||
```JavaScript
|
||||
{
|
||||
// Returns the current of the path from the provided object. If eval() is available, a compiled getter will be
|
||||
// used for better performance.
|
||||
getValueFrom: function(obj) { }
|
||||
|
||||
|
||||
// Attempts to set the value of the path from the provided object. Returns true IFF the path was reachable and
|
||||
// set.
|
||||
setValueFrom: function(obj, newValue) { }
|
||||
}
|
||||
```
|
||||
|
||||
Path objects are interned (e.g. `assert(Path.get('foo.bar.baz') === Path.get('foo.bar.baz'));`) and are used internally to avoid excessive parsing of path strings. Observers which take path strings as arguments will also accept Path objects.
|
||||
|
||||
## About delivery of changes
|
||||
|
||||
observe-js is intended for use in environments which implement Object.observe, but it supports use in environments which do not.
|
||||
|
||||
If `Object.observe` is present, and observers have changes to report, their callbacks will be invoked at the end of the current turn (microtask). In a browser environment, this is generally at the end of an event.
|
||||
|
||||
If `Object.observe` is absent, `Platform.performMicrotaskCheckpoint()` must be called to trigger delivery of changes. If `Object.observe` is implemented, `Platform.performMicrotaskCheckpoint()` has no effect.
|
||||
183
bower_components/observe-js/benchmark/benchmark.js
vendored
Normal file
183
bower_components/observe-js/benchmark/benchmark.js
vendored
Normal file
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* 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) {
|
||||
'use strict';
|
||||
|
||||
function now() {
|
||||
return global.performance && typeof performance.now == 'function' ?
|
||||
performance.now() : Date.now();
|
||||
}
|
||||
|
||||
function checkpoint() {
|
||||
if (global.Platform &&
|
||||
typeof Platform.performMicrotaskCheckpoint == 'function') {
|
||||
Platform.performMicrotaskCheckpoint();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(rafaelw): Add simple Promise polyfill for IE.
|
||||
|
||||
var TESTING_TICKS = 400;
|
||||
var TICKS_PER_FRAME = 16;
|
||||
var MAX_RUNS = 50;
|
||||
|
||||
function Benchmark(testingTicks, ticksPerFrame, maxRuns) {
|
||||
this.testingTicks = testingTicks || TESTING_TICKS;
|
||||
this.ticksPerFrame = ticksPerFrame || TICKS_PER_FRAME;
|
||||
this.maxRuns = maxRuns || 50;
|
||||
this.average = 0;
|
||||
}
|
||||
|
||||
Benchmark.prototype = {
|
||||
// Abstract API
|
||||
setup: function(variation) {},
|
||||
test: function() {
|
||||
throw Error('Not test function found');
|
||||
},
|
||||
cleanup: function() {},
|
||||
|
||||
runOne: function(variation) {
|
||||
this.setup(variation);
|
||||
|
||||
var before = now();
|
||||
this.test(variation);
|
||||
|
||||
var self = this;
|
||||
|
||||
return Promise.resolve().then(function() {
|
||||
checkpoint();
|
||||
|
||||
var after = now();
|
||||
|
||||
self.cleanup(variation);
|
||||
return after - before;
|
||||
});
|
||||
},
|
||||
|
||||
runMany: function(count, variation) {
|
||||
var self = this;
|
||||
|
||||
return new Promise(function(fulfill) {
|
||||
var total = 0;
|
||||
|
||||
function next(time) {
|
||||
if (!count) {
|
||||
fulfill(total);
|
||||
return;
|
||||
}
|
||||
|
||||
self.runOne(variation).then(function(time) {
|
||||
count--;
|
||||
total += time;
|
||||
next();
|
||||
});
|
||||
}
|
||||
|
||||
requestAnimationFrame(next);
|
||||
});
|
||||
},
|
||||
|
||||
runVariation: function(variation, reportFn) {
|
||||
var self = this;
|
||||
reportFn = reportFn || function() {}
|
||||
|
||||
return new Promise(function(fulfill) {
|
||||
self.runMany(3, variation).then(function(time) {
|
||||
return time/3;
|
||||
}).then(function(estimate) {
|
||||
var runsPerFrame = Math.ceil(self.ticksPerFrame / estimate);
|
||||
var frames = Math.ceil(self.testingTicks / self.ticksPerFrame);
|
||||
var maxFrames = Math.ceil(self.maxRuns / runsPerFrame);
|
||||
|
||||
frames = Math.min(frames, maxFrames);
|
||||
var count = 0;
|
||||
var total = 0;
|
||||
|
||||
function next() {
|
||||
if (!frames) {
|
||||
self.average = total / count;
|
||||
self.dispose();
|
||||
fulfill(self.average);
|
||||
return;
|
||||
}
|
||||
|
||||
self.runMany(runsPerFrame, variation).then(function(time) {
|
||||
frames--;
|
||||
total += time;
|
||||
count += runsPerFrame;
|
||||
reportFn(variation, count);
|
||||
next();
|
||||
});
|
||||
}
|
||||
|
||||
next();
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
run: function(variations, reportFn) {
|
||||
if (!Array.isArray(variations)) {
|
||||
return this.runVariation(variations, reportFn);
|
||||
}
|
||||
|
||||
var self = this;
|
||||
variations = variations.slice();
|
||||
return new Promise(function(fulfill) {
|
||||
var results = [];
|
||||
|
||||
function next() {
|
||||
if (!variations.length) {
|
||||
fulfill(results);
|
||||
return;
|
||||
}
|
||||
|
||||
var variation = variations.shift();
|
||||
self.runVariation(variation, reportFn).then(function(time) {
|
||||
results.push(time);
|
||||
next();
|
||||
});
|
||||
}
|
||||
|
||||
next();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function all(benchmarks, variations, statusFn) {
|
||||
return new Promise(function(fulfill) {
|
||||
var results = [];
|
||||
var current;
|
||||
|
||||
function next() {
|
||||
current = benchmarks.shift();
|
||||
|
||||
if (!current) {
|
||||
fulfill(results);
|
||||
return;
|
||||
}
|
||||
|
||||
function update(variation, runs) {
|
||||
statusFn(current, variation, runs);
|
||||
}
|
||||
|
||||
current.run(variations, update).then(function(time) {
|
||||
results.push(time);
|
||||
next();
|
||||
});
|
||||
}
|
||||
|
||||
next();
|
||||
});
|
||||
}
|
||||
|
||||
global.Benchmark = Benchmark;
|
||||
global.Benchmark.all = all;
|
||||
|
||||
})(this);
|
||||
40
bower_components/observe-js/benchmark/d8_benchmarks.js
vendored
Normal file
40
bower_components/observe-js/benchmark/d8_benchmarks.js
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
var console = {
|
||||
log: print
|
||||
};
|
||||
|
||||
var requestAnimationFrame = function(callback) {
|
||||
callback();
|
||||
}
|
||||
|
||||
recordCount = 0;
|
||||
|
||||
var alert = print;
|
||||
|
||||
function reportResults(times) {
|
||||
console.log(JSON.stringify(times));
|
||||
}
|
||||
|
||||
function reportStatus(b, variation, count) {
|
||||
console.log(b.objectCount + ' objects, ' + count + ' runs.');
|
||||
}
|
||||
|
||||
var objectCounts = [ 4000, 8000, 16000 ];
|
||||
|
||||
var benchmarks = [];
|
||||
|
||||
objectCounts.forEach(function(objectCount, i) {
|
||||
benchmarks.push(
|
||||
new SetupPathBenchmark('', objectCount));
|
||||
});
|
||||
|
||||
Benchmark.all(benchmarks, 0, reportStatus).then(reportResults);
|
||||
|
||||
181
bower_components/observe-js/benchmark/index.html
vendored
Normal file
181
bower_components/observe-js/benchmark/index.html
vendored
Normal file
@@ -0,0 +1,181 @@
|
||||
<html>
|
||||
<!--
|
||||
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
|
||||
-->
|
||||
<head>
|
||||
<title>Observation Benchmarks</title>
|
||||
<meta charset="utf-8">
|
||||
<script src="../src/observe.js"></script>
|
||||
<script src="chartjs/Chart.js"></script>
|
||||
<script src="benchmark.js"></script>
|
||||
<script src="observation_benchmark.js"></script>
|
||||
<style>
|
||||
* {
|
||||
font-family: arial, helvetica, sans-serif;
|
||||
font-weight: 400;
|
||||
}
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background-color: rgba(0, 0, 0, .1);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Observation Benchmarks</h1>
|
||||
|
||||
<select id="benchmarkSelect">
|
||||
<option>ObjectBenchmark</option>
|
||||
<option>SetupObjectBenchmark</option>
|
||||
<option>ArrayBenchmark</option>
|
||||
<option>SetupArrayBenchmark</option>
|
||||
<option>PathBenchmark</option>
|
||||
<option>SetupPathBenchmark</option>
|
||||
</select>
|
||||
<select id="configSelect">
|
||||
</select>
|
||||
|
||||
<button id="go">Run Benchmarks</button>
|
||||
|
||||
<span>Object Count: </span>
|
||||
<input id="objectCountInput" style="width: 200px" value="4000, 8000, 16000, 32000"><br>
|
||||
<span>Mutation Count: </span>
|
||||
<input id="mutationCountInput" style="width: 200px" value="0, 100, 200, 400, 800, 1600"><br>
|
||||
<br>
|
||||
<span id="status"></span>
|
||||
|
||||
<section style="width: 100%">
|
||||
<article>
|
||||
<div style="display:inline-block; padding-bottom: 20px">
|
||||
Times in ms
|
||||
</div>
|
||||
<div style="display:inline-block">
|
||||
<canvas id="times" width="800" height="400"></canvas>
|
||||
</div>
|
||||
<div style="display:inline-block">
|
||||
<ul id="legendList">
|
||||
</ul>
|
||||
</div>
|
||||
</article>
|
||||
</section>
|
||||
<h3 style="margin-left: 440px">Object Set Size</h3>
|
||||
<script>
|
||||
var benchmark;
|
||||
var goButton = document.getElementById('go');
|
||||
|
||||
var objectCountInput = document.getElementById('objectCountInput');
|
||||
var mutationCountInput = document.getElementById('mutationCountInput');
|
||||
|
||||
var statusSpan = document.getElementById('status');
|
||||
|
||||
var timesCanvas = document.getElementById('times');
|
||||
var benchmarkSelect = document.getElementById('benchmarkSelect');
|
||||
var configSelect = document.getElementById('configSelect');
|
||||
|
||||
function changeBenchmark() {
|
||||
benchmark = window[benchmarkSelect.value];
|
||||
configSelect.textContent = '';
|
||||
benchmark.configs.forEach(function(config) {
|
||||
var option = document.createElement('option');
|
||||
option.textContent = config;
|
||||
configSelect.appendChild(option);
|
||||
});
|
||||
|
||||
document.title = benchmarkSelect.value;
|
||||
}
|
||||
|
||||
benchmarkSelect.addEventListener('change', changeBenchmark);
|
||||
|
||||
changeBenchmark();
|
||||
var ul = document.getElementById('legendList');
|
||||
var colors = [
|
||||
[0, 0, 255],
|
||||
[138,43,226],
|
||||
[165,42,42],
|
||||
[100,149,237],
|
||||
[220,20,60],
|
||||
[184,134,11]
|
||||
].map(function(rgb) {
|
||||
return 'rgba(' + rgb.join(',') + ',.7)';
|
||||
});
|
||||
|
||||
goButton.addEventListener('click', function() {
|
||||
goButton.disabled = true;
|
||||
goButton.textContent = 'Running...';
|
||||
ul.textContent = '';
|
||||
|
||||
var objectCounts = objectCountInput.value.split(',').map(function(val) {
|
||||
return Number(val);
|
||||
});
|
||||
var mutationCounts = mutationCountInput.value.split(',').map(function(val) {
|
||||
return Number(val);
|
||||
});
|
||||
|
||||
mutationCounts.forEach(function(count, i) {
|
||||
var li = document.createElement('li');
|
||||
li.textContent = count + ' mutations.'
|
||||
li.style.color = colors[i];
|
||||
ul.appendChild(li);
|
||||
});
|
||||
|
||||
var results = [];
|
||||
|
||||
function benchmarkComplete(times) {
|
||||
timesArray = [];
|
||||
var index = 0;
|
||||
|
||||
|
||||
mutationCounts.forEach(function(mutationCount, i) {
|
||||
timesArray.push([]);
|
||||
objectCounts.forEach(function(objectCount, j) {
|
||||
timesArray[i][j] = times[j][i];
|
||||
});
|
||||
});
|
||||
|
||||
timesCanvas.height = 400;
|
||||
timesCanvas.width = 800;
|
||||
timesCanvas.setAttribute('style', '');
|
||||
|
||||
var ctx = timesCanvas.getContext("2d");
|
||||
new Chart(ctx).Line({
|
||||
labels: objectCounts,
|
||||
datasets: timesArray.map(function(times, i) {
|
||||
return {
|
||||
fillColor: 'rgba(255, 255, 255, 0)',
|
||||
strokeColor: colors[i],
|
||||
pointColor: colors[i],
|
||||
pointStrokeColor: "#fff",
|
||||
data: times
|
||||
};
|
||||
})
|
||||
}, {
|
||||
bezierCurve: false
|
||||
});
|
||||
|
||||
goButton.disabled = false;
|
||||
goButton.textContent = 'Run Benchmarks';
|
||||
statusSpan.textContent = '';
|
||||
}
|
||||
|
||||
function updateStatus(benchmark, mutationCount, count) {
|
||||
statusSpan.textContent = 'Testing: ' +
|
||||
benchmark.objectCount + ' objects, ' +
|
||||
mutationCount + ' mutations ... ' +
|
||||
count + ' runs';
|
||||
}
|
||||
|
||||
var benchmarks = objectCounts.map(function(objectCount) {
|
||||
return new benchmark(configSelect.value, objectCount);
|
||||
});
|
||||
|
||||
Benchmark.all(benchmarks, mutationCounts, updateStatus)
|
||||
.then(benchmarkComplete);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
357
bower_components/observe-js/benchmark/observation_benchmark.js
vendored
Normal file
357
bower_components/observe-js/benchmark/observation_benchmark.js
vendored
Normal file
@@ -0,0 +1,357 @@
|
||||
/*
|
||||
* 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) {
|
||||
'use strict';
|
||||
|
||||
var createObject = ('__proto__' in {}) ?
|
||||
function(obj) { return obj; } :
|
||||
function(obj) {
|
||||
var proto = obj.__proto__;
|
||||
if (!proto)
|
||||
return obj;
|
||||
var newObject = Object.create(proto);
|
||||
Object.getOwnPropertyNames(obj).forEach(function(name) {
|
||||
Object.defineProperty(newObject, name,
|
||||
Object.getOwnPropertyDescriptor(obj, name));
|
||||
});
|
||||
return newObject;
|
||||
};
|
||||
|
||||
function ObservationBenchmark(objectCount) {
|
||||
Benchmark.call(this);
|
||||
this.objectCount = objectCount;
|
||||
}
|
||||
|
||||
ObservationBenchmark.prototype = createObject({
|
||||
__proto__: Benchmark.prototype,
|
||||
|
||||
setup: function() {
|
||||
this.mutations = 0;
|
||||
|
||||
if (this.objects)
|
||||
return;
|
||||
|
||||
this.objects = [];
|
||||
this.observers = [];
|
||||
this.objectIndex = 0;
|
||||
|
||||
while (this.objects.length < this.objectCount) {
|
||||
var obj = this.newObject();
|
||||
this.objects.push(obj);
|
||||
var observer = this.newObserver(obj);
|
||||
observer.open(this.observerCallback, this);
|
||||
this.observers.push(observer);
|
||||
}
|
||||
},
|
||||
|
||||
test: function(mutationCount) {
|
||||
while (mutationCount > 0) {
|
||||
var obj = this.objects[this.objectIndex];
|
||||
mutationCount -= this.mutateObject(obj);
|
||||
this.mutations++;
|
||||
this.objectIndex++;
|
||||
if (this.objectIndex == this.objects.length) {
|
||||
this.objectIndex = 0;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
cleanup: function() {
|
||||
if (this.mutations !== 0)
|
||||
alert('Error: mutationCount == ' + this.mutationCount);
|
||||
|
||||
this.mutations = 0;
|
||||
},
|
||||
|
||||
dispose: function() {
|
||||
this.objects = null;
|
||||
while (this.observers.length) {
|
||||
this.observers.pop().close();
|
||||
}
|
||||
this.observers = null;
|
||||
if (Observer._allObserversCount != 0) {
|
||||
alert('Observers leaked');
|
||||
}
|
||||
},
|
||||
|
||||
observerCallback: function() {
|
||||
this.mutations--;
|
||||
}
|
||||
});
|
||||
|
||||
function SetupObservationBenchmark(objectCount) {
|
||||
Benchmark.call(this);
|
||||
this.objectCount = objectCount;
|
||||
}
|
||||
|
||||
SetupObservationBenchmark.prototype = createObject({
|
||||
__proto__: Benchmark.prototype,
|
||||
|
||||
setup: function() {
|
||||
this.mutations = 0;
|
||||
this.objects = [];
|
||||
this.observers = [];
|
||||
|
||||
while (this.objects.length < this.objectCount) {
|
||||
var obj = this.newObject();
|
||||
this.objects.push(obj);
|
||||
}
|
||||
},
|
||||
|
||||
test: function() {
|
||||
for (var i = 0; i < this.objects.length; i++) {
|
||||
var obj = this.objects[i];
|
||||
var observer = this.newObserver(obj);
|
||||
observer.open(this.observerCallback, this);
|
||||
this.observers.push(observer);
|
||||
}
|
||||
},
|
||||
|
||||
cleanup: function() {
|
||||
while (this.observers.length) {
|
||||
this.observers.pop().close();
|
||||
}
|
||||
if (Observer._allObserversCount != 0) {
|
||||
alert('Observers leaked');
|
||||
}
|
||||
this.objects = null;
|
||||
this.observers = null;
|
||||
|
||||
},
|
||||
|
||||
dispose: function() {
|
||||
}
|
||||
});
|
||||
|
||||
function ObjectBenchmark(config, objectCount) {
|
||||
ObservationBenchmark.call(this, objectCount);
|
||||
this.properties = [];
|
||||
for (var i = 0; i < ObjectBenchmark.propertyCount; i++) {
|
||||
this.properties.push(String.fromCharCode(97 + i));
|
||||
}
|
||||
}
|
||||
|
||||
ObjectBenchmark.configs = [];
|
||||
ObjectBenchmark.propertyCount = 15;
|
||||
|
||||
ObjectBenchmark.prototype = createObject({
|
||||
__proto__: ObservationBenchmark.prototype,
|
||||
|
||||
newObject: function() {
|
||||
var obj = {};
|
||||
for (var j = 0; j < ObjectBenchmark.propertyCount; j++)
|
||||
obj[this.properties[j]] = j;
|
||||
|
||||
return obj;
|
||||
},
|
||||
|
||||
newObserver: function(obj) {
|
||||
return new ObjectObserver(obj);
|
||||
},
|
||||
|
||||
mutateObject: function(obj) {
|
||||
var size = Math.floor(ObjectBenchmark.propertyCount / 3);
|
||||
for (var i = 0; i < size; i++) {
|
||||
obj[this.properties[i]]++;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
});
|
||||
|
||||
function SetupObjectBenchmark(config, objectCount) {
|
||||
SetupObservationBenchmark.call(this, objectCount);
|
||||
this.properties = [];
|
||||
for (var i = 0; i < ObjectBenchmark.propertyCount; i++) {
|
||||
this.properties.push(String.fromCharCode(97 + i));
|
||||
}
|
||||
}
|
||||
|
||||
SetupObjectBenchmark.configs = [];
|
||||
SetupObjectBenchmark.propertyCount = 15;
|
||||
|
||||
SetupObjectBenchmark.prototype = createObject({
|
||||
__proto__: SetupObservationBenchmark.prototype,
|
||||
|
||||
newObject: function() {
|
||||
var obj = {};
|
||||
for (var j = 0; j < SetupObjectBenchmark.propertyCount; j++)
|
||||
obj[this.properties[j]] = j;
|
||||
|
||||
return obj;
|
||||
},
|
||||
|
||||
newObserver: function(obj) {
|
||||
return new ObjectObserver(obj);
|
||||
}
|
||||
});
|
||||
|
||||
function ArrayBenchmark(config, objectCount) {
|
||||
ObservationBenchmark.call(this, objectCount);
|
||||
var tokens = config.split('/');
|
||||
this.operation = tokens[0];
|
||||
this.undo = tokens[1];
|
||||
};
|
||||
|
||||
ArrayBenchmark.configs = ['splice', 'update', 'push/pop', 'shift/unshift'];
|
||||
ArrayBenchmark.elementCount = 100;
|
||||
|
||||
ArrayBenchmark.prototype = createObject({
|
||||
__proto__: ObservationBenchmark.prototype,
|
||||
|
||||
newObject: function() {
|
||||
var array = [];
|
||||
for (var i = 0; i < ArrayBenchmark.elementCount; i++)
|
||||
array.push(i);
|
||||
return array;
|
||||
},
|
||||
|
||||
newObserver: function(array) {
|
||||
return new ArrayObserver(array);
|
||||
},
|
||||
|
||||
mutateObject: function(array) {
|
||||
switch (this.operation) {
|
||||
case 'update':
|
||||
var mutationsMade = 0;
|
||||
var size = Math.floor(ArrayBenchmark.elementCount / 10);
|
||||
for (var j = 0; j < size; j++) {
|
||||
array[j*size] += 1;
|
||||
mutationsMade++;
|
||||
}
|
||||
return mutationsMade;
|
||||
|
||||
case 'splice':
|
||||
var size = Math.floor(ArrayBenchmark.elementCount / 5);
|
||||
var removed = array.splice(size, size);
|
||||
Array.prototype.splice.apply(array, [size*2, 0].concat(removed));
|
||||
return size * 2;
|
||||
|
||||
default:
|
||||
var val = array[this.undo]();
|
||||
array[this.operation](val + 1);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function SetupArrayBenchmark(config, objectCount) {
|
||||
ObservationBenchmark.call(this, objectCount);
|
||||
};
|
||||
|
||||
SetupArrayBenchmark.configs = [];
|
||||
SetupArrayBenchmark.propertyCount = 15;
|
||||
|
||||
SetupArrayBenchmark.prototype = createObject({
|
||||
__proto__: SetupObservationBenchmark.prototype,
|
||||
|
||||
newObject: function() {
|
||||
var array = [];
|
||||
for (var i = 0; i < ArrayBenchmark.elementCount; i++)
|
||||
array.push(i);
|
||||
return array;
|
||||
},
|
||||
|
||||
newObserver: function(array) {
|
||||
return new ArrayObserver(array);
|
||||
}
|
||||
});
|
||||
|
||||
function PathBenchmark(config, objectCount) {
|
||||
ObservationBenchmark.call(this, objectCount);
|
||||
this.leaf = config === 'leaf';
|
||||
this.path = Path.get('foo.bar.baz');
|
||||
this.firstPathProp = Path.get(this.path[0]);
|
||||
}
|
||||
|
||||
PathBenchmark.configs = ['leaf', 'root'];
|
||||
|
||||
PathBenchmark.prototype = createObject({
|
||||
__proto__: ObservationBenchmark.prototype,
|
||||
|
||||
newPath: function(parts, value) {
|
||||
var obj = {};
|
||||
var ref = obj;
|
||||
var prop;
|
||||
for (var i = 0; i < parts.length - 1; i++) {
|
||||
prop = parts[i];
|
||||
ref[prop] = {};
|
||||
ref = ref[prop];
|
||||
}
|
||||
|
||||
prop = parts[parts.length - 1];
|
||||
ref[prop] = value;
|
||||
|
||||
return obj;
|
||||
},
|
||||
|
||||
newObject: function() {
|
||||
return this.newPath(this.path, 1);
|
||||
},
|
||||
|
||||
newObserver: function(obj) {
|
||||
return new PathObserver(obj, this.path);
|
||||
},
|
||||
|
||||
mutateObject: function(obj) {
|
||||
var val = this.path.getValueFrom(obj);
|
||||
if (this.leaf) {
|
||||
this.path.setValueFrom(obj, val + 1);
|
||||
} else {
|
||||
this.firstPathProp.setValueFrom(obj, this.newPath(this.path.slice(1), val + 1));
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
|
||||
function SetupPathBenchmark(config, objectCount) {
|
||||
ObservationBenchmark.call(this, objectCount);
|
||||
this.path = Path.get('foo.bar.baz');
|
||||
}
|
||||
|
||||
SetupPathBenchmark.configs = [];
|
||||
|
||||
SetupPathBenchmark.prototype = createObject({
|
||||
__proto__: SetupObservationBenchmark.prototype,
|
||||
|
||||
newPath: function(parts, value) {
|
||||
var obj = {};
|
||||
var ref = obj;
|
||||
var prop;
|
||||
for (var i = 0; i < parts.length - 1; i++) {
|
||||
prop = parts[i];
|
||||
ref[prop] = {};
|
||||
ref = ref[prop];
|
||||
}
|
||||
|
||||
prop = parts[parts.length - 1];
|
||||
ref[prop] = value;
|
||||
|
||||
return obj;
|
||||
},
|
||||
|
||||
newObject: function() {
|
||||
return this.newPath(this.path, 1);
|
||||
},
|
||||
|
||||
newObserver: function(obj) {
|
||||
return new PathObserver(obj, this.path);
|
||||
}
|
||||
});
|
||||
|
||||
global.ObjectBenchmark = ObjectBenchmark;
|
||||
global.SetupObjectBenchmark = SetupObjectBenchmark;
|
||||
global.ArrayBenchmark = ArrayBenchmark;
|
||||
global.SetupArrayBenchmark = SetupArrayBenchmark;
|
||||
global.PathBenchmark = PathBenchmark;
|
||||
global.SetupPathBenchmark = SetupPathBenchmark;
|
||||
|
||||
})(this);
|
||||
22
bower_components/observe-js/bower.json
vendored
Normal file
22
bower_components/observe-js/bower.json
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "observe-js",
|
||||
"homepage": "https://github.com/Polymer/observe-js",
|
||||
"authors": [
|
||||
"The Polymer Authors"
|
||||
],
|
||||
"description": "A library for observing Arrays, Objects and PathValues",
|
||||
"main": "src/observe.js",
|
||||
"keywords": [
|
||||
"Object.observe"
|
||||
],
|
||||
"license": "BSD",
|
||||
"private": true,
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"tests"
|
||||
],
|
||||
"version": "0.5.1"
|
||||
}
|
||||
4
bower_components/observe-js/codereview.settings
vendored
Normal file
4
bower_components/observe-js/codereview.settings
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
# This file is used by gcl to get repository specific information.
|
||||
CODE_REVIEW_SERVER: https://codereview.appspot.com
|
||||
VIEW_VC: https://github.com/Polymer/observe-js/commit/
|
||||
|
||||
32
bower_components/observe-js/conf/karma.conf.js
vendored
Normal file
32
bower_components/observe-js/conf/karma.conf.js
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* @license
|
||||
* 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
|
||||
*/
|
||||
|
||||
module.exports = function(karma) {
|
||||
var common = require('../../tools/test/karma-common.conf.js');
|
||||
karma.set(common.mixin_common_opts(karma, {
|
||||
// base path, that will be used to resolve files and exclude
|
||||
basePath: '../',
|
||||
|
||||
// list of files / patterns to load in the browser
|
||||
files: [
|
||||
'node_modules/chai/chai.js',
|
||||
'conf/mocha.conf.js',
|
||||
'src/observe.js',
|
||||
'util/array_reduction.js',
|
||||
'tests/*.js'
|
||||
],
|
||||
|
||||
// list of files to exclude
|
||||
exclude: [
|
||||
'tests/d8_array_fuzzer.js',
|
||||
'tests/d8_planner_test.js'
|
||||
],
|
||||
}));
|
||||
};
|
||||
15
bower_components/observe-js/conf/mocha.conf.js
vendored
Normal file
15
bower_components/observe-js/conf/mocha.conf.js
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* @license
|
||||
* 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
|
||||
*/
|
||||
|
||||
mocha.setup({
|
||||
ui:'tdd',
|
||||
ignoreLeaks: true
|
||||
});
|
||||
var assert = chai.assert;
|
||||
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);
|
||||
32
bower_components/observe-js/gruntfile.js
vendored
Normal file
32
bower_components/observe-js/gruntfile.js
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
module.exports = function(grunt) {
|
||||
grunt.initConfig({
|
||||
karma: {
|
||||
options: {
|
||||
configFile: 'conf/karma.conf.js',
|
||||
keepalive: true
|
||||
},
|
||||
buildbot: {
|
||||
reporters: ['crbot'],
|
||||
logLevel: 'OFF'
|
||||
},
|
||||
'observe-js': {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
grunt.loadTasks('../tools/tasks');
|
||||
grunt.loadNpmTasks('grunt-karma');
|
||||
|
||||
grunt.registerTask('default', 'test');
|
||||
grunt.registerTask('test', ['override-chrome-launcher', 'karma:observe-js']);
|
||||
grunt.registerTask('test-buildbot', ['override-chrome-launcher', 'karma:buildbot']);
|
||||
};
|
||||
73
bower_components/observe-js/index.html
vendored
Normal file
73
bower_components/observe-js/index.html
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
<!--
|
||||
@license
|
||||
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
|
||||
-->
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>polymer api</title>
|
||||
<style>
|
||||
html, body {
|
||||
font-family: Arial, sans-serif;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
[noviewer] [ifnoviewer] {
|
||||
display: block;
|
||||
}
|
||||
[detector], [ifnoviewer], [noviewer] [ifviewer] {
|
||||
display: none;
|
||||
}
|
||||
[ifviewer], [ifnoviewer] {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
iframe {
|
||||
border: none;
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
#remote {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
}
|
||||
</style>
|
||||
<script src="../webcomponentsjs/webcomponents.js"></script>
|
||||
<link rel="import" href="../polymer-home-page/polymer-home-page.html">
|
||||
</head>
|
||||
<body>
|
||||
<img detector src="../polymer-home-page/bowager-logo.png" onerror="noviewer()">
|
||||
<polymer-home-page ifviewer></polymer-home-page>
|
||||
<div ifnoviewer>
|
||||
<span id="remote">[remote]</span>
|
||||
<iframe></iframe>
|
||||
</div>
|
||||
<!-- -->
|
||||
<script>
|
||||
var remoteDocs = 'http://turbogadgetry.com/bowertopia/components/';
|
||||
// if no local info viewer, load it remotely
|
||||
function noviewer() {
|
||||
document.body.setAttribute('noviewer', '');
|
||||
var path = location.pathname.split('/');
|
||||
var module = path.pop() || path.pop();
|
||||
document.querySelector('iframe').src = remoteDocs + module;
|
||||
document.querySelector('title').textContent = module;
|
||||
}
|
||||
// for testing only
|
||||
var opts = window.location.search;
|
||||
if (opts.indexOf('noviewer') >= 0) {
|
||||
noviewer();
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
33
bower_components/observe-js/package.json
vendored
Normal file
33
bower_components/observe-js/package.json
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"name": "observe-js",
|
||||
"version": "0.4.2",
|
||||
"description": "observe-js is a library for observing changes on JavaScript objects/arrays",
|
||||
"main": "src/observe.js",
|
||||
"directories": {
|
||||
"example": "examples",
|
||||
"test": "tests"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Polymer/observe-js.git"
|
||||
},
|
||||
"author": "The Polymer Authors",
|
||||
"license": "BSD",
|
||||
"readmeFilename": "README.md",
|
||||
"devDependencies": {
|
||||
"chai": "*",
|
||||
"mocha": "*",
|
||||
"grunt": "*",
|
||||
"grunt-karma": "*",
|
||||
"karma": "~0.12.0",
|
||||
"karma-mocha": "*",
|
||||
"karma-firefox-launcher": "*",
|
||||
"karma-ie-launcher": "*",
|
||||
"karma-safari-launcher": "*",
|
||||
"karma-script-launcher": "*",
|
||||
"karma-crbot-reporter": "*"
|
||||
}
|
||||
}
|
||||
1711
bower_components/observe-js/src/observe.js
vendored
Normal file
1711
bower_components/observe-js/src/observe.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
309
bower_components/observe-js/util/planner.js
vendored
Normal file
309
bower_components/observe-js/util/planner.js
vendored
Normal file
@@ -0,0 +1,309 @@
|
||||
// Copyright 2012 Google Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
(function(global) {
|
||||
|
||||
"use strict";
|
||||
|
||||
function ArraySet() {
|
||||
this.entries = [];
|
||||
}
|
||||
|
||||
ArraySet.prototype = {
|
||||
add: function(key) {
|
||||
if (this.entries.indexOf(key) >= 0)
|
||||
return;
|
||||
|
||||
this.entries.push(key);
|
||||
},
|
||||
|
||||
delete: function(key) {
|
||||
var i = this.entries.indexOf(key);
|
||||
if (i < 0)
|
||||
return;
|
||||
|
||||
this.entries.splice(i, 1);
|
||||
},
|
||||
|
||||
first: function() {
|
||||
return this.entries[0];
|
||||
},
|
||||
|
||||
get size() {
|
||||
return this.entries.length;
|
||||
}
|
||||
};
|
||||
|
||||
function UIDSet() {
|
||||
this.entries = {};
|
||||
this.size = 0;
|
||||
}
|
||||
|
||||
UIDSet.prototype = {
|
||||
add: function(key) {
|
||||
if (this.entries[key.__UID__] !== undefined)
|
||||
return;
|
||||
|
||||
this.entries[key.__UID__] = key;
|
||||
this.size++;
|
||||
},
|
||||
|
||||
delete: function(key) {
|
||||
if (this.entries[key.__UID__] === undefined)
|
||||
return;
|
||||
|
||||
this.entries[key.__UID__] = undefined;
|
||||
this.size--;
|
||||
}
|
||||
};
|
||||
|
||||
function Heap(scoreFunction, populate) {
|
||||
this.scoreFunction = scoreFunction;
|
||||
this.content = populate || [];
|
||||
if (this.content.length)
|
||||
this.build();
|
||||
}
|
||||
|
||||
Heap.prototype = {
|
||||
get size() {
|
||||
return this.content.length;
|
||||
},
|
||||
|
||||
build: function() {
|
||||
var lastNonLeaf = Math.floor(this.content.length / 2) - 1;
|
||||
for (var i = lastNonLeaf; i >= 0; i--)
|
||||
this.sinkDown(i);
|
||||
},
|
||||
|
||||
push: function(element) {
|
||||
this.content.push(element);
|
||||
this.bubbleUp(this.content.length - 1);
|
||||
},
|
||||
|
||||
pop: function() {
|
||||
var result = this.content[0];
|
||||
var end = this.content.pop();
|
||||
if (this.content.length) {
|
||||
this.content[0] = end;
|
||||
this.sinkDown(0);
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
delete: function(element) {
|
||||
var len = this.content.length;
|
||||
for (var i = 0; i < len; i++) {
|
||||
if (this.content[i] == element) {
|
||||
var end = this.content.pop();
|
||||
if (i != len - 1) {
|
||||
this.content[i] = end;
|
||||
if (this.scoreFunction(end) < this.scoreFunction(node)) this.bubbleUp(i);
|
||||
else this.sinkDown(i);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
bubbleUp: function(n) {
|
||||
var element = this.content[n];
|
||||
while (n > 0) {
|
||||
var parentN = Math.floor((n + 1) / 2) - 1,
|
||||
parent = this.content[parentN];
|
||||
|
||||
if (this.scoreFunction(element) <= this.scoreFunction(parent))
|
||||
break;
|
||||
|
||||
this.content[parentN] = element;
|
||||
this.content[n] = parent;
|
||||
n = parentN;
|
||||
}
|
||||
},
|
||||
|
||||
sinkDown: function(n) {
|
||||
var length = this.content.length,
|
||||
element = this.content[n],
|
||||
elemScore = this.scoreFunction(element);
|
||||
|
||||
do {
|
||||
var child2N = (n + 1) * 2
|
||||
var child1N = child2N - 1;
|
||||
|
||||
var swap = null;
|
||||
var swapScore = elemScore;
|
||||
|
||||
if (child1N < length) {
|
||||
var child1 = this.content[child1N],
|
||||
child1Score = this.scoreFunction(child1);
|
||||
if (child1Score > elemScore) {
|
||||
swap = child1N;
|
||||
swapScore = child1Score;
|
||||
}
|
||||
}
|
||||
|
||||
if (child2N < length) {
|
||||
var child2 = this.content[child2N],
|
||||
child2Score = this.scoreFunction(child2);
|
||||
if (child2Score > swapScore)
|
||||
swap = child2N;
|
||||
}
|
||||
|
||||
if (swap != null) {
|
||||
this.content[n] = this.content[swap];
|
||||
this.content[swap] = element;
|
||||
n = swap;
|
||||
}
|
||||
} while (swap != null);
|
||||
}
|
||||
};
|
||||
|
||||
function Variable(stayFunc) {
|
||||
this.stayFunc = stayFunc;
|
||||
this.methods = new ArraySet;
|
||||
};
|
||||
|
||||
Variable.prototype = {
|
||||
freeMethod: function() {
|
||||
return this.methods.first();
|
||||
}
|
||||
}
|
||||
|
||||
function Method(constraint, variable) {
|
||||
this.constraint = constraint;
|
||||
this.variable = variable;
|
||||
};
|
||||
|
||||
function Constraint(planner) {
|
||||
this.planner = planner;
|
||||
this.methods = [];
|
||||
};
|
||||
|
||||
Constraint.prototype = {
|
||||
addMethod: function(variable) {
|
||||
var method = new Method(this, variable);
|
||||
this.methods.push(method);
|
||||
method.__UID__ = this.planner.methodUIDCounter++;
|
||||
return method;
|
||||
},
|
||||
|
||||
reset: function() {
|
||||
this.methods.forEach(function(method) {
|
||||
method.variable.methods.add(method);
|
||||
});
|
||||
},
|
||||
|
||||
remove: function() {
|
||||
this.methods.forEach(function(method) {
|
||||
method.variable.methods.delete(method);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function Planner() {
|
||||
this.variables = [];
|
||||
this.constraints = [];
|
||||
this.variableUIDCounter = 1;
|
||||
this.methodUIDCounter = 1;
|
||||
};
|
||||
|
||||
Planner.prototype = {
|
||||
addVariable: function(stayFunc) {
|
||||
var variable = new Variable(stayFunc);
|
||||
variable.__UID__ = this.variableUIDCounter++;
|
||||
this.variables.push(variable);
|
||||
return variable;
|
||||
},
|
||||
|
||||
addConstraint: function() {
|
||||
var constraint = new Constraint(this);
|
||||
this.constraints.push(constraint);
|
||||
return constraint;
|
||||
},
|
||||
|
||||
removeConstraint: function(constraint) {
|
||||
var index = this.constraints.indexOf(constraint);
|
||||
if (index < 0)
|
||||
return;
|
||||
|
||||
constraint.remove();
|
||||
this.constraints.splice(index, 1);
|
||||
|
||||
this.constraints.forEach(function(constraint) {
|
||||
constraint.reset();
|
||||
});
|
||||
|
||||
this.variables = this.variables.filter(function(variable) {
|
||||
return variable.methods.size;
|
||||
});
|
||||
},
|
||||
|
||||
getPlan: function() {
|
||||
this.variables.forEach(function(variable) {
|
||||
variable.priority = variable.stayFunc();
|
||||
});
|
||||
|
||||
this.constraints.forEach(function(constraint) {
|
||||
constraint.reset();
|
||||
});
|
||||
|
||||
var methods = [];
|
||||
var free = [];
|
||||
var overconstrained = new UIDSet;
|
||||
|
||||
this.variables.forEach(function(variable) {
|
||||
var methodCount = variable.methods.size;
|
||||
|
||||
if (methodCount > 1)
|
||||
overconstrained.add(variable);
|
||||
else if (methodCount == 1)
|
||||
free.push(variable);
|
||||
});
|
||||
|
||||
free = new Heap(function(variable) {
|
||||
return variable.priority;
|
||||
}, free);
|
||||
|
||||
while (free.size) {
|
||||
var lowest;
|
||||
do {
|
||||
lowest = free.pop();
|
||||
} while (free.size && !lowest.methods.size);
|
||||
|
||||
if (!lowest.methods.size)
|
||||
break;
|
||||
|
||||
var method = lowest.freeMethod();
|
||||
var constraint = method.constraint;
|
||||
|
||||
constraint.remove();
|
||||
constraint.methods.forEach(function(method) {
|
||||
var variable = method.variable;
|
||||
if (variable.methods.size == 1) {
|
||||
overconstrained.delete(variable);
|
||||
free.push(variable);
|
||||
}
|
||||
});
|
||||
|
||||
methods.push(method);
|
||||
}
|
||||
|
||||
if (overconstrained.size)
|
||||
return undefined;
|
||||
|
||||
return methods.reverse();
|
||||
}
|
||||
}
|
||||
|
||||
global.Planner = Planner;
|
||||
})(this);
|
||||
Reference in New Issue
Block a user