summaryrefslogtreecommitdiffstats
path: root/third_party
diff options
context:
space:
mode:
authorjlklein <jlklein@chromium.org>2015-05-08 10:58:00 -0700
committerCommit bot <commit-bot@chromium.org>2015-05-08 17:59:01 +0000
commitbac1d7de5e7bc83b2454a218768240d11636d600 (patch)
treee4d24a25b79927cb6484cab0ccb2c84e63059db4 /third_party
parentf7c37d56082175b8b21e0c8cbdea72a7d8b3ea26 (diff)
downloadchromium_src-bac1d7de5e7bc83b2454a218768240d11636d600.zip
chromium_src-bac1d7de5e7bc83b2454a218768240d11636d600.tar.gz
chromium_src-bac1d7de5e7bc83b2454a218768240d11636d600.tar.bz2
Pull more-routing and transitively observe-js into third_party/polymer.
This will replace usage in c/b/r/settings/routing. BUG=485381 Disabling presubmit due to errors with "=====" in README.md files. NOPRESUBMIT=true Review URL: https://codereview.chromium.org/1132583003 Cr-Commit-Position: refs/heads/master@{#328982}
Diffstat (limited to 'third_party')
-rw-r--r--third_party/polymer/v0_8/bower.json4
-rw-r--r--third_party/polymer/v0_8/components-chromium/iron-collapse/.bower.json8
-rw-r--r--third_party/polymer/v0_8/components-chromium/iron-collapse/iron-collapse-extracted.js1
-rw-r--r--third_party/polymer/v0_8/components-chromium/iron-input/.bower.json8
-rw-r--r--third_party/polymer/v0_8/components-chromium/iron-input/iron-input-extracted.js39
-rw-r--r--third_party/polymer/v0_8/components-chromium/iron-resizable-behavior/.bower.json8
-rw-r--r--third_party/polymer/v0_8/components-chromium/iron-resizable-behavior/iron-resizable-behavior-extracted.js19
-rw-r--r--third_party/polymer/v0_8/components-chromium/iron-selector/.bower.json14
-rw-r--r--third_party/polymer/v0_8/components-chromium/iron-selector/iron-multi-selectable-extracted.js2
-rw-r--r--third_party/polymer/v0_8/components-chromium/iron-selector/iron-selectable-extracted.js16
-rw-r--r--third_party/polymer/v0_8/components-chromium/iron-selector/iron-selection-extracted.js14
-rw-r--r--third_party/polymer/v0_8/components-chromium/more-routing/.bower.json46
-rw-r--r--third_party/polymer/v0_8/components-chromium/more-routing/README.md338
-rw-r--r--third_party/polymer/v0_8/components-chromium/more-routing/bower.json37
-rw-r--r--third_party/polymer/v0_8/components-chromium/more-routing/driver-extracted.js104
-rw-r--r--third_party/polymer/v0_8/components-chromium/more-routing/driver.html8
-rw-r--r--third_party/polymer/v0_8/components-chromium/more-routing/driver/hash-extracted.js35
-rw-r--r--third_party/polymer/v0_8/components-chromium/more-routing/driver/hash.html10
-rw-r--r--third_party/polymer/v0_8/components-chromium/more-routing/driver/mock-extracted.js16
-rw-r--r--third_party/polymer/v0_8/components-chromium/more-routing/driver/mock.html10
-rw-r--r--third_party/polymer/v0_8/components-chromium/more-routing/driver/path-extracted.js29
-rw-r--r--third_party/polymer/v0_8/components-chromium/more-routing/driver/path.html10
-rw-r--r--third_party/polymer/v0_8/components-chromium/more-routing/index.html25
-rw-r--r--third_party/polymer/v0_8/components-chromium/more-routing/more-route-context-aware-extracted.js52
-rw-r--r--third_party/polymer/v0_8/components-chromium/more-routing/more-route-context-aware.html13
-rw-r--r--third_party/polymer/v0_8/components-chromium/more-routing/more-route-extracted.js178
-rw-r--r--third_party/polymer/v0_8/components-chromium/more-routing/more-route-selection-extracted.js180
-rw-r--r--third_party/polymer/v0_8/components-chromium/more-routing/more-route-selection.html17
-rw-r--r--third_party/polymer/v0_8/components-chromium/more-routing/more-route-selector-extracted.js155
-rw-r--r--third_party/polymer/v0_8/components-chromium/more-routing/more-route-selector.html25
-rw-r--r--third_party/polymer/v0_8/components-chromium/more-routing/more-route.html14
-rw-r--r--third_party/polymer/v0_8/components-chromium/more-routing/more-routing-config-extracted.js46
-rw-r--r--third_party/polymer/v0_8/components-chromium/more-routing/more-routing-config.html16
-rw-r--r--third_party/polymer/v0_8/components-chromium/more-routing/more-routing.html12
-rw-r--r--third_party/polymer/v0_8/components-chromium/more-routing/route-extracted.js183
-rw-r--r--third_party/polymer/v0_8/components-chromium/more-routing/route.html10
-rw-r--r--third_party/polymer/v0_8/components-chromium/more-routing/routing-extracted.js126
-rw-r--r--third_party/polymer/v0_8/components-chromium/more-routing/routing.html10
-rw-r--r--third_party/polymer/v0_8/components-chromium/observe-js/.bower.json31
-rw-r--r--third_party/polymer/v0_8/components-chromium/observe-js/AUTHORS9
-rw-r--r--third_party/polymer/v0_8/components-chromium/observe-js/README.md203
-rw-r--r--third_party/polymer/v0_8/components-chromium/observe-js/bower.json21
-rw-r--r--third_party/polymer/v0_8/components-chromium/observe-js/codereview.settings4
-rw-r--r--third_party/polymer/v0_8/components-chromium/observe-js/gruntfile.js32
-rw-r--r--third_party/polymer/v0_8/components-chromium/observe-js/index.html73
-rw-r--r--third_party/polymer/v0_8/components-chromium/observe-js/observe-js.html9
-rw-r--r--third_party/polymer/v0_8/components-chromium/observe-js/package.json33
-rw-r--r--third_party/polymer/v0_8/components-chromium/observe-js/src/observe.js1711
-rw-r--r--third_party/polymer/v0_8/components-chromium/observe-js/util/planner.js309
-rw-r--r--third_party/polymer/v0_8/components-chromium/paper-behaviors/.bower.json4
-rw-r--r--third_party/polymer/v0_8/components-chromium/paper-button/.bower.json8
-rw-r--r--third_party/polymer/v0_8/components-chromium/paper-button/paper-button-extracted.js69
-rw-r--r--third_party/polymer/v0_8/components-chromium/paper-button/paper-button.html3
-rw-r--r--third_party/polymer/v0_8/components-chromium/paper-drawer-panel/.bower.json8
-rw-r--r--third_party/polymer/v0_8/components-chromium/paper-drawer-panel/paper-drawer-panel-extracted.js29
-rw-r--r--third_party/polymer/v0_8/components-chromium/paper-input/.bower.json8
-rw-r--r--third_party/polymer/v0_8/components-chromium/paper-input/paper-input-behavior-extracted.js107
-rw-r--r--third_party/polymer/v0_8/components-chromium/paper-input/paper-input-behavior.html15
-rw-r--r--third_party/polymer/v0_8/components-chromium/paper-input/paper-input-container-extracted.js4
-rw-r--r--third_party/polymer/v0_8/components-chromium/paper-input/paper-input-container.html16
-rw-r--r--third_party/polymer/v0_8/components-chromium/paper-input/paper-input-extracted.js95
-rw-r--r--third_party/polymer/v0_8/components-chromium/paper-input/paper-input.html5
-rw-r--r--third_party/polymer/v0_8/components-chromium/paper-ripple/.bower.json8
-rw-r--r--third_party/polymer/v0_8/components-chromium/paper-ripple/bower.json1
-rw-r--r--third_party/polymer/v0_8/components-chromium/paper-ripple/paper-ripple-extracted.js3
-rw-r--r--third_party/polymer/v0_8/components-chromium/paper-ripple/paper-ripple.html12
-rw-r--r--third_party/polymer/v0_8/components-chromium/polymer/polymer.html184
-rw-r--r--third_party/polymer/v0_8/components/iron-collapse/.bower.json8
-rw-r--r--third_party/polymer/v0_8/components/iron-collapse/iron-collapse.html1
-rw-r--r--third_party/polymer/v0_8/components/iron-input/.bower.json8
-rw-r--r--third_party/polymer/v0_8/components/iron-input/iron-input.html39
-rw-r--r--third_party/polymer/v0_8/components/iron-resizable-behavior/.bower.json8
-rw-r--r--third_party/polymer/v0_8/components/iron-resizable-behavior/iron-resizable-behavior.html19
-rw-r--r--third_party/polymer/v0_8/components/iron-selector/.bower.json14
-rw-r--r--third_party/polymer/v0_8/components/iron-selector/iron-multi-selectable.html2
-rw-r--r--third_party/polymer/v0_8/components/iron-selector/iron-selectable.html16
-rw-r--r--third_party/polymer/v0_8/components/iron-selector/iron-selection.html14
-rw-r--r--third_party/polymer/v0_8/components/more-routing/.bower.json46
-rw-r--r--third_party/polymer/v0_8/components/more-routing/README.md338
-rw-r--r--third_party/polymer/v0_8/components/more-routing/bower.json37
-rw-r--r--third_party/polymer/v0_8/components/more-routing/driver.html113
-rw-r--r--third_party/polymer/v0_8/components/more-routing/driver/hash.html46
-rw-r--r--third_party/polymer/v0_8/components/more-routing/driver/mock.html27
-rw-r--r--third_party/polymer/v0_8/components/more-routing/driver/path.html40
-rw-r--r--third_party/polymer/v0_8/components/more-routing/index.html25
-rw-r--r--third_party/polymer/v0_8/components/more-routing/more-route-context-aware.html66
-rw-r--r--third_party/polymer/v0_8/components/more-routing/more-route-selection.html198
-rw-r--r--third_party/polymer/v0_8/components/more-routing/more-route-selector.html184
-rw-r--r--third_party/polymer/v0_8/components/more-routing/more-route.html193
-rw-r--r--third_party/polymer/v0_8/components/more-routing/more-routing-config.html63
-rw-r--r--third_party/polymer/v0_8/components/more-routing/more-routing.html12
-rw-r--r--third_party/polymer/v0_8/components/more-routing/route.html194
-rw-r--r--third_party/polymer/v0_8/components/more-routing/routing.html137
-rw-r--r--third_party/polymer/v0_8/components/observe-js/.bower.json31
-rw-r--r--third_party/polymer/v0_8/components/observe-js/AUTHORS9
-rw-r--r--third_party/polymer/v0_8/components/observe-js/README.md203
-rw-r--r--third_party/polymer/v0_8/components/observe-js/bower.json21
-rw-r--r--third_party/polymer/v0_8/components/observe-js/codereview.settings4
-rw-r--r--third_party/polymer/v0_8/components/observe-js/gruntfile.js32
-rw-r--r--third_party/polymer/v0_8/components/observe-js/index.html73
-rw-r--r--third_party/polymer/v0_8/components/observe-js/observe-js.html9
-rw-r--r--third_party/polymer/v0_8/components/observe-js/package.json33
-rw-r--r--third_party/polymer/v0_8/components/observe-js/src/observe.js1711
-rw-r--r--third_party/polymer/v0_8/components/observe-js/util/planner.js309
-rw-r--r--third_party/polymer/v0_8/components/paper-behaviors/.bower.json4
-rw-r--r--third_party/polymer/v0_8/components/paper-button/.bower.json8
-rw-r--r--third_party/polymer/v0_8/components/paper-button/paper-button.html77
-rw-r--r--third_party/polymer/v0_8/components/paper-drawer-panel/.bower.json8
-rw-r--r--third_party/polymer/v0_8/components/paper-drawer-panel/paper-drawer-panel.html29
-rw-r--r--third_party/polymer/v0_8/components/paper-input/.bower.json8
-rw-r--r--third_party/polymer/v0_8/components/paper-input/paper-input-behavior.html123
-rw-r--r--third_party/polymer/v0_8/components/paper-input/paper-input-container.html20
-rw-r--r--third_party/polymer/v0_8/components/paper-input/paper-input.html100
-rw-r--r--third_party/polymer/v0_8/components/paper-ripple/.bower.json8
-rw-r--r--third_party/polymer/v0_8/components/paper-ripple/bower.json1
-rw-r--r--third_party/polymer/v0_8/components/paper-ripple/paper-ripple.html16
-rwxr-xr-xthird_party/polymer/v0_8/reproduce.sh1
117 files changed, 9094 insertions, 444 deletions
diff --git a/third_party/polymer/v0_8/bower.json b/third_party/polymer/v0_8/bower.json
index 4cf0c3b..39c160f 100644
--- a/third_party/polymer/v0_8/bower.json
+++ b/third_party/polymer/v0_8/bower.json
@@ -17,6 +17,8 @@
"paper-menu": "PolymerElements/paper-menu#^0.8.0",
"paper-ripple": "PolymerElements/paper-ripple#^0.8.0",
"paper-styles": "PolymerElements/paper-styles#^0.8.0",
- "paper-toggle-button": "PolymerElements/paper-toggle-button#^0.8.0"
+ "paper-toggle-button": "PolymerElements/paper-toggle-button#^0.8.0",
+
+ "more-routing": "PolymerLabs/more-routing#^0.8.0"
}
}
diff --git a/third_party/polymer/v0_8/components-chromium/iron-collapse/.bower.json b/third_party/polymer/v0_8/components-chromium/iron-collapse/.bower.json
index 06965c7e..4cb2453 100644
--- a/third_party/polymer/v0_8/components-chromium/iron-collapse/.bower.json
+++ b/third_party/polymer/v0_8/components-chromium/iron-collapse/.bower.json
@@ -1,6 +1,6 @@
{
"name": "iron-collapse",
- "version": "0.8.2",
+ "version": "0.8.3",
"authors": [
"The Polymer Authors"
],
@@ -28,11 +28,11 @@
"iron-doc-viewer": "PolymerElements/iron-doc-viewer#^0.8.0",
"paper-styles": "PolymerElements/paper-styles#^0.8.0"
},
- "_release": "0.8.2",
+ "_release": "0.8.3",
"_resolution": {
"type": "version",
- "tag": "v0.8.2",
- "commit": "235ac1fbc638795b8ca0026b42304fba29afd45c"
+ "tag": "v0.8.3",
+ "commit": "783e5ea589e9c4cf23755471a9ad2e1e9e597a65"
},
"_source": "git://github.com/PolymerElements/iron-collapse.git",
"_target": "^0.8.0",
diff --git a/third_party/polymer/v0_8/components-chromium/iron-collapse/iron-collapse-extracted.js b/third_party/polymer/v0_8/components-chromium/iron-collapse/iron-collapse-extracted.js
index feb8473..e383953 100644
--- a/third_party/polymer/v0_8/components-chromium/iron-collapse/iron-collapse-extracted.js
+++ b/third_party/polymer/v0_8/components-chromium/iron-collapse/iron-collapse-extracted.js
@@ -29,6 +29,7 @@
opened: {
type: Boolean,
value: false,
+ notify: true,
observer: 'openedChanged'
}
diff --git a/third_party/polymer/v0_8/components-chromium/iron-input/.bower.json b/third_party/polymer/v0_8/components-chromium/iron-input/.bower.json
index 9a43046..074b666 100644
--- a/third_party/polymer/v0_8/components-chromium/iron-input/.bower.json
+++ b/third_party/polymer/v0_8/components-chromium/iron-input/.bower.json
@@ -1,6 +1,6 @@
{
"name": "iron-input",
- "version": "0.8.1",
+ "version": "0.8.3",
"authors": "The Polymer Authors",
"keywords": [
"web-components",
@@ -27,11 +27,11 @@
"web-component-tester": "Polymer/web-component-tester#^2.2.3",
"webcomponentsjs": "Polymer/webcomponentsjs#^0.6.0"
},
- "_release": "0.8.1",
+ "_release": "0.8.3",
"_resolution": {
"type": "version",
- "tag": "v0.8.1",
- "commit": "2aab343ceb47fd96e58c7898ae114deb7fefd20d"
+ "tag": "v0.8.3",
+ "commit": "6ab99b7e7bb9923911671c0d757492d1964e8120"
},
"_source": "git://github.com/PolymerElements/iron-input.git",
"_target": "^0.8.0",
diff --git a/third_party/polymer/v0_8/components-chromium/iron-input/iron-input-extracted.js b/third_party/polymer/v0_8/components-chromium/iron-input/iron-input-extracted.js
index 5a8c0c3..b21395a 100644
--- a/third_party/polymer/v0_8/components-chromium/iron-input/iron-input-extracted.js
+++ b/third_party/polymer/v0_8/components-chromium/iron-input/iron-input-extracted.js
@@ -14,6 +14,19 @@
bindValue: {
observer: '_bindValueChanged',
type: String
+ },
+
+ /**
+ * Set to true to prevent the user from entering invalid input or setting
+ * invalid `bindValue`.
+ */
+ preventInvalidInput: {
+ type: Boolean
+ },
+
+ _previousValidInput: {
+ type: String,
+ value: ''
}
},
@@ -22,18 +35,36 @@
'input': '_onInput'
},
- attached: function() {
+ ready: function() {
+ this._validateValue();
this.bindValue = this.value;
},
_bindValueChanged: function() {
- this.value = this.bindValue;
+ // If this was called as a result of user input, then |_validateValue|
+ // has already been called in |_onInput|, and it doesn't need to be
+ // called again.
+ if (this.value != this.bindValue) {
+ this.value = this.bindValue;
+ this._validateValue();
+ }
+
// manually notify because we don't want to notify until after setting value
this.fire('bind-value-changed', {value: this.bindValue});
},
- _onInput: function(event) {
- this.bindValue = event.target.value;
+ _onInput: function() {
+ this._validateValue();
+ },
+
+ _validateValue: function() {
+ var value;
+ if (this.preventInvalidInput && !this.validity.valid) {
+ value = this._previousValidInput;
+ } else {
+ value = this._previousValidInput = this.value;
+ }
+ this.bindValue = this.value = value;
}
})
diff --git a/third_party/polymer/v0_8/components-chromium/iron-resizable-behavior/.bower.json b/third_party/polymer/v0_8/components-chromium/iron-resizable-behavior/.bower.json
index 93072c2..3df2b52 100644
--- a/third_party/polymer/v0_8/components-chromium/iron-resizable-behavior/.bower.json
+++ b/third_party/polymer/v0_8/components-chromium/iron-resizable-behavior/.bower.json
@@ -1,6 +1,6 @@
{
"name": "iron-resizable-behavior",
- "version": "0.8.0",
+ "version": "0.8.1",
"private": true,
"main": "iron-resizable-behavior.html",
"authors": [
@@ -16,11 +16,11 @@
"web-component-tester": "*"
},
"homepage": "https://github.com/polymerelements/iron-resizable-behavior",
- "_release": "0.8.0",
+ "_release": "0.8.1",
"_resolution": {
"type": "version",
- "tag": "v0.8.0",
- "commit": "c7b09f87758efc6c6483e2854b992aab4042be51"
+ "tag": "v0.8.1",
+ "commit": "50415abf3c9acc0be0d5bec8e021beb9a52288ce"
},
"_source": "git://github.com/polymerelements/iron-resizable-behavior.git",
"_target": "^0.8.0",
diff --git a/third_party/polymer/v0_8/components-chromium/iron-resizable-behavior/iron-resizable-behavior-extracted.js b/third_party/polymer/v0_8/components-chromium/iron-resizable-behavior/iron-resizable-behavior-extracted.js
index 24ce5e3..9d30161 100644
--- a/third_party/polymer/v0_8/components-chromium/iron-resizable-behavior/iron-resizable-behavior-extracted.js
+++ b/third_party/polymer/v0_8/components-chromium/iron-resizable-behavior/iron-resizable-behavior-extracted.js
@@ -18,6 +18,7 @@
Polymer.IronResizableBehavior = {
properties: {
_parentResizable: {
+ type: Object,
observer: '_parentResizableChanged'
}
},
@@ -90,27 +91,15 @@
* that should be notified of a resize change.
*/
stopResizeNotificationsFor: function(target) {
- index = this._interestedResizables.indexOf(target);
+ var index = this._interestedResizables.indexOf(target);
if (index > -1) {
this._interestedResizables.splice(index, 1);
}
},
- /**
- * User should implement to introduce filtering when notifying children.
- * Generally, children that are hidden by the resizable (e.g. non-active
- * pages) need not be notified during resize, since they will be notified
- * again when becoming un-hidden.
- *
- * Return `true` if the resizable passed as argument should be notified of
- * resize.
- *
- * @method resizerShouldNotify
- * @param {Element} el
- */
- // TODO(cdata): Currently behaviors cannot define "abstract" methods..
- //resizerShouldNotify: function(el) { return true; },
+ // TODO(cdata): Currently behaviors cannot define "abstract" methods.
+ // resizerShouldNotify: function(el) { return true; },
_parentResizableChanged: function(parentResizable) {
if (parentResizable) {
diff --git a/third_party/polymer/v0_8/components-chromium/iron-selector/.bower.json b/third_party/polymer/v0_8/components-chromium/iron-selector/.bower.json
index 10b2667..c6c8240 100644
--- a/third_party/polymer/v0_8/components-chromium/iron-selector/.bower.json
+++ b/third_party/polymer/v0_8/components-chromium/iron-selector/.bower.json
@@ -1,6 +1,6 @@
{
"name": "iron-selector",
- "version": "0.8.4",
+ "version": "0.8.5",
"private": true,
"main": [
"iron-selector.html"
@@ -18,14 +18,14 @@
"web-component-tester": "Polymer/web-component-tester#^2.2.3",
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.6.0"
},
- "homepage": "https://github.com/polymerelements/iron-selector",
- "_release": "0.8.4",
+ "homepage": "https://github.com/PolymerElements/iron-selector",
+ "_release": "0.8.5",
"_resolution": {
"type": "version",
- "tag": "v0.8.4",
- "commit": "a094802a4e03ceb0b574accfcde9654b4334efc0"
+ "tag": "v0.8.5",
+ "commit": "6b56de55e3e7f8ed108c9c227c85bc2a2f360d0d"
},
- "_source": "git://github.com/polymerelements/iron-selector.git",
+ "_source": "git://github.com/PolymerElements/iron-selector.git",
"_target": "^0.8.0",
- "_originalSource": "polymerelements/iron-selector"
+ "_originalSource": "PolymerElements/iron-selector"
} \ No newline at end of file
diff --git a/third_party/polymer/v0_8/components-chromium/iron-selector/iron-multi-selectable-extracted.js b/third_party/polymer/v0_8/components-chromium/iron-selector/iron-multi-selectable-extracted.js
index 2aef4e4..d4df0bd 100644
--- a/third_party/polymer/v0_8/components-chromium/iron-selector/iron-multi-selectable-extracted.js
+++ b/third_party/polymer/v0_8/components-chromium/iron-selector/iron-multi-selectable-extracted.js
@@ -53,7 +53,7 @@
* `value` will be toggled; otherwise the `value` will be selected.
*
* @method select
- * @param {String} value the value to select.
+ * @param {string} value the value to select.
*/
select: function(value) {
if (this.multi) {
diff --git a/third_party/polymer/v0_8/components-chromium/iron-selector/iron-selectable-extracted.js b/third_party/polymer/v0_8/components-chromium/iron-selector/iron-selectable-extracted.js
index 953e7bc..644e024 100644
--- a/third_party/polymer/v0_8/components-chromium/iron-selector/iron-selectable-extracted.js
+++ b/third_party/polymer/v0_8/components-chromium/iron-selector/iron-selectable-extracted.js
@@ -9,7 +9,7 @@
* set this to the name of the attribute.
*
* @attribute attrForSelected
- * @type String
+ * @type {string}
*/
attrForSelected: {
type: String,
@@ -20,7 +20,7 @@
* Gets or sets the selected element. The default is to use the index of the item.
*
* @attribute selected
- * @type String
+ * @type {string}
*/
selected: {
type: String,
@@ -31,7 +31,7 @@
* Returns the currently selected item.
*
* @attribute selectedItem
- * @type Object
+ * @type {Object}
*/
selectedItem: {
type: Object,
@@ -45,7 +45,7 @@
* Set to empty string to listen to no events.
*
* @attribute activateEvent
- * @type String
+ * @type {string}
* @default 'click'
*/
activateEvent: {
@@ -59,7 +59,7 @@
* are selectable.
*
* @attribute selectable
- * @type String
+ * @type {string}
*/
selectable: String,
@@ -67,7 +67,7 @@
* The class to set on elements when selected.
*
* @attribute selectedClass
- * @type String
+ * @type {string}
*/
selectedClass: {
type: String,
@@ -78,7 +78,7 @@
* The attribute to set on elements when selected.
*
* @attribute selectedAttribute
- * @type String
+ * @type {string}
*/
selectedAttribute: {
type: String,
@@ -142,7 +142,7 @@
* Selects the given value.
*
* @method select
- * @param {String} value the value to select.
+ * @param {string} value the value to select.
*/
select: function(value) {
this.selected = value;
diff --git a/third_party/polymer/v0_8/components-chromium/iron-selector/iron-selection-extracted.js b/third_party/polymer/v0_8/components-chromium/iron-selector/iron-selection-extracted.js
index f901d5d..2758326 100644
--- a/third_party/polymer/v0_8/components-chromium/iron-selector/iron-selection-extracted.js
+++ b/third_party/polymer/v0_8/components-chromium/iron-selector/iron-selection-extracted.js
@@ -1,5 +1,9 @@
+ /**
+ * @param {!Function} selectCallback
+ * @constructor
+ */
Polymer.IronSelection = function(selectCallback) {
this.selection = [];
this.selectCallback = selectCallback;
@@ -37,7 +41,7 @@
* Indicates if a given item is selected.
*
* @method isSelected
- * @param {any} item The item whose selection state should be checked.
+ * @param {*} item The item whose selection state should be checked.
* @returns Returns true if `item` is selected.
*/
isSelected: function(item) {
@@ -48,8 +52,8 @@
* Sets the selection state for a given item to either selected or deselected.
*
* @method setItemSelected
- * @param {any} item The item to select.
- * @param {Boolean} isSelected True for selected, false for deselected.
+ * @param {*} item The item to select.
+ * @param {boolean} isSelected True for selected, false for deselected.
*/
setItemSelected: function(item, isSelected) {
if (item != null) {
@@ -73,7 +77,7 @@
* the `item` will be selected.
*
* @method select
- * @param {any} item The item to select.
+ * @param {*} item The item to select.
*/
select: function(item) {
if (this.multi) {
@@ -88,7 +92,7 @@
* Toggles the selection state for `item`.
*
* @method toggle
- * @param {any} item The item to toggle.
+ * @param {*} item The item to toggle.
*/
toggle: function(item) {
this.setItemSelected(item, !this.isSelected(item));
diff --git a/third_party/polymer/v0_8/components-chromium/more-routing/.bower.json b/third_party/polymer/v0_8/components-chromium/more-routing/.bower.json
new file mode 100644
index 0000000..0ad7a53
--- /dev/null
+++ b/third_party/polymer/v0_8/components-chromium/more-routing/.bower.json
@@ -0,0 +1,46 @@
+{
+ "name": "more-routing",
+ "version": "0.8.0-rc1",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "description": "A composable suite of objects and elements to make routing with web components a breeze.",
+ "keywords": [
+ "web-component",
+ "web-components",
+ "polymer",
+ "routing",
+ "router"
+ ],
+ "main": "more-routing.html",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerLabs/more-routing/",
+ "ignore": [
+ "/.*",
+ "/test/",
+ "/demo/"
+ ],
+ "dependencies": {
+ "polymer": "Polymer/polymer#v0.8.0-rc.7",
+ "observe-js": "Polymer/observe-js#0.5.6-rc1"
+ },
+ "devDependencies": {
+ "iron-doc-viewer": "PolymerElements/iron-doc-viewer#^0.8.5",
+ "iron-selector": "PolymerElements/iron-selector#^0.8.2",
+ "paper-styles": "PolymerElements/paper-styles#^0.8.9",
+ "iron-flex-layout": "PolymerElements/iron-flex-layout#^0.8.1",
+ "web-component-tester": "*"
+ },
+ "resolutions": {
+ "observe-js": "0.5.6-rc1"
+ },
+ "_release": "0.8.0-rc1",
+ "_resolution": {
+ "type": "version",
+ "tag": "v0.8.0-rc1",
+ "commit": "751ec450f5e8e8f5f5323dc6f16c43586eb9d142"
+ },
+ "_source": "git://github.com/PolymerLabs/more-routing.git",
+ "_target": "^0.8.0",
+ "_originalSource": "PolymerLabs/more-routing"
+} \ No newline at end of file
diff --git a/third_party/polymer/v0_8/components-chromium/more-routing/README.md b/third_party/polymer/v0_8/components-chromium/more-routing/README.md
new file mode 100644
index 0000000..880ccfe
--- /dev/null
+++ b/third_party/polymer/v0_8/components-chromium/more-routing/README.md
@@ -0,0 +1,338 @@
+Routing
+=======
+
+A composable suite of objects and elements to make routing with web components
+a breeze.
+
+* [Hash-](#MoreRouting.HashDriver) and [path-](#MoreRouting.PathDriver)based
+ routing.
+* [Named routes](#more-routing).
+* [Nested (mounted) routes](#more-route--nesting).
+* [Declarative route switching](#more-route-switch).
+* [Polymer helpers](#polymer-helpers--filters) for easy integration into existing elements.
+
+[Rob Dodson](https://github.com/robdodson) has whipped up a great video
+that can get you started with more-routing:
+
+<p align="center">
+ <a href="https://www.youtube.com/watch?v=-67kb7poIT8">
+ <img src="http://img.youtube.com/vi/-67kb7poIT8/0.jpg" alt="Moar routing with... more-routing">
+ </a>
+</p>
+
+Or, TL;DR:
+
+```html
+<link rel="import" href="../more-routing/more-routing.html">
+
+<more-routing-config driver="path"></more-routing-config>
+<more-route name="user" path="/users/:userId">
+ <more-route name="user-bio" path="/bio"></more-route>
+</more-route>
+
+<more-route-selector selectedParams="{{params}}">
+ <core-pages>
+ <section route="/">
+ This is the index.
+ </section>
+
+ <section route="/about">
+ It's a routing demo!
+ <a href="{{ urlFor('user-bio', {userId: 1}) }}">Read about user 1</a>.
+ </section>
+
+ <section route="user">
+ <header>Heyo user {{params.userId}}!</header>
+ <template if="{{ route('user-bio').active }}">
+ All the details about {{params.userId}} that you didn't want to know...
+ </template>
+ </section>
+ </core-pages>
+</more-route-selector>
+```
+
+And finally, check out [the demo](demo/) for a project that makes comprehensive
+use of the various features in more-routing.
+
+
+Element API
+===========
+
+<a name="more-routing-config"></a>
+`<more-routing-config>`
+----------------
+
+_Defined in [`more-routing-config.html`](more-routing-config.html)._
+
+The declarative interface for configuring [`MoreRouting`](#MoreRouting).
+Currently, this lets you declare which [driver](#MoreRouting.Driver) you wish
+to use (`hash` or `path`):
+
+```html
+<more-routing-config driver="hash"></more-routing-config>
+```
+
+You should place this as early in the load process for your app as you can. Any
+routes defined prior to the driver being set will trigger an error.
+
+
+<a name="more-route"></a>
+`<more-route>`
+--------------
+
+_Defined in [`more-route.html`](more-route.html)._
+
+Reference routes by path, and extract their params:
+
+```html
+<more-route path="/users/:userId" params="{{user}}"></more-route>
+```
+
+Declare a named route:
+
+```html
+<more-route path="/users/:userId" name="user"></more-route>
+```
+
+Reference a named route:
+
+```html
+<more-route name="user" params="{{user}}"></more-route>
+```
+
+
+<a name="more-route--nesting"></a>
+### Route Nesting
+
+Routes can also be nested:
+
+```html
+<more-route path="/users/:userId" name="user">
+ <more-route path="/bio" name="user-bio"></more-route>
+</more-route>
+```
+
+In this example, the route named `user-bio` will match `/users/:userId/bio`.
+
+Finally, `<more-route>` elements can declare a routing context for the element
+that contains them by setting the `context` attribute. See the
+[routed elements](#more-route-selector--routed-elements) section for more info.
+
+
+<a name="more-route-selector"></a>
+`<more-route-selector>`
+-----------------------
+
+_Defined in [`more-route-selector.html`](more-route-selector.html)._
+
+Manages a [`<core-selector>`](https://www.polymer-project.org/docs/elements/core-elements.html#core-selector)
+(or anything that extends it/looks like one), where each item in the selector
+have an associated route. The most specific route that is active will be
+selected.
+
+```html
+<more-route-selector>
+ <core-pages>
+ <section route="/">The index!</section>
+ <section route="user">A user (named route)</section>
+ <section route="/about">Another route</section>
+ </core-pages>
+</more-route-selector>
+```
+
+By default, `more-route-selector` will look for the `route` attribute on any
+children of the `core-selector` (change this via `routeAttribute`).
+
+It exposes information about the selected route via a few properties:
+
+`selectedParams`: The params of the selected route.
+
+`selectedRoute`: The [`MoreRouting.Route`](#MoreRouting.Route) representing the
+selected route.
+
+`selectedPath`: The path expression of the selected route.
+
+`selectedIndex`: The index of the selected route (relative to `routes`).
+
+
+<a name="more-route-selector--routed-elements"></a>
+### Routed Elements
+
+Elements can declare a route to be associated with, which allows
+`<more-route-selector>` to be smart and use that as the route it checks against
+for your element. For example:
+
+```html
+<polymer-element name="routed-element">
+ <template>
+ <more-route path="/my/route" context></more-route>
+ I'm a routed element!
+ </template>
+</polymer-element>
+```
+
+```html
+<more-route-selector>
+ <core-pages>
+ <section route="/">The index!</section>
+ <routed-element></routed-element>
+ </core-pages>
+</more-route-selector>
+```
+
+In this example, The `<more-route-selector>` will choose `<routed-element>`
+whenever the path begins with `/my/route`. Keep it DRY!
+
+
+<a name="more-route-selector--nesting-contexts"></a>
+### Nesting Contexts
+
+Similar to [`more-route`'s nesting behavior](#more-route--nesting), any items in
+the core-selector also behave as nesting contexts. Any route declared within a
+routing context is effectively _mounted_ on the context route.
+
+Taking the example element, `<routed-element>` above; if we were to add the
+following to its template:
+
+```html
+<more-route path="/:tab" params="{{params}}"></more-route>
+```
+
+That route's full path would be `/my/route/:tab`, because `/my/route` is the
+context in which it is nested. This allows you to create custom elements that
+make use of routes, _while not requiring knowledge of the app's route
+hierarchy_. Very handy for composable components!
+
+**Note:** All items in a `<more-route-selector>` are treated as routing
+contexts!
+
+
+<a name="polymer-helpers"></a>
+Polymer Helpers
+---------------
+
+<a name="polymer-helpers--filters"></a>
+### Filters
+
+_Defined in [`polymer-expressions.html`](polymer-expressions.html)._
+
+Several filters (functions) are exposed to templates for your convenience:
+
+#### `route`
+
+You can fetch a `MoreRouting.Route` object via the `route` filter. Handy for
+reading params, etc on the fly.
+
+```html
+<x-user model="{{ route('user').params }}"></x-user>
+```
+
+**Note:** The `route()` helper is unfortunately _not_ aware of the current
+routing context. Consider using only named routes to avoid confusion!
+
+#### `urlFor`
+
+Generates a URL for the specified route and params:
+
+```html
+<a href="{{ urlFor('user', {userId: 1}) }}">User 1</a>
+```
+
+
+JavaScript API
+==============
+
+<a name="MoreRouting"></a>
+`MoreRouting`
+-------------
+
+_Defined in [`routing.html`](routing.html)._
+
+The main entry point into `more-routing`, exposed as a global JavaScript
+namespace of `MoreRouting`. For the most part, all elements and helpers are
+built on top of it.
+
+`MoreRouting` manages the current [driver](#MoreRouting.Driver), and maintains
+an identity map of all routes.
+
+
+<a name="MoreRouting.driver"></a>
+### `MoreRouting.driver`
+
+Before you can make use of navigation and URL parsing, a driver must be
+registered. Simply assign an instance of `MoreRouting.Driver` to this property.
+
+This is exposed as a declarative element via
+[`<more-routing-config driver="...">`](#more-routing).
+
+
+<a name="MoreRouting.getRoute"></a>
+### `MoreRouting.getRoute`
+
+Returns a [`MoreRouting.Route`](#MoreRouting.Route), by path...
+
+ MoreRouting.getRoute('/users/:userId')
+
+...or by name:
+
+ MoreRouting.getRoute('user')
+
+Because routes are identity mapped, `getRoute` guarantees that it will return
+the same `Route` object for the same path.
+
+
+<a name="MoreRouting.Route"></a>
+`MoreRouting.Route`
+-------------------
+
+_Defined in [`route.html`](route.html)._
+
+The embodiment for an individual route. It has various handy properties.
+Highlights:
+
+``active``: Whether the route is active (the current URL matches).
+
+``params``: A map of param keys to their values (matching the `:named` tokens)
+within the path.
+
+``path``: The path expression that this route matches.
+
+### Paths
+
+Path expressions begin with a `/` (to disambiguate them from route names), and
+are a series of tokens separated by `/`.
+
+Tokens can be of the form `:named`, where they named a parameter. Or they can
+be regular strings, at which point they are static path parts.
+
+Should be familiar from many other routing systems.
+
+
+<a href="MoreRouting.Driver"></a>
+`MoreRouting.Driver`
+--------------------
+
+_Defined in [`driver.html`](driver.html)._
+
+Drivers manage how the URL is read, and how to navigate to URLs. There are two
+built in drivers:
+
+
+<a href="MoreRouting.HashDriver"></a>
+### `MoreRouting.HashDriver`
+
+_Defined in [`hash-driver.html`](hash-driver.html)._
+
+Provides hash-based routing, generating URLs like `#!/users/1/bio`. It has a
+configurable prefix (after the `#`). By default, it uses a prefix of `!/`
+(to fit the [AJAX-crawling spec](https://developers.google.com/webmasters/ajax-crawling/docs/specification)).
+
+
+<a href="MoreRouting.PathDriver"></a>
+### `MoreRouting.PathDriver`
+
+_Defined in [`path-driver.html`](path-driver.html)._
+
+Provides true path-based routing (via `pushState`), generating URLs like
+`/users/1/bio`. If your web app is mounted on a path other than `/`, you can
+specify that mount point via the `prefix`.
diff --git a/third_party/polymer/v0_8/components-chromium/more-routing/bower.json b/third_party/polymer/v0_8/components-chromium/more-routing/bower.json
new file mode 100644
index 0000000..434fe51
--- /dev/null
+++ b/third_party/polymer/v0_8/components-chromium/more-routing/bower.json
@@ -0,0 +1,37 @@
+{
+ "name": "more-routing",
+ "version": "0.8.0",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "description": "A composable suite of objects and elements to make routing with web components a breeze.",
+ "keywords": [
+ "web-component",
+ "web-components",
+ "polymer",
+ "routing",
+ "router"
+ ],
+ "main": "more-routing.html",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerLabs/more-routing/",
+ "ignore": [
+ "/.*",
+ "/test/",
+ "/demo/"
+ ],
+ "dependencies": {
+ "polymer": "Polymer/polymer#v0.8.0-rc.7",
+ "observe-js": "Polymer/observe-js#0.5.6-rc1"
+ },
+ "devDependencies": {
+ "iron-doc-viewer": "PolymerElements/iron-doc-viewer#^0.8.5",
+ "iron-selector": "PolymerElements/iron-selector#^0.8.2",
+ "paper-styles": "PolymerElements/paper-styles#^0.8.9",
+ "iron-flex-layout": "PolymerElements/iron-flex-layout#^0.8.1",
+ "web-component-tester": "*"
+ },
+ "resolutions": {
+ "observe-js": "0.5.6-rc1"
+ }
+}
diff --git a/third_party/polymer/v0_8/components-chromium/more-routing/driver-extracted.js b/third_party/polymer/v0_8/components-chromium/more-routing/driver-extracted.js
new file mode 100644
index 0000000..eaf1862
--- /dev/null
+++ b/third_party/polymer/v0_8/components-chromium/more-routing/driver-extracted.js
@@ -0,0 +1,104 @@
+
+(function(scope) {
+var MoreRouting = scope.MoreRouting = scope.MoreRouting || {};
+MoreRouting.Driver = Driver;
+
+/**
+ * TODO(nevir): Docs.
+ */
+function Driver(opt_config) {
+ var config = opt_config || {};
+ if (config.prefix) this.prefix = config.prefix;
+
+ this._activeRoutes = [];
+
+ this._rootRoutes = [];
+}
+
+Driver.prototype.manageRoute = function manageRoute(route) {
+ route.driver = this;
+ this._appendRoute(route);
+
+ if (route.parent) {
+ if (route.parent.active) {
+ // Remember: `processPathParts` takes just the path parts relative to that
+ // route; not the full set.
+ route.processPathParts(this.currentPathParts.slice(route.parent.depth));
+ }
+ } else {
+ route.processPathParts(this.currentPathParts);
+ }
+
+ if (route.active) this._activeRoutes.push(route);
+};
+
+Driver.prototype.urlForParts = function urlForParts(parts) {
+ return this.prefix + parts.join(this.separator);
+};
+
+Driver.prototype.navigateToParts = function(parts) {
+ return this.navigateToUrl(this.urlForParts(parts));
+};
+
+Driver.prototype.navigateToUrl = function navigateToUrl(url) {
+ throw new Error(this.constructor.name + '#navigateToUrl not implemented');
+};
+
+// Subclass Interface
+
+Driver.prototype.prefix = '/';
+Driver.prototype.separator = '/';
+
+Driver.prototype.setCurrentPath = function setCurrentPath(path) {
+ this.currentPathParts = this.splitPath(path);
+ var newRoutes = this._matchingRoutes(this.currentPathParts);
+
+ // active -> inactive.
+ for (var i = 0, route; route = this._activeRoutes[i]; i++) {
+ if (newRoutes.indexOf(route) === -1) {
+ route.processPathParts(null);
+ }
+ }
+
+ this._activeRoutes = newRoutes;
+}
+
+Driver.prototype.splitPath = function splitPath(rawPath) {
+ if (this.prefix && rawPath.indexOf(this.prefix) !== 0) {
+ throw new Error(
+ 'Invalid path "' + rawPath + '"; ' +
+ 'expected it to be prefixed by "' + this.prefix + '"');
+ }
+ var path = rawPath.substr(this.prefix.length);
+ var parts = path.split(this.separator);
+ // Ignore trailing separators.
+ if (!parts[parts.length - 1]) parts.pop();
+
+ return parts;
+};
+
+// Internal Implementation
+Driver.prototype._appendRoute = function _appendRoute(route) {
+ if (route.parent) {
+ // We only care about root routes.
+ return;
+ }
+ this._rootRoutes.push(route);
+};
+
+Driver.prototype._matchingRoutes = function _matchingRoutes(parts, rootRoutes) {
+ var routes = [];
+ var candidates = rootRoutes || this._rootRoutes;
+ var route;
+ for (var i = 0; i < candidates.length; i++) {
+ route = candidates[i];
+ route.processPathParts(parts);
+ if (route.active) {
+ routes.push(route);
+ routes = routes.concat(this._matchingRoutes(parts.slice(route.compiled.length), route.children));
+ }
+ }
+ return routes;
+}
+
+})(window);
diff --git a/third_party/polymer/v0_8/components-chromium/more-routing/driver.html b/third_party/polymer/v0_8/components-chromium/more-routing/driver.html
new file mode 100644
index 0000000..d0537730
--- /dev/null
+++ b/third_party/polymer/v0_8/components-chromium/more-routing/driver.html
@@ -0,0 +1,8 @@
+<!--
+Copyright (c) 2015 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
+--><html><head></head><body><script src="driver-extracted.js"></script></body></html> \ No newline at end of file
diff --git a/third_party/polymer/v0_8/components-chromium/more-routing/driver/hash-extracted.js b/third_party/polymer/v0_8/components-chromium/more-routing/driver/hash-extracted.js
new file mode 100644
index 0000000..50abd21
--- /dev/null
+++ b/third_party/polymer/v0_8/components-chromium/more-routing/driver/hash-extracted.js
@@ -0,0 +1,35 @@
+
+(function(scope) {
+var MoreRouting = scope.MoreRouting = scope.MoreRouting || {};
+MoreRouting.HashDriver = HashDriver;
+
+/**
+ * TODO(nevir): Docs.
+ */
+function HashDriver() {
+ MoreRouting.Driver.apply(this, arguments);
+ this._bindEvents();
+ this._read();
+}
+HashDriver.prototype = Object.create(MoreRouting.Driver.prototype);
+
+// By default, we prefer hashbang; but you can prefix with any string you wish.
+HashDriver.prototype.prefix = '!/';
+
+HashDriver.prototype.urlForParts = function urlForParts(parts) {
+ return '#' + MoreRouting.Driver.prototype.urlForParts.call(this, parts);
+};
+
+HashDriver.prototype.navigateToUrl = function navigateToUrl(url) {
+ window.location.hash = url;
+};
+
+HashDriver.prototype._bindEvents = function _bindEvents() {
+ window.addEventListener('hashchange', this._read.bind(this));
+};
+
+HashDriver.prototype._read = function _read() {
+ this.setCurrentPath(window.location.hash.substr(1) || this.prefix);
+};
+
+})(window);
diff --git a/third_party/polymer/v0_8/components-chromium/more-routing/driver/hash.html b/third_party/polymer/v0_8/components-chromium/more-routing/driver/hash.html
new file mode 100644
index 0000000..d92ddca
--- /dev/null
+++ b/third_party/polymer/v0_8/components-chromium/more-routing/driver/hash.html
@@ -0,0 +1,10 @@
+<!--
+Copyright (c) 2015 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
+--><html><head><link rel="import" href="../driver.html">
+
+</head><body><script src="hash-extracted.js"></script></body></html> \ No newline at end of file
diff --git a/third_party/polymer/v0_8/components-chromium/more-routing/driver/mock-extracted.js b/third_party/polymer/v0_8/components-chromium/more-routing/driver/mock-extracted.js
new file mode 100644
index 0000000..0933095
--- /dev/null
+++ b/third_party/polymer/v0_8/components-chromium/more-routing/driver/mock-extracted.js
@@ -0,0 +1,16 @@
+
+(function(scope) {
+var MoreRouting = scope.MoreRouting = scope.MoreRouting || {};
+MoreRouting.MockDriver = MockDriver;
+
+/** A mock driver for use in your tests. */
+function MockDriver() {
+ MoreRouting.Driver.apply(this, arguments);
+}
+MockDriver.prototype = Object.create(MoreRouting.Driver.prototype);
+
+MockDriver.prototype.navigateToUrl = function navigateToUrl(url) {
+ this.setCurrentPath(url);
+};
+
+})(window);
diff --git a/third_party/polymer/v0_8/components-chromium/more-routing/driver/mock.html b/third_party/polymer/v0_8/components-chromium/more-routing/driver/mock.html
new file mode 100644
index 0000000..764c9f0
--- /dev/null
+++ b/third_party/polymer/v0_8/components-chromium/more-routing/driver/mock.html
@@ -0,0 +1,10 @@
+<!--
+Copyright (c) 2015 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
+--><html><head><link rel="import" href="../driver.html">
+
+</head><body><script src="mock-extracted.js"></script></body></html> \ No newline at end of file
diff --git a/third_party/polymer/v0_8/components-chromium/more-routing/driver/path-extracted.js b/third_party/polymer/v0_8/components-chromium/more-routing/driver/path-extracted.js
new file mode 100644
index 0000000..ad64fd57
--- /dev/null
+++ b/third_party/polymer/v0_8/components-chromium/more-routing/driver/path-extracted.js
@@ -0,0 +1,29 @@
+
+(function(scope) {
+var MoreRouting = scope.MoreRouting = scope.MoreRouting || {};
+MoreRouting.PathDriver = PathDriver;
+
+/**
+ * TODO(nevir): Docs.
+ */
+function PathDriver() {
+ MoreRouting.Driver.apply(this, arguments);
+ this._bindEvents();
+ this._read();
+}
+PathDriver.prototype = Object.create(MoreRouting.Driver.prototype);
+
+PathDriver.prototype.navigateToUrl = function navigateToUrl(url) {
+ window.history.pushState({}, '', url);
+ this._read();
+};
+
+PathDriver.prototype._bindEvents = function _bindEvents() {
+ window.addEventListener('popstate', this._read.bind(this));
+};
+
+PathDriver.prototype._read = function _read() {
+ this.setCurrentPath(window.location.pathname);
+};
+
+})(window);
diff --git a/third_party/polymer/v0_8/components-chromium/more-routing/driver/path.html b/third_party/polymer/v0_8/components-chromium/more-routing/driver/path.html
new file mode 100644
index 0000000..c867f3bf
--- /dev/null
+++ b/third_party/polymer/v0_8/components-chromium/more-routing/driver/path.html
@@ -0,0 +1,10 @@
+<!--
+Copyright (c) 2015 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
+--><html><head><link rel="import" href="../driver.html">
+
+</head><body><script src="path-extracted.js"></script></body></html> \ No newline at end of file
diff --git a/third_party/polymer/v0_8/components-chromium/more-routing/index.html b/third_party/polymer/v0_8/components-chromium/more-routing/index.html
new file mode 100644
index 0000000..67f8282
--- /dev/null
+++ b/third_party/polymer/v0_8/components-chromium/more-routing/index.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 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
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-doc-viewer/iron-doc-viewer.html">
+
+</head>
+<body>
+
+ <iron-doc-viewer></iron-doc-viewer>
+
+</body>
+</html>
diff --git a/third_party/polymer/v0_8/components-chromium/more-routing/more-route-context-aware-extracted.js b/third_party/polymer/v0_8/components-chromium/more-routing/more-route-context-aware-extracted.js
new file mode 100644
index 0000000..38377c1
--- /dev/null
+++ b/third_party/polymer/v0_8/components-chromium/more-routing/more-route-context-aware-extracted.js
@@ -0,0 +1,52 @@
+
+
+ MoreRouting.ContextAware = {
+
+ /** @override */
+ ready: function() {
+ this._makeRoutingReady();
+ },
+
+ /**
+ * Calls `routingReady`, and ensures that it is called in a top-down manner.
+ *
+ * We need to be sure that parent nodes have `routingReady` triggered before
+ * their children so that they can properly configure nested routes.
+ *
+ * Unfortunately, `ready` is sometimes bottom-up, sometimes top-down.
+ * Ideally, this wouldn't be necessary.
+ *
+ * @see https://github.com/Polymer/polymer/pull/1448
+ */
+ _makeRoutingReady: function() {
+ if (this.routingIsReady) return;
+
+ var node = this;
+ while (node = Polymer.dom(node).parentNode) {
+ if (typeof node._makeRoutingReady === 'function') break;
+ }
+ if (node) node._makeRoutingReady();
+
+ this.parentRoute = this._findParentRoute();
+ this.routingIsReady = true;
+ if (typeof this.routingReady === 'function') this.routingReady();
+ },
+
+ _findParentRoute: function() {
+ var node = this;
+ while (node) {
+ node = Polymer.dom(node).parentNode;
+ if (node && node.nodeType !== Node.ELEMENT_NODE) {
+ node = node.host;
+ }
+
+ var route = node && node.moreRouteContext;
+ if (route instanceof MoreRouting.Route) {
+ return route;
+ }
+ }
+ return null;
+ },
+
+ };
+
diff --git a/third_party/polymer/v0_8/components-chromium/more-routing/more-route-context-aware.html b/third_party/polymer/v0_8/components-chromium/more-routing/more-route-context-aware.html
new file mode 100644
index 0000000..abc3b43
--- /dev/null
+++ b/third_party/polymer/v0_8/components-chromium/more-routing/more-route-context-aware.html
@@ -0,0 +1,13 @@
+<!--
+Copyright (c) 2015 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
+--><html><head><link rel="import" href="../polymer/polymer.html">
+
+<link rel="import" href="route.html">
+<link rel="import" href="routing.html">
+
+</head><body><script src="more-route-context-aware-extracted.js"></script></body></html> \ No newline at end of file
diff --git a/third_party/polymer/v0_8/components-chromium/more-routing/more-route-extracted.js b/third_party/polymer/v0_8/components-chromium/more-routing/more-route-extracted.js
new file mode 100644
index 0000000..7a5ea6a
--- /dev/null
+++ b/third_party/polymer/v0_8/components-chromium/more-routing/more-route-extracted.js
@@ -0,0 +1,178 @@
+
+
+ Polymer({
+
+ is: 'more-route',
+
+ behaviors: [
+ MoreRouting.ContextAware,
+ ],
+
+ properties: {
+
+ /**
+ * The name of this route. Behavior differs based on the presence of
+ * `path` during _declaration_.
+ *
+ * If `path` is present during declaration, it is registered via `name`.
+ *
+ * Otherwise, this `more-route` becomes a `reference` to the route with
+ * `name`. Changing `name` will update which route is referenced.
+ */
+ name: {
+ type: String,
+ observer: '_nameChanged',
+ },
+
+ /**
+ * A path expression used to parse parameters from the window's URL.
+ */
+ path: {
+ type: String,
+ obserer: '_pathChanged',
+ },
+
+ /**
+ * Whether this route should become a context for the element that
+ * contains it.
+ */
+ context: {
+ type: Boolean,
+ },
+
+ /**
+ * The underlying `MoreRouting.Route` object that is being wrapped.
+ *
+ * @type {MoreRouting.Route}
+ */
+ route: {
+ type: Object,
+ readOnly: true,
+ notify: true,
+ observer: '_routeChanged',
+ },
+
+ /**
+ * The full path expression for this route, including routes this is
+ * nested within.
+ */
+ fullPath: {
+ type: String,
+ readOnly: true,
+ notify: true,
+ },
+
+ /**
+ * Param values matching the current URL, or an empty object if not
+ * `active`.
+ */
+ params: {
+ type: Object,
+ // readOnly: true,
+ notify: true,
+ },
+
+ /**
+ * Whether the route matches the current URL.
+ */
+ active: {
+ type: Boolean,
+ readOnly: true,
+ notify: true,
+ },
+
+ },
+
+ routingReady: function() {
+ this._identityChanged();
+ },
+
+ _nameChanged: function(newName, oldName) {
+ if (oldName) {
+ console.error('Changing the `name` property is not supported for', this);
+ return;
+ }
+ this._identityChanged();
+ },
+
+ _pathChanged: function(newPath, oldPath) {
+ if (oldPath) {
+ console.error('Changing the `path` property is not supported for', this);
+ return;
+ }
+ this._identityChanged();
+ },
+
+ _identityChanged: function() {
+ if (!this.routingIsReady) return;
+
+ if (this.name && this.path) {
+ this._setRoute(MoreRouting.registerNamedRoute(this.name, this.path, this.parentRoute));
+ } else if (this.name) {
+ this._setRoute(MoreRouting.getRouteByName(this.name));
+ } else if (this.path) {
+ this._setRoute(MoreRouting.getRouteByPath(this.path, this.parentRoute));
+ } else {
+ this._setRoute(null);
+ }
+ },
+
+ _routeChanged: function() {
+ this._observeRoute();
+ this._setFullPath(this.route.fullPath);
+ // this._setParams(this.route.params);
+ this.params = this.route.params;
+ this._setActive(this.route.active);
+
+ // @see MoreRouting.ContextAware
+ this.moreRouteContext = this.route;
+
+ if (this.context) {
+ var parent = Polymer.dom(this).parentNode;
+ if (parent.nodeType !== Node.ELEMENT_NODE) {
+ parent = parent.host;
+ }
+
+ if (parent.nodeType === Node.ELEMENT_NODE) {
+ parent.moreRouteContext = this.route;
+ } else {
+ console.warn('Unable to determine parent element for', this, '- not setting a context');
+ }
+ }
+ },
+
+ _observeRoute: function() {
+ // TODO(nevir) https://github.com/Polymore/more-routing/issues/24
+ if (this._routeObserver) this._routeObserver.close();
+ if (this._paramObserver) this._paramObserver.close();
+ if (!this.route) return;
+
+ this._routeObserver = new CompoundObserver();
+ this._routeObserver.addPath(this.route, 'active');
+ this._routeObserver.open(function() {
+ this._setActive(this.route.active);
+ }.bind(this));
+
+ this._paramObserver = new ObjectObserver(this.route.params);
+ this._paramObserver.open(function(added, removed, changed, getOldValue) {
+ var keys = Object.keys(added).concat(Object.keys(removed)).concat(Object.keys(changed));
+ keys.forEach(function(key) {
+ this.notifyPath('params.' + key, this.params[key]);
+ }.bind(this));
+ }.bind(this));
+ },
+
+ urlFor: function(params) {
+ return this.route.urlFor(params);
+ },
+
+ navigateTo: function(params) {
+ return this.route.navigateTo(params);
+ },
+
+ isCurrentUrl: function(params) {
+ return this.route.isCurrentUrl(params);
+ },
+
+ });
+
diff --git a/third_party/polymer/v0_8/components-chromium/more-routing/more-route-selection-extracted.js b/third_party/polymer/v0_8/components-chromium/more-routing/more-route-selection-extracted.js
new file mode 100644
index 0000000..4562e4d
--- /dev/null
+++ b/third_party/polymer/v0_8/components-chromium/more-routing/more-route-selection-extracted.js
@@ -0,0 +1,180 @@
+
+
+ Polymer({
+
+ is: 'more-route-selection',
+
+ behaviors: [
+ MoreRouting.ContextAware,
+ ],
+
+ properties: {
+
+ /**
+ * Routes to select from, as either a path expression or route name.
+ *
+ * You can either specify routes via this attribute, or as child nodes
+ * to this element, but not both.
+ *
+ * @type {String|Array<string|MoreRouting.Route>}
+ */
+ routes: {
+ type: String,
+ observer: '_routesChanged',
+ },
+
+ /**
+ * The selected `MoreRouting.Route` object, or `null`.
+ *
+ * @type {MoreRouting.Route}
+ */
+ selectedRoute: {
+ type: Object,
+ value: null,
+ readOnly: true,
+ notify: true,
+ },
+
+ /**
+ * The index of the selected route (relative to `routes`). -1 when there
+ * is no active route.
+ */
+ selectedIndex: {
+ type: Number,
+ value: -1,
+ readOnly: true,
+ notify: true,
+ },
+
+ /**
+ * The _full_ path expression of the selected route, or `null`.
+ */
+ selectedPath: {
+ type: String,
+ readOnly: true,
+ notify: true,
+ },
+
+ /**
+ * The params of the selected route, or an empty object if no route.
+ */
+ selectedParams: {
+ type: Object,
+ readOnly: true,
+ notify: true,
+ },
+
+ },
+
+ /**
+ * @event more-route-change fires when a new route is selected.
+ * @detail {{
+ * newRoute: MoreRouting.Route, oldRoute: MoreRouting.Route,
+ * newIndex: number, oldIndex: number,
+ * newPath: ?string, oldPath: ?string,
+ * newParams: Object, oldParams: Object,
+ * }}
+ */
+
+ routingReady: function() {
+ this._routesChanged();
+ },
+
+ _routesChanged: function() {
+ if (!this.routingIsReady) return;
+ var routes = this.routes || [];
+ if (typeof routes === 'string') {
+ routes = routes.split(/\s+/);
+ }
+ this._routeInfo = this._sortIndexes(routes.map(function(route, index) {
+ return {
+ model: MoreRouting.getRoute(route, this.parentRoute),
+ index: index,
+ };
+ }.bind(this)));
+
+ this._observeRoutes();
+ this._evaluate();
+ },
+
+ /**
+ * Tracks changes to the routes.
+ */
+ _observeRoutes: function() {
+ if (this._observer) {
+ this._observer.close();
+ }
+ // TODO(nevir): https://github.com/Polymore/more-routing/issues/24
+ this._observer = new CompoundObserver();
+ for (var i = 0, routeInfo; routeInfo = this._routeInfo[i]; i++) {
+ this._observer.addPath(routeInfo.model, 'active');
+ }
+ this._observer.open(this._evaluate.bind(this));
+ },
+
+ _evaluate: function() {
+ var newIndex = -1;
+ var newRoute = null;
+ var oldIndex = this.selectedIndex;
+
+ for (var i = 0, routeInfo; routeInfo = this._routeInfo[i]; i++) {
+ if (routeInfo.model && routeInfo.model.active) {
+ newIndex = routeInfo.index;
+ newRoute = routeInfo.model;
+ break;
+ }
+ }
+ if (newIndex === oldIndex) return;
+
+ var oldRoute = this.selectedRoute;
+ var oldPath = this.selectedPath;
+ var oldParams = this.selectedParams;
+
+ var newPath = newRoute ? newRoute.fullPath : null;
+ var newParams = newRoute ? newRoute.params : {};
+
+ this._setSelectedRoute(newRoute);
+ this._setSelectedIndex(newIndex);
+ this._setSelectedPath(newPath);
+ this._setSelectedParams(newParams);
+
+ this.fire('more-route-change', {
+ newRoute: newRoute, oldRoute: oldRoute,
+ newIndex: newIndex, oldIndex: oldIndex,
+ newPath: newPath, oldPath: oldPath,
+ newParams: newParams, oldParams: oldParams,
+ });
+ },
+ /**
+ * We want the most specific routes to match first, so we must create a
+ * mapping of indexes within `routes` that map
+ */
+ _sortIndexes: function(routeInfo) {
+ return routeInfo.sort(function(a, b) {
+ if (!a.model) {
+ return 1;
+ } else if (!b.model) {
+ return -1;
+ // Routes with more path parts are most definitely more specific.
+ } else if (a.model.depth < b.model.depth) {
+ return 1;
+ } if (a.model.depth > b.model.depth) {
+ return -1;
+ } else {
+
+ // Also, routes with fewer params are more specific. For example
+ // `/users/foo` is more specific than `/users/:id`.
+ if (a.model.numParams < b.model.numParams) {
+ return -1;
+ } else if (a.model.numParams > b.model.numParams) {
+ return 1;
+ } else {
+ // Equally specific; we fall back to the default (and hopefully
+ // stable) sort order.
+ return 0;
+ }
+ }
+ });
+ },
+
+ });
diff --git a/third_party/polymer/v0_8/components-chromium/more-routing/more-route-selection.html b/third_party/polymer/v0_8/components-chromium/more-routing/more-route-selection.html
new file mode 100644
index 0000000..d21341f
--- /dev/null
+++ b/third_party/polymer/v0_8/components-chromium/more-routing/more-route-selection.html
@@ -0,0 +1,17 @@
+<!--
+Copyright (c) 2015 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
+--><html><head><link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../observe-js/observe-js.html">
+
+<link rel="import" href="more-route-context-aware.html">
+<link rel="import" href="route.html">
+
+<!--
+TODO(nevir): Document.
+-->
+</head><body><script src="more-route-selection-extracted.js"></script></body></html> \ No newline at end of file
diff --git a/third_party/polymer/v0_8/components-chromium/more-routing/more-route-selector-extracted.js b/third_party/polymer/v0_8/components-chromium/more-routing/more-route-selector-extracted.js
new file mode 100644
index 0000000..a6e5e01
--- /dev/null
+++ b/third_party/polymer/v0_8/components-chromium/more-routing/more-route-selector-extracted.js
@@ -0,0 +1,155 @@
+
+Polymer({
+
+ is: 'more-route-selector',
+
+ behaviors: [
+ MoreRouting.ContextAware,
+ ],
+
+ properties: {
+
+ /**
+ * The attribute to read route expressions from (on children).
+ */
+ routeAttribute: {
+ type: String,
+ value: 'route',
+ },
+
+ /**
+ * The routes managed by this element (inferred from the items that are
+ * defined by the selector it targets).
+ */
+ routes: {
+ type: Array,
+ readOnly: true,
+ notify: true,
+ },
+
+ /**
+ * The selected `MoreRouting.Route` object, or `null`.
+ *
+ * @type {MoreRouting.Route}
+ */
+ selectedRoute: {
+ type: Object,
+ value: null,
+ readOnly: true,
+ notify: true,
+ },
+
+ /**
+ * The index of the selected route (relative to `routes`). -1 when there
+ * is no active route.
+ */
+ selectedIndex: {
+ type: Number,
+ value: -1,
+ readOnly: true,
+ notify: true,
+ },
+
+ /**
+ * The _full_ path expression of the selected route, or `null`.
+ */
+ selectedPath: {
+ type: String,
+ readOnly: true,
+ notify: true,
+ },
+
+ /**
+ * The params of the selected route, or an empty object if no route.
+ */
+ selectedParams: {
+ type: Object,
+ readOnly: true,
+ notify: true,
+ },
+
+ },
+
+ /**
+ * @event more-route-selected fires when a new route is selected.
+ * @param {{
+ * newRoute: MoreRouting.Route, oldRoute: MoreRouting.Route,
+ * newIndex: number, oldIndex: number,
+ * newPath: ?string, oldPath: ?string,
+ * newParams: Object, oldParams: Object,
+ * }}
+ */
+
+ attached: function() {
+ this._managedSelector = this._findTargetSelector();
+ if (!this._managedSelector) {
+ console.warn(this, 'was built without a selector to manage. It will do nothing.');
+ return;
+ }
+
+ this._managedSelector.addEventListener(
+ 'selected-item-changed', this._onSelectedItemChanged.bind(this));
+ this._updateRoutes();
+ },
+
+ /**
+ * Handle a change in selected item, driven by the targeted selector.
+ *
+ * Note that this will fail if a route is chosen that requires params not
+ * defined by the current URL.
+ */
+ _onSelectedItemChanged: function(event) {
+ var route = this._routeForItem(event.detail.value);
+ if (!route) return;
+ route.navigateTo();
+ },
+
+ _updateRoutes: function() {
+ var routes = [];
+ if (this._managedSelector) {
+ routes = this._managedSelector.items.map(this._routeForItem.bind(this));
+ }
+ this._setRoutes(routes);
+ },
+
+ _onMoreRouteChange: function(event) {
+ if (!this._managedSelector) return;
+ var route = event.detail.newRoute;
+ this._managedSelector.select(this.routes.indexOf(route));
+ },
+
+ _findTargetSelector: function() {
+ var children = Polymer.dom(this).children;
+ if (children.length !== 1) {
+ console.error(this, 'expects only a single selector child');
+ return null;
+ }
+
+ var child = children[0];
+ if ('selected' in child && 'items' in child) {
+ return child;
+ } else {
+ console.error(this, 'can only manage children that are selectors');
+ return null;
+ }
+ },
+
+ _routeForItem: function(item) {
+ if (!item) return null;
+ if (item.moreRouteContext && item.moreRouteContext instanceof MoreRouting.Route) {
+ return item.moreRouteContext;
+ }
+
+ if (!item.hasAttribute(this.routeAttribute)) {
+ console.warn(item, 'is missing a context route or "' + this.routeAttribute + '" attribute');
+ return null;
+ }
+ var expression = item.getAttribute(this.routeAttribute);
+ var route = MoreRouting.getRoute(expression, this.parentRoute);
+ // Associate the route w/ its element while we're here.
+ item.moreRouteContext = route;
+
+ return route;
+ },
+
+});
diff --git a/third_party/polymer/v0_8/components-chromium/more-routing/more-route-selector.html b/third_party/polymer/v0_8/components-chromium/more-routing/more-route-selector.html
new file mode 100644
index 0000000..bf4e175
--- /dev/null
+++ b/third_party/polymer/v0_8/components-chromium/more-routing/more-route-selector.html
@@ -0,0 +1,25 @@
+<!--
+Copyright (c) 2015 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
+--><html><head><link rel="import" href="../polymer/polymer.html">
+
+<link rel="import" href="more-route-context-aware.html">
+<link rel="import" href="more-route-selection.html">
+
+<!--
+TODO(nevir): Document.
+
+TODO(nevir): Support child addition/removal/reorder.
+-->
+</head><body><dom-module id="more-route-selector">
+ <template>
+ <more-route-selection id="selection" routes="[[routes]]" on-more-route-change="_onMoreRouteChange">
+ </more-route-selection>
+ <content></content>
+ </template>
+</dom-module>
+<script src="more-route-selector-extracted.js"></script></body></html> \ No newline at end of file
diff --git a/third_party/polymer/v0_8/components-chromium/more-routing/more-route.html b/third_party/polymer/v0_8/components-chromium/more-routing/more-route.html
new file mode 100644
index 0000000..6b11286
--- /dev/null
+++ b/third_party/polymer/v0_8/components-chromium/more-routing/more-route.html
@@ -0,0 +1,14 @@
+<!--
+Copyright (c) 2015 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
+--><html><head><link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../observe-js/observe-js.html">
+
+<link rel="import" href="routing.html">
+<link rel="import" href="more-route-context-aware.html">
+
+</head><body><script src="more-route-extracted.js"></script></body></html> \ No newline at end of file
diff --git a/third_party/polymer/v0_8/components-chromium/more-routing/more-routing-config-extracted.js b/third_party/polymer/v0_8/components-chromium/more-routing/more-routing-config-extracted.js
new file mode 100644
index 0000000..1011224
--- /dev/null
+++ b/third_party/polymer/v0_8/components-chromium/more-routing/more-routing-config-extracted.js
@@ -0,0 +1,46 @@
+
+
+ Polymer({
+
+ is: 'more-routing-config',
+
+ properties: {
+
+ /**
+ * The routing driver to use.
+ *
+ * * `hash`: `MoreRouting.HashDriver`
+ * * `path`: `MoreRouting.PathDriver`
+ * * `mock`: `MoreRouting.MockDriver`
+ *
+ */
+ driver: String,
+
+ /**
+ *
+ */
+ urlPrefix: String,
+
+ },
+
+ ready: function() {
+ var config = {};
+ if (this.urlPrefix) config.prefix = this.urlPrefix;
+
+ var driver;
+ // TODO(nevir): Support custom drivers, too.
+ if (this.driver === 'hash') {
+ driver = new MoreRouting.HashDriver(config);
+ } else if (this.driver === 'path') {
+ driver = new MoreRouting.PathDriver(config);
+ } else if (this.driver === 'mock') {
+ driver = new MoreRouting.MockDriver(config);
+ } else {
+ throw new Error('Unknown driver type "' + this.driver + '"');
+ }
+
+ MoreRouting.driver = driver;
+ },
+
+ });
+
diff --git a/third_party/polymer/v0_8/components-chromium/more-routing/more-routing-config.html b/third_party/polymer/v0_8/components-chromium/more-routing/more-routing-config.html
new file mode 100644
index 0000000..5c72aba
--- /dev/null
+++ b/third_party/polymer/v0_8/components-chromium/more-routing/more-routing-config.html
@@ -0,0 +1,16 @@
+<!--
+Copyright (c) 2015 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
+--><html><head><link rel="import" href="../polymer/polymer.html">
+
+<link rel="import" href="routing.html">
+<!-- TODO(nevir): import on demand? -->
+<link rel="import" href="driver/hash.html">
+<link rel="import" href="driver/mock.html">
+<link rel="import" href="driver/path.html">
+
+</head><body><script src="more-routing-config-extracted.js"></script></body></html> \ No newline at end of file
diff --git a/third_party/polymer/v0_8/components-chromium/more-routing/more-routing.html b/third_party/polymer/v0_8/components-chromium/more-routing/more-routing.html
new file mode 100644
index 0000000..43c3eeb3
--- /dev/null
+++ b/third_party/polymer/v0_8/components-chromium/more-routing/more-routing.html
@@ -0,0 +1,12 @@
+<!--
+Copyright (c) 2015 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
+-->
+<link rel="import" href="more-routing-config.html">
+<link rel="import" href="routing.html">
+<link rel="import" href="more-route.html">
+<link rel="import" href="more-route-selector.html">
diff --git a/third_party/polymer/v0_8/components-chromium/more-routing/route-extracted.js b/third_party/polymer/v0_8/components-chromium/more-routing/route-extracted.js
new file mode 100644
index 0000000..abf24cd
--- /dev/null
+++ b/third_party/polymer/v0_8/components-chromium/more-routing/route-extracted.js
@@ -0,0 +1,183 @@
+
+(function(scope) {
+var MoreRouting = scope.MoreRouting = scope.MoreRouting || {};
+MoreRouting.Route = Route;
+
+// Note that this can differ from the part separator defined by the driver. The
+// driver's separator is used when parsing/generating URLs given to the client,
+// whereas this one is for route definitions.
+var PART_SEPARATOR = '/';
+var PARAM_SENTINEL = ':';
+var SEPARATOR_CLEANER = /\/\/+/g;
+
+/**
+ * TODO(nevir): Docs.
+ */
+function Route(path, parent) {
+ this.path = path;
+ this.parent = parent;
+ this.fullPath = path;
+ this.compiled = this._compile(this.path);
+ this.active = false;
+ this.driver = null;
+
+ this.parts = [];
+ this.children = [];
+
+ // Param values matching the current URL, or an empty object if not `active`.
+ //
+ // To make data "binding" easy, `Route` guarantees that `params` will always
+ // be the same object; just make a reference to it.
+ if (this.parent) {
+ this.params = Object.create(this.parent.params);
+ this.parent.children.push(this);
+ this.fullPath = this.parent.fullPath + this.fullPath;
+ this.depth = this.parent.depth + this.compiled.length;
+ this.numParams = this.parent.numParams + countParams(this.compiled);
+ } else {
+ this.params = {};
+ this.depth = this.compiled.length;
+ this.numParams = countParams(this.compiled);
+ }
+
+ this._paramObserver = new ObjectObserver(this.params);
+ this._paramObserver.open(this._navigateToParams.bind(this));
+}
+
+Route.isPath = function isPath(pathOrName) {
+ return pathOrName.indexOf(PART_SEPARATOR) === 0;
+};
+
+Route.joinPath = function joinPath(paths) {
+ var joined = Array.prototype.join.call(arguments, PART_SEPARATOR);
+ joined = joined.replace(SEPARATOR_CLEANER, PART_SEPARATOR);
+
+ var minLength = joined.length - PART_SEPARATOR.length;
+ if (joined.substr(minLength) === PART_SEPARATOR) {
+ joined = joined.substr(0, minLength);
+ }
+
+ return joined;
+};
+
+Route.prototype.urlFor = function urlFor(params) {
+ return this.driver.urlForParts(this.partsForParams(params));
+};
+
+Route.prototype.navigateTo = function navigateTo(params) {
+ return this.driver.navigateToParts(this.partsForParams(params));
+}
+
+Route.prototype.isCurrentUrl = function isCurrentUrl(params) {
+ if (!this.active) return false;
+ var currentKeys = Object.keys(this.params);
+ for (var i = 0, key; key = currentKeys[i]; i++) {
+ if (this.params[key] !== String(params[key])) {
+ return false;
+ }
+ }
+ return true;
+};
+
+// Driver Interface
+
+Route.prototype.partsForParams = function partsForParams(params, silent) {
+ var parts = this.parent && this.parent.partsForParams(params, silent) || [];
+ for (var i = 0, config; config = this.compiled[i]; i++) {
+ if (config.type === 'static') {
+ parts.push(config.part);
+ } else if (config.type === 'param') {
+ var value
+ if (params && config.name in params) {
+ value = params[config.name];
+ } else {
+ value = this.params[config.name];
+ }
+ if (value === undefined) {
+ if (silent) {
+ return null;
+ } else {
+ throw new Error('Missing param "' + config.name + '" for route ' + this);
+ }
+ }
+ parts.push(value);
+ }
+ }
+ return parts;
+};
+
+/**
+ * Called by the driver whenever it has detected a change to the URL.
+ *
+ * @param {Array.<String>|null} parts The parts of the URL, or null if the
+ * route should be disabled.
+ */
+Route.prototype.processPathParts = function processPathParts(parts) {
+ this.parts = parts;
+ this.active = this.matchesPathParts(parts);
+ if (this.active) {
+ var keys = Object.keys(this.params);
+ for (var i = 0; i < keys.length; i++) {
+ delete this.params[keys[i]];
+ }
+ for (var i = 0, config; config = this.compiled[i]; i++) {
+ if (config.type === 'param') {
+ this.params[config.name] = parts[i];
+ }
+ }
+ } else {
+ for (key in this.params) {
+ this.params[key] = undefined;
+ }
+ }
+ this._paramObserver.discardChanges();
+};
+
+Route.prototype.matchesPathParts = function matchesPathParts(parts) {
+ if (!parts) return false;
+ if (parts.length < this.compiled.length) return false;
+ for (var i = 0, config; config = this.compiled[i]; i++) {
+ if (config.type === 'static' && parts[i] !== config.part) {
+ return false;
+ }
+ }
+ return true;
+};
+
+Route.prototype.toString = function toString() {
+ return this.path;
+};
+
+// Internal Implementation
+
+Route.prototype._compile = function _compile(rawPath) {
+ // Not strictly required, but helps us stay consistent w/ `getRoute`, etc.
+ if (rawPath.indexOf(PART_SEPARATOR) !== 0) {
+ throw new Error('Route paths must begin with a path separator; got: "' + rawPath + '"');
+ }
+ var path = rawPath.substr(PART_SEPARATOR.length);
+ if (path === '') return [];
+
+ return path.split(PART_SEPARATOR).map(function(part) {
+ // raw fragment.
+ if (part.substr(0, 1) == PARAM_SENTINEL) {
+ return {type: 'param', name: part.substr(1)};
+ } else {
+ return {type: 'static', part: part};
+ }
+ });
+};
+
+Route.prototype._navigateToParams = function _navigateToParams() {
+ var parts = this.partsForParams(this.params, true);
+ if (!parts) return;
+ this.driver.navigateToParts(parts);
+};
+
+function countParams(compiled) {
+ return compiled.reduce(function(count, part) {
+ return count + (part.type === 'param' ? 1 : 0);
+ }, 0);
+}
+
+})(window);
diff --git a/third_party/polymer/v0_8/components-chromium/more-routing/route.html b/third_party/polymer/v0_8/components-chromium/more-routing/route.html
new file mode 100644
index 0000000..4d0d8ea
--- /dev/null
+++ b/third_party/polymer/v0_8/components-chromium/more-routing/route.html
@@ -0,0 +1,10 @@
+<!--
+Copyright (c) 2015 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
+--><html><head><link rel="import" href="../observe-js/observe-js.html">
+
+</head><body><script src="route-extracted.js"></script></body></html> \ No newline at end of file
diff --git a/third_party/polymer/v0_8/components-chromium/more-routing/routing-extracted.js b/third_party/polymer/v0_8/components-chromium/more-routing/routing-extracted.js
new file mode 100644
index 0000000..008b8fa
--- /dev/null
+++ b/third_party/polymer/v0_8/components-chromium/more-routing/routing-extracted.js
@@ -0,0 +1,126 @@
+
+(function(scope) {
+var MoreRouting = scope.MoreRouting = scope.MoreRouting || {};
+
+// Route singletons.
+var routesByPath = {};
+var pathsByName = {};
+
+// Route Management
+
+/**
+ * Retrieves (or builds) the singleton `Route` for the given path expression or
+ * route name.
+ *
+ * Paths begin with `/`; anything else is considered a name.
+ *
+ * For convenience, `Route` objects can also be passed (and will be returned) -
+ * this can be used as a route coercion function.
+ *
+ * @param {String|MoreRouting.Route} pathOrName
+ * @param {MoreRouting.Route} parent
+ * @return {MoreRouting.Route}
+ */
+MoreRouting.getRoute = function getRoute(pathOrName, parent) {
+ if (typeof pathOrName !== 'string') return pathOrName;
+ if (this.isPath(pathOrName)) {
+ return this.getRouteByPath(pathOrName, parent);
+ } else {
+ return this.getRouteByName(pathOrName);
+ }
+}
+
+/**
+ * Retrieves (or builds) the singleton `Route` for the given path expression.
+ *
+ * @param {String} path
+ * @param {MoreRouting.Route} parent
+ * @return {MoreRouting.Route}
+ */
+MoreRouting.getRouteByPath = function getRouteByPath(path, parent) {
+ var fullPath = (parent ? parent.fullPath : '') + path;
+ if (!routesByPath[fullPath]) {
+ routesByPath[fullPath] = new this.Route(path, parent);
+ this.driver.manageRoute(routesByPath[fullPath]);
+ }
+ return routesByPath[fullPath];
+}
+
+/**
+ * Retrieves the route registered via `name`.
+ *
+ * @param {String} name
+ * @return {MoreRouting.Route}
+ */
+MoreRouting.getRouteByName = function getRouteByName(name) {
+ var path = pathsByName[name];
+ if (!path) {
+ throw new Error('No route named "' + name + '" has been registered');
+ }
+ return this.getRouteByPath(path);
+}
+
+/**
+ * @param {String} path
+ * @return {MoreRouting.Route} The newly registered route.
+ */
+MoreRouting.registerNamedRoute = function registerNamedRoute(name, path, parent) {
+ if (pathsByName[name]) {
+ console.warn(
+ 'Overwriting route named "' + name + '" with path:', path,
+ 'previously:', pathsByName[name]);
+ }
+ var route = this.getRouteByPath(path, parent);
+ pathsByName[name] = route.fullPath;
+ return route;
+};
+
+// Route Shortcuts
+MoreRouting.urlFor = function urlFor(pathOrName, params) {
+ return this.getRoute(pathOrName).urlFor(params);
+};
+
+MoreRouting.navigateTo = function navigateTo(pathOrName, params) {
+ return this.getRoute(pathOrName).navigateTo(params);
+};
+
+MoreRouting.isCurrentUrl = function isCurrentUrl(pathOrName, params) {
+ return this.getRoute(pathOrName).isCurrentUrl(params);
+};
+
+// Utility
+
+/**
+ *
+ */
+MoreRouting.isPath = function isPath(pathOrName) {
+ return this.Route.isPath(pathOrName);
+}
+
+/**
+ * @param {...String} paths
+ */
+MoreRouting.joinPath = function joinPath(paths) {
+ return this.Route.joinPath.apply(this.Route, arguments);
+}
+
+// Driver Management
+
+var driver;
+Object.defineProperty(MoreRouting, 'driver', {
+ get: function getDriver() {
+ if (!driver) {
+ throw new Error('No routing driver configured. Did you forget <more-routing-config>?');
+ }
+ return driver;
+ },
+ set: function setDriver(newDriver) {
+ if (driver) {
+ console.warn('Changing routing drivers is not supported, ignoring. You should have only one <more-routing-config> on the page!');
+ return;
+ }
+ driver = newDriver;
+ }
+});
+
+})(window);
diff --git a/third_party/polymer/v0_8/components-chromium/more-routing/routing.html b/third_party/polymer/v0_8/components-chromium/more-routing/routing.html
new file mode 100644
index 0000000..4780074
--- /dev/null
+++ b/third_party/polymer/v0_8/components-chromium/more-routing/routing.html
@@ -0,0 +1,10 @@
+<!--
+Copyright (c) 2015 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
+--><html><head><link rel="import" href="route.html">
+
+</head><body><script src="routing-extracted.js"></script></body></html> \ No newline at end of file
diff --git a/third_party/polymer/v0_8/components-chromium/observe-js/.bower.json b/third_party/polymer/v0_8/components-chromium/observe-js/.bower.json
new file mode 100644
index 0000000..6f6c206
--- /dev/null
+++ b/third_party/polymer/v0_8/components-chromium/observe-js/.bower.json
@@ -0,0 +1,31 @@
+{
+ "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.6-rc1",
+ "_release": "0.5.6-rc1",
+ "_resolution": {
+ "type": "version",
+ "tag": "0.5.6-rc1",
+ "commit": "7e94bb14d7c44b221af7bcc874cf9898f26747d8"
+ },
+ "_source": "git://github.com/Polymer/observe-js.git",
+ "_target": "0.5.6-rc1",
+ "_originalSource": "Polymer/observe-js"
+} \ No newline at end of file
diff --git a/third_party/polymer/v0_8/components-chromium/observe-js/AUTHORS b/third_party/polymer/v0_8/components-chromium/observe-js/AUTHORS
new file mode 100644
index 0000000..0617765
--- /dev/null
+++ b/third_party/polymer/v0_8/components-chromium/observe-js/AUTHORS
@@ -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>
diff --git a/third_party/polymer/v0_8/components-chromium/observe-js/README.md b/third_party/polymer/v0_8/components-chromium/observe-js/README.md
new file mode 100644
index 0000000..e6268a2
--- /dev/null
+++ b/third_party/polymer/v0_8/components-chromium/observe-js/README.md
@@ -0,0 +1,203 @@
+[![Build status](http://www.polymer-project.org/build/observe-js/status.png "Build status")](http://build.chromium.org/p/client.polymer/waterfall) [![Analytics](https://ga-beacon.appspot.com/UA-39334307-2/Polymer/observe-js/README)](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](https://github.com/arv/ecmascript-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, function(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 value 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.
diff --git a/third_party/polymer/v0_8/components-chromium/observe-js/bower.json b/third_party/polymer/v0_8/components-chromium/observe-js/bower.json
new file mode 100644
index 0000000..4c94f61
--- /dev/null
+++ b/third_party/polymer/v0_8/components-chromium/observe-js/bower.json
@@ -0,0 +1,21 @@
+{
+ "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"
+ ]
+}
diff --git a/third_party/polymer/v0_8/components-chromium/observe-js/codereview.settings b/third_party/polymer/v0_8/components-chromium/observe-js/codereview.settings
new file mode 100644
index 0000000..dca487f
--- /dev/null
+++ b/third_party/polymer/v0_8/components-chromium/observe-js/codereview.settings
@@ -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/
+
diff --git a/third_party/polymer/v0_8/components-chromium/observe-js/gruntfile.js b/third_party/polymer/v0_8/components-chromium/observe-js/gruntfile.js
new file mode 100644
index 0000000..d2f794e
--- /dev/null
+++ b/third_party/polymer/v0_8/components-chromium/observe-js/gruntfile.js
@@ -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']);
+};
diff --git a/third_party/polymer/v0_8/components-chromium/observe-js/index.html b/third_party/polymer/v0_8/components-chromium/observe-js/index.html
new file mode 100644
index 0000000..e47cfb5
--- /dev/null
+++ b/third_party/polymer/v0_8/components-chromium/observe-js/index.html
@@ -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>
diff --git a/third_party/polymer/v0_8/components-chromium/observe-js/observe-js.html b/third_party/polymer/v0_8/components-chromium/observe-js/observe-js.html
new file mode 100644
index 0000000..000c2ba
--- /dev/null
+++ b/third_party/polymer/v0_8/components-chromium/observe-js/observe-js.html
@@ -0,0 +1,9 @@
+<!--
+Copyright (c) 2015 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
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+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
+-->
+<script src="src/observe.js"></script>
diff --git a/third_party/polymer/v0_8/components-chromium/observe-js/package.json b/third_party/polymer/v0_8/components-chromium/observe-js/package.json
new file mode 100644
index 0000000..f863539
--- /dev/null
+++ b/third_party/polymer/v0_8/components-chromium/observe-js/package.json
@@ -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": "*"
+ }
+}
diff --git a/third_party/polymer/v0_8/components-chromium/observe-js/src/observe.js b/third_party/polymer/v0_8/components-chromium/observe-js/src/observe.js
new file mode 100644
index 0000000..f96ba57
--- /dev/null
+++ b/third_party/polymer/v0_8/components-chromium/observe-js/src/observe.js
@@ -0,0 +1,1711 @@
+/*
+ * 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 testingExposeCycleCount = global.testingExposeCycleCount;
+
+ // Detect and do basic sanity checking on Object/Array.observe.
+ function detectObjectObserve() {
+ if (typeof Object.observe !== 'function' ||
+ typeof Array.observe !== 'function') {
+ return false;
+ }
+
+ var records = [];
+
+ function callback(recs) {
+ records = recs;
+ }
+
+ var test = {};
+ var arr = [];
+ Object.observe(test, callback);
+ Array.observe(arr, callback);
+ test.id = 1;
+ test.id = 2;
+ delete test.id;
+ arr.push(1, 2);
+ arr.length = 0;
+
+ Object.deliverChangeRecords(callback);
+ if (records.length !== 5)
+ return false;
+
+ if (records[0].type != 'add' ||
+ records[1].type != 'update' ||
+ records[2].type != 'delete' ||
+ records[3].type != 'splice' ||
+ records[4].type != 'splice') {
+ return false;
+ }
+
+ Object.unobserve(test, callback);
+ Array.unobserve(arr, callback);
+
+ return true;
+ }
+
+ var hasObserve = detectObjectObserve();
+
+ function detectEval() {
+ // Don't test for eval if we're running in a Chrome App environment.
+ // We check for APIs set that only exist in a Chrome App context.
+ if (typeof chrome !== 'undefined' && chrome.app && chrome.app.runtime) {
+ return false;
+ }
+
+ // Firefox OS Apps do not allow eval. This feature detection is very hacky
+ // but even if some other platform adds support for this function this code
+ // will continue to work.
+ if (typeof navigator != 'undefined' && navigator.getDeviceStorage) {
+ return false;
+ }
+
+ try {
+ var f = new Function('', 'return true;');
+ return f();
+ } catch (ex) {
+ return false;
+ }
+ }
+
+ var hasEval = detectEval();
+
+ function isIndex(s) {
+ return +s === s >>> 0 && s !== '';
+ }
+
+ function toNumber(s) {
+ return +s;
+ }
+
+ function isObject(obj) {
+ return obj === Object(obj);
+ }
+
+ var numberIsNaN = global.Number.isNaN || function(value) {
+ return typeof value === 'number' && global.isNaN(value);
+ }
+
+ function areSameValue(left, right) {
+ if (left === right)
+ return left !== 0 || 1 / left === 1 / right;
+ if (numberIsNaN(left) && numberIsNaN(right))
+ return true;
+
+ return left !== left && right !== right;
+ }
+
+ 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;
+ };
+
+ var identStart = '[\$_a-zA-Z]';
+ var identPart = '[\$_a-zA-Z0-9]';
+ var identRegExp = new RegExp('^' + identStart + '+' + identPart + '*' + '$');
+
+ function getPathCharType(char) {
+ if (char === undefined)
+ return 'eof';
+
+ var code = char.charCodeAt(0);
+
+ switch(code) {
+ case 0x5B: // [
+ case 0x5D: // ]
+ case 0x2E: // .
+ case 0x22: // "
+ case 0x27: // '
+ case 0x30: // 0
+ return char;
+
+ case 0x5F: // _
+ case 0x24: // $
+ return 'ident';
+
+ case 0x20: // Space
+ case 0x09: // Tab
+ case 0x0A: // Newline
+ case 0x0D: // Return
+ case 0xA0: // No-break space
+ case 0xFEFF: // Byte Order Mark
+ case 0x2028: // Line Separator
+ case 0x2029: // Paragraph Separator
+ return 'ws';
+ }
+
+ // a-z, A-Z
+ if ((0x61 <= code && code <= 0x7A) || (0x41 <= code && code <= 0x5A))
+ return 'ident';
+
+ // 1-9
+ if (0x31 <= code && code <= 0x39)
+ return 'number';
+
+ return 'else';
+ }
+
+ var pathStateMachine = {
+ 'beforePath': {
+ 'ws': ['beforePath'],
+ 'ident': ['inIdent', 'append'],
+ '[': ['beforeElement'],
+ 'eof': ['afterPath']
+ },
+
+ 'inPath': {
+ 'ws': ['inPath'],
+ '.': ['beforeIdent'],
+ '[': ['beforeElement'],
+ 'eof': ['afterPath']
+ },
+
+ 'beforeIdent': {
+ 'ws': ['beforeIdent'],
+ 'ident': ['inIdent', 'append']
+ },
+
+ 'inIdent': {
+ 'ident': ['inIdent', 'append'],
+ '0': ['inIdent', 'append'],
+ 'number': ['inIdent', 'append'],
+ 'ws': ['inPath', 'push'],
+ '.': ['beforeIdent', 'push'],
+ '[': ['beforeElement', 'push'],
+ 'eof': ['afterPath', 'push']
+ },
+
+ 'beforeElement': {
+ 'ws': ['beforeElement'],
+ '0': ['afterZero', 'append'],
+ 'number': ['inIndex', 'append'],
+ "'": ['inSingleQuote', 'append', ''],
+ '"': ['inDoubleQuote', 'append', '']
+ },
+
+ 'afterZero': {
+ 'ws': ['afterElement', 'push'],
+ ']': ['inPath', 'push']
+ },
+
+ 'inIndex': {
+ '0': ['inIndex', 'append'],
+ 'number': ['inIndex', 'append'],
+ 'ws': ['afterElement'],
+ ']': ['inPath', 'push']
+ },
+
+ 'inSingleQuote': {
+ "'": ['afterElement'],
+ 'eof': ['error'],
+ 'else': ['inSingleQuote', 'append']
+ },
+
+ 'inDoubleQuote': {
+ '"': ['afterElement'],
+ 'eof': ['error'],
+ 'else': ['inDoubleQuote', 'append']
+ },
+
+ 'afterElement': {
+ 'ws': ['afterElement'],
+ ']': ['inPath', 'push']
+ }
+ }
+
+ function noop() {}
+
+ function parsePath(path) {
+ var keys = [];
+ var index = -1;
+ var c, newChar, key, type, transition, action, typeMap, mode = 'beforePath';
+
+ var actions = {
+ push: function() {
+ if (key === undefined)
+ return;
+
+ keys.push(key);
+ key = undefined;
+ },
+
+ append: function() {
+ if (key === undefined)
+ key = newChar
+ else
+ key += newChar;
+ }
+ };
+
+ function maybeUnescapeQuote() {
+ if (index >= path.length)
+ return;
+
+ var nextChar = path[index + 1];
+ if ((mode == 'inSingleQuote' && nextChar == "'") ||
+ (mode == 'inDoubleQuote' && nextChar == '"')) {
+ index++;
+ newChar = nextChar;
+ actions.append();
+ return true;
+ }
+ }
+
+ while (mode) {
+ index++;
+ c = path[index];
+
+ if (c == '\\' && maybeUnescapeQuote(mode))
+ continue;
+
+ type = getPathCharType(c);
+ typeMap = pathStateMachine[mode];
+ transition = typeMap[type] || typeMap['else'] || 'error';
+
+ if (transition == 'error')
+ return; // parse error;
+
+ mode = transition[0];
+ action = actions[transition[1]] || noop;
+ newChar = transition[2] === undefined ? c : transition[2];
+ action();
+
+ if (mode === 'afterPath') {
+ return keys;
+ }
+ }
+
+ return; // parse error
+ }
+
+ function isIdent(s) {
+ return identRegExp.test(s);
+ }
+
+ var constructorIsPrivate = {};
+
+ function Path(parts, privateToken) {
+ if (privateToken !== constructorIsPrivate)
+ throw Error('Use Path.get to retrieve path objects');
+
+ for (var i = 0; i < parts.length; i++) {
+ this.push(String(parts[i]));
+ }
+
+ if (hasEval && this.length) {
+ this.getValueFrom = this.compiledGetValueFromFn();
+ }
+ }
+
+ // TODO(rafaelw): Make simple LRU cache
+ var pathCache = {};
+
+ function getPath(pathString) {
+ if (pathString instanceof Path)
+ return pathString;
+
+ if (pathString == null || pathString.length == 0)
+ pathString = '';
+
+ if (typeof pathString != 'string') {
+ if (isIndex(pathString.length)) {
+ // Constructed with array-like (pre-parsed) keys
+ return new Path(pathString, constructorIsPrivate);
+ }
+
+ pathString = String(pathString);
+ }
+
+ var path = pathCache[pathString];
+ if (path)
+ return path;
+
+ var parts = parsePath(pathString);
+ if (!parts)
+ return invalidPath;
+
+ var path = new Path(parts, constructorIsPrivate);
+ pathCache[pathString] = path;
+ return path;
+ }
+
+ Path.get = getPath;
+
+ function formatAccessor(key) {
+ if (isIndex(key)) {
+ return '[' + key + ']';
+ } else {
+ return '["' + key.replace(/"/g, '\\"') + '"]';
+ }
+ }
+
+ Path.prototype = createObject({
+ __proto__: [],
+ valid: true,
+
+ toString: function() {
+ var pathString = '';
+ for (var i = 0; i < this.length; i++) {
+ var key = this[i];
+ if (isIdent(key)) {
+ pathString += i ? '.' + key : key;
+ } else {
+ pathString += formatAccessor(key);
+ }
+ }
+
+ return pathString;
+ },
+
+ getValueFrom: function(obj, directObserver) {
+ for (var i = 0; i < this.length; i++) {
+ if (obj == null)
+ return;
+ obj = obj[this[i]];
+ }
+ return obj;
+ },
+
+ iterateObjects: function(obj, observe) {
+ for (var i = 0; i < this.length; i++) {
+ if (i)
+ obj = obj[this[i - 1]];
+ if (!isObject(obj))
+ return;
+ observe(obj, this[i]);
+ }
+ },
+
+ compiledGetValueFromFn: function() {
+ var str = '';
+ var pathString = 'obj';
+ str += 'if (obj != null';
+ var i = 0;
+ var key;
+ for (; i < (this.length - 1); i++) {
+ key = this[i];
+ pathString += isIdent(key) ? '.' + key : formatAccessor(key);
+ str += ' &&\n ' + pathString + ' != null';
+ }
+ str += ')\n';
+
+ var key = this[i];
+ pathString += isIdent(key) ? '.' + key : formatAccessor(key);
+
+ str += ' return ' + pathString + ';\nelse\n return undefined;';
+ return new Function('obj', str);
+ },
+
+ setValueFrom: function(obj, value) {
+ if (!this.length)
+ return false;
+
+ for (var i = 0; i < this.length - 1; i++) {
+ if (!isObject(obj))
+ return false;
+ obj = obj[this[i]];
+ }
+
+ if (!isObject(obj))
+ return false;
+
+ obj[this[i]] = value;
+ return true;
+ }
+ });
+
+ var invalidPath = new Path('', constructorIsPrivate);
+ invalidPath.valid = false;
+ invalidPath.getValueFrom = invalidPath.setValueFrom = function() {};
+
+ var MAX_DIRTY_CHECK_CYCLES = 1000;
+
+ function dirtyCheck(observer) {
+ var cycles = 0;
+ while (cycles < MAX_DIRTY_CHECK_CYCLES && observer.check_()) {
+ cycles++;
+ }
+ if (testingExposeCycleCount)
+ global.dirtyCheckCycleCount = cycles;
+
+ return cycles > 0;
+ }
+
+ function objectIsEmpty(object) {
+ for (var prop in object)
+ return false;
+ return true;
+ }
+
+ function diffIsEmpty(diff) {
+ return objectIsEmpty(diff.added) &&
+ objectIsEmpty(diff.removed) &&
+ objectIsEmpty(diff.changed);
+ }
+
+ function diffObjectFromOldObject(object, oldObject) {
+ var added = {};
+ var removed = {};
+ var changed = {};
+
+ for (var prop in oldObject) {
+ var newValue = object[prop];
+
+ if (newValue !== undefined && newValue === oldObject[prop])
+ continue;
+
+ if (!(prop in object)) {
+ removed[prop] = undefined;
+ continue;
+ }
+
+ if (newValue !== oldObject[prop])
+ changed[prop] = newValue;
+ }
+
+ for (var prop in object) {
+ if (prop in oldObject)
+ continue;
+
+ added[prop] = object[prop];
+ }
+
+ if (Array.isArray(object) && object.length !== oldObject.length)
+ changed.length = object.length;
+
+ return {
+ added: added,
+ removed: removed,
+ changed: changed
+ };
+ }
+
+ var eomTasks = [];
+ function runEOMTasks() {
+ if (!eomTasks.length)
+ return false;
+
+ for (var i = 0; i < eomTasks.length; i++) {
+ eomTasks[i]();
+ }
+ eomTasks.length = 0;
+ return true;
+ }
+
+ var runEOM = hasObserve ? (function(){
+ return function(fn) {
+ return Promise.resolve().then(fn);
+ }
+ })() :
+ (function() {
+ return function(fn) {
+ eomTasks.push(fn);
+ };
+ })();
+
+ var observedObjectCache = [];
+
+ function newObservedObject() {
+ var observer;
+ var object;
+ var discardRecords = false;
+ var first = true;
+
+ function callback(records) {
+ if (observer && observer.state_ === OPENED && !discardRecords)
+ observer.check_(records);
+ }
+
+ return {
+ open: function(obs) {
+ if (observer)
+ throw Error('ObservedObject in use');
+
+ if (!first)
+ Object.deliverChangeRecords(callback);
+
+ observer = obs;
+ first = false;
+ },
+ observe: function(obj, arrayObserve) {
+ object = obj;
+ if (arrayObserve)
+ Array.observe(object, callback);
+ else
+ Object.observe(object, callback);
+ },
+ deliver: function(discard) {
+ discardRecords = discard;
+ Object.deliverChangeRecords(callback);
+ discardRecords = false;
+ },
+ close: function() {
+ observer = undefined;
+ Object.unobserve(object, callback);
+ observedObjectCache.push(this);
+ }
+ };
+ }
+
+ /*
+ * The observedSet abstraction is a perf optimization which reduces the total
+ * number of Object.observe observations of a set of objects. The idea is that
+ * groups of Observers will have some object dependencies in common and this
+ * observed set ensures that each object in the transitive closure of
+ * dependencies is only observed once. The observedSet acts as a write barrier
+ * such that whenever any change comes through, all Observers are checked for
+ * changed values.
+ *
+ * Note that this optimization is explicitly moving work from setup-time to
+ * change-time.
+ *
+ * TODO(rafaelw): Implement "garbage collection". In order to move work off
+ * the critical path, when Observers are closed, their observed objects are
+ * not Object.unobserve(d). As a result, it's possible that if the observedSet
+ * is kept open, but some Observers have been closed, it could cause "leaks"
+ * (prevent otherwise collectable objects from being collected). At some
+ * point, we should implement incremental "gc" which keeps a list of
+ * observedSets which may need clean-up and does small amounts of cleanup on a
+ * timeout until all is clean.
+ */
+
+ function getObservedObject(observer, object, arrayObserve) {
+ var dir = observedObjectCache.pop() || newObservedObject();
+ dir.open(observer);
+ dir.observe(object, arrayObserve);
+ return dir;
+ }
+
+ var observedSetCache = [];
+
+ function newObservedSet() {
+ var observerCount = 0;
+ var observers = [];
+ var objects = [];
+ var rootObj;
+ var rootObjProps;
+
+ function observe(obj, prop) {
+ if (!obj)
+ return;
+
+ if (obj === rootObj)
+ rootObjProps[prop] = true;
+
+ if (objects.indexOf(obj) < 0) {
+ objects.push(obj);
+ Object.observe(obj, callback);
+ }
+
+ observe(Object.getPrototypeOf(obj), prop);
+ }
+
+ function allRootObjNonObservedProps(recs) {
+ for (var i = 0; i < recs.length; i++) {
+ var rec = recs[i];
+ if (rec.object !== rootObj ||
+ rootObjProps[rec.name] ||
+ rec.type === 'setPrototype') {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ function callback(recs) {
+ if (allRootObjNonObservedProps(recs))
+ return;
+
+ var observer;
+ for (var i = 0; i < observers.length; i++) {
+ observer = observers[i];
+ if (observer.state_ == OPENED) {
+ observer.iterateObjects_(observe);
+ }
+ }
+
+ for (var i = 0; i < observers.length; i++) {
+ observer = observers[i];
+ if (observer.state_ == OPENED) {
+ observer.check_();
+ }
+ }
+ }
+
+ var record = {
+ objects: objects,
+ get rootObject() { return rootObj; },
+ set rootObject(value) {
+ rootObj = value;
+ rootObjProps = {};
+ },
+ open: function(obs, object) {
+ observers.push(obs);
+ observerCount++;
+ obs.iterateObjects_(observe);
+ },
+ close: function(obs) {
+ observerCount--;
+ if (observerCount > 0) {
+ return;
+ }
+
+ for (var i = 0; i < objects.length; i++) {
+ Object.unobserve(objects[i], callback);
+ Observer.unobservedCount++;
+ }
+
+ observers.length = 0;
+ objects.length = 0;
+ rootObj = undefined;
+ rootObjProps = undefined;
+ observedSetCache.push(this);
+ if (lastObservedSet === this)
+ lastObservedSet = null;
+ },
+ };
+
+ return record;
+ }
+
+ var lastObservedSet;
+
+ function getObservedSet(observer, obj) {
+ if (!lastObservedSet || lastObservedSet.rootObject !== obj) {
+ lastObservedSet = observedSetCache.pop() || newObservedSet();
+ lastObservedSet.rootObject = obj;
+ }
+ lastObservedSet.open(observer, obj);
+ return lastObservedSet;
+ }
+
+ var UNOPENED = 0;
+ var OPENED = 1;
+ var CLOSED = 2;
+ var RESETTING = 3;
+
+ var nextObserverId = 1;
+
+ function Observer() {
+ this.state_ = UNOPENED;
+ this.callback_ = undefined;
+ this.target_ = undefined; // TODO(rafaelw): Should be WeakRef
+ this.directObserver_ = undefined;
+ this.value_ = undefined;
+ this.id_ = nextObserverId++;
+ }
+
+ Observer.prototype = {
+ open: function(callback, target) {
+ if (this.state_ != UNOPENED)
+ throw Error('Observer has already been opened.');
+
+ addToAll(this);
+ this.callback_ = callback;
+ this.target_ = target;
+ this.connect_();
+ this.state_ = OPENED;
+ return this.value_;
+ },
+
+ close: function() {
+ if (this.state_ != OPENED)
+ return;
+
+ removeFromAll(this);
+ this.disconnect_();
+ this.value_ = undefined;
+ this.callback_ = undefined;
+ this.target_ = undefined;
+ this.state_ = CLOSED;
+ },
+
+ deliver: function() {
+ if (this.state_ != OPENED)
+ return;
+
+ dirtyCheck(this);
+ },
+
+ report_: function(changes) {
+ try {
+ this.callback_.apply(this.target_, changes);
+ } catch (ex) {
+ Observer._errorThrownDuringCallback = true;
+ console.error('Exception caught during observer callback: ' +
+ (ex.stack || ex));
+ }
+ },
+
+ discardChanges: function() {
+ this.check_(undefined, true);
+ return this.value_;
+ }
+ }
+
+ var collectObservers = !hasObserve;
+ var allObservers;
+ Observer._allObserversCount = 0;
+
+ if (collectObservers) {
+ allObservers = [];
+ }
+
+ function addToAll(observer) {
+ Observer._allObserversCount++;
+ if (!collectObservers)
+ return;
+
+ allObservers.push(observer);
+ }
+
+ function removeFromAll(observer) {
+ Observer._allObserversCount--;
+ }
+
+ var runningMicrotaskCheckpoint = false;
+
+ global.Platform = global.Platform || {};
+
+ global.Platform.performMicrotaskCheckpoint = function() {
+ if (runningMicrotaskCheckpoint)
+ return;
+
+ if (!collectObservers)
+ return;
+
+ runningMicrotaskCheckpoint = true;
+
+ var cycles = 0;
+ var anyChanged, toCheck;
+
+ do {
+ cycles++;
+ toCheck = allObservers;
+ allObservers = [];
+ anyChanged = false;
+
+ for (var i = 0; i < toCheck.length; i++) {
+ var observer = toCheck[i];
+ if (observer.state_ != OPENED)
+ continue;
+
+ if (observer.check_())
+ anyChanged = true;
+
+ allObservers.push(observer);
+ }
+ if (runEOMTasks())
+ anyChanged = true;
+ } while (cycles < MAX_DIRTY_CHECK_CYCLES && anyChanged);
+
+ if (testingExposeCycleCount)
+ global.dirtyCheckCycleCount = cycles;
+
+ runningMicrotaskCheckpoint = false;
+ };
+
+ if (collectObservers) {
+ global.Platform.clearObservers = function() {
+ allObservers = [];
+ };
+ }
+
+ function ObjectObserver(object) {
+ Observer.call(this);
+ this.value_ = object;
+ this.oldObject_ = undefined;
+ }
+
+ ObjectObserver.prototype = createObject({
+ __proto__: Observer.prototype,
+
+ arrayObserve: false,
+
+ connect_: function(callback, target) {
+ if (hasObserve) {
+ this.directObserver_ = getObservedObject(this, this.value_,
+ this.arrayObserve);
+ } else {
+ this.oldObject_ = this.copyObject(this.value_);
+ }
+
+ },
+
+ copyObject: function(object) {
+ var copy = Array.isArray(object) ? [] : {};
+ for (var prop in object) {
+ copy[prop] = object[prop];
+ };
+ if (Array.isArray(object))
+ copy.length = object.length;
+ return copy;
+ },
+
+ check_: function(changeRecords, skipChanges) {
+ var diff;
+ var oldValues;
+ if (hasObserve) {
+ if (!changeRecords)
+ return false;
+
+ oldValues = {};
+ diff = diffObjectFromChangeRecords(this.value_, changeRecords,
+ oldValues);
+ } else {
+ oldValues = this.oldObject_;
+ diff = diffObjectFromOldObject(this.value_, this.oldObject_);
+ }
+
+ if (diffIsEmpty(diff))
+ return false;
+
+ if (!hasObserve)
+ this.oldObject_ = this.copyObject(this.value_);
+
+ this.report_([
+ diff.added || {},
+ diff.removed || {},
+ diff.changed || {},
+ function(property) {
+ return oldValues[property];
+ }
+ ]);
+
+ return true;
+ },
+
+ disconnect_: function() {
+ if (hasObserve) {
+ this.directObserver_.close();
+ this.directObserver_ = undefined;
+ } else {
+ this.oldObject_ = undefined;
+ }
+ },
+
+ deliver: function() {
+ if (this.state_ != OPENED)
+ return;
+
+ if (hasObserve)
+ this.directObserver_.deliver(false);
+ else
+ dirtyCheck(this);
+ },
+
+ discardChanges: function() {
+ if (this.directObserver_)
+ this.directObserver_.deliver(true);
+ else
+ this.oldObject_ = this.copyObject(this.value_);
+
+ return this.value_;
+ }
+ });
+
+ function ArrayObserver(array) {
+ if (!Array.isArray(array))
+ throw Error('Provided object is not an Array');
+ ObjectObserver.call(this, array);
+ }
+
+ ArrayObserver.prototype = createObject({
+
+ __proto__: ObjectObserver.prototype,
+
+ arrayObserve: true,
+
+ copyObject: function(arr) {
+ return arr.slice();
+ },
+
+ check_: function(changeRecords) {
+ var splices;
+ if (hasObserve) {
+ if (!changeRecords)
+ return false;
+ splices = projectArraySplices(this.value_, changeRecords);
+ } else {
+ splices = calcSplices(this.value_, 0, this.value_.length,
+ this.oldObject_, 0, this.oldObject_.length);
+ }
+
+ if (!splices || !splices.length)
+ return false;
+
+ if (!hasObserve)
+ this.oldObject_ = this.copyObject(this.value_);
+
+ this.report_([splices]);
+ return true;
+ }
+ });
+
+ ArrayObserver.applySplices = function(previous, current, splices) {
+ splices.forEach(function(splice) {
+ var spliceArgs = [splice.index, splice.removed.length];
+ var addIndex = splice.index;
+ while (addIndex < splice.index + splice.addedCount) {
+ spliceArgs.push(current[addIndex]);
+ addIndex++;
+ }
+
+ Array.prototype.splice.apply(previous, spliceArgs);
+ });
+ };
+
+ function PathObserver(object, path) {
+ Observer.call(this);
+
+ this.object_ = object;
+ this.path_ = getPath(path);
+ this.directObserver_ = undefined;
+ }
+
+ PathObserver.prototype = createObject({
+ __proto__: Observer.prototype,
+
+ get path() {
+ return this.path_;
+ },
+
+ connect_: function() {
+ if (hasObserve)
+ this.directObserver_ = getObservedSet(this, this.object_);
+
+ this.check_(undefined, true);
+ },
+
+ disconnect_: function() {
+ this.value_ = undefined;
+
+ if (this.directObserver_) {
+ this.directObserver_.close(this);
+ this.directObserver_ = undefined;
+ }
+ },
+
+ iterateObjects_: function(observe) {
+ this.path_.iterateObjects(this.object_, observe);
+ },
+
+ check_: function(changeRecords, skipChanges) {
+ var oldValue = this.value_;
+ this.value_ = this.path_.getValueFrom(this.object_);
+ if (skipChanges || areSameValue(this.value_, oldValue))
+ return false;
+
+ this.report_([this.value_, oldValue, this]);
+ return true;
+ },
+
+ setValue: function(newValue) {
+ if (this.path_)
+ this.path_.setValueFrom(this.object_, newValue);
+ }
+ });
+
+ function CompoundObserver(reportChangesOnOpen) {
+ Observer.call(this);
+
+ this.reportChangesOnOpen_ = reportChangesOnOpen;
+ this.value_ = [];
+ this.directObserver_ = undefined;
+ this.observed_ = [];
+ }
+
+ var observerSentinel = {};
+
+ CompoundObserver.prototype = createObject({
+ __proto__: Observer.prototype,
+
+ connect_: function() {
+ if (hasObserve) {
+ var object;
+ var needsDirectObserver = false;
+ for (var i = 0; i < this.observed_.length; i += 2) {
+ object = this.observed_[i]
+ if (object !== observerSentinel) {
+ needsDirectObserver = true;
+ break;
+ }
+ }
+
+ if (needsDirectObserver)
+ this.directObserver_ = getObservedSet(this, object);
+ }
+
+ this.check_(undefined, !this.reportChangesOnOpen_);
+ },
+
+ disconnect_: function() {
+ for (var i = 0; i < this.observed_.length; i += 2) {
+ if (this.observed_[i] === observerSentinel)
+ this.observed_[i + 1].close();
+ }
+ this.observed_.length = 0;
+ this.value_.length = 0;
+
+ if (this.directObserver_) {
+ this.directObserver_.close(this);
+ this.directObserver_ = undefined;
+ }
+ },
+
+ addPath: function(object, path) {
+ if (this.state_ != UNOPENED && this.state_ != RESETTING)
+ throw Error('Cannot add paths once started.');
+
+ var path = getPath(path);
+ this.observed_.push(object, path);
+ if (!this.reportChangesOnOpen_)
+ return;
+ var index = this.observed_.length / 2 - 1;
+ this.value_[index] = path.getValueFrom(object);
+ },
+
+ addObserver: function(observer) {
+ if (this.state_ != UNOPENED && this.state_ != RESETTING)
+ throw Error('Cannot add observers once started.');
+
+ this.observed_.push(observerSentinel, observer);
+ if (!this.reportChangesOnOpen_)
+ return;
+ var index = this.observed_.length / 2 - 1;
+ this.value_[index] = observer.open(this.deliver, this);
+ },
+
+ startReset: function() {
+ if (this.state_ != OPENED)
+ throw Error('Can only reset while open');
+
+ this.state_ = RESETTING;
+ this.disconnect_();
+ },
+
+ finishReset: function() {
+ if (this.state_ != RESETTING)
+ throw Error('Can only finishReset after startReset');
+ this.state_ = OPENED;
+ this.connect_();
+
+ return this.value_;
+ },
+
+ iterateObjects_: function(observe) {
+ var object;
+ for (var i = 0; i < this.observed_.length; i += 2) {
+ object = this.observed_[i]
+ if (object !== observerSentinel)
+ this.observed_[i + 1].iterateObjects(object, observe)
+ }
+ },
+
+ check_: function(changeRecords, skipChanges) {
+ var oldValues;
+ for (var i = 0; i < this.observed_.length; i += 2) {
+ var object = this.observed_[i];
+ var path = this.observed_[i+1];
+ var value;
+ if (object === observerSentinel) {
+ var observable = path;
+ value = this.state_ === UNOPENED ?
+ observable.open(this.deliver, this) :
+ observable.discardChanges();
+ } else {
+ value = path.getValueFrom(object);
+ }
+
+ if (skipChanges) {
+ this.value_[i / 2] = value;
+ continue;
+ }
+
+ if (areSameValue(value, this.value_[i / 2]))
+ continue;
+
+ oldValues = oldValues || [];
+ oldValues[i / 2] = this.value_[i / 2];
+ this.value_[i / 2] = value;
+ }
+
+ if (!oldValues)
+ return false;
+
+ // TODO(rafaelw): Having observed_ as the third callback arg here is
+ // pretty lame API. Fix.
+ this.report_([this.value_, oldValues, this.observed_]);
+ return true;
+ }
+ });
+
+ function identFn(value) { return value; }
+
+ function ObserverTransform(observable, getValueFn, setValueFn,
+ dontPassThroughSet) {
+ this.callback_ = undefined;
+ this.target_ = undefined;
+ this.value_ = undefined;
+ this.observable_ = observable;
+ this.getValueFn_ = getValueFn || identFn;
+ this.setValueFn_ = setValueFn || identFn;
+ // TODO(rafaelw): This is a temporary hack. PolymerExpressions needs this
+ // at the moment because of a bug in it's dependency tracking.
+ this.dontPassThroughSet_ = dontPassThroughSet;
+ }
+
+ ObserverTransform.prototype = {
+ open: function(callback, target) {
+ this.callback_ = callback;
+ this.target_ = target;
+ this.value_ =
+ this.getValueFn_(this.observable_.open(this.observedCallback_, this));
+ return this.value_;
+ },
+
+ observedCallback_: function(value) {
+ value = this.getValueFn_(value);
+ if (areSameValue(value, this.value_))
+ return;
+ var oldValue = this.value_;
+ this.value_ = value;
+ this.callback_.call(this.target_, this.value_, oldValue);
+ },
+
+ discardChanges: function() {
+ this.value_ = this.getValueFn_(this.observable_.discardChanges());
+ return this.value_;
+ },
+
+ deliver: function() {
+ return this.observable_.deliver();
+ },
+
+ setValue: function(value) {
+ value = this.setValueFn_(value);
+ if (!this.dontPassThroughSet_ && this.observable_.setValue)
+ return this.observable_.setValue(value);
+ },
+
+ close: function() {
+ if (this.observable_)
+ this.observable_.close();
+ this.callback_ = undefined;
+ this.target_ = undefined;
+ this.observable_ = undefined;
+ this.value_ = undefined;
+ this.getValueFn_ = undefined;
+ this.setValueFn_ = undefined;
+ }
+ }
+
+ var expectedRecordTypes = {
+ add: true,
+ update: true,
+ delete: true
+ };
+
+ function diffObjectFromChangeRecords(object, changeRecords, oldValues) {
+ var added = {};
+ var removed = {};
+
+ for (var i = 0; i < changeRecords.length; i++) {
+ var record = changeRecords[i];
+ if (!expectedRecordTypes[record.type]) {
+ console.error('Unknown changeRecord type: ' + record.type);
+ console.error(record);
+ continue;
+ }
+
+ if (!(record.name in oldValues))
+ oldValues[record.name] = record.oldValue;
+
+ if (record.type == 'update')
+ continue;
+
+ if (record.type == 'add') {
+ if (record.name in removed)
+ delete removed[record.name];
+ else
+ added[record.name] = true;
+
+ continue;
+ }
+
+ // type = 'delete'
+ if (record.name in added) {
+ delete added[record.name];
+ delete oldValues[record.name];
+ } else {
+ removed[record.name] = true;
+ }
+ }
+
+ for (var prop in added)
+ added[prop] = object[prop];
+
+ for (var prop in removed)
+ removed[prop] = undefined;
+
+ var changed = {};
+ for (var prop in oldValues) {
+ if (prop in added || prop in removed)
+ continue;
+
+ var newValue = object[prop];
+ if (oldValues[prop] !== newValue)
+ changed[prop] = newValue;
+ }
+
+ return {
+ added: added,
+ removed: removed,
+ changed: changed
+ };
+ }
+
+ function newSplice(index, removed, addedCount) {
+ return {
+ index: index,
+ removed: removed,
+ addedCount: addedCount
+ };
+ }
+
+ var EDIT_LEAVE = 0;
+ var EDIT_UPDATE = 1;
+ var EDIT_ADD = 2;
+ var EDIT_DELETE = 3;
+
+ function ArraySplice() {}
+
+ ArraySplice.prototype = {
+
+ // Note: This function is *based* on the computation of the Levenshtein
+ // "edit" distance. The one change is that "updates" are treated as two
+ // edits - not one. With Array splices, an update is really a delete
+ // followed by an add. By retaining this, we optimize for "keeping" the
+ // maximum array items in the original array. For example:
+ //
+ // 'xxxx123' -> '123yyyy'
+ //
+ // With 1-edit updates, the shortest path would be just to update all seven
+ // characters. With 2-edit updates, we delete 4, leave 3, and add 4. This
+ // leaves the substring '123' intact.
+ calcEditDistances: function(current, currentStart, currentEnd,
+ old, oldStart, oldEnd) {
+ // "Deletion" columns
+ var rowCount = oldEnd - oldStart + 1;
+ var columnCount = currentEnd - currentStart + 1;
+ var distances = new Array(rowCount);
+
+ // "Addition" rows. Initialize null column.
+ for (var i = 0; i < rowCount; i++) {
+ distances[i] = new Array(columnCount);
+ distances[i][0] = i;
+ }
+
+ // Initialize null row
+ for (var j = 0; j < columnCount; j++)
+ distances[0][j] = j;
+
+ for (var i = 1; i < rowCount; i++) {
+ for (var j = 1; j < columnCount; j++) {
+ if (this.equals(current[currentStart + j - 1], old[oldStart + i - 1]))
+ distances[i][j] = distances[i - 1][j - 1];
+ else {
+ var north = distances[i - 1][j] + 1;
+ var west = distances[i][j - 1] + 1;
+ distances[i][j] = north < west ? north : west;
+ }
+ }
+ }
+
+ return distances;
+ },
+
+ // This starts at the final weight, and walks "backward" by finding
+ // the minimum previous weight recursively until the origin of the weight
+ // matrix.
+ spliceOperationsFromEditDistances: function(distances) {
+ var i = distances.length - 1;
+ var j = distances[0].length - 1;
+ var current = distances[i][j];
+ var edits = [];
+ while (i > 0 || j > 0) {
+ if (i == 0) {
+ edits.push(EDIT_ADD);
+ j--;
+ continue;
+ }
+ if (j == 0) {
+ edits.push(EDIT_DELETE);
+ i--;
+ continue;
+ }
+ var northWest = distances[i - 1][j - 1];
+ var west = distances[i - 1][j];
+ var north = distances[i][j - 1];
+
+ var min;
+ if (west < north)
+ min = west < northWest ? west : northWest;
+ else
+ min = north < northWest ? north : northWest;
+
+ if (min == northWest) {
+ if (northWest == current) {
+ edits.push(EDIT_LEAVE);
+ } else {
+ edits.push(EDIT_UPDATE);
+ current = northWest;
+ }
+ i--;
+ j--;
+ } else if (min == west) {
+ edits.push(EDIT_DELETE);
+ i--;
+ current = west;
+ } else {
+ edits.push(EDIT_ADD);
+ j--;
+ current = north;
+ }
+ }
+
+ edits.reverse();
+ return edits;
+ },
+
+ /**
+ * Splice Projection functions:
+ *
+ * A splice map is a representation of how a previous array of items
+ * was transformed into a new array of items. Conceptually it is a list of
+ * tuples of
+ *
+ * <index, removed, addedCount>
+ *
+ * which are kept in ascending index order of. The tuple represents that at
+ * the |index|, |removed| sequence of items were removed, and counting forward
+ * from |index|, |addedCount| items were added.
+ */
+
+ /**
+ * Lacking individual splice mutation information, the minimal set of
+ * splices can be synthesized given the previous state and final state of an
+ * array. The basic approach is to calculate the edit distance matrix and
+ * choose the shortest path through it.
+ *
+ * Complexity: O(l * p)
+ * l: The length of the current array
+ * p: The length of the old array
+ */
+ calcSplices: function(current, currentStart, currentEnd,
+ old, oldStart, oldEnd) {
+ var prefixCount = 0;
+ var suffixCount = 0;
+
+ var minLength = Math.min(currentEnd - currentStart, oldEnd - oldStart);
+ if (currentStart == 0 && oldStart == 0)
+ prefixCount = this.sharedPrefix(current, old, minLength);
+
+ if (currentEnd == current.length && oldEnd == old.length)
+ suffixCount = this.sharedSuffix(current, old, minLength - prefixCount);
+
+ currentStart += prefixCount;
+ oldStart += prefixCount;
+ currentEnd -= suffixCount;
+ oldEnd -= suffixCount;
+
+ if (currentEnd - currentStart == 0 && oldEnd - oldStart == 0)
+ return [];
+
+ if (currentStart == currentEnd) {
+ var splice = newSplice(currentStart, [], 0);
+ while (oldStart < oldEnd)
+ splice.removed.push(old[oldStart++]);
+
+ return [ splice ];
+ } else if (oldStart == oldEnd)
+ return [ newSplice(currentStart, [], currentEnd - currentStart) ];
+
+ var ops = this.spliceOperationsFromEditDistances(
+ this.calcEditDistances(current, currentStart, currentEnd,
+ old, oldStart, oldEnd));
+
+ var splice = undefined;
+ var splices = [];
+ var index = currentStart;
+ var oldIndex = oldStart;
+ for (var i = 0; i < ops.length; i++) {
+ switch(ops[i]) {
+ case EDIT_LEAVE:
+ if (splice) {
+ splices.push(splice);
+ splice = undefined;
+ }
+
+ index++;
+ oldIndex++;
+ break;
+ case EDIT_UPDATE:
+ if (!splice)
+ splice = newSplice(index, [], 0);
+
+ splice.addedCount++;
+ index++;
+
+ splice.removed.push(old[oldIndex]);
+ oldIndex++;
+ break;
+ case EDIT_ADD:
+ if (!splice)
+ splice = newSplice(index, [], 0);
+
+ splice.addedCount++;
+ index++;
+ break;
+ case EDIT_DELETE:
+ if (!splice)
+ splice = newSplice(index, [], 0);
+
+ splice.removed.push(old[oldIndex]);
+ oldIndex++;
+ break;
+ }
+ }
+
+ if (splice) {
+ splices.push(splice);
+ }
+ return splices;
+ },
+
+ sharedPrefix: function(current, old, searchLength) {
+ for (var i = 0; i < searchLength; i++)
+ if (!this.equals(current[i], old[i]))
+ return i;
+ return searchLength;
+ },
+
+ sharedSuffix: function(current, old, searchLength) {
+ var index1 = current.length;
+ var index2 = old.length;
+ var count = 0;
+ while (count < searchLength && this.equals(current[--index1], old[--index2]))
+ count++;
+
+ return count;
+ },
+
+ calculateSplices: function(current, previous) {
+ return this.calcSplices(current, 0, current.length, previous, 0,
+ previous.length);
+ },
+
+ equals: function(currentValue, previousValue) {
+ return currentValue === previousValue;
+ }
+ };
+
+ var arraySplice = new ArraySplice();
+
+ function calcSplices(current, currentStart, currentEnd,
+ old, oldStart, oldEnd) {
+ return arraySplice.calcSplices(current, currentStart, currentEnd,
+ old, oldStart, oldEnd);
+ }
+
+ function intersect(start1, end1, start2, end2) {
+ // Disjoint
+ if (end1 < start2 || end2 < start1)
+ return -1;
+
+ // Adjacent
+ if (end1 == start2 || end2 == start1)
+ return 0;
+
+ // Non-zero intersect, span1 first
+ if (start1 < start2) {
+ if (end1 < end2)
+ return end1 - start2; // Overlap
+ else
+ return end2 - start2; // Contained
+ } else {
+ // Non-zero intersect, span2 first
+ if (end2 < end1)
+ return end2 - start1; // Overlap
+ else
+ return end1 - start1; // Contained
+ }
+ }
+
+ function mergeSplice(splices, index, removed, addedCount) {
+
+ var splice = newSplice(index, removed, addedCount);
+
+ var inserted = false;
+ var insertionOffset = 0;
+
+ for (var i = 0; i < splices.length; i++) {
+ var current = splices[i];
+ current.index += insertionOffset;
+
+ if (inserted)
+ continue;
+
+ var intersectCount = intersect(splice.index,
+ splice.index + splice.removed.length,
+ current.index,
+ current.index + current.addedCount);
+
+ if (intersectCount >= 0) {
+ // Merge the two splices
+
+ splices.splice(i, 1);
+ i--;
+
+ insertionOffset -= current.addedCount - current.removed.length;
+
+ splice.addedCount += current.addedCount - intersectCount;
+ var deleteCount = splice.removed.length +
+ current.removed.length - intersectCount;
+
+ if (!splice.addedCount && !deleteCount) {
+ // merged splice is a noop. discard.
+ inserted = true;
+ } else {
+ var removed = current.removed;
+
+ if (splice.index < current.index) {
+ // some prefix of splice.removed is prepended to current.removed.
+ var prepend = splice.removed.slice(0, current.index - splice.index);
+ Array.prototype.push.apply(prepend, removed);
+ removed = prepend;
+ }
+
+ if (splice.index + splice.removed.length > current.index + current.addedCount) {
+ // some suffix of splice.removed is appended to current.removed.
+ var append = splice.removed.slice(current.index + current.addedCount - splice.index);
+ Array.prototype.push.apply(removed, append);
+ }
+
+ splice.removed = removed;
+ if (current.index < splice.index) {
+ splice.index = current.index;
+ }
+ }
+ } else if (splice.index < current.index) {
+ // Insert splice here.
+
+ inserted = true;
+
+ splices.splice(i, 0, splice);
+ i++;
+
+ var offset = splice.addedCount - splice.removed.length
+ current.index += offset;
+ insertionOffset += offset;
+ }
+ }
+
+ if (!inserted)
+ splices.push(splice);
+ }
+
+ function createInitialSplices(array, changeRecords) {
+ var splices = [];
+
+ for (var i = 0; i < changeRecords.length; i++) {
+ var record = changeRecords[i];
+ switch(record.type) {
+ case 'splice':
+ mergeSplice(splices, record.index, record.removed.slice(), record.addedCount);
+ break;
+ case 'add':
+ case 'update':
+ case 'delete':
+ if (!isIndex(record.name))
+ continue;
+ var index = toNumber(record.name);
+ if (index < 0)
+ continue;
+ mergeSplice(splices, index, [record.oldValue], 1);
+ break;
+ default:
+ console.error('Unexpected record type: ' + JSON.stringify(record));
+ break;
+ }
+ }
+
+ return splices;
+ }
+
+ function projectArraySplices(array, changeRecords) {
+ var splices = [];
+
+ createInitialSplices(array, changeRecords).forEach(function(splice) {
+ if (splice.addedCount == 1 && splice.removed.length == 1) {
+ if (splice.removed[0] !== array[splice.index])
+ splices.push(splice);
+
+ return
+ };
+
+ splices = splices.concat(calcSplices(array, splice.index, splice.index + splice.addedCount,
+ splice.removed, 0, splice.removed.length));
+ });
+
+ return splices;
+ }
+
+ // Export the observe-js object for **Node.js**, with backwards-compatibility
+ // for the old `require()` API. Also ensure `exports` is not a DOM Element.
+ // If we're in the browser, export as a global object.
+
+ var expose = global;
+
+ if (typeof exports !== 'undefined' && !exports.nodeType) {
+ if (typeof module !== 'undefined' && module.exports) {
+ exports = module.exports;
+ }
+ expose = exports;
+ }
+
+ expose.Observer = Observer;
+ expose.Observer.runEOM_ = runEOM;
+ expose.Observer.observerSentinel_ = observerSentinel; // for testing.
+ expose.Observer.hasObjectObserve = hasObserve;
+ expose.ArrayObserver = ArrayObserver;
+ expose.ArrayObserver.calculateSplices = function(current, previous) {
+ return arraySplice.calculateSplices(current, previous);
+ };
+
+ expose.ArraySplice = ArraySplice;
+ expose.ObjectObserver = ObjectObserver;
+ expose.PathObserver = PathObserver;
+ expose.CompoundObserver = CompoundObserver;
+ expose.Path = Path;
+ expose.ObserverTransform = ObserverTransform;
+
+})(typeof global !== 'undefined' && global && typeof module !== 'undefined' && module ? global : this || window);
diff --git a/third_party/polymer/v0_8/components-chromium/observe-js/util/planner.js b/third_party/polymer/v0_8/components-chromium/observe-js/util/planner.js
new file mode 100644
index 0000000..b75f06d
--- /dev/null
+++ b/third_party/polymer/v0_8/components-chromium/observe-js/util/planner.js
@@ -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);
diff --git a/third_party/polymer/v0_8/components-chromium/paper-behaviors/.bower.json b/third_party/polymer/v0_8/components-chromium/paper-behaviors/.bower.json
index ed10bab..8897b08 100644
--- a/third_party/polymer/v0_8/components-chromium/paper-behaviors/.bower.json
+++ b/third_party/polymer/v0_8/components-chromium/paper-behaviors/.bower.json
@@ -35,7 +35,7 @@
"tag": "v0.8.3",
"commit": "d111ed7a3991f3fb6b87b362efbecd7167be25e1"
},
- "_source": "git://github.com/polymerelements/paper-behaviors.git",
+ "_source": "git://github.com/PolymerElements/paper-behaviors.git",
"_target": "^0.8.0",
- "_originalSource": "polymerelements/paper-behaviors"
+ "_originalSource": "PolymerElements/paper-behaviors"
} \ No newline at end of file
diff --git a/third_party/polymer/v0_8/components-chromium/paper-button/.bower.json b/third_party/polymer/v0_8/components-chromium/paper-button/.bower.json
index cb2b76f..62776a0 100644
--- a/third_party/polymer/v0_8/components-chromium/paper-button/.bower.json
+++ b/third_party/polymer/v0_8/components-chromium/paper-button/.bower.json
@@ -1,6 +1,6 @@
{
"name": "paper-button",
- "version": "0.8.2",
+ "version": "0.8.3",
"authors": [
"The Polymer Authors"
],
@@ -34,11 +34,11 @@
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.6.0",
"web-component-tester": "*"
},
- "_release": "0.8.2",
+ "_release": "0.8.3",
"_resolution": {
"type": "version",
- "tag": "v0.8.2",
- "commit": "64f95d9fe781c34efe30ec73ad93078e45857e85"
+ "tag": "v0.8.3",
+ "commit": "9361301aeb12a97f7729f0e7cd8641b7e568bc6f"
},
"_source": "git://github.com/PolymerElements/paper-button.git",
"_target": "^0.8.0",
diff --git a/third_party/polymer/v0_8/components-chromium/paper-button/paper-button-extracted.js b/third_party/polymer/v0_8/components-chromium/paper-button/paper-button-extracted.js
index c3a9ab1..6181650 100644
--- a/third_party/polymer/v0_8/components-chromium/paper-button/paper-button-extracted.js
+++ b/third_party/polymer/v0_8/components-chromium/paper-button/paper-button-extracted.js
@@ -1,39 +1,40 @@
- Polymer({
-
- behaviors: [
- Polymer.PaperButtonBehavior
- ],
-
- properties: {
-
- /**
- * If true, the button should be styled with a shadow.
- *
- * @attribute raised
- * @type boolean
- * @default false
- */
- raised: {
- type: Boolean,
- reflectToAttribute: true,
- value: false,
- observer: '_buttonStateChanged'
- }
-
- },
-
- ready: function() {
- if (!this.hasAttribute('role')) {
- this.setAttribute('role', 'button');
- }
- },
-
- _buttonStateChanged: function() {
- this._calculateElevation();
+ Polymer({
+
+ is: 'paper-button',
+
+ behaviors: [
+ Polymer.PaperButtonBehavior
+ ],
+
+ properties: {
+
+ /**
+ * If true, the button should be styled with a shadow.
+ *
+ * @attribute raised
+ * @type boolean
+ * @default false
+ */
+ raised: {
+ type: Boolean,
+ reflectToAttribute: true,
+ value: false,
+ observer: '_buttonStateChanged'
}
- });
+ },
+
+ ready: function() {
+ if (!this.hasAttribute('role')) {
+ this.setAttribute('role', 'button');
+ }
+ },
+
+ _buttonStateChanged: function() {
+ this._calculateElevation();
+ }
+
+ });
- \ No newline at end of file
diff --git a/third_party/polymer/v0_8/components-chromium/paper-button/paper-button.html b/third_party/polymer/v0_8/components-chromium/paper-button/paper-button.html
index 7388df6..22d7a2d 100644
--- a/third_party/polymer/v0_8/components-chromium/paper-button/paper-button.html
+++ b/third_party/polymer/v0_8/components-chromium/paper-button/paper-button.html
@@ -112,5 +112,6 @@ The opacity of the ripple is not customizable via CSS.
</template>
- </dom-module>
+</dom-module>
+
<script src="paper-button-extracted.js"></script></body></html> \ No newline at end of file
diff --git a/third_party/polymer/v0_8/components-chromium/paper-drawer-panel/.bower.json b/third_party/polymer/v0_8/components-chromium/paper-drawer-panel/.bower.json
index dfd4325..b09ad58 100644
--- a/third_party/polymer/v0_8/components-chromium/paper-drawer-panel/.bower.json
+++ b/third_party/polymer/v0_8/components-chromium/paper-drawer-panel/.bower.json
@@ -1,6 +1,6 @@
{
"name": "paper-drawer-panel",
- "version": "0.8.2",
+ "version": "0.8.3",
"authors": [
"The Polymer Authors"
],
@@ -27,11 +27,11 @@
"iron-doc-viewer": "PolymerElements/iron-doc-viewer#^0.8.0",
"paper-styles": "PolymerElements/paper-styles#^0.8.0"
},
- "_release": "0.8.2",
+ "_release": "0.8.3",
"_resolution": {
"type": "version",
- "tag": "v0.8.2",
- "commit": "4e4b30fe8aab07b5edd0d206728c57509d47b1f6"
+ "tag": "v0.8.3",
+ "commit": "48222bc964338c0291c21bbdf92a1b1d3d30b589"
},
"_source": "git://github.com/PolymerElements/paper-drawer-panel.git",
"_target": "^0.8.0",
diff --git a/third_party/polymer/v0_8/components-chromium/paper-drawer-panel/paper-drawer-panel-extracted.js b/third_party/polymer/v0_8/components-chromium/paper-drawer-panel/paper-drawer-panel-extracted.js
index 4adf049..2e1071f 100644
--- a/third_party/polymer/v0_8/components-chromium/paper-drawer-panel/paper-drawer-panel-extracted.js
+++ b/third_party/polymer/v0_8/components-chromium/paper-drawer-panel/paper-drawer-panel-extracted.js
@@ -22,9 +22,8 @@
/**
* Fired when the narrow layout changes.
*
- * @event paper-responsive-change
- * @param {Object} detail
- * @param {boolean} detail.narrow true if the panel is in narrow layout.
+ * @event paper-responsive-change {{narrow: boolean}} detail -
+ * narrow: true if the panel is in narrow layout.
*/
/**
@@ -34,10 +33,9 @@
* This event is fired both when a panel is selected and deselected.
* The `isSelected` detail property contains the selection state.
*
- * @event paper-select
- * @param {Object} detail
- * @param {boolean} detail.isSelected true for selection and false for deselection
- * @param {Object} detail.item the panel that the event refers to
+ * @event paper-select {{isSelected: boolean, item: Object}} detail -
+ * isSelected: True for selection and false for deselection.
+ * item: The panel that the event refers to.
*/
properties: {
@@ -75,6 +73,7 @@
// Whether the user is dragging the drawer interactively.
dragging: {
+ type: Boolean,
value: false
},
@@ -93,6 +92,7 @@
// How many pixels on the side of the screen are sensitive to edge
// swipes and peek.
edgeSwipeSensitivity: {
+ type: Number,
value: 30
},
@@ -111,6 +111,7 @@
// Whether the browser has support for the transform CSS property.
hasTransform: {
+ type: Boolean,
value: function() {
return 'transform' in this.style;
}
@@ -118,6 +119,7 @@
// Whether the browser has support for the will-change CSS property.
hasWillChange: {
+ type: Boolean,
value: function() {
return 'willChange' in this.style;
}
@@ -138,7 +140,10 @@
},
// Whether the drawer is peeking out from the edge.
- peeking: false,
+ peeking: {
+ type: Boolean,
+ value: false
+ },
/**
* Max-width when the panel changes to narrow layout.
@@ -183,19 +188,25 @@
* automatically be hidden in wide layout.
*/
drawerToggleAttribute: {
+ type: String,
value: 'paper-drawer-toggle'
},
/**
* Whether the transition is enabled.
*/
- transition: false,
+ transition: {
+ type: Boolean,
+ value: false
+ },
/**
* Starting X coordinate of a tracking gesture. It is non-null only between trackStart and
* trackEnd events.
+ * @type {?number}
*/
_startX: {
+ type: Number,
value: null
}
diff --git a/third_party/polymer/v0_8/components-chromium/paper-input/.bower.json b/third_party/polymer/v0_8/components-chromium/paper-input/.bower.json
index 9b2481a..7309e73 100644
--- a/third_party/polymer/v0_8/components-chromium/paper-input/.bower.json
+++ b/third_party/polymer/v0_8/components-chromium/paper-input/.bower.json
@@ -1,6 +1,6 @@
{
"name": "paper-input",
- "version": "0.8.1",
+ "version": "0.8.2",
"authors": [
"The Polymer Authors"
],
@@ -32,11 +32,11 @@
"web-component-tester": "Polymer/web-component-tester#^2.2.3",
"webcomponentsjs": "Polymer/webcomponentsjs#^0.6.0"
},
- "_release": "0.8.1",
+ "_release": "0.8.2",
"_resolution": {
"type": "version",
- "tag": "v0.8.1",
- "commit": "a761e0a4f9abac125d7c150e71633fd6bdc07616"
+ "tag": "v0.8.2",
+ "commit": "59028225a51c6add666503f73a32f7e2e30491e4"
},
"_source": "git://github.com/PolymerElements/paper-input.git",
"_target": "^0.8.0",
diff --git a/third_party/polymer/v0_8/components-chromium/paper-input/paper-input-behavior-extracted.js b/third_party/polymer/v0_8/components-chromium/paper-input/paper-input-behavior-extracted.js
new file mode 100644
index 0000000..b7c06ad
--- /dev/null
+++ b/third_party/polymer/v0_8/components-chromium/paper-input/paper-input-behavior-extracted.js
@@ -0,0 +1,107 @@
+
+
+ Polymer.PaperInputBehavior = {
+
+ properties: {
+
+ /**
+ * The label for this input.
+ */
+ label: {
+ type: String
+ },
+
+ /**
+ * The value for this input.
+ */
+ value: {
+ notify: true,
+ type: String
+ },
+
+ /**
+ * Set to true to disable this input.
+ */
+ disabled: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * Set to true to prevent the user from entering invalid input.
+ */
+ preventInvalidInput: {
+ type: Boolean
+ },
+
+ /**
+ * The type of the input. The supported types are `text`, `number` and `password`.
+ */
+ type: {
+ type: String
+ },
+
+ /**
+ * A pattern to validate the `input` with.
+ */
+ pattern: {
+ type: String
+ },
+
+ /**
+ * Set to true to mark the input as required.
+ */
+ required: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * The maximum length of the input value.
+ */
+ maxlength: {
+ type: Number
+ },
+
+ /**
+ * The error message to display when the input is invalid.
+ */
+ errorMessage: {
+ type: String
+ },
+
+ /**
+ * Set to true to show a character counter.
+ */
+ charCounter: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * Set to true to disable the floating label.
+ */
+ noLabelFloat: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * Set to true to auto-validate the input value.
+ */
+ autoValidate: {
+ type: Boolean,
+ value: false
+ }
+
+ },
+
+ /**
+ * Returns a reference to the input element.
+ */
+ get inputElement() {
+ return this.$.input;
+ }
+
+ };
+
diff --git a/third_party/polymer/v0_8/components-chromium/paper-input/paper-input-behavior.html b/third_party/polymer/v0_8/components-chromium/paper-input/paper-input-behavior.html
new file mode 100644
index 0000000..ab881ef
--- /dev/null
+++ b/third_party/polymer/v0_8/components-chromium/paper-input/paper-input-behavior.html
@@ -0,0 +1,15 @@
+<!--
+@license
+Copyright (c) 2015 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
+--><html><head><link rel="import" href="../polymer/polymer.html">
+
+<!--
+Use `Polymer.PaperInputBehavior` to implement your own `<paper-input>`.
+-->
+
+</head><body><script src="paper-input-behavior-extracted.js"></script></body></html> \ No newline at end of file
diff --git a/third_party/polymer/v0_8/components-chromium/paper-input/paper-input-container-extracted.js b/third_party/polymer/v0_8/components-chromium/paper-input/paper-input-container-extracted.js
index 3a7bbcd..3d4abb4 100644
--- a/third_party/polymer/v0_8/components-chromium/paper-input/paper-input-container-extracted.js
+++ b/third_party/polymer/v0_8/components-chromium/paper-input/paper-input-container-extracted.js
@@ -160,7 +160,7 @@
},
_computeInputContentClass: function(noLabelFloat, focused, _inputHasContent, _inputIsInvalid) {
- var cls = 'input-content relative';
+ var cls = 'input-content';
if (!noLabelFloat) {
if (_inputHasContent) {
cls += ' label-is-floating';
@@ -179,7 +179,7 @@
},
_computeUnderlineClass: function(focused, _inputIsInvalid) {
- var cls = 'relative';
+ var cls = 'underline';
if (_inputIsInvalid) {
cls += ' is-invalid';
} else if (focused) {
diff --git a/third_party/polymer/v0_8/components-chromium/paper-input/paper-input-container.html b/third_party/polymer/v0_8/components-chromium/paper-input/paper-input-container.html
index d4819e8..bcc9295 100644
--- a/third_party/polymer/v0_8/components-chromium/paper-input/paper-input-container.html
+++ b/third_party/polymer/v0_8/components-chromium/paper-input/paper-input-container.html
@@ -49,6 +49,11 @@ For example:
--mixin(--paper-input-container);
}
+ :host([disabled]) {
+ pointer-events: none;
+ opacity: 0.33;
+ }
+
.floated-label-placeholder {
mixin(--paper-input-container-label-font);
}
@@ -89,6 +94,12 @@ For example:
background: var(--paper-input-container-color);
}
+ :host([disabled]) .unfocused-line {
+ border-bottom: 1px dashed;
+ border-color: var(--paper-input-container-color);
+ background: transparent;
+ }
+
.input-content ::content label,
.input-content ::content .paper-input-label {
position: absolute;
@@ -164,6 +175,11 @@ For example:
color: var(--paper-input-container-focus-color);
}
+ .input-content,
+ .underline {
+ position: relative;
+ }
+
</style>
<template>
diff --git a/third_party/polymer/v0_8/components-chromium/paper-input/paper-input-extracted.js b/third_party/polymer/v0_8/components-chromium/paper-input/paper-input-extracted.js
index 9f85a72..271e559 100644
--- a/third_party/polymer/v0_8/components-chromium/paper-input/paper-input-extracted.js
+++ b/third_party/polymer/v0_8/components-chromium/paper-input/paper-input-extracted.js
@@ -6,98 +6,9 @@
is: 'paper-input',
- properties: {
-
- /**
- * The label for this input.
- */
- label: {
- type: String
- },
-
- /**
- * The value for this input.
- */
- value: {
- notify: true,
- type: String
- },
-
- /**
- * Set to true to prevent the user from entering invalid input.
- */
- preventInvalidInput: {
- type: Boolean
- },
-
- /**
- * The type of the input. The supported types are `text`, `number` and `password`.
- */
- type: {
- type: String
- },
-
- /**
- * A pattern to validate the `input` with.
- */
- pattern: {
- type: String
- },
-
- /**
- * Set to true to mark the input as required.
- */
- required: {
- type: Boolean,
- value: false
- },
-
- /**
- * The maximum length of the input value.
- */
- maxlength: {
- type: Number
- },
-
- /**
- * The error message to display when the input is invalid.
- */
- errorMessage: {
- type: String
- },
-
- /**
- * Set to true to show a character counter.
- */
- charCounter: {
- type: Boolean,
- value: false
- },
-
- /**
- * Set to true to disable the floating label.
- */
- noLabelFloat: {
- type: Boolean,
- value: false
- },
-
- /**
- * Set to true to auto-validate the input value.
- */
- autoValidate: {
- type: Boolean,
- value: false
- }
-
- },
-
- /**
- * Returns a reference to the input element.
- */
- get inputElement() {
- return this.$.input;
- }
+ behaviors: [
+ Polymer.PaperInputBehavior
+ ]
})
diff --git a/third_party/polymer/v0_8/components-chromium/paper-input/paper-input.html b/third_party/polymer/v0_8/components-chromium/paper-input/paper-input.html
index 2d8d785..f818852 100644
--- a/third_party/polymer/v0_8/components-chromium/paper-input/paper-input.html
+++ b/third_party/polymer/v0_8/components-chromium/paper-input/paper-input.html
@@ -8,6 +8,7 @@ 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
--><html><head><link rel="import" href="../polymer/polymer.html">
<link rel="import" href="../iron-input/iron-input.html">
+<link rel="import" href="paper-input-behavior.html">
<link rel="import" href="paper-input-container.html">
<link rel="import" href="paper-input-error.html">
<link rel="import" href="paper-input-char-counter.html">
@@ -20,13 +21,13 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
<template>
- <paper-input-container no-label-float$="[[noLabelFloat]]" auto-validate$="[[autoValidate]]">
+ <paper-input-container no-label-float$="[[noLabelFloat]]" auto-validate$="[[autoValidate]]" disabled$="[[disabled]]">
<template is="x-if" if="[[label]]">
<label>[[parent.label]]</label>
</template>
- <input is="iron-input" id="input" bind-value="{{value}}" prevent-invalid-input="[[preventInvalidInput]]" type$="[[type]]" pattern$="[[pattern]]" maxlength$="[[maxlength]]" required$="[[required]]">
+ <input is="iron-input" id="input" bind-value="{{value}}" prevent-invalid-input="[[preventInvalidInput]]" type$="[[type]]" pattern$="[[pattern]]" maxlength$="[[maxlength]]" required$="[[required]]" disabled$="[[disabled]]">
<template is="x-if" if="[[errorMessage]]">
<paper-input-error>[[parent.errorMessage]]</paper-input-error>
diff --git a/third_party/polymer/v0_8/components-chromium/paper-ripple/.bower.json b/third_party/polymer/v0_8/components-chromium/paper-ripple/.bower.json
index 62815ae..1194843 100644
--- a/third_party/polymer/v0_8/components-chromium/paper-ripple/.bower.json
+++ b/third_party/polymer/v0_8/components-chromium/paper-ripple/.bower.json
@@ -1,5 +1,6 @@
{
"name": "paper-ripple",
+ "version": "0.8.3",
"private": true,
"dependencies": {
"polymer": "polymer/polymer#v0.8.0-rc.7"
@@ -14,12 +15,11 @@
"web-component-tester": "~2.2.3"
},
"homepage": "https://github.com/PolymerElements/paper-ripple",
- "version": "0.8.2",
- "_release": "0.8.2",
+ "_release": "0.8.3",
"_resolution": {
"type": "version",
- "tag": "v0.8.2",
- "commit": "7f1399055ff05cc37e3b577d97d00d664816e1d2"
+ "tag": "v0.8.3",
+ "commit": "dae4d3e1df6748aed651dfa2012121674d0b6b05"
},
"_source": "git://github.com/PolymerElements/paper-ripple.git",
"_target": "^0.8.0",
diff --git a/third_party/polymer/v0_8/components-chromium/paper-ripple/bower.json b/third_party/polymer/v0_8/components-chromium/paper-ripple/bower.json
index 5e261d5..5009035 100644
--- a/third_party/polymer/v0_8/components-chromium/paper-ripple/bower.json
+++ b/third_party/polymer/v0_8/components-chromium/paper-ripple/bower.json
@@ -1,5 +1,6 @@
{
"name": "paper-ripple",
+ "version": "0.8.3",
"private": true,
"dependencies": {
"polymer": "polymer/polymer#v0.8.0-rc.7"
diff --git a/third_party/polymer/v0_8/components-chromium/paper-ripple/paper-ripple-extracted.js b/third_party/polymer/v0_8/components-chromium/paper-ripple/paper-ripple-extracted.js
index af02d20..a9dfb8f 100644
--- a/third_party/polymer/v0_8/components-chromium/paper-ripple/paper-ripple-extracted.js
+++ b/third_party/polymer/v0_8/components-chromium/paper-ripple/paper-ripple-extracted.js
@@ -230,10 +230,11 @@
dx = this.xNow - (this.containerMetrics.width / 2);
dy = this.yNow - (this.containerMetrics.height / 2);
- Polymer.Base.translate3d(this.waveContainer, dx + 'px', dy + 'px', 0);
// 2d transform for safari because of border-radius and overflow:hidden clipping bug.
// https://bugs.webkit.org/show_bug.cgi?id=98538
+ this.waveContainer.style.webkitTransform = 'translate(' + dx + 'px, ' + dy + 'px)';
+ this.waveContainer.style.transform = 'translate3d(' + dx + 'px, ' + dy + 'px, 0)';
this.wave.style.webkitTransform = 'scale(' + scale + ',' + scale + ')';
this.wave.style.transform = 'scale3d(' + scale + ',' + scale + ',1)';
},
diff --git a/third_party/polymer/v0_8/components-chromium/paper-ripple/paper-ripple.html b/third_party/polymer/v0_8/components-chromium/paper-ripple/paper-ripple.html
index 554f5ba..0d64daf 100644
--- a/third_party/polymer/v0_8/components-chromium/paper-ripple/paper-ripple.html
+++ b/third_party/polymer/v0_8/components-chromium/paper-ripple/paper-ripple.html
@@ -14,21 +14,21 @@ Example:
<paper-ripple></paper-ripple>
-`paper-ripple` listens to "down" and "up" events so it would display ripple
+`paper-ripple` listens to "mousedown" and "mouseup" events so it would display ripple
effect when touches on it. You can also defeat the default behavior and
manually route the down and up actions to the ripple element. Note that it is
-important if you call downAction() you will have to make sure to call upAction()
-so that `paper-ripple` would end the animation loop.
+important if you call mousedownAction() you will have to make sure to call
+mouseupAction() so that `paper-ripple` would end the animation loop.
Example:
<paper-ripple id="ripple" style="pointer-events: none;"></paper-ripple>
...
downAction: function(e) {
- this.$.ripple.downAction({x: e.x, y: e.y});
+ this.$.ripple.mousedownAction({x: e.x, y: e.y});
},
upAction: function(e) {
- this.$.ripple.upAction();
+ this.$.ripple.mouseupAction();
}
Styling ripple effect:
@@ -78,7 +78,7 @@ animation finishes to perform some action.
/* This resolves a rendering issue in Chrome 40 where the
ripple is not properly clipped by its parent (which may have
rounded corners. See: http://jsbin.com/temexa/4 */
- -webkit-transform: translate3d(0, 0, 0);
+ -webkit-transform: translate(0, 0);
transform: translate3d(0, 0, 0);
}
diff --git a/third_party/polymer/v0_8/components-chromium/polymer/polymer.html b/third_party/polymer/v0_8/components-chromium/polymer/polymer.html
index 8d752ac..6e9cb404 100644
--- a/third_party/polymer/v0_8/components-chromium/polymer/polymer.html
+++ b/third_party/polymer/v0_8/components-chromium/polymer/polymer.html
@@ -1,12 +1,178 @@
-<!--
+<html><head><meta charset="UTF-8"><!--
+Keeping structured data in sync requires that Polymer understand the path
+associations of data being bound. The `x-array-selector` element ensures path
+linkage when selecting specific items from an array (either single or multiple).
+The `items` property accepts an array of user data, and via the `select(item)`
+and `deselect(item)` API, updates the `selected` property which may be bound to
+other parts of the application, and any changes to sub-fields of `selected`
+item(s) will be kept in sync with items in the `items` array. When `multi`
+is false, `selected` is a property representing the last selected item. When
+`multi` is true, `selected` is an array of multiply selected items.
+
+```html
+<dom-module id="employee-list">
+
+ <template>
+
+ <div> Employee list: </div>
+ <template is="x-repeat" id="employeeList" items="{{employees}}">
+ <div>First name: <span>{{item.first}}</span></div>
+ <div>Last name: <span>{{item.last}}</span></div>
+ <button on-click="toggleSelection">Select</button>
+ </template>
+
+ <x-array-selector id="selector" items="{{employees}}" selected="{{selected}}" multi toggle></x-array-selector>
+
+ <div> Selected employees: </div>
+ <template is="x-repeat" items="{{selected}}">
+ <div>First name: <span>{{item.first}}</span></div>
+ <div>Last name: <span>{{item.last}}</span></div>
+ </template>
+
+ </template>
+
+ <script>
+ Polymer({
+ is: 'employee-list',
+ ready: function() {
+ this.employees = [
+ {first: 'Bob', last: 'Smith'},
+ {first: 'Sally', last: 'Johnson'},
+ ...
+ ];
+ },
+ toggleSelection: function(e) {
+ var item = this.$.employeeList.itemForElement(e.target);
+ this.$.selector.select(item);
+ }
+ });
+ </script>
+
+</dom-module>
+```
+--><!--
@license
-Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+Copyright (c) 2015 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
---><html><head><meta charset="UTF-8"><!--
+--><!--
+
+**THIS ELEMENT IS EXPERIMENTAL. API AND NAME SUBJECT TO CHANGE.**
+
+The `x-repeat` element is a custom `HTMLTemplateElement` type extension that
+automatically stamps and binds one instance of template content to each object
+in a user-provided array. `x-repeat` accepts an `items` property, and one
+instance of the template is stamped for each item into the DOM at the location
+of the `x-repeat` element. The `item` property will be set on each instance's
+binding scope, thus templates should bind to sub-properties of `item`.
+
+Example:
+
+```html
+<dom-module id="employee-list">
+
+ <template>
+
+ <div> Employee list: </div>
+ <template is="x-repeat" items="{{employees}}">
+ <div>First name: <span>{{item.first}}</span></div>
+ <div>Last name: <span>{{item.last}}</span></div>
+ </template>
+
+ </template>
+
+ <script>
+ Polymer({
+ is: 'employee-list',
+ ready: function() {
+ this.employees = [
+ {first: 'Bob', last: 'Smith'},
+ {first: 'Sally', last: 'Johnson'},
+ ...
+ ];
+ }
+ });
+ </script>
+
+</dom-module>
+```
+
+Notifications for changes to items sub-properties will be forwarded to template
+instances, which will update via the normal structured data notification system.
+
+Mutations to the `items` array itself (`push`, `pop`, `splice`, `shift`,
+`unshift`) are observed via `Array.observe` (where supported, or an
+shim of this API on unsupported browsers), and template instances are kept in
+sync with the data in the array.
+
+A view-specific filter/sort may be applied to each `x-repeat` by supplying a
+`filter` and/or `sort` property. This may be a string that names a function on
+the host, or a function may be assigned to the property directly. The functions
+should implemented following the standard `Array` filter/sort API.
+
+In order to re-run the filter or sort functions based on changes to sub-fields
+of `items`, the `observe` property may be set as a space-separated list of
+`item` sub-fields that should cause a re-filter/sort when modified.
+
+For example, for an `x-repeat` with a filter of the following:
+
+```js
+isEngineer: function(item) {
+ return item.type == 'engineer' || item.manager.type == 'engineer';
+}
+```
+
+Then the `observe` property should be configured as follows:
+
+```html
+<template is="x-repeat" items="{{employees}}"
+ filter="isEngineer" observe="type manager.type">
+```
+
+--><!--
+
+**THIS ELEMENT IS EXPERIMENTAL. API AND NAME SUBJECT TO CHANGE.**
+
+Polymer's binding features are only available within templates that are managed
+by Polymer. As such, these features are available in templates used to define
+Polymer elements, for example, but not for elements placed directly in the main
+document.
+
+In order to use Polymer bindings without defining a new custom element, elements
+utilizing bindings may be wrapped with the `x-autobind` template extension.
+This template will immediately stamp itself into the main document and bind
+elements to the template itself as the binding scope.
+
+```html
+<!doctype html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <script src="components/webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="components/polymer/polymer.html">
+ <link rel="import" href="components/core-ajax/core-ajax.html">
+
+</head>
+<body>
+
+ <template is="x-autobind">
+
+ <core-ajax url="http://..." lastresponse="{{data}}"></core-ajax>
+
+ <template is="x-repeat" items="{{data}}">
+ <div><span>{{item.first}}</span> <span>{{item.last}}</span></div>
+ </template>
+
+ </template>
+
+</body>
+</html>
+```
+
+--><!--
The `x-style` extension of the native `<style>` element allows defining styles
in the main document that can take advantage of several special features of
@@ -58,7 +224,13 @@ Example:
Note, all features of `x-style` are available when defining styles as part of Polymer elements (e.g. `<style>` elements within `<dom-module>`'s used for defining Polymer elements. The `x-style` extension should only be used for defining document styles, outside of a custom element's local DOM.
--->
-
-</head><body>
+--><!-- employ 'Annotations' module --><!--
+@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
+--></head><body>
<script src="polymer.js"></script></body></html> \ No newline at end of file
diff --git a/third_party/polymer/v0_8/components/iron-collapse/.bower.json b/third_party/polymer/v0_8/components/iron-collapse/.bower.json
index 06965c7e..4cb2453 100644
--- a/third_party/polymer/v0_8/components/iron-collapse/.bower.json
+++ b/third_party/polymer/v0_8/components/iron-collapse/.bower.json
@@ -1,6 +1,6 @@
{
"name": "iron-collapse",
- "version": "0.8.2",
+ "version": "0.8.3",
"authors": [
"The Polymer Authors"
],
@@ -28,11 +28,11 @@
"iron-doc-viewer": "PolymerElements/iron-doc-viewer#^0.8.0",
"paper-styles": "PolymerElements/paper-styles#^0.8.0"
},
- "_release": "0.8.2",
+ "_release": "0.8.3",
"_resolution": {
"type": "version",
- "tag": "v0.8.2",
- "commit": "235ac1fbc638795b8ca0026b42304fba29afd45c"
+ "tag": "v0.8.3",
+ "commit": "783e5ea589e9c4cf23755471a9ad2e1e9e597a65"
},
"_source": "git://github.com/PolymerElements/iron-collapse.git",
"_target": "^0.8.0",
diff --git a/third_party/polymer/v0_8/components/iron-collapse/iron-collapse.html b/third_party/polymer/v0_8/components/iron-collapse/iron-collapse.html
index b79aa87..7962870 100644
--- a/third_party/polymer/v0_8/components/iron-collapse/iron-collapse.html
+++ b/third_party/polymer/v0_8/components/iron-collapse/iron-collapse.html
@@ -105,6 +105,7 @@ and instead put a div inside and style that.
opened: {
type: Boolean,
value: false,
+ notify: true,
observer: 'openedChanged'
}
diff --git a/third_party/polymer/v0_8/components/iron-input/.bower.json b/third_party/polymer/v0_8/components/iron-input/.bower.json
index 9a43046..074b666 100644
--- a/third_party/polymer/v0_8/components/iron-input/.bower.json
+++ b/third_party/polymer/v0_8/components/iron-input/.bower.json
@@ -1,6 +1,6 @@
{
"name": "iron-input",
- "version": "0.8.1",
+ "version": "0.8.3",
"authors": "The Polymer Authors",
"keywords": [
"web-components",
@@ -27,11 +27,11 @@
"web-component-tester": "Polymer/web-component-tester#^2.2.3",
"webcomponentsjs": "Polymer/webcomponentsjs#^0.6.0"
},
- "_release": "0.8.1",
+ "_release": "0.8.3",
"_resolution": {
"type": "version",
- "tag": "v0.8.1",
- "commit": "2aab343ceb47fd96e58c7898ae114deb7fefd20d"
+ "tag": "v0.8.3",
+ "commit": "6ab99b7e7bb9923911671c0d757492d1964e8120"
},
"_source": "git://github.com/PolymerElements/iron-input.git",
"_target": "^0.8.0",
diff --git a/third_party/polymer/v0_8/components/iron-input/iron-input.html b/third_party/polymer/v0_8/components/iron-input/iron-input.html
index 7839767..e05fd9a 100644
--- a/third_party/polymer/v0_8/components/iron-input/iron-input.html
+++ b/third_party/polymer/v0_8/components/iron-input/iron-input.html
@@ -37,6 +37,19 @@ for two-way data binding. `bind-value` will notify if it is changed either by us
bindValue: {
observer: '_bindValueChanged',
type: String
+ },
+
+ /**
+ * Set to true to prevent the user from entering invalid input or setting
+ * invalid `bindValue`.
+ */
+ preventInvalidInput: {
+ type: Boolean
+ },
+
+ _previousValidInput: {
+ type: String,
+ value: ''
}
},
@@ -45,18 +58,36 @@ for two-way data binding. `bind-value` will notify if it is changed either by us
'input': '_onInput'
},
- attached: function() {
+ ready: function() {
+ this._validateValue();
this.bindValue = this.value;
},
_bindValueChanged: function() {
- this.value = this.bindValue;
+ // If this was called as a result of user input, then |_validateValue|
+ // has already been called in |_onInput|, and it doesn't need to be
+ // called again.
+ if (this.value != this.bindValue) {
+ this.value = this.bindValue;
+ this._validateValue();
+ }
+
// manually notify because we don't want to notify until after setting value
this.fire('bind-value-changed', {value: this.bindValue});
},
- _onInput: function(event) {
- this.bindValue = event.target.value;
+ _onInput: function() {
+ this._validateValue();
+ },
+
+ _validateValue: function() {
+ var value;
+ if (this.preventInvalidInput && !this.validity.valid) {
+ value = this._previousValidInput;
+ } else {
+ value = this._previousValidInput = this.value;
+ }
+ this.bindValue = this.value = value;
}
})
diff --git a/third_party/polymer/v0_8/components/iron-resizable-behavior/.bower.json b/third_party/polymer/v0_8/components/iron-resizable-behavior/.bower.json
index 93072c2..3df2b52 100644
--- a/third_party/polymer/v0_8/components/iron-resizable-behavior/.bower.json
+++ b/third_party/polymer/v0_8/components/iron-resizable-behavior/.bower.json
@@ -1,6 +1,6 @@
{
"name": "iron-resizable-behavior",
- "version": "0.8.0",
+ "version": "0.8.1",
"private": true,
"main": "iron-resizable-behavior.html",
"authors": [
@@ -16,11 +16,11 @@
"web-component-tester": "*"
},
"homepage": "https://github.com/polymerelements/iron-resizable-behavior",
- "_release": "0.8.0",
+ "_release": "0.8.1",
"_resolution": {
"type": "version",
- "tag": "v0.8.0",
- "commit": "c7b09f87758efc6c6483e2854b992aab4042be51"
+ "tag": "v0.8.1",
+ "commit": "50415abf3c9acc0be0d5bec8e021beb9a52288ce"
},
"_source": "git://github.com/polymerelements/iron-resizable-behavior.git",
"_target": "^0.8.0",
diff --git a/third_party/polymer/v0_8/components/iron-resizable-behavior/iron-resizable-behavior.html b/third_party/polymer/v0_8/components/iron-resizable-behavior/iron-resizable-behavior.html
index 9c6d79a..44b5d38 100644
--- a/third_party/polymer/v0_8/components/iron-resizable-behavior/iron-resizable-behavior.html
+++ b/third_party/polymer/v0_8/components/iron-resizable-behavior/iron-resizable-behavior.html
@@ -30,6 +30,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
Polymer.IronResizableBehavior = {
properties: {
_parentResizable: {
+ type: Object,
observer: '_parentResizableChanged'
}
},
@@ -102,27 +103,15 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
* that should be notified of a resize change.
*/
stopResizeNotificationsFor: function(target) {
- index = this._interestedResizables.indexOf(target);
+ var index = this._interestedResizables.indexOf(target);
if (index > -1) {
this._interestedResizables.splice(index, 1);
}
},
- /**
- * User should implement to introduce filtering when notifying children.
- * Generally, children that are hidden by the resizable (e.g. non-active
- * pages) need not be notified during resize, since they will be notified
- * again when becoming un-hidden.
- *
- * Return `true` if the resizable passed as argument should be notified of
- * resize.
- *
- * @method resizerShouldNotify
- * @param {Element} el
- */
- // TODO(cdata): Currently behaviors cannot define "abstract" methods..
- //resizerShouldNotify: function(el) { return true; },
+ // TODO(cdata): Currently behaviors cannot define "abstract" methods.
+ // resizerShouldNotify: function(el) { return true; },
_parentResizableChanged: function(parentResizable) {
if (parentResizable) {
diff --git a/third_party/polymer/v0_8/components/iron-selector/.bower.json b/third_party/polymer/v0_8/components/iron-selector/.bower.json
index 10b2667..c6c8240 100644
--- a/third_party/polymer/v0_8/components/iron-selector/.bower.json
+++ b/third_party/polymer/v0_8/components/iron-selector/.bower.json
@@ -1,6 +1,6 @@
{
"name": "iron-selector",
- "version": "0.8.4",
+ "version": "0.8.5",
"private": true,
"main": [
"iron-selector.html"
@@ -18,14 +18,14 @@
"web-component-tester": "Polymer/web-component-tester#^2.2.3",
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.6.0"
},
- "homepage": "https://github.com/polymerelements/iron-selector",
- "_release": "0.8.4",
+ "homepage": "https://github.com/PolymerElements/iron-selector",
+ "_release": "0.8.5",
"_resolution": {
"type": "version",
- "tag": "v0.8.4",
- "commit": "a094802a4e03ceb0b574accfcde9654b4334efc0"
+ "tag": "v0.8.5",
+ "commit": "6b56de55e3e7f8ed108c9c227c85bc2a2f360d0d"
},
- "_source": "git://github.com/polymerelements/iron-selector.git",
+ "_source": "git://github.com/PolymerElements/iron-selector.git",
"_target": "^0.8.0",
- "_originalSource": "polymerelements/iron-selector"
+ "_originalSource": "PolymerElements/iron-selector"
} \ No newline at end of file
diff --git a/third_party/polymer/v0_8/components/iron-selector/iron-multi-selectable.html b/third_party/polymer/v0_8/components/iron-selector/iron-multi-selectable.html
index cdf16cf..91896d8 100644
--- a/third_party/polymer/v0_8/components/iron-selector/iron-multi-selectable.html
+++ b/third_party/polymer/v0_8/components/iron-selector/iron-multi-selectable.html
@@ -65,7 +65,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
* `value` will be toggled; otherwise the `value` will be selected.
*
* @method select
- * @param {String} value the value to select.
+ * @param {string} value the value to select.
*/
select: function(value) {
if (this.multi) {
diff --git a/third_party/polymer/v0_8/components/iron-selector/iron-selectable.html b/third_party/polymer/v0_8/components/iron-selector/iron-selectable.html
index 4961d3a..bcfb6b2 100644
--- a/third_party/polymer/v0_8/components/iron-selector/iron-selectable.html
+++ b/third_party/polymer/v0_8/components/iron-selector/iron-selectable.html
@@ -21,7 +21,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
* set this to the name of the attribute.
*
* @attribute attrForSelected
- * @type String
+ * @type {string}
*/
attrForSelected: {
type: String,
@@ -32,7 +32,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
* Gets or sets the selected element. The default is to use the index of the item.
*
* @attribute selected
- * @type String
+ * @type {string}
*/
selected: {
type: String,
@@ -43,7 +43,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
* Returns the currently selected item.
*
* @attribute selectedItem
- * @type Object
+ * @type {Object}
*/
selectedItem: {
type: Object,
@@ -57,7 +57,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
* Set to empty string to listen to no events.
*
* @attribute activateEvent
- * @type String
+ * @type {string}
* @default 'click'
*/
activateEvent: {
@@ -71,7 +71,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
* are selectable.
*
* @attribute selectable
- * @type String
+ * @type {string}
*/
selectable: String,
@@ -79,7 +79,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
* The class to set on elements when selected.
*
* @attribute selectedClass
- * @type String
+ * @type {string}
*/
selectedClass: {
type: String,
@@ -90,7 +90,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
* The attribute to set on elements when selected.
*
* @attribute selectedAttribute
- * @type String
+ * @type {string}
*/
selectedAttribute: {
type: String,
@@ -154,7 +154,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
* Selects the given value.
*
* @method select
- * @param {String} value the value to select.
+ * @param {string} value the value to select.
*/
select: function(value) {
this.selected = value;
diff --git a/third_party/polymer/v0_8/components/iron-selector/iron-selection.html b/third_party/polymer/v0_8/components/iron-selector/iron-selection.html
index 0177199..0ff04cf 100644
--- a/third_party/polymer/v0_8/components/iron-selector/iron-selection.html
+++ b/third_party/polymer/v0_8/components/iron-selector/iron-selection.html
@@ -12,6 +12,10 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
<script>
+ /**
+ * @param {!Function} selectCallback
+ * @constructor
+ */
Polymer.IronSelection = function(selectCallback) {
this.selection = [];
this.selectCallback = selectCallback;
@@ -49,7 +53,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
* Indicates if a given item is selected.
*
* @method isSelected
- * @param {any} item The item whose selection state should be checked.
+ * @param {*} item The item whose selection state should be checked.
* @returns Returns true if `item` is selected.
*/
isSelected: function(item) {
@@ -60,8 +64,8 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
* Sets the selection state for a given item to either selected or deselected.
*
* @method setItemSelected
- * @param {any} item The item to select.
- * @param {Boolean} isSelected True for selected, false for deselected.
+ * @param {*} item The item to select.
+ * @param {boolean} isSelected True for selected, false for deselected.
*/
setItemSelected: function(item, isSelected) {
if (item != null) {
@@ -85,7 +89,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
* the `item` will be selected.
*
* @method select
- * @param {any} item The item to select.
+ * @param {*} item The item to select.
*/
select: function(item) {
if (this.multi) {
@@ -100,7 +104,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
* Toggles the selection state for `item`.
*
* @method toggle
- * @param {any} item The item to toggle.
+ * @param {*} item The item to toggle.
*/
toggle: function(item) {
this.setItemSelected(item, !this.isSelected(item));
diff --git a/third_party/polymer/v0_8/components/more-routing/.bower.json b/third_party/polymer/v0_8/components/more-routing/.bower.json
new file mode 100644
index 0000000..0ad7a53
--- /dev/null
+++ b/third_party/polymer/v0_8/components/more-routing/.bower.json
@@ -0,0 +1,46 @@
+{
+ "name": "more-routing",
+ "version": "0.8.0-rc1",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "description": "A composable suite of objects and elements to make routing with web components a breeze.",
+ "keywords": [
+ "web-component",
+ "web-components",
+ "polymer",
+ "routing",
+ "router"
+ ],
+ "main": "more-routing.html",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerLabs/more-routing/",
+ "ignore": [
+ "/.*",
+ "/test/",
+ "/demo/"
+ ],
+ "dependencies": {
+ "polymer": "Polymer/polymer#v0.8.0-rc.7",
+ "observe-js": "Polymer/observe-js#0.5.6-rc1"
+ },
+ "devDependencies": {
+ "iron-doc-viewer": "PolymerElements/iron-doc-viewer#^0.8.5",
+ "iron-selector": "PolymerElements/iron-selector#^0.8.2",
+ "paper-styles": "PolymerElements/paper-styles#^0.8.9",
+ "iron-flex-layout": "PolymerElements/iron-flex-layout#^0.8.1",
+ "web-component-tester": "*"
+ },
+ "resolutions": {
+ "observe-js": "0.5.6-rc1"
+ },
+ "_release": "0.8.0-rc1",
+ "_resolution": {
+ "type": "version",
+ "tag": "v0.8.0-rc1",
+ "commit": "751ec450f5e8e8f5f5323dc6f16c43586eb9d142"
+ },
+ "_source": "git://github.com/PolymerLabs/more-routing.git",
+ "_target": "^0.8.0",
+ "_originalSource": "PolymerLabs/more-routing"
+} \ No newline at end of file
diff --git a/third_party/polymer/v0_8/components/more-routing/README.md b/third_party/polymer/v0_8/components/more-routing/README.md
new file mode 100644
index 0000000..880ccfe
--- /dev/null
+++ b/third_party/polymer/v0_8/components/more-routing/README.md
@@ -0,0 +1,338 @@
+Routing
+=======
+
+A composable suite of objects and elements to make routing with web components
+a breeze.
+
+* [Hash-](#MoreRouting.HashDriver) and [path-](#MoreRouting.PathDriver)based
+ routing.
+* [Named routes](#more-routing).
+* [Nested (mounted) routes](#more-route--nesting).
+* [Declarative route switching](#more-route-switch).
+* [Polymer helpers](#polymer-helpers--filters) for easy integration into existing elements.
+
+[Rob Dodson](https://github.com/robdodson) has whipped up a great video
+that can get you started with more-routing:
+
+<p align="center">
+ <a href="https://www.youtube.com/watch?v=-67kb7poIT8">
+ <img src="http://img.youtube.com/vi/-67kb7poIT8/0.jpg" alt="Moar routing with... more-routing">
+ </a>
+</p>
+
+Or, TL;DR:
+
+```html
+<link rel="import" href="../more-routing/more-routing.html">
+
+<more-routing-config driver="path"></more-routing-config>
+<more-route name="user" path="/users/:userId">
+ <more-route name="user-bio" path="/bio"></more-route>
+</more-route>
+
+<more-route-selector selectedParams="{{params}}">
+ <core-pages>
+ <section route="/">
+ This is the index.
+ </section>
+
+ <section route="/about">
+ It's a routing demo!
+ <a href="{{ urlFor('user-bio', {userId: 1}) }}">Read about user 1</a>.
+ </section>
+
+ <section route="user">
+ <header>Heyo user {{params.userId}}!</header>
+ <template if="{{ route('user-bio').active }}">
+ All the details about {{params.userId}} that you didn't want to know...
+ </template>
+ </section>
+ </core-pages>
+</more-route-selector>
+```
+
+And finally, check out [the demo](demo/) for a project that makes comprehensive
+use of the various features in more-routing.
+
+
+Element API
+===========
+
+<a name="more-routing-config"></a>
+`<more-routing-config>`
+----------------
+
+_Defined in [`more-routing-config.html`](more-routing-config.html)._
+
+The declarative interface for configuring [`MoreRouting`](#MoreRouting).
+Currently, this lets you declare which [driver](#MoreRouting.Driver) you wish
+to use (`hash` or `path`):
+
+```html
+<more-routing-config driver="hash"></more-routing-config>
+```
+
+You should place this as early in the load process for your app as you can. Any
+routes defined prior to the driver being set will trigger an error.
+
+
+<a name="more-route"></a>
+`<more-route>`
+--------------
+
+_Defined in [`more-route.html`](more-route.html)._
+
+Reference routes by path, and extract their params:
+
+```html
+<more-route path="/users/:userId" params="{{user}}"></more-route>
+```
+
+Declare a named route:
+
+```html
+<more-route path="/users/:userId" name="user"></more-route>
+```
+
+Reference a named route:
+
+```html
+<more-route name="user" params="{{user}}"></more-route>
+```
+
+
+<a name="more-route--nesting"></a>
+### Route Nesting
+
+Routes can also be nested:
+
+```html
+<more-route path="/users/:userId" name="user">
+ <more-route path="/bio" name="user-bio"></more-route>
+</more-route>
+```
+
+In this example, the route named `user-bio` will match `/users/:userId/bio`.
+
+Finally, `<more-route>` elements can declare a routing context for the element
+that contains them by setting the `context` attribute. See the
+[routed elements](#more-route-selector--routed-elements) section for more info.
+
+
+<a name="more-route-selector"></a>
+`<more-route-selector>`
+-----------------------
+
+_Defined in [`more-route-selector.html`](more-route-selector.html)._
+
+Manages a [`<core-selector>`](https://www.polymer-project.org/docs/elements/core-elements.html#core-selector)
+(or anything that extends it/looks like one), where each item in the selector
+have an associated route. The most specific route that is active will be
+selected.
+
+```html
+<more-route-selector>
+ <core-pages>
+ <section route="/">The index!</section>
+ <section route="user">A user (named route)</section>
+ <section route="/about">Another route</section>
+ </core-pages>
+</more-route-selector>
+```
+
+By default, `more-route-selector` will look for the `route` attribute on any
+children of the `core-selector` (change this via `routeAttribute`).
+
+It exposes information about the selected route via a few properties:
+
+`selectedParams`: The params of the selected route.
+
+`selectedRoute`: The [`MoreRouting.Route`](#MoreRouting.Route) representing the
+selected route.
+
+`selectedPath`: The path expression of the selected route.
+
+`selectedIndex`: The index of the selected route (relative to `routes`).
+
+
+<a name="more-route-selector--routed-elements"></a>
+### Routed Elements
+
+Elements can declare a route to be associated with, which allows
+`<more-route-selector>` to be smart and use that as the route it checks against
+for your element. For example:
+
+```html
+<polymer-element name="routed-element">
+ <template>
+ <more-route path="/my/route" context></more-route>
+ I'm a routed element!
+ </template>
+</polymer-element>
+```
+
+```html
+<more-route-selector>
+ <core-pages>
+ <section route="/">The index!</section>
+ <routed-element></routed-element>
+ </core-pages>
+</more-route-selector>
+```
+
+In this example, The `<more-route-selector>` will choose `<routed-element>`
+whenever the path begins with `/my/route`. Keep it DRY!
+
+
+<a name="more-route-selector--nesting-contexts"></a>
+### Nesting Contexts
+
+Similar to [`more-route`'s nesting behavior](#more-route--nesting), any items in
+the core-selector also behave as nesting contexts. Any route declared within a
+routing context is effectively _mounted_ on the context route.
+
+Taking the example element, `<routed-element>` above; if we were to add the
+following to its template:
+
+```html
+<more-route path="/:tab" params="{{params}}"></more-route>
+```
+
+That route's full path would be `/my/route/:tab`, because `/my/route` is the
+context in which it is nested. This allows you to create custom elements that
+make use of routes, _while not requiring knowledge of the app's route
+hierarchy_. Very handy for composable components!
+
+**Note:** All items in a `<more-route-selector>` are treated as routing
+contexts!
+
+
+<a name="polymer-helpers"></a>
+Polymer Helpers
+---------------
+
+<a name="polymer-helpers--filters"></a>
+### Filters
+
+_Defined in [`polymer-expressions.html`](polymer-expressions.html)._
+
+Several filters (functions) are exposed to templates for your convenience:
+
+#### `route`
+
+You can fetch a `MoreRouting.Route` object via the `route` filter. Handy for
+reading params, etc on the fly.
+
+```html
+<x-user model="{{ route('user').params }}"></x-user>
+```
+
+**Note:** The `route()` helper is unfortunately _not_ aware of the current
+routing context. Consider using only named routes to avoid confusion!
+
+#### `urlFor`
+
+Generates a URL for the specified route and params:
+
+```html
+<a href="{{ urlFor('user', {userId: 1}) }}">User 1</a>
+```
+
+
+JavaScript API
+==============
+
+<a name="MoreRouting"></a>
+`MoreRouting`
+-------------
+
+_Defined in [`routing.html`](routing.html)._
+
+The main entry point into `more-routing`, exposed as a global JavaScript
+namespace of `MoreRouting`. For the most part, all elements and helpers are
+built on top of it.
+
+`MoreRouting` manages the current [driver](#MoreRouting.Driver), and maintains
+an identity map of all routes.
+
+
+<a name="MoreRouting.driver"></a>
+### `MoreRouting.driver`
+
+Before you can make use of navigation and URL parsing, a driver must be
+registered. Simply assign an instance of `MoreRouting.Driver` to this property.
+
+This is exposed as a declarative element via
+[`<more-routing-config driver="...">`](#more-routing).
+
+
+<a name="MoreRouting.getRoute"></a>
+### `MoreRouting.getRoute`
+
+Returns a [`MoreRouting.Route`](#MoreRouting.Route), by path...
+
+ MoreRouting.getRoute('/users/:userId')
+
+...or by name:
+
+ MoreRouting.getRoute('user')
+
+Because routes are identity mapped, `getRoute` guarantees that it will return
+the same `Route` object for the same path.
+
+
+<a name="MoreRouting.Route"></a>
+`MoreRouting.Route`
+-------------------
+
+_Defined in [`route.html`](route.html)._
+
+The embodiment for an individual route. It has various handy properties.
+Highlights:
+
+``active``: Whether the route is active (the current URL matches).
+
+``params``: A map of param keys to their values (matching the `:named` tokens)
+within the path.
+
+``path``: The path expression that this route matches.
+
+### Paths
+
+Path expressions begin with a `/` (to disambiguate them from route names), and
+are a series of tokens separated by `/`.
+
+Tokens can be of the form `:named`, where they named a parameter. Or they can
+be regular strings, at which point they are static path parts.
+
+Should be familiar from many other routing systems.
+
+
+<a href="MoreRouting.Driver"></a>
+`MoreRouting.Driver`
+--------------------
+
+_Defined in [`driver.html`](driver.html)._
+
+Drivers manage how the URL is read, and how to navigate to URLs. There are two
+built in drivers:
+
+
+<a href="MoreRouting.HashDriver"></a>
+### `MoreRouting.HashDriver`
+
+_Defined in [`hash-driver.html`](hash-driver.html)._
+
+Provides hash-based routing, generating URLs like `#!/users/1/bio`. It has a
+configurable prefix (after the `#`). By default, it uses a prefix of `!/`
+(to fit the [AJAX-crawling spec](https://developers.google.com/webmasters/ajax-crawling/docs/specification)).
+
+
+<a href="MoreRouting.PathDriver"></a>
+### `MoreRouting.PathDriver`
+
+_Defined in [`path-driver.html`](path-driver.html)._
+
+Provides true path-based routing (via `pushState`), generating URLs like
+`/users/1/bio`. If your web app is mounted on a path other than `/`, you can
+specify that mount point via the `prefix`.
diff --git a/third_party/polymer/v0_8/components/more-routing/bower.json b/third_party/polymer/v0_8/components/more-routing/bower.json
new file mode 100644
index 0000000..434fe51
--- /dev/null
+++ b/third_party/polymer/v0_8/components/more-routing/bower.json
@@ -0,0 +1,37 @@
+{
+ "name": "more-routing",
+ "version": "0.8.0",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "description": "A composable suite of objects and elements to make routing with web components a breeze.",
+ "keywords": [
+ "web-component",
+ "web-components",
+ "polymer",
+ "routing",
+ "router"
+ ],
+ "main": "more-routing.html",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerLabs/more-routing/",
+ "ignore": [
+ "/.*",
+ "/test/",
+ "/demo/"
+ ],
+ "dependencies": {
+ "polymer": "Polymer/polymer#v0.8.0-rc.7",
+ "observe-js": "Polymer/observe-js#0.5.6-rc1"
+ },
+ "devDependencies": {
+ "iron-doc-viewer": "PolymerElements/iron-doc-viewer#^0.8.5",
+ "iron-selector": "PolymerElements/iron-selector#^0.8.2",
+ "paper-styles": "PolymerElements/paper-styles#^0.8.9",
+ "iron-flex-layout": "PolymerElements/iron-flex-layout#^0.8.1",
+ "web-component-tester": "*"
+ },
+ "resolutions": {
+ "observe-js": "0.5.6-rc1"
+ }
+}
diff --git a/third_party/polymer/v0_8/components/more-routing/driver.html b/third_party/polymer/v0_8/components/more-routing/driver.html
new file mode 100644
index 0000000..031c87d
--- /dev/null
+++ b/third_party/polymer/v0_8/components/more-routing/driver.html
@@ -0,0 +1,113 @@
+<!--
+Copyright (c) 2015 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>
+(function(scope) {
+var MoreRouting = scope.MoreRouting = scope.MoreRouting || {};
+MoreRouting.Driver = Driver;
+
+/**
+ * TODO(nevir): Docs.
+ */
+function Driver(opt_config) {
+ var config = opt_config || {};
+ if (config.prefix) this.prefix = config.prefix;
+
+ this._activeRoutes = [];
+
+ this._rootRoutes = [];
+}
+
+Driver.prototype.manageRoute = function manageRoute(route) {
+ route.driver = this;
+ this._appendRoute(route);
+
+ if (route.parent) {
+ if (route.parent.active) {
+ // Remember: `processPathParts` takes just the path parts relative to that
+ // route; not the full set.
+ route.processPathParts(this.currentPathParts.slice(route.parent.depth));
+ }
+ } else {
+ route.processPathParts(this.currentPathParts);
+ }
+
+ if (route.active) this._activeRoutes.push(route);
+};
+
+Driver.prototype.urlForParts = function urlForParts(parts) {
+ return this.prefix + parts.join(this.separator);
+};
+
+Driver.prototype.navigateToParts = function(parts) {
+ return this.navigateToUrl(this.urlForParts(parts));
+};
+
+Driver.prototype.navigateToUrl = function navigateToUrl(url) {
+ throw new Error(this.constructor.name + '#navigateToUrl not implemented');
+};
+
+// Subclass Interface
+
+Driver.prototype.prefix = '/';
+Driver.prototype.separator = '/';
+
+Driver.prototype.setCurrentPath = function setCurrentPath(path) {
+ this.currentPathParts = this.splitPath(path);
+ var newRoutes = this._matchingRoutes(this.currentPathParts);
+
+ // active -> inactive.
+ for (var i = 0, route; route = this._activeRoutes[i]; i++) {
+ if (newRoutes.indexOf(route) === -1) {
+ route.processPathParts(null);
+ }
+ }
+
+ this._activeRoutes = newRoutes;
+}
+
+Driver.prototype.splitPath = function splitPath(rawPath) {
+ if (this.prefix && rawPath.indexOf(this.prefix) !== 0) {
+ throw new Error(
+ 'Invalid path "' + rawPath + '"; ' +
+ 'expected it to be prefixed by "' + this.prefix + '"');
+ }
+ var path = rawPath.substr(this.prefix.length);
+ var parts = path.split(this.separator);
+ // Ignore trailing separators.
+ if (!parts[parts.length - 1]) parts.pop();
+
+ return parts;
+};
+
+// Internal Implementation
+Driver.prototype._appendRoute = function _appendRoute(route) {
+ if (route.parent) {
+ // We only care about root routes.
+ return;
+ }
+ this._rootRoutes.push(route);
+};
+
+Driver.prototype._matchingRoutes = function _matchingRoutes(parts, rootRoutes) {
+ var routes = [];
+ var candidates = rootRoutes || this._rootRoutes;
+ var route;
+ for (var i = 0; i < candidates.length; i++) {
+ route = candidates[i];
+ route.processPathParts(parts);
+ if (route.active) {
+ routes.push(route);
+ routes = routes.concat(this._matchingRoutes(parts.slice(route.compiled.length), route.children));
+ }
+ }
+ return routes;
+}
+
+})(window);
+</script>
diff --git a/third_party/polymer/v0_8/components/more-routing/driver/hash.html b/third_party/polymer/v0_8/components/more-routing/driver/hash.html
new file mode 100644
index 0000000..e20ded1
--- /dev/null
+++ b/third_party/polymer/v0_8/components/more-routing/driver/hash.html
@@ -0,0 +1,46 @@
+<!--
+Copyright (c) 2015 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
+-->
+<link rel="import" href="../driver.html">
+
+<script>
+(function(scope) {
+var MoreRouting = scope.MoreRouting = scope.MoreRouting || {};
+MoreRouting.HashDriver = HashDriver;
+
+/**
+ * TODO(nevir): Docs.
+ */
+function HashDriver() {
+ MoreRouting.Driver.apply(this, arguments);
+ this._bindEvents();
+ this._read();
+}
+HashDriver.prototype = Object.create(MoreRouting.Driver.prototype);
+
+// By default, we prefer hashbang; but you can prefix with any string you wish.
+HashDriver.prototype.prefix = '!/';
+
+HashDriver.prototype.urlForParts = function urlForParts(parts) {
+ return '#' + MoreRouting.Driver.prototype.urlForParts.call(this, parts);
+};
+
+HashDriver.prototype.navigateToUrl = function navigateToUrl(url) {
+ window.location.hash = url;
+};
+
+HashDriver.prototype._bindEvents = function _bindEvents() {
+ window.addEventListener('hashchange', this._read.bind(this));
+};
+
+HashDriver.prototype._read = function _read() {
+ this.setCurrentPath(window.location.hash.substr(1) || this.prefix);
+};
+
+})(window);
+</script>
diff --git a/third_party/polymer/v0_8/components/more-routing/driver/mock.html b/third_party/polymer/v0_8/components/more-routing/driver/mock.html
new file mode 100644
index 0000000..714f43b
--- /dev/null
+++ b/third_party/polymer/v0_8/components/more-routing/driver/mock.html
@@ -0,0 +1,27 @@
+<!--
+Copyright (c) 2015 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
+-->
+<link rel="import" href="../driver.html">
+
+<script>
+(function(scope) {
+var MoreRouting = scope.MoreRouting = scope.MoreRouting || {};
+MoreRouting.MockDriver = MockDriver;
+
+/** A mock driver for use in your tests. */
+function MockDriver() {
+ MoreRouting.Driver.apply(this, arguments);
+}
+MockDriver.prototype = Object.create(MoreRouting.Driver.prototype);
+
+MockDriver.prototype.navigateToUrl = function navigateToUrl(url) {
+ this.setCurrentPath(url);
+};
+
+})(window);
+</script>
diff --git a/third_party/polymer/v0_8/components/more-routing/driver/path.html b/third_party/polymer/v0_8/components/more-routing/driver/path.html
new file mode 100644
index 0000000..9cbb5ea
--- /dev/null
+++ b/third_party/polymer/v0_8/components/more-routing/driver/path.html
@@ -0,0 +1,40 @@
+<!--
+Copyright (c) 2015 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
+-->
+<link rel="import" href="../driver.html">
+
+<script>
+(function(scope) {
+var MoreRouting = scope.MoreRouting = scope.MoreRouting || {};
+MoreRouting.PathDriver = PathDriver;
+
+/**
+ * TODO(nevir): Docs.
+ */
+function PathDriver() {
+ MoreRouting.Driver.apply(this, arguments);
+ this._bindEvents();
+ this._read();
+}
+PathDriver.prototype = Object.create(MoreRouting.Driver.prototype);
+
+PathDriver.prototype.navigateToUrl = function navigateToUrl(url) {
+ window.history.pushState({}, '', url);
+ this._read();
+};
+
+PathDriver.prototype._bindEvents = function _bindEvents() {
+ window.addEventListener('popstate', this._read.bind(this));
+};
+
+PathDriver.prototype._read = function _read() {
+ this.setCurrentPath(window.location.pathname);
+};
+
+})(window);
+</script>
diff --git a/third_party/polymer/v0_8/components/more-routing/index.html b/third_party/polymer/v0_8/components/more-routing/index.html
new file mode 100644
index 0000000..67f8282
--- /dev/null
+++ b/third_party/polymer/v0_8/components/more-routing/index.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 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
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-doc-viewer/iron-doc-viewer.html">
+
+</head>
+<body>
+
+ <iron-doc-viewer></iron-doc-viewer>
+
+</body>
+</html>
diff --git a/third_party/polymer/v0_8/components/more-routing/more-route-context-aware.html b/third_party/polymer/v0_8/components/more-routing/more-route-context-aware.html
new file mode 100644
index 0000000..0da57c2
--- /dev/null
+++ b/third_party/polymer/v0_8/components/more-routing/more-route-context-aware.html
@@ -0,0 +1,66 @@
+<!--
+Copyright (c) 2015 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
+-->
+<link rel="import" href="../polymer/polymer.html">
+
+<link rel="import" href="route.html">
+<link rel="import" href="routing.html">
+
+<script>
+
+ MoreRouting.ContextAware = {
+
+ /** @override */
+ ready: function() {
+ this._makeRoutingReady();
+ },
+
+ /**
+ * Calls `routingReady`, and ensures that it is called in a top-down manner.
+ *
+ * We need to be sure that parent nodes have `routingReady` triggered before
+ * their children so that they can properly configure nested routes.
+ *
+ * Unfortunately, `ready` is sometimes bottom-up, sometimes top-down.
+ * Ideally, this wouldn't be necessary.
+ *
+ * @see https://github.com/Polymer/polymer/pull/1448
+ */
+ _makeRoutingReady: function() {
+ if (this.routingIsReady) return;
+
+ var node = this;
+ while (node = Polymer.dom(node).parentNode) {
+ if (typeof node._makeRoutingReady === 'function') break;
+ }
+ if (node) node._makeRoutingReady();
+
+ this.parentRoute = this._findParentRoute();
+ this.routingIsReady = true;
+ if (typeof this.routingReady === 'function') this.routingReady();
+ },
+
+ _findParentRoute: function() {
+ var node = this;
+ while (node) {
+ node = Polymer.dom(node).parentNode;
+ if (node && node.nodeType !== Node.ELEMENT_NODE) {
+ node = node.host;
+ }
+
+ var route = node && node.moreRouteContext;
+ if (route instanceof MoreRouting.Route) {
+ return route;
+ }
+ }
+ return null;
+ },
+
+ };
+
+</script>
diff --git a/third_party/polymer/v0_8/components/more-routing/more-route-selection.html b/third_party/polymer/v0_8/components/more-routing/more-route-selection.html
new file mode 100644
index 0000000..1afdd56
--- /dev/null
+++ b/third_party/polymer/v0_8/components/more-routing/more-route-selection.html
@@ -0,0 +1,198 @@
+<!--
+Copyright (c) 2015 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
+-->
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../observe-js/observe-js.html">
+
+<link rel="import" href="more-route-context-aware.html">
+<link rel="import" href="route.html">
+
+<!--
+TODO(nevir): Document.
+-->
+<script>
+
+ Polymer({
+
+ is: 'more-route-selection',
+
+ behaviors: [
+ MoreRouting.ContextAware,
+ ],
+
+ properties: {
+
+ /**
+ * Routes to select from, as either a path expression or route name.
+ *
+ * You can either specify routes via this attribute, or as child nodes
+ * to this element, but not both.
+ *
+ * @type {String|Array<string|MoreRouting.Route>}
+ */
+ routes: {
+ type: String,
+ observer: '_routesChanged',
+ },
+
+ /**
+ * The selected `MoreRouting.Route` object, or `null`.
+ *
+ * @type {MoreRouting.Route}
+ */
+ selectedRoute: {
+ type: Object,
+ value: null,
+ readOnly: true,
+ notify: true,
+ },
+
+ /**
+ * The index of the selected route (relative to `routes`). -1 when there
+ * is no active route.
+ */
+ selectedIndex: {
+ type: Number,
+ value: -1,
+ readOnly: true,
+ notify: true,
+ },
+
+ /**
+ * The _full_ path expression of the selected route, or `null`.
+ */
+ selectedPath: {
+ type: String,
+ readOnly: true,
+ notify: true,
+ },
+
+ /**
+ * The params of the selected route, or an empty object if no route.
+ */
+ selectedParams: {
+ type: Object,
+ readOnly: true,
+ notify: true,
+ },
+
+ },
+
+ /**
+ * @event more-route-change fires when a new route is selected.
+ * @detail {{
+ * newRoute: MoreRouting.Route, oldRoute: MoreRouting.Route,
+ * newIndex: number, oldIndex: number,
+ * newPath: ?string, oldPath: ?string,
+ * newParams: Object, oldParams: Object,
+ * }}
+ */
+
+ routingReady: function() {
+ this._routesChanged();
+ },
+
+ _routesChanged: function() {
+ if (!this.routingIsReady) return;
+ var routes = this.routes || [];
+ if (typeof routes === 'string') {
+ routes = routes.split(/\s+/);
+ }
+ this._routeInfo = this._sortIndexes(routes.map(function(route, index) {
+ return {
+ model: MoreRouting.getRoute(route, this.parentRoute),
+ index: index,
+ };
+ }.bind(this)));
+
+ this._observeRoutes();
+ this._evaluate();
+ },
+
+ /**
+ * Tracks changes to the routes.
+ */
+ _observeRoutes: function() {
+ if (this._observer) {
+ this._observer.close();
+ }
+ // TODO(nevir): https://github.com/Polymore/more-routing/issues/24
+ this._observer = new CompoundObserver();
+ for (var i = 0, routeInfo; routeInfo = this._routeInfo[i]; i++) {
+ this._observer.addPath(routeInfo.model, 'active');
+ }
+ this._observer.open(this._evaluate.bind(this));
+ },
+
+ _evaluate: function() {
+ var newIndex = -1;
+ var newRoute = null;
+ var oldIndex = this.selectedIndex;
+
+ for (var i = 0, routeInfo; routeInfo = this._routeInfo[i]; i++) {
+ if (routeInfo.model && routeInfo.model.active) {
+ newIndex = routeInfo.index;
+ newRoute = routeInfo.model;
+ break;
+ }
+ }
+ if (newIndex === oldIndex) return;
+
+ var oldRoute = this.selectedRoute;
+ var oldPath = this.selectedPath;
+ var oldParams = this.selectedParams;
+
+ var newPath = newRoute ? newRoute.fullPath : null;
+ var newParams = newRoute ? newRoute.params : {};
+
+ this._setSelectedRoute(newRoute);
+ this._setSelectedIndex(newIndex);
+ this._setSelectedPath(newPath);
+ this._setSelectedParams(newParams);
+
+ this.fire('more-route-change', {
+ newRoute: newRoute, oldRoute: oldRoute,
+ newIndex: newIndex, oldIndex: oldIndex,
+ newPath: newPath, oldPath: oldPath,
+ newParams: newParams, oldParams: oldParams,
+ });
+ },
+ /**
+ * We want the most specific routes to match first, so we must create a
+ * mapping of indexes within `routes` that map
+ */
+ _sortIndexes: function(routeInfo) {
+ return routeInfo.sort(function(a, b) {
+ if (!a.model) {
+ return 1;
+ } else if (!b.model) {
+ return -1;
+ // Routes with more path parts are most definitely more specific.
+ } else if (a.model.depth < b.model.depth) {
+ return 1;
+ } if (a.model.depth > b.model.depth) {
+ return -1;
+ } else {
+
+ // Also, routes with fewer params are more specific. For example
+ // `/users/foo` is more specific than `/users/:id`.
+ if (a.model.numParams < b.model.numParams) {
+ return -1;
+ } else if (a.model.numParams > b.model.numParams) {
+ return 1;
+ } else {
+ // Equally specific; we fall back to the default (and hopefully
+ // stable) sort order.
+ return 0;
+ }
+ }
+ });
+ },
+
+ });
+</script>
diff --git a/third_party/polymer/v0_8/components/more-routing/more-route-selector.html b/third_party/polymer/v0_8/components/more-routing/more-route-selector.html
new file mode 100644
index 0000000..9ad1907
--- /dev/null
+++ b/third_party/polymer/v0_8/components/more-routing/more-route-selector.html
@@ -0,0 +1,184 @@
+<!--
+Copyright (c) 2015 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
+-->
+<link rel="import" href="../polymer/polymer.html">
+
+<link rel="import" href="more-route-context-aware.html">
+<link rel="import" href="more-route-selection.html">
+
+<!--
+TODO(nevir): Document.
+
+TODO(nevir): Support child addition/removal/reorder.
+-->
+<dom-module id="more-route-selector">
+ <template>
+ <more-route-selection
+ id="selection"
+ routes="[[routes]]"
+ on-more-route-change="_onMoreRouteChange">
+ </more-route-selection>
+ <content></content>
+ </template>
+</dom-module>
+<script>
+Polymer({
+
+ is: 'more-route-selector',
+
+ behaviors: [
+ MoreRouting.ContextAware,
+ ],
+
+ properties: {
+
+ /**
+ * The attribute to read route expressions from (on children).
+ */
+ routeAttribute: {
+ type: String,
+ value: 'route',
+ },
+
+ /**
+ * The routes managed by this element (inferred from the items that are
+ * defined by the selector it targets).
+ */
+ routes: {
+ type: Array,
+ readOnly: true,
+ notify: true,
+ },
+
+ /**
+ * The selected `MoreRouting.Route` object, or `null`.
+ *
+ * @type {MoreRouting.Route}
+ */
+ selectedRoute: {
+ type: Object,
+ value: null,
+ readOnly: true,
+ notify: true,
+ },
+
+ /**
+ * The index of the selected route (relative to `routes`). -1 when there
+ * is no active route.
+ */
+ selectedIndex: {
+ type: Number,
+ value: -1,
+ readOnly: true,
+ notify: true,
+ },
+
+ /**
+ * The _full_ path expression of the selected route, or `null`.
+ */
+ selectedPath: {
+ type: String,
+ readOnly: true,
+ notify: true,
+ },
+
+ /**
+ * The params of the selected route, or an empty object if no route.
+ */
+ selectedParams: {
+ type: Object,
+ readOnly: true,
+ notify: true,
+ },
+
+ },
+
+ /**
+ * @event more-route-selected fires when a new route is selected.
+ * @param {{
+ * newRoute: MoreRouting.Route, oldRoute: MoreRouting.Route,
+ * newIndex: number, oldIndex: number,
+ * newPath: ?string, oldPath: ?string,
+ * newParams: Object, oldParams: Object,
+ * }}
+ */
+
+ attached: function() {
+ this._managedSelector = this._findTargetSelector();
+ if (!this._managedSelector) {
+ console.warn(this, 'was built without a selector to manage. It will do nothing.');
+ return;
+ }
+
+ this._managedSelector.addEventListener(
+ 'selected-item-changed', this._onSelectedItemChanged.bind(this));
+ this._updateRoutes();
+ },
+
+ /**
+ * Handle a change in selected item, driven by the targeted selector.
+ *
+ * Note that this will fail if a route is chosen that requires params not
+ * defined by the current URL.
+ */
+ _onSelectedItemChanged: function(event) {
+ var route = this._routeForItem(event.detail.value);
+ if (!route) return;
+ route.navigateTo();
+ },
+
+ _updateRoutes: function() {
+ var routes = [];
+ if (this._managedSelector) {
+ routes = this._managedSelector.items.map(this._routeForItem.bind(this));
+ }
+ this._setRoutes(routes);
+ },
+
+ _onMoreRouteChange: function(event) {
+ if (!this._managedSelector) return;
+ var route = event.detail.newRoute;
+ this._managedSelector.select(this.routes.indexOf(route));
+ },
+
+ _findTargetSelector: function() {
+ var children = Polymer.dom(this).children;
+ if (children.length !== 1) {
+ console.error(this, 'expects only a single selector child');
+ return null;
+ }
+
+ var child = children[0];
+ if ('selected' in child && 'items' in child) {
+ return child;
+ } else {
+ console.error(this, 'can only manage children that are selectors');
+ return null;
+ }
+ },
+
+ _routeForItem: function(item) {
+ if (!item) return null;
+ if (item.moreRouteContext && item.moreRouteContext instanceof MoreRouting.Route) {
+ return item.moreRouteContext;
+ }
+
+ if (!item.hasAttribute(this.routeAttribute)) {
+ console.warn(item, 'is missing a context route or "' + this.routeAttribute + '" attribute');
+ return null;
+ }
+ var expression = item.getAttribute(this.routeAttribute);
+ var route = MoreRouting.getRoute(expression, this.parentRoute);
+ // Associate the route w/ its element while we're here.
+ item.moreRouteContext = route;
+
+ return route;
+ },
+
+});
+</script>
diff --git a/third_party/polymer/v0_8/components/more-routing/more-route.html b/third_party/polymer/v0_8/components/more-routing/more-route.html
new file mode 100644
index 0000000..2b60660
--- /dev/null
+++ b/third_party/polymer/v0_8/components/more-routing/more-route.html
@@ -0,0 +1,193 @@
+<!--
+Copyright (c) 2015 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
+-->
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../observe-js/observe-js.html">
+
+<link rel="import" href="routing.html">
+<link rel="import" href="more-route-context-aware.html">
+
+<script>
+
+ Polymer({
+
+ is: 'more-route',
+
+ behaviors: [
+ MoreRouting.ContextAware,
+ ],
+
+ properties: {
+
+ /**
+ * The name of this route. Behavior differs based on the presence of
+ * `path` during _declaration_.
+ *
+ * If `path` is present during declaration, it is registered via `name`.
+ *
+ * Otherwise, this `more-route` becomes a `reference` to the route with
+ * `name`. Changing `name` will update which route is referenced.
+ */
+ name: {
+ type: String,
+ observer: '_nameChanged',
+ },
+
+ /**
+ * A path expression used to parse parameters from the window's URL.
+ */
+ path: {
+ type: String,
+ obserer: '_pathChanged',
+ },
+
+ /**
+ * Whether this route should become a context for the element that
+ * contains it.
+ */
+ context: {
+ type: Boolean,
+ },
+
+ /**
+ * The underlying `MoreRouting.Route` object that is being wrapped.
+ *
+ * @type {MoreRouting.Route}
+ */
+ route: {
+ type: Object,
+ readOnly: true,
+ notify: true,
+ observer: '_routeChanged',
+ },
+
+ /**
+ * The full path expression for this route, including routes this is
+ * nested within.
+ */
+ fullPath: {
+ type: String,
+ readOnly: true,
+ notify: true,
+ },
+
+ /**
+ * Param values matching the current URL, or an empty object if not
+ * `active`.
+ */
+ params: {
+ type: Object,
+ // readOnly: true,
+ notify: true,
+ },
+
+ /**
+ * Whether the route matches the current URL.
+ */
+ active: {
+ type: Boolean,
+ readOnly: true,
+ notify: true,
+ },
+
+ },
+
+ routingReady: function() {
+ this._identityChanged();
+ },
+
+ _nameChanged: function(newName, oldName) {
+ if (oldName) {
+ console.error('Changing the `name` property is not supported for', this);
+ return;
+ }
+ this._identityChanged();
+ },
+
+ _pathChanged: function(newPath, oldPath) {
+ if (oldPath) {
+ console.error('Changing the `path` property is not supported for', this);
+ return;
+ }
+ this._identityChanged();
+ },
+
+ _identityChanged: function() {
+ if (!this.routingIsReady) return;
+
+ if (this.name && this.path) {
+ this._setRoute(MoreRouting.registerNamedRoute(this.name, this.path, this.parentRoute));
+ } else if (this.name) {
+ this._setRoute(MoreRouting.getRouteByName(this.name));
+ } else if (this.path) {
+ this._setRoute(MoreRouting.getRouteByPath(this.path, this.parentRoute));
+ } else {
+ this._setRoute(null);
+ }
+ },
+
+ _routeChanged: function() {
+ this._observeRoute();
+ this._setFullPath(this.route.fullPath);
+ // this._setParams(this.route.params);
+ this.params = this.route.params;
+ this._setActive(this.route.active);
+
+ // @see MoreRouting.ContextAware
+ this.moreRouteContext = this.route;
+
+ if (this.context) {
+ var parent = Polymer.dom(this).parentNode;
+ if (parent.nodeType !== Node.ELEMENT_NODE) {
+ parent = parent.host;
+ }
+
+ if (parent.nodeType === Node.ELEMENT_NODE) {
+ parent.moreRouteContext = this.route;
+ } else {
+ console.warn('Unable to determine parent element for', this, '- not setting a context');
+ }
+ }
+ },
+
+ _observeRoute: function() {
+ // TODO(nevir) https://github.com/Polymore/more-routing/issues/24
+ if (this._routeObserver) this._routeObserver.close();
+ if (this._paramObserver) this._paramObserver.close();
+ if (!this.route) return;
+
+ this._routeObserver = new CompoundObserver();
+ this._routeObserver.addPath(this.route, 'active');
+ this._routeObserver.open(function() {
+ this._setActive(this.route.active);
+ }.bind(this));
+
+ this._paramObserver = new ObjectObserver(this.route.params);
+ this._paramObserver.open(function(added, removed, changed, getOldValue) {
+ var keys = Object.keys(added).concat(Object.keys(removed)).concat(Object.keys(changed));
+ keys.forEach(function(key) {
+ this.notifyPath('params.' + key, this.params[key]);
+ }.bind(this));
+ }.bind(this));
+ },
+
+ urlFor: function(params) {
+ return this.route.urlFor(params);
+ },
+
+ navigateTo: function(params) {
+ return this.route.navigateTo(params);
+ },
+
+ isCurrentUrl: function(params) {
+ return this.route.isCurrentUrl(params);
+ },
+
+ });
+
+</script>
diff --git a/third_party/polymer/v0_8/components/more-routing/more-routing-config.html b/third_party/polymer/v0_8/components/more-routing/more-routing-config.html
new file mode 100644
index 0000000..3d9b70f
--- /dev/null
+++ b/third_party/polymer/v0_8/components/more-routing/more-routing-config.html
@@ -0,0 +1,63 @@
+<!--
+Copyright (c) 2015 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
+-->
+<link rel="import" href="../polymer/polymer.html">
+
+<link rel="import" href="routing.html">
+<!-- TODO(nevir): import on demand? -->
+<link rel="import" href="driver/hash.html">
+<link rel="import" href="driver/mock.html">
+<link rel="import" href="driver/path.html">
+
+<script>
+
+ Polymer({
+
+ is: 'more-routing-config',
+
+ properties: {
+
+ /**
+ * The routing driver to use.
+ *
+ * * `hash`: `MoreRouting.HashDriver`
+ * * `path`: `MoreRouting.PathDriver`
+ * * `mock`: `MoreRouting.MockDriver`
+ *
+ */
+ driver: String,
+
+ /**
+ *
+ */
+ urlPrefix: String,
+
+ },
+
+ ready: function() {
+ var config = {};
+ if (this.urlPrefix) config.prefix = this.urlPrefix;
+
+ var driver;
+ // TODO(nevir): Support custom drivers, too.
+ if (this.driver === 'hash') {
+ driver = new MoreRouting.HashDriver(config);
+ } else if (this.driver === 'path') {
+ driver = new MoreRouting.PathDriver(config);
+ } else if (this.driver === 'mock') {
+ driver = new MoreRouting.MockDriver(config);
+ } else {
+ throw new Error('Unknown driver type "' + this.driver + '"');
+ }
+
+ MoreRouting.driver = driver;
+ },
+
+ });
+
+</script>
diff --git a/third_party/polymer/v0_8/components/more-routing/more-routing.html b/third_party/polymer/v0_8/components/more-routing/more-routing.html
new file mode 100644
index 0000000..43c3eeb3
--- /dev/null
+++ b/third_party/polymer/v0_8/components/more-routing/more-routing.html
@@ -0,0 +1,12 @@
+<!--
+Copyright (c) 2015 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
+-->
+<link rel="import" href="more-routing-config.html">
+<link rel="import" href="routing.html">
+<link rel="import" href="more-route.html">
+<link rel="import" href="more-route-selector.html">
diff --git a/third_party/polymer/v0_8/components/more-routing/route.html b/third_party/polymer/v0_8/components/more-routing/route.html
new file mode 100644
index 0000000..ea9f344
--- /dev/null
+++ b/third_party/polymer/v0_8/components/more-routing/route.html
@@ -0,0 +1,194 @@
+<!--
+Copyright (c) 2015 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
+-->
+<link rel="import" href="../observe-js/observe-js.html">
+
+<script>
+(function(scope) {
+var MoreRouting = scope.MoreRouting = scope.MoreRouting || {};
+MoreRouting.Route = Route;
+
+// Note that this can differ from the part separator defined by the driver. The
+// driver's separator is used when parsing/generating URLs given to the client,
+// whereas this one is for route definitions.
+var PART_SEPARATOR = '/';
+var PARAM_SENTINEL = ':';
+var SEPARATOR_CLEANER = /\/\/+/g;
+
+/**
+ * TODO(nevir): Docs.
+ */
+function Route(path, parent) {
+ this.path = path;
+ this.parent = parent;
+ this.fullPath = path;
+ this.compiled = this._compile(this.path);
+ this.active = false;
+ this.driver = null;
+
+ this.parts = [];
+ this.children = [];
+
+ // Param values matching the current URL, or an empty object if not `active`.
+ //
+ // To make data "binding" easy, `Route` guarantees that `params` will always
+ // be the same object; just make a reference to it.
+ if (this.parent) {
+ this.params = Object.create(this.parent.params);
+ this.parent.children.push(this);
+ this.fullPath = this.parent.fullPath + this.fullPath;
+ this.depth = this.parent.depth + this.compiled.length;
+ this.numParams = this.parent.numParams + countParams(this.compiled);
+ } else {
+ this.params = {};
+ this.depth = this.compiled.length;
+ this.numParams = countParams(this.compiled);
+ }
+
+ this._paramObserver = new ObjectObserver(this.params);
+ this._paramObserver.open(this._navigateToParams.bind(this));
+}
+
+Route.isPath = function isPath(pathOrName) {
+ return pathOrName.indexOf(PART_SEPARATOR) === 0;
+};
+
+Route.joinPath = function joinPath(paths) {
+ var joined = Array.prototype.join.call(arguments, PART_SEPARATOR);
+ joined = joined.replace(SEPARATOR_CLEANER, PART_SEPARATOR);
+
+ var minLength = joined.length - PART_SEPARATOR.length;
+ if (joined.substr(minLength) === PART_SEPARATOR) {
+ joined = joined.substr(0, minLength);
+ }
+
+ return joined;
+};
+
+Route.prototype.urlFor = function urlFor(params) {
+ return this.driver.urlForParts(this.partsForParams(params));
+};
+
+Route.prototype.navigateTo = function navigateTo(params) {
+ return this.driver.navigateToParts(this.partsForParams(params));
+}
+
+Route.prototype.isCurrentUrl = function isCurrentUrl(params) {
+ if (!this.active) return false;
+ var currentKeys = Object.keys(this.params);
+ for (var i = 0, key; key = currentKeys[i]; i++) {
+ if (this.params[key] !== String(params[key])) {
+ return false;
+ }
+ }
+ return true;
+};
+
+// Driver Interface
+
+Route.prototype.partsForParams = function partsForParams(params, silent) {
+ var parts = this.parent && this.parent.partsForParams(params, silent) || [];
+ for (var i = 0, config; config = this.compiled[i]; i++) {
+ if (config.type === 'static') {
+ parts.push(config.part);
+ } else if (config.type === 'param') {
+ var value
+ if (params && config.name in params) {
+ value = params[config.name];
+ } else {
+ value = this.params[config.name];
+ }
+ if (value === undefined) {
+ if (silent) {
+ return null;
+ } else {
+ throw new Error('Missing param "' + config.name + '" for route ' + this);
+ }
+ }
+ parts.push(value);
+ }
+ }
+ return parts;
+};
+
+/**
+ * Called by the driver whenever it has detected a change to the URL.
+ *
+ * @param {Array.<String>|null} parts The parts of the URL, or null if the
+ * route should be disabled.
+ */
+Route.prototype.processPathParts = function processPathParts(parts) {
+ this.parts = parts;
+ this.active = this.matchesPathParts(parts);
+ if (this.active) {
+ var keys = Object.keys(this.params);
+ for (var i = 0; i < keys.length; i++) {
+ delete this.params[keys[i]];
+ }
+ for (var i = 0, config; config = this.compiled[i]; i++) {
+ if (config.type === 'param') {
+ this.params[config.name] = parts[i];
+ }
+ }
+ } else {
+ for (key in this.params) {
+ this.params[key] = undefined;
+ }
+ }
+ this._paramObserver.discardChanges();
+};
+
+Route.prototype.matchesPathParts = function matchesPathParts(parts) {
+ if (!parts) return false;
+ if (parts.length < this.compiled.length) return false;
+ for (var i = 0, config; config = this.compiled[i]; i++) {
+ if (config.type === 'static' && parts[i] !== config.part) {
+ return false;
+ }
+ }
+ return true;
+};
+
+Route.prototype.toString = function toString() {
+ return this.path;
+};
+
+// Internal Implementation
+
+Route.prototype._compile = function _compile(rawPath) {
+ // Not strictly required, but helps us stay consistent w/ `getRoute`, etc.
+ if (rawPath.indexOf(PART_SEPARATOR) !== 0) {
+ throw new Error('Route paths must begin with a path separator; got: "' + rawPath + '"');
+ }
+ var path = rawPath.substr(PART_SEPARATOR.length);
+ if (path === '') return [];
+
+ return path.split(PART_SEPARATOR).map(function(part) {
+ // raw fragment.
+ if (part.substr(0, 1) == PARAM_SENTINEL) {
+ return {type: 'param', name: part.substr(1)};
+ } else {
+ return {type: 'static', part: part};
+ }
+ });
+};
+
+Route.prototype._navigateToParams = function _navigateToParams() {
+ var parts = this.partsForParams(this.params, true);
+ if (!parts) return;
+ this.driver.navigateToParts(parts);
+};
+
+function countParams(compiled) {
+ return compiled.reduce(function(count, part) {
+ return count + (part.type === 'param' ? 1 : 0);
+ }, 0);
+}
+
+})(window);
+</script>
diff --git a/third_party/polymer/v0_8/components/more-routing/routing.html b/third_party/polymer/v0_8/components/more-routing/routing.html
new file mode 100644
index 0000000..0b1cf50
--- /dev/null
+++ b/third_party/polymer/v0_8/components/more-routing/routing.html
@@ -0,0 +1,137 @@
+<!--
+Copyright (c) 2015 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
+-->
+<link rel="import" href="route.html">
+
+<script>
+(function(scope) {
+var MoreRouting = scope.MoreRouting = scope.MoreRouting || {};
+
+// Route singletons.
+var routesByPath = {};
+var pathsByName = {};
+
+// Route Management
+
+/**
+ * Retrieves (or builds) the singleton `Route` for the given path expression or
+ * route name.
+ *
+ * Paths begin with `/`; anything else is considered a name.
+ *
+ * For convenience, `Route` objects can also be passed (and will be returned) -
+ * this can be used as a route coercion function.
+ *
+ * @param {String|MoreRouting.Route} pathOrName
+ * @param {MoreRouting.Route} parent
+ * @return {MoreRouting.Route}
+ */
+MoreRouting.getRoute = function getRoute(pathOrName, parent) {
+ if (typeof pathOrName !== 'string') return pathOrName;
+ if (this.isPath(pathOrName)) {
+ return this.getRouteByPath(pathOrName, parent);
+ } else {
+ return this.getRouteByName(pathOrName);
+ }
+}
+
+/**
+ * Retrieves (or builds) the singleton `Route` for the given path expression.
+ *
+ * @param {String} path
+ * @param {MoreRouting.Route} parent
+ * @return {MoreRouting.Route}
+ */
+MoreRouting.getRouteByPath = function getRouteByPath(path, parent) {
+ var fullPath = (parent ? parent.fullPath : '') + path;
+ if (!routesByPath[fullPath]) {
+ routesByPath[fullPath] = new this.Route(path, parent);
+ this.driver.manageRoute(routesByPath[fullPath]);
+ }
+ return routesByPath[fullPath];
+}
+
+/**
+ * Retrieves the route registered via `name`.
+ *
+ * @param {String} name
+ * @return {MoreRouting.Route}
+ */
+MoreRouting.getRouteByName = function getRouteByName(name) {
+ var path = pathsByName[name];
+ if (!path) {
+ throw new Error('No route named "' + name + '" has been registered');
+ }
+ return this.getRouteByPath(path);
+}
+
+/**
+ * @param {String} path
+ * @return {MoreRouting.Route} The newly registered route.
+ */
+MoreRouting.registerNamedRoute = function registerNamedRoute(name, path, parent) {
+ if (pathsByName[name]) {
+ console.warn(
+ 'Overwriting route named "' + name + '" with path:', path,
+ 'previously:', pathsByName[name]);
+ }
+ var route = this.getRouteByPath(path, parent);
+ pathsByName[name] = route.fullPath;
+ return route;
+};
+
+// Route Shortcuts
+MoreRouting.urlFor = function urlFor(pathOrName, params) {
+ return this.getRoute(pathOrName).urlFor(params);
+};
+
+MoreRouting.navigateTo = function navigateTo(pathOrName, params) {
+ return this.getRoute(pathOrName).navigateTo(params);
+};
+
+MoreRouting.isCurrentUrl = function isCurrentUrl(pathOrName, params) {
+ return this.getRoute(pathOrName).isCurrentUrl(params);
+};
+
+// Utility
+
+/**
+ *
+ */
+MoreRouting.isPath = function isPath(pathOrName) {
+ return this.Route.isPath(pathOrName);
+}
+
+/**
+ * @param {...String} paths
+ */
+MoreRouting.joinPath = function joinPath(paths) {
+ return this.Route.joinPath.apply(this.Route, arguments);
+}
+
+// Driver Management
+
+var driver;
+Object.defineProperty(MoreRouting, 'driver', {
+ get: function getDriver() {
+ if (!driver) {
+ throw new Error('No routing driver configured. Did you forget <more-routing-config>?');
+ }
+ return driver;
+ },
+ set: function setDriver(newDriver) {
+ if (driver) {
+ console.warn('Changing routing drivers is not supported, ignoring. You should have only one <more-routing-config> on the page!');
+ return;
+ }
+ driver = newDriver;
+ }
+});
+
+})(window);
+</script>
diff --git a/third_party/polymer/v0_8/components/observe-js/.bower.json b/third_party/polymer/v0_8/components/observe-js/.bower.json
new file mode 100644
index 0000000..6f6c206
--- /dev/null
+++ b/third_party/polymer/v0_8/components/observe-js/.bower.json
@@ -0,0 +1,31 @@
+{
+ "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.6-rc1",
+ "_release": "0.5.6-rc1",
+ "_resolution": {
+ "type": "version",
+ "tag": "0.5.6-rc1",
+ "commit": "7e94bb14d7c44b221af7bcc874cf9898f26747d8"
+ },
+ "_source": "git://github.com/Polymer/observe-js.git",
+ "_target": "0.5.6-rc1",
+ "_originalSource": "Polymer/observe-js"
+} \ No newline at end of file
diff --git a/third_party/polymer/v0_8/components/observe-js/AUTHORS b/third_party/polymer/v0_8/components/observe-js/AUTHORS
new file mode 100644
index 0000000..0617765
--- /dev/null
+++ b/third_party/polymer/v0_8/components/observe-js/AUTHORS
@@ -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>
diff --git a/third_party/polymer/v0_8/components/observe-js/README.md b/third_party/polymer/v0_8/components/observe-js/README.md
new file mode 100644
index 0000000..e6268a2
--- /dev/null
+++ b/third_party/polymer/v0_8/components/observe-js/README.md
@@ -0,0 +1,203 @@
+[![Build status](http://www.polymer-project.org/build/observe-js/status.png "Build status")](http://build.chromium.org/p/client.polymer/waterfall) [![Analytics](https://ga-beacon.appspot.com/UA-39334307-2/Polymer/observe-js/README)](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](https://github.com/arv/ecmascript-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, function(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 value 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.
diff --git a/third_party/polymer/v0_8/components/observe-js/bower.json b/third_party/polymer/v0_8/components/observe-js/bower.json
new file mode 100644
index 0000000..4c94f61
--- /dev/null
+++ b/third_party/polymer/v0_8/components/observe-js/bower.json
@@ -0,0 +1,21 @@
+{
+ "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"
+ ]
+}
diff --git a/third_party/polymer/v0_8/components/observe-js/codereview.settings b/third_party/polymer/v0_8/components/observe-js/codereview.settings
new file mode 100644
index 0000000..dca487f
--- /dev/null
+++ b/third_party/polymer/v0_8/components/observe-js/codereview.settings
@@ -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/
+
diff --git a/third_party/polymer/v0_8/components/observe-js/gruntfile.js b/third_party/polymer/v0_8/components/observe-js/gruntfile.js
new file mode 100644
index 0000000..d2f794e
--- /dev/null
+++ b/third_party/polymer/v0_8/components/observe-js/gruntfile.js
@@ -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']);
+};
diff --git a/third_party/polymer/v0_8/components/observe-js/index.html b/third_party/polymer/v0_8/components/observe-js/index.html
new file mode 100644
index 0000000..e47cfb5
--- /dev/null
+++ b/third_party/polymer/v0_8/components/observe-js/index.html
@@ -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>
diff --git a/third_party/polymer/v0_8/components/observe-js/observe-js.html b/third_party/polymer/v0_8/components/observe-js/observe-js.html
new file mode 100644
index 0000000..000c2ba
--- /dev/null
+++ b/third_party/polymer/v0_8/components/observe-js/observe-js.html
@@ -0,0 +1,9 @@
+<!--
+Copyright (c) 2015 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
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+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
+-->
+<script src="src/observe.js"></script>
diff --git a/third_party/polymer/v0_8/components/observe-js/package.json b/third_party/polymer/v0_8/components/observe-js/package.json
new file mode 100644
index 0000000..f863539
--- /dev/null
+++ b/third_party/polymer/v0_8/components/observe-js/package.json
@@ -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": "*"
+ }
+}
diff --git a/third_party/polymer/v0_8/components/observe-js/src/observe.js b/third_party/polymer/v0_8/components/observe-js/src/observe.js
new file mode 100644
index 0000000..f96ba57
--- /dev/null
+++ b/third_party/polymer/v0_8/components/observe-js/src/observe.js
@@ -0,0 +1,1711 @@
+/*
+ * 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 testingExposeCycleCount = global.testingExposeCycleCount;
+
+ // Detect and do basic sanity checking on Object/Array.observe.
+ function detectObjectObserve() {
+ if (typeof Object.observe !== 'function' ||
+ typeof Array.observe !== 'function') {
+ return false;
+ }
+
+ var records = [];
+
+ function callback(recs) {
+ records = recs;
+ }
+
+ var test = {};
+ var arr = [];
+ Object.observe(test, callback);
+ Array.observe(arr, callback);
+ test.id = 1;
+ test.id = 2;
+ delete test.id;
+ arr.push(1, 2);
+ arr.length = 0;
+
+ Object.deliverChangeRecords(callback);
+ if (records.length !== 5)
+ return false;
+
+ if (records[0].type != 'add' ||
+ records[1].type != 'update' ||
+ records[2].type != 'delete' ||
+ records[3].type != 'splice' ||
+ records[4].type != 'splice') {
+ return false;
+ }
+
+ Object.unobserve(test, callback);
+ Array.unobserve(arr, callback);
+
+ return true;
+ }
+
+ var hasObserve = detectObjectObserve();
+
+ function detectEval() {
+ // Don't test for eval if we're running in a Chrome App environment.
+ // We check for APIs set that only exist in a Chrome App context.
+ if (typeof chrome !== 'undefined' && chrome.app && chrome.app.runtime) {
+ return false;
+ }
+
+ // Firefox OS Apps do not allow eval. This feature detection is very hacky
+ // but even if some other platform adds support for this function this code
+ // will continue to work.
+ if (typeof navigator != 'undefined' && navigator.getDeviceStorage) {
+ return false;
+ }
+
+ try {
+ var f = new Function('', 'return true;');
+ return f();
+ } catch (ex) {
+ return false;
+ }
+ }
+
+ var hasEval = detectEval();
+
+ function isIndex(s) {
+ return +s === s >>> 0 && s !== '';
+ }
+
+ function toNumber(s) {
+ return +s;
+ }
+
+ function isObject(obj) {
+ return obj === Object(obj);
+ }
+
+ var numberIsNaN = global.Number.isNaN || function(value) {
+ return typeof value === 'number' && global.isNaN(value);
+ }
+
+ function areSameValue(left, right) {
+ if (left === right)
+ return left !== 0 || 1 / left === 1 / right;
+ if (numberIsNaN(left) && numberIsNaN(right))
+ return true;
+
+ return left !== left && right !== right;
+ }
+
+ 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;
+ };
+
+ var identStart = '[\$_a-zA-Z]';
+ var identPart = '[\$_a-zA-Z0-9]';
+ var identRegExp = new RegExp('^' + identStart + '+' + identPart + '*' + '$');
+
+ function getPathCharType(char) {
+ if (char === undefined)
+ return 'eof';
+
+ var code = char.charCodeAt(0);
+
+ switch(code) {
+ case 0x5B: // [
+ case 0x5D: // ]
+ case 0x2E: // .
+ case 0x22: // "
+ case 0x27: // '
+ case 0x30: // 0
+ return char;
+
+ case 0x5F: // _
+ case 0x24: // $
+ return 'ident';
+
+ case 0x20: // Space
+ case 0x09: // Tab
+ case 0x0A: // Newline
+ case 0x0D: // Return
+ case 0xA0: // No-break space
+ case 0xFEFF: // Byte Order Mark
+ case 0x2028: // Line Separator
+ case 0x2029: // Paragraph Separator
+ return 'ws';
+ }
+
+ // a-z, A-Z
+ if ((0x61 <= code && code <= 0x7A) || (0x41 <= code && code <= 0x5A))
+ return 'ident';
+
+ // 1-9
+ if (0x31 <= code && code <= 0x39)
+ return 'number';
+
+ return 'else';
+ }
+
+ var pathStateMachine = {
+ 'beforePath': {
+ 'ws': ['beforePath'],
+ 'ident': ['inIdent', 'append'],
+ '[': ['beforeElement'],
+ 'eof': ['afterPath']
+ },
+
+ 'inPath': {
+ 'ws': ['inPath'],
+ '.': ['beforeIdent'],
+ '[': ['beforeElement'],
+ 'eof': ['afterPath']
+ },
+
+ 'beforeIdent': {
+ 'ws': ['beforeIdent'],
+ 'ident': ['inIdent', 'append']
+ },
+
+ 'inIdent': {
+ 'ident': ['inIdent', 'append'],
+ '0': ['inIdent', 'append'],
+ 'number': ['inIdent', 'append'],
+ 'ws': ['inPath', 'push'],
+ '.': ['beforeIdent', 'push'],
+ '[': ['beforeElement', 'push'],
+ 'eof': ['afterPath', 'push']
+ },
+
+ 'beforeElement': {
+ 'ws': ['beforeElement'],
+ '0': ['afterZero', 'append'],
+ 'number': ['inIndex', 'append'],
+ "'": ['inSingleQuote', 'append', ''],
+ '"': ['inDoubleQuote', 'append', '']
+ },
+
+ 'afterZero': {
+ 'ws': ['afterElement', 'push'],
+ ']': ['inPath', 'push']
+ },
+
+ 'inIndex': {
+ '0': ['inIndex', 'append'],
+ 'number': ['inIndex', 'append'],
+ 'ws': ['afterElement'],
+ ']': ['inPath', 'push']
+ },
+
+ 'inSingleQuote': {
+ "'": ['afterElement'],
+ 'eof': ['error'],
+ 'else': ['inSingleQuote', 'append']
+ },
+
+ 'inDoubleQuote': {
+ '"': ['afterElement'],
+ 'eof': ['error'],
+ 'else': ['inDoubleQuote', 'append']
+ },
+
+ 'afterElement': {
+ 'ws': ['afterElement'],
+ ']': ['inPath', 'push']
+ }
+ }
+
+ function noop() {}
+
+ function parsePath(path) {
+ var keys = [];
+ var index = -1;
+ var c, newChar, key, type, transition, action, typeMap, mode = 'beforePath';
+
+ var actions = {
+ push: function() {
+ if (key === undefined)
+ return;
+
+ keys.push(key);
+ key = undefined;
+ },
+
+ append: function() {
+ if (key === undefined)
+ key = newChar
+ else
+ key += newChar;
+ }
+ };
+
+ function maybeUnescapeQuote() {
+ if (index >= path.length)
+ return;
+
+ var nextChar = path[index + 1];
+ if ((mode == 'inSingleQuote' && nextChar == "'") ||
+ (mode == 'inDoubleQuote' && nextChar == '"')) {
+ index++;
+ newChar = nextChar;
+ actions.append();
+ return true;
+ }
+ }
+
+ while (mode) {
+ index++;
+ c = path[index];
+
+ if (c == '\\' && maybeUnescapeQuote(mode))
+ continue;
+
+ type = getPathCharType(c);
+ typeMap = pathStateMachine[mode];
+ transition = typeMap[type] || typeMap['else'] || 'error';
+
+ if (transition == 'error')
+ return; // parse error;
+
+ mode = transition[0];
+ action = actions[transition[1]] || noop;
+ newChar = transition[2] === undefined ? c : transition[2];
+ action();
+
+ if (mode === 'afterPath') {
+ return keys;
+ }
+ }
+
+ return; // parse error
+ }
+
+ function isIdent(s) {
+ return identRegExp.test(s);
+ }
+
+ var constructorIsPrivate = {};
+
+ function Path(parts, privateToken) {
+ if (privateToken !== constructorIsPrivate)
+ throw Error('Use Path.get to retrieve path objects');
+
+ for (var i = 0; i < parts.length; i++) {
+ this.push(String(parts[i]));
+ }
+
+ if (hasEval && this.length) {
+ this.getValueFrom = this.compiledGetValueFromFn();
+ }
+ }
+
+ // TODO(rafaelw): Make simple LRU cache
+ var pathCache = {};
+
+ function getPath(pathString) {
+ if (pathString instanceof Path)
+ return pathString;
+
+ if (pathString == null || pathString.length == 0)
+ pathString = '';
+
+ if (typeof pathString != 'string') {
+ if (isIndex(pathString.length)) {
+ // Constructed with array-like (pre-parsed) keys
+ return new Path(pathString, constructorIsPrivate);
+ }
+
+ pathString = String(pathString);
+ }
+
+ var path = pathCache[pathString];
+ if (path)
+ return path;
+
+ var parts = parsePath(pathString);
+ if (!parts)
+ return invalidPath;
+
+ var path = new Path(parts, constructorIsPrivate);
+ pathCache[pathString] = path;
+ return path;
+ }
+
+ Path.get = getPath;
+
+ function formatAccessor(key) {
+ if (isIndex(key)) {
+ return '[' + key + ']';
+ } else {
+ return '["' + key.replace(/"/g, '\\"') + '"]';
+ }
+ }
+
+ Path.prototype = createObject({
+ __proto__: [],
+ valid: true,
+
+ toString: function() {
+ var pathString = '';
+ for (var i = 0; i < this.length; i++) {
+ var key = this[i];
+ if (isIdent(key)) {
+ pathString += i ? '.' + key : key;
+ } else {
+ pathString += formatAccessor(key);
+ }
+ }
+
+ return pathString;
+ },
+
+ getValueFrom: function(obj, directObserver) {
+ for (var i = 0; i < this.length; i++) {
+ if (obj == null)
+ return;
+ obj = obj[this[i]];
+ }
+ return obj;
+ },
+
+ iterateObjects: function(obj, observe) {
+ for (var i = 0; i < this.length; i++) {
+ if (i)
+ obj = obj[this[i - 1]];
+ if (!isObject(obj))
+ return;
+ observe(obj, this[i]);
+ }
+ },
+
+ compiledGetValueFromFn: function() {
+ var str = '';
+ var pathString = 'obj';
+ str += 'if (obj != null';
+ var i = 0;
+ var key;
+ for (; i < (this.length - 1); i++) {
+ key = this[i];
+ pathString += isIdent(key) ? '.' + key : formatAccessor(key);
+ str += ' &&\n ' + pathString + ' != null';
+ }
+ str += ')\n';
+
+ var key = this[i];
+ pathString += isIdent(key) ? '.' + key : formatAccessor(key);
+
+ str += ' return ' + pathString + ';\nelse\n return undefined;';
+ return new Function('obj', str);
+ },
+
+ setValueFrom: function(obj, value) {
+ if (!this.length)
+ return false;
+
+ for (var i = 0; i < this.length - 1; i++) {
+ if (!isObject(obj))
+ return false;
+ obj = obj[this[i]];
+ }
+
+ if (!isObject(obj))
+ return false;
+
+ obj[this[i]] = value;
+ return true;
+ }
+ });
+
+ var invalidPath = new Path('', constructorIsPrivate);
+ invalidPath.valid = false;
+ invalidPath.getValueFrom = invalidPath.setValueFrom = function() {};
+
+ var MAX_DIRTY_CHECK_CYCLES = 1000;
+
+ function dirtyCheck(observer) {
+ var cycles = 0;
+ while (cycles < MAX_DIRTY_CHECK_CYCLES && observer.check_()) {
+ cycles++;
+ }
+ if (testingExposeCycleCount)
+ global.dirtyCheckCycleCount = cycles;
+
+ return cycles > 0;
+ }
+
+ function objectIsEmpty(object) {
+ for (var prop in object)
+ return false;
+ return true;
+ }
+
+ function diffIsEmpty(diff) {
+ return objectIsEmpty(diff.added) &&
+ objectIsEmpty(diff.removed) &&
+ objectIsEmpty(diff.changed);
+ }
+
+ function diffObjectFromOldObject(object, oldObject) {
+ var added = {};
+ var removed = {};
+ var changed = {};
+
+ for (var prop in oldObject) {
+ var newValue = object[prop];
+
+ if (newValue !== undefined && newValue === oldObject[prop])
+ continue;
+
+ if (!(prop in object)) {
+ removed[prop] = undefined;
+ continue;
+ }
+
+ if (newValue !== oldObject[prop])
+ changed[prop] = newValue;
+ }
+
+ for (var prop in object) {
+ if (prop in oldObject)
+ continue;
+
+ added[prop] = object[prop];
+ }
+
+ if (Array.isArray(object) && object.length !== oldObject.length)
+ changed.length = object.length;
+
+ return {
+ added: added,
+ removed: removed,
+ changed: changed
+ };
+ }
+
+ var eomTasks = [];
+ function runEOMTasks() {
+ if (!eomTasks.length)
+ return false;
+
+ for (var i = 0; i < eomTasks.length; i++) {
+ eomTasks[i]();
+ }
+ eomTasks.length = 0;
+ return true;
+ }
+
+ var runEOM = hasObserve ? (function(){
+ return function(fn) {
+ return Promise.resolve().then(fn);
+ }
+ })() :
+ (function() {
+ return function(fn) {
+ eomTasks.push(fn);
+ };
+ })();
+
+ var observedObjectCache = [];
+
+ function newObservedObject() {
+ var observer;
+ var object;
+ var discardRecords = false;
+ var first = true;
+
+ function callback(records) {
+ if (observer && observer.state_ === OPENED && !discardRecords)
+ observer.check_(records);
+ }
+
+ return {
+ open: function(obs) {
+ if (observer)
+ throw Error('ObservedObject in use');
+
+ if (!first)
+ Object.deliverChangeRecords(callback);
+
+ observer = obs;
+ first = false;
+ },
+ observe: function(obj, arrayObserve) {
+ object = obj;
+ if (arrayObserve)
+ Array.observe(object, callback);
+ else
+ Object.observe(object, callback);
+ },
+ deliver: function(discard) {
+ discardRecords = discard;
+ Object.deliverChangeRecords(callback);
+ discardRecords = false;
+ },
+ close: function() {
+ observer = undefined;
+ Object.unobserve(object, callback);
+ observedObjectCache.push(this);
+ }
+ };
+ }
+
+ /*
+ * The observedSet abstraction is a perf optimization which reduces the total
+ * number of Object.observe observations of a set of objects. The idea is that
+ * groups of Observers will have some object dependencies in common and this
+ * observed set ensures that each object in the transitive closure of
+ * dependencies is only observed once. The observedSet acts as a write barrier
+ * such that whenever any change comes through, all Observers are checked for
+ * changed values.
+ *
+ * Note that this optimization is explicitly moving work from setup-time to
+ * change-time.
+ *
+ * TODO(rafaelw): Implement "garbage collection". In order to move work off
+ * the critical path, when Observers are closed, their observed objects are
+ * not Object.unobserve(d). As a result, it's possible that if the observedSet
+ * is kept open, but some Observers have been closed, it could cause "leaks"
+ * (prevent otherwise collectable objects from being collected). At some
+ * point, we should implement incremental "gc" which keeps a list of
+ * observedSets which may need clean-up and does small amounts of cleanup on a
+ * timeout until all is clean.
+ */
+
+ function getObservedObject(observer, object, arrayObserve) {
+ var dir = observedObjectCache.pop() || newObservedObject();
+ dir.open(observer);
+ dir.observe(object, arrayObserve);
+ return dir;
+ }
+
+ var observedSetCache = [];
+
+ function newObservedSet() {
+ var observerCount = 0;
+ var observers = [];
+ var objects = [];
+ var rootObj;
+ var rootObjProps;
+
+ function observe(obj, prop) {
+ if (!obj)
+ return;
+
+ if (obj === rootObj)
+ rootObjProps[prop] = true;
+
+ if (objects.indexOf(obj) < 0) {
+ objects.push(obj);
+ Object.observe(obj, callback);
+ }
+
+ observe(Object.getPrototypeOf(obj), prop);
+ }
+
+ function allRootObjNonObservedProps(recs) {
+ for (var i = 0; i < recs.length; i++) {
+ var rec = recs[i];
+ if (rec.object !== rootObj ||
+ rootObjProps[rec.name] ||
+ rec.type === 'setPrototype') {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ function callback(recs) {
+ if (allRootObjNonObservedProps(recs))
+ return;
+
+ var observer;
+ for (var i = 0; i < observers.length; i++) {
+ observer = observers[i];
+ if (observer.state_ == OPENED) {
+ observer.iterateObjects_(observe);
+ }
+ }
+
+ for (var i = 0; i < observers.length; i++) {
+ observer = observers[i];
+ if (observer.state_ == OPENED) {
+ observer.check_();
+ }
+ }
+ }
+
+ var record = {
+ objects: objects,
+ get rootObject() { return rootObj; },
+ set rootObject(value) {
+ rootObj = value;
+ rootObjProps = {};
+ },
+ open: function(obs, object) {
+ observers.push(obs);
+ observerCount++;
+ obs.iterateObjects_(observe);
+ },
+ close: function(obs) {
+ observerCount--;
+ if (observerCount > 0) {
+ return;
+ }
+
+ for (var i = 0; i < objects.length; i++) {
+ Object.unobserve(objects[i], callback);
+ Observer.unobservedCount++;
+ }
+
+ observers.length = 0;
+ objects.length = 0;
+ rootObj = undefined;
+ rootObjProps = undefined;
+ observedSetCache.push(this);
+ if (lastObservedSet === this)
+ lastObservedSet = null;
+ },
+ };
+
+ return record;
+ }
+
+ var lastObservedSet;
+
+ function getObservedSet(observer, obj) {
+ if (!lastObservedSet || lastObservedSet.rootObject !== obj) {
+ lastObservedSet = observedSetCache.pop() || newObservedSet();
+ lastObservedSet.rootObject = obj;
+ }
+ lastObservedSet.open(observer, obj);
+ return lastObservedSet;
+ }
+
+ var UNOPENED = 0;
+ var OPENED = 1;
+ var CLOSED = 2;
+ var RESETTING = 3;
+
+ var nextObserverId = 1;
+
+ function Observer() {
+ this.state_ = UNOPENED;
+ this.callback_ = undefined;
+ this.target_ = undefined; // TODO(rafaelw): Should be WeakRef
+ this.directObserver_ = undefined;
+ this.value_ = undefined;
+ this.id_ = nextObserverId++;
+ }
+
+ Observer.prototype = {
+ open: function(callback, target) {
+ if (this.state_ != UNOPENED)
+ throw Error('Observer has already been opened.');
+
+ addToAll(this);
+ this.callback_ = callback;
+ this.target_ = target;
+ this.connect_();
+ this.state_ = OPENED;
+ return this.value_;
+ },
+
+ close: function() {
+ if (this.state_ != OPENED)
+ return;
+
+ removeFromAll(this);
+ this.disconnect_();
+ this.value_ = undefined;
+ this.callback_ = undefined;
+ this.target_ = undefined;
+ this.state_ = CLOSED;
+ },
+
+ deliver: function() {
+ if (this.state_ != OPENED)
+ return;
+
+ dirtyCheck(this);
+ },
+
+ report_: function(changes) {
+ try {
+ this.callback_.apply(this.target_, changes);
+ } catch (ex) {
+ Observer._errorThrownDuringCallback = true;
+ console.error('Exception caught during observer callback: ' +
+ (ex.stack || ex));
+ }
+ },
+
+ discardChanges: function() {
+ this.check_(undefined, true);
+ return this.value_;
+ }
+ }
+
+ var collectObservers = !hasObserve;
+ var allObservers;
+ Observer._allObserversCount = 0;
+
+ if (collectObservers) {
+ allObservers = [];
+ }
+
+ function addToAll(observer) {
+ Observer._allObserversCount++;
+ if (!collectObservers)
+ return;
+
+ allObservers.push(observer);
+ }
+
+ function removeFromAll(observer) {
+ Observer._allObserversCount--;
+ }
+
+ var runningMicrotaskCheckpoint = false;
+
+ global.Platform = global.Platform || {};
+
+ global.Platform.performMicrotaskCheckpoint = function() {
+ if (runningMicrotaskCheckpoint)
+ return;
+
+ if (!collectObservers)
+ return;
+
+ runningMicrotaskCheckpoint = true;
+
+ var cycles = 0;
+ var anyChanged, toCheck;
+
+ do {
+ cycles++;
+ toCheck = allObservers;
+ allObservers = [];
+ anyChanged = false;
+
+ for (var i = 0; i < toCheck.length; i++) {
+ var observer = toCheck[i];
+ if (observer.state_ != OPENED)
+ continue;
+
+ if (observer.check_())
+ anyChanged = true;
+
+ allObservers.push(observer);
+ }
+ if (runEOMTasks())
+ anyChanged = true;
+ } while (cycles < MAX_DIRTY_CHECK_CYCLES && anyChanged);
+
+ if (testingExposeCycleCount)
+ global.dirtyCheckCycleCount = cycles;
+
+ runningMicrotaskCheckpoint = false;
+ };
+
+ if (collectObservers) {
+ global.Platform.clearObservers = function() {
+ allObservers = [];
+ };
+ }
+
+ function ObjectObserver(object) {
+ Observer.call(this);
+ this.value_ = object;
+ this.oldObject_ = undefined;
+ }
+
+ ObjectObserver.prototype = createObject({
+ __proto__: Observer.prototype,
+
+ arrayObserve: false,
+
+ connect_: function(callback, target) {
+ if (hasObserve) {
+ this.directObserver_ = getObservedObject(this, this.value_,
+ this.arrayObserve);
+ } else {
+ this.oldObject_ = this.copyObject(this.value_);
+ }
+
+ },
+
+ copyObject: function(object) {
+ var copy = Array.isArray(object) ? [] : {};
+ for (var prop in object) {
+ copy[prop] = object[prop];
+ };
+ if (Array.isArray(object))
+ copy.length = object.length;
+ return copy;
+ },
+
+ check_: function(changeRecords, skipChanges) {
+ var diff;
+ var oldValues;
+ if (hasObserve) {
+ if (!changeRecords)
+ return false;
+
+ oldValues = {};
+ diff = diffObjectFromChangeRecords(this.value_, changeRecords,
+ oldValues);
+ } else {
+ oldValues = this.oldObject_;
+ diff = diffObjectFromOldObject(this.value_, this.oldObject_);
+ }
+
+ if (diffIsEmpty(diff))
+ return false;
+
+ if (!hasObserve)
+ this.oldObject_ = this.copyObject(this.value_);
+
+ this.report_([
+ diff.added || {},
+ diff.removed || {},
+ diff.changed || {},
+ function(property) {
+ return oldValues[property];
+ }
+ ]);
+
+ return true;
+ },
+
+ disconnect_: function() {
+ if (hasObserve) {
+ this.directObserver_.close();
+ this.directObserver_ = undefined;
+ } else {
+ this.oldObject_ = undefined;
+ }
+ },
+
+ deliver: function() {
+ if (this.state_ != OPENED)
+ return;
+
+ if (hasObserve)
+ this.directObserver_.deliver(false);
+ else
+ dirtyCheck(this);
+ },
+
+ discardChanges: function() {
+ if (this.directObserver_)
+ this.directObserver_.deliver(true);
+ else
+ this.oldObject_ = this.copyObject(this.value_);
+
+ return this.value_;
+ }
+ });
+
+ function ArrayObserver(array) {
+ if (!Array.isArray(array))
+ throw Error('Provided object is not an Array');
+ ObjectObserver.call(this, array);
+ }
+
+ ArrayObserver.prototype = createObject({
+
+ __proto__: ObjectObserver.prototype,
+
+ arrayObserve: true,
+
+ copyObject: function(arr) {
+ return arr.slice();
+ },
+
+ check_: function(changeRecords) {
+ var splices;
+ if (hasObserve) {
+ if (!changeRecords)
+ return false;
+ splices = projectArraySplices(this.value_, changeRecords);
+ } else {
+ splices = calcSplices(this.value_, 0, this.value_.length,
+ this.oldObject_, 0, this.oldObject_.length);
+ }
+
+ if (!splices || !splices.length)
+ return false;
+
+ if (!hasObserve)
+ this.oldObject_ = this.copyObject(this.value_);
+
+ this.report_([splices]);
+ return true;
+ }
+ });
+
+ ArrayObserver.applySplices = function(previous, current, splices) {
+ splices.forEach(function(splice) {
+ var spliceArgs = [splice.index, splice.removed.length];
+ var addIndex = splice.index;
+ while (addIndex < splice.index + splice.addedCount) {
+ spliceArgs.push(current[addIndex]);
+ addIndex++;
+ }
+
+ Array.prototype.splice.apply(previous, spliceArgs);
+ });
+ };
+
+ function PathObserver(object, path) {
+ Observer.call(this);
+
+ this.object_ = object;
+ this.path_ = getPath(path);
+ this.directObserver_ = undefined;
+ }
+
+ PathObserver.prototype = createObject({
+ __proto__: Observer.prototype,
+
+ get path() {
+ return this.path_;
+ },
+
+ connect_: function() {
+ if (hasObserve)
+ this.directObserver_ = getObservedSet(this, this.object_);
+
+ this.check_(undefined, true);
+ },
+
+ disconnect_: function() {
+ this.value_ = undefined;
+
+ if (this.directObserver_) {
+ this.directObserver_.close(this);
+ this.directObserver_ = undefined;
+ }
+ },
+
+ iterateObjects_: function(observe) {
+ this.path_.iterateObjects(this.object_, observe);
+ },
+
+ check_: function(changeRecords, skipChanges) {
+ var oldValue = this.value_;
+ this.value_ = this.path_.getValueFrom(this.object_);
+ if (skipChanges || areSameValue(this.value_, oldValue))
+ return false;
+
+ this.report_([this.value_, oldValue, this]);
+ return true;
+ },
+
+ setValue: function(newValue) {
+ if (this.path_)
+ this.path_.setValueFrom(this.object_, newValue);
+ }
+ });
+
+ function CompoundObserver(reportChangesOnOpen) {
+ Observer.call(this);
+
+ this.reportChangesOnOpen_ = reportChangesOnOpen;
+ this.value_ = [];
+ this.directObserver_ = undefined;
+ this.observed_ = [];
+ }
+
+ var observerSentinel = {};
+
+ CompoundObserver.prototype = createObject({
+ __proto__: Observer.prototype,
+
+ connect_: function() {
+ if (hasObserve) {
+ var object;
+ var needsDirectObserver = false;
+ for (var i = 0; i < this.observed_.length; i += 2) {
+ object = this.observed_[i]
+ if (object !== observerSentinel) {
+ needsDirectObserver = true;
+ break;
+ }
+ }
+
+ if (needsDirectObserver)
+ this.directObserver_ = getObservedSet(this, object);
+ }
+
+ this.check_(undefined, !this.reportChangesOnOpen_);
+ },
+
+ disconnect_: function() {
+ for (var i = 0; i < this.observed_.length; i += 2) {
+ if (this.observed_[i] === observerSentinel)
+ this.observed_[i + 1].close();
+ }
+ this.observed_.length = 0;
+ this.value_.length = 0;
+
+ if (this.directObserver_) {
+ this.directObserver_.close(this);
+ this.directObserver_ = undefined;
+ }
+ },
+
+ addPath: function(object, path) {
+ if (this.state_ != UNOPENED && this.state_ != RESETTING)
+ throw Error('Cannot add paths once started.');
+
+ var path = getPath(path);
+ this.observed_.push(object, path);
+ if (!this.reportChangesOnOpen_)
+ return;
+ var index = this.observed_.length / 2 - 1;
+ this.value_[index] = path.getValueFrom(object);
+ },
+
+ addObserver: function(observer) {
+ if (this.state_ != UNOPENED && this.state_ != RESETTING)
+ throw Error('Cannot add observers once started.');
+
+ this.observed_.push(observerSentinel, observer);
+ if (!this.reportChangesOnOpen_)
+ return;
+ var index = this.observed_.length / 2 - 1;
+ this.value_[index] = observer.open(this.deliver, this);
+ },
+
+ startReset: function() {
+ if (this.state_ != OPENED)
+ throw Error('Can only reset while open');
+
+ this.state_ = RESETTING;
+ this.disconnect_();
+ },
+
+ finishReset: function() {
+ if (this.state_ != RESETTING)
+ throw Error('Can only finishReset after startReset');
+ this.state_ = OPENED;
+ this.connect_();
+
+ return this.value_;
+ },
+
+ iterateObjects_: function(observe) {
+ var object;
+ for (var i = 0; i < this.observed_.length; i += 2) {
+ object = this.observed_[i]
+ if (object !== observerSentinel)
+ this.observed_[i + 1].iterateObjects(object, observe)
+ }
+ },
+
+ check_: function(changeRecords, skipChanges) {
+ var oldValues;
+ for (var i = 0; i < this.observed_.length; i += 2) {
+ var object = this.observed_[i];
+ var path = this.observed_[i+1];
+ var value;
+ if (object === observerSentinel) {
+ var observable = path;
+ value = this.state_ === UNOPENED ?
+ observable.open(this.deliver, this) :
+ observable.discardChanges();
+ } else {
+ value = path.getValueFrom(object);
+ }
+
+ if (skipChanges) {
+ this.value_[i / 2] = value;
+ continue;
+ }
+
+ if (areSameValue(value, this.value_[i / 2]))
+ continue;
+
+ oldValues = oldValues || [];
+ oldValues[i / 2] = this.value_[i / 2];
+ this.value_[i / 2] = value;
+ }
+
+ if (!oldValues)
+ return false;
+
+ // TODO(rafaelw): Having observed_ as the third callback arg here is
+ // pretty lame API. Fix.
+ this.report_([this.value_, oldValues, this.observed_]);
+ return true;
+ }
+ });
+
+ function identFn(value) { return value; }
+
+ function ObserverTransform(observable, getValueFn, setValueFn,
+ dontPassThroughSet) {
+ this.callback_ = undefined;
+ this.target_ = undefined;
+ this.value_ = undefined;
+ this.observable_ = observable;
+ this.getValueFn_ = getValueFn || identFn;
+ this.setValueFn_ = setValueFn || identFn;
+ // TODO(rafaelw): This is a temporary hack. PolymerExpressions needs this
+ // at the moment because of a bug in it's dependency tracking.
+ this.dontPassThroughSet_ = dontPassThroughSet;
+ }
+
+ ObserverTransform.prototype = {
+ open: function(callback, target) {
+ this.callback_ = callback;
+ this.target_ = target;
+ this.value_ =
+ this.getValueFn_(this.observable_.open(this.observedCallback_, this));
+ return this.value_;
+ },
+
+ observedCallback_: function(value) {
+ value = this.getValueFn_(value);
+ if (areSameValue(value, this.value_))
+ return;
+ var oldValue = this.value_;
+ this.value_ = value;
+ this.callback_.call(this.target_, this.value_, oldValue);
+ },
+
+ discardChanges: function() {
+ this.value_ = this.getValueFn_(this.observable_.discardChanges());
+ return this.value_;
+ },
+
+ deliver: function() {
+ return this.observable_.deliver();
+ },
+
+ setValue: function(value) {
+ value = this.setValueFn_(value);
+ if (!this.dontPassThroughSet_ && this.observable_.setValue)
+ return this.observable_.setValue(value);
+ },
+
+ close: function() {
+ if (this.observable_)
+ this.observable_.close();
+ this.callback_ = undefined;
+ this.target_ = undefined;
+ this.observable_ = undefined;
+ this.value_ = undefined;
+ this.getValueFn_ = undefined;
+ this.setValueFn_ = undefined;
+ }
+ }
+
+ var expectedRecordTypes = {
+ add: true,
+ update: true,
+ delete: true
+ };
+
+ function diffObjectFromChangeRecords(object, changeRecords, oldValues) {
+ var added = {};
+ var removed = {};
+
+ for (var i = 0; i < changeRecords.length; i++) {
+ var record = changeRecords[i];
+ if (!expectedRecordTypes[record.type]) {
+ console.error('Unknown changeRecord type: ' + record.type);
+ console.error(record);
+ continue;
+ }
+
+ if (!(record.name in oldValues))
+ oldValues[record.name] = record.oldValue;
+
+ if (record.type == 'update')
+ continue;
+
+ if (record.type == 'add') {
+ if (record.name in removed)
+ delete removed[record.name];
+ else
+ added[record.name] = true;
+
+ continue;
+ }
+
+ // type = 'delete'
+ if (record.name in added) {
+ delete added[record.name];
+ delete oldValues[record.name];
+ } else {
+ removed[record.name] = true;
+ }
+ }
+
+ for (var prop in added)
+ added[prop] = object[prop];
+
+ for (var prop in removed)
+ removed[prop] = undefined;
+
+ var changed = {};
+ for (var prop in oldValues) {
+ if (prop in added || prop in removed)
+ continue;
+
+ var newValue = object[prop];
+ if (oldValues[prop] !== newValue)
+ changed[prop] = newValue;
+ }
+
+ return {
+ added: added,
+ removed: removed,
+ changed: changed
+ };
+ }
+
+ function newSplice(index, removed, addedCount) {
+ return {
+ index: index,
+ removed: removed,
+ addedCount: addedCount
+ };
+ }
+
+ var EDIT_LEAVE = 0;
+ var EDIT_UPDATE = 1;
+ var EDIT_ADD = 2;
+ var EDIT_DELETE = 3;
+
+ function ArraySplice() {}
+
+ ArraySplice.prototype = {
+
+ // Note: This function is *based* on the computation of the Levenshtein
+ // "edit" distance. The one change is that "updates" are treated as two
+ // edits - not one. With Array splices, an update is really a delete
+ // followed by an add. By retaining this, we optimize for "keeping" the
+ // maximum array items in the original array. For example:
+ //
+ // 'xxxx123' -> '123yyyy'
+ //
+ // With 1-edit updates, the shortest path would be just to update all seven
+ // characters. With 2-edit updates, we delete 4, leave 3, and add 4. This
+ // leaves the substring '123' intact.
+ calcEditDistances: function(current, currentStart, currentEnd,
+ old, oldStart, oldEnd) {
+ // "Deletion" columns
+ var rowCount = oldEnd - oldStart + 1;
+ var columnCount = currentEnd - currentStart + 1;
+ var distances = new Array(rowCount);
+
+ // "Addition" rows. Initialize null column.
+ for (var i = 0; i < rowCount; i++) {
+ distances[i] = new Array(columnCount);
+ distances[i][0] = i;
+ }
+
+ // Initialize null row
+ for (var j = 0; j < columnCount; j++)
+ distances[0][j] = j;
+
+ for (var i = 1; i < rowCount; i++) {
+ for (var j = 1; j < columnCount; j++) {
+ if (this.equals(current[currentStart + j - 1], old[oldStart + i - 1]))
+ distances[i][j] = distances[i - 1][j - 1];
+ else {
+ var north = distances[i - 1][j] + 1;
+ var west = distances[i][j - 1] + 1;
+ distances[i][j] = north < west ? north : west;
+ }
+ }
+ }
+
+ return distances;
+ },
+
+ // This starts at the final weight, and walks "backward" by finding
+ // the minimum previous weight recursively until the origin of the weight
+ // matrix.
+ spliceOperationsFromEditDistances: function(distances) {
+ var i = distances.length - 1;
+ var j = distances[0].length - 1;
+ var current = distances[i][j];
+ var edits = [];
+ while (i > 0 || j > 0) {
+ if (i == 0) {
+ edits.push(EDIT_ADD);
+ j--;
+ continue;
+ }
+ if (j == 0) {
+ edits.push(EDIT_DELETE);
+ i--;
+ continue;
+ }
+ var northWest = distances[i - 1][j - 1];
+ var west = distances[i - 1][j];
+ var north = distances[i][j - 1];
+
+ var min;
+ if (west < north)
+ min = west < northWest ? west : northWest;
+ else
+ min = north < northWest ? north : northWest;
+
+ if (min == northWest) {
+ if (northWest == current) {
+ edits.push(EDIT_LEAVE);
+ } else {
+ edits.push(EDIT_UPDATE);
+ current = northWest;
+ }
+ i--;
+ j--;
+ } else if (min == west) {
+ edits.push(EDIT_DELETE);
+ i--;
+ current = west;
+ } else {
+ edits.push(EDIT_ADD);
+ j--;
+ current = north;
+ }
+ }
+
+ edits.reverse();
+ return edits;
+ },
+
+ /**
+ * Splice Projection functions:
+ *
+ * A splice map is a representation of how a previous array of items
+ * was transformed into a new array of items. Conceptually it is a list of
+ * tuples of
+ *
+ * <index, removed, addedCount>
+ *
+ * which are kept in ascending index order of. The tuple represents that at
+ * the |index|, |removed| sequence of items were removed, and counting forward
+ * from |index|, |addedCount| items were added.
+ */
+
+ /**
+ * Lacking individual splice mutation information, the minimal set of
+ * splices can be synthesized given the previous state and final state of an
+ * array. The basic approach is to calculate the edit distance matrix and
+ * choose the shortest path through it.
+ *
+ * Complexity: O(l * p)
+ * l: The length of the current array
+ * p: The length of the old array
+ */
+ calcSplices: function(current, currentStart, currentEnd,
+ old, oldStart, oldEnd) {
+ var prefixCount = 0;
+ var suffixCount = 0;
+
+ var minLength = Math.min(currentEnd - currentStart, oldEnd - oldStart);
+ if (currentStart == 0 && oldStart == 0)
+ prefixCount = this.sharedPrefix(current, old, minLength);
+
+ if (currentEnd == current.length && oldEnd == old.length)
+ suffixCount = this.sharedSuffix(current, old, minLength - prefixCount);
+
+ currentStart += prefixCount;
+ oldStart += prefixCount;
+ currentEnd -= suffixCount;
+ oldEnd -= suffixCount;
+
+ if (currentEnd - currentStart == 0 && oldEnd - oldStart == 0)
+ return [];
+
+ if (currentStart == currentEnd) {
+ var splice = newSplice(currentStart, [], 0);
+ while (oldStart < oldEnd)
+ splice.removed.push(old[oldStart++]);
+
+ return [ splice ];
+ } else if (oldStart == oldEnd)
+ return [ newSplice(currentStart, [], currentEnd - currentStart) ];
+
+ var ops = this.spliceOperationsFromEditDistances(
+ this.calcEditDistances(current, currentStart, currentEnd,
+ old, oldStart, oldEnd));
+
+ var splice = undefined;
+ var splices = [];
+ var index = currentStart;
+ var oldIndex = oldStart;
+ for (var i = 0; i < ops.length; i++) {
+ switch(ops[i]) {
+ case EDIT_LEAVE:
+ if (splice) {
+ splices.push(splice);
+ splice = undefined;
+ }
+
+ index++;
+ oldIndex++;
+ break;
+ case EDIT_UPDATE:
+ if (!splice)
+ splice = newSplice(index, [], 0);
+
+ splice.addedCount++;
+ index++;
+
+ splice.removed.push(old[oldIndex]);
+ oldIndex++;
+ break;
+ case EDIT_ADD:
+ if (!splice)
+ splice = newSplice(index, [], 0);
+
+ splice.addedCount++;
+ index++;
+ break;
+ case EDIT_DELETE:
+ if (!splice)
+ splice = newSplice(index, [], 0);
+
+ splice.removed.push(old[oldIndex]);
+ oldIndex++;
+ break;
+ }
+ }
+
+ if (splice) {
+ splices.push(splice);
+ }
+ return splices;
+ },
+
+ sharedPrefix: function(current, old, searchLength) {
+ for (var i = 0; i < searchLength; i++)
+ if (!this.equals(current[i], old[i]))
+ return i;
+ return searchLength;
+ },
+
+ sharedSuffix: function(current, old, searchLength) {
+ var index1 = current.length;
+ var index2 = old.length;
+ var count = 0;
+ while (count < searchLength && this.equals(current[--index1], old[--index2]))
+ count++;
+
+ return count;
+ },
+
+ calculateSplices: function(current, previous) {
+ return this.calcSplices(current, 0, current.length, previous, 0,
+ previous.length);
+ },
+
+ equals: function(currentValue, previousValue) {
+ return currentValue === previousValue;
+ }
+ };
+
+ var arraySplice = new ArraySplice();
+
+ function calcSplices(current, currentStart, currentEnd,
+ old, oldStart, oldEnd) {
+ return arraySplice.calcSplices(current, currentStart, currentEnd,
+ old, oldStart, oldEnd);
+ }
+
+ function intersect(start1, end1, start2, end2) {
+ // Disjoint
+ if (end1 < start2 || end2 < start1)
+ return -1;
+
+ // Adjacent
+ if (end1 == start2 || end2 == start1)
+ return 0;
+
+ // Non-zero intersect, span1 first
+ if (start1 < start2) {
+ if (end1 < end2)
+ return end1 - start2; // Overlap
+ else
+ return end2 - start2; // Contained
+ } else {
+ // Non-zero intersect, span2 first
+ if (end2 < end1)
+ return end2 - start1; // Overlap
+ else
+ return end1 - start1; // Contained
+ }
+ }
+
+ function mergeSplice(splices, index, removed, addedCount) {
+
+ var splice = newSplice(index, removed, addedCount);
+
+ var inserted = false;
+ var insertionOffset = 0;
+
+ for (var i = 0; i < splices.length; i++) {
+ var current = splices[i];
+ current.index += insertionOffset;
+
+ if (inserted)
+ continue;
+
+ var intersectCount = intersect(splice.index,
+ splice.index + splice.removed.length,
+ current.index,
+ current.index + current.addedCount);
+
+ if (intersectCount >= 0) {
+ // Merge the two splices
+
+ splices.splice(i, 1);
+ i--;
+
+ insertionOffset -= current.addedCount - current.removed.length;
+
+ splice.addedCount += current.addedCount - intersectCount;
+ var deleteCount = splice.removed.length +
+ current.removed.length - intersectCount;
+
+ if (!splice.addedCount && !deleteCount) {
+ // merged splice is a noop. discard.
+ inserted = true;
+ } else {
+ var removed = current.removed;
+
+ if (splice.index < current.index) {
+ // some prefix of splice.removed is prepended to current.removed.
+ var prepend = splice.removed.slice(0, current.index - splice.index);
+ Array.prototype.push.apply(prepend, removed);
+ removed = prepend;
+ }
+
+ if (splice.index + splice.removed.length > current.index + current.addedCount) {
+ // some suffix of splice.removed is appended to current.removed.
+ var append = splice.removed.slice(current.index + current.addedCount - splice.index);
+ Array.prototype.push.apply(removed, append);
+ }
+
+ splice.removed = removed;
+ if (current.index < splice.index) {
+ splice.index = current.index;
+ }
+ }
+ } else if (splice.index < current.index) {
+ // Insert splice here.
+
+ inserted = true;
+
+ splices.splice(i, 0, splice);
+ i++;
+
+ var offset = splice.addedCount - splice.removed.length
+ current.index += offset;
+ insertionOffset += offset;
+ }
+ }
+
+ if (!inserted)
+ splices.push(splice);
+ }
+
+ function createInitialSplices(array, changeRecords) {
+ var splices = [];
+
+ for (var i = 0; i < changeRecords.length; i++) {
+ var record = changeRecords[i];
+ switch(record.type) {
+ case 'splice':
+ mergeSplice(splices, record.index, record.removed.slice(), record.addedCount);
+ break;
+ case 'add':
+ case 'update':
+ case 'delete':
+ if (!isIndex(record.name))
+ continue;
+ var index = toNumber(record.name);
+ if (index < 0)
+ continue;
+ mergeSplice(splices, index, [record.oldValue], 1);
+ break;
+ default:
+ console.error('Unexpected record type: ' + JSON.stringify(record));
+ break;
+ }
+ }
+
+ return splices;
+ }
+
+ function projectArraySplices(array, changeRecords) {
+ var splices = [];
+
+ createInitialSplices(array, changeRecords).forEach(function(splice) {
+ if (splice.addedCount == 1 && splice.removed.length == 1) {
+ if (splice.removed[0] !== array[splice.index])
+ splices.push(splice);
+
+ return
+ };
+
+ splices = splices.concat(calcSplices(array, splice.index, splice.index + splice.addedCount,
+ splice.removed, 0, splice.removed.length));
+ });
+
+ return splices;
+ }
+
+ // Export the observe-js object for **Node.js**, with backwards-compatibility
+ // for the old `require()` API. Also ensure `exports` is not a DOM Element.
+ // If we're in the browser, export as a global object.
+
+ var expose = global;
+
+ if (typeof exports !== 'undefined' && !exports.nodeType) {
+ if (typeof module !== 'undefined' && module.exports) {
+ exports = module.exports;
+ }
+ expose = exports;
+ }
+
+ expose.Observer = Observer;
+ expose.Observer.runEOM_ = runEOM;
+ expose.Observer.observerSentinel_ = observerSentinel; // for testing.
+ expose.Observer.hasObjectObserve = hasObserve;
+ expose.ArrayObserver = ArrayObserver;
+ expose.ArrayObserver.calculateSplices = function(current, previous) {
+ return arraySplice.calculateSplices(current, previous);
+ };
+
+ expose.ArraySplice = ArraySplice;
+ expose.ObjectObserver = ObjectObserver;
+ expose.PathObserver = PathObserver;
+ expose.CompoundObserver = CompoundObserver;
+ expose.Path = Path;
+ expose.ObserverTransform = ObserverTransform;
+
+})(typeof global !== 'undefined' && global && typeof module !== 'undefined' && module ? global : this || window);
diff --git a/third_party/polymer/v0_8/components/observe-js/util/planner.js b/third_party/polymer/v0_8/components/observe-js/util/planner.js
new file mode 100644
index 0000000..b75f06d
--- /dev/null
+++ b/third_party/polymer/v0_8/components/observe-js/util/planner.js
@@ -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);
diff --git a/third_party/polymer/v0_8/components/paper-behaviors/.bower.json b/third_party/polymer/v0_8/components/paper-behaviors/.bower.json
index ed10bab..8897b08 100644
--- a/third_party/polymer/v0_8/components/paper-behaviors/.bower.json
+++ b/third_party/polymer/v0_8/components/paper-behaviors/.bower.json
@@ -35,7 +35,7 @@
"tag": "v0.8.3",
"commit": "d111ed7a3991f3fb6b87b362efbecd7167be25e1"
},
- "_source": "git://github.com/polymerelements/paper-behaviors.git",
+ "_source": "git://github.com/PolymerElements/paper-behaviors.git",
"_target": "^0.8.0",
- "_originalSource": "polymerelements/paper-behaviors"
+ "_originalSource": "PolymerElements/paper-behaviors"
} \ No newline at end of file
diff --git a/third_party/polymer/v0_8/components/paper-button/.bower.json b/third_party/polymer/v0_8/components/paper-button/.bower.json
index cb2b76f..62776a0 100644
--- a/third_party/polymer/v0_8/components/paper-button/.bower.json
+++ b/third_party/polymer/v0_8/components/paper-button/.bower.json
@@ -1,6 +1,6 @@
{
"name": "paper-button",
- "version": "0.8.2",
+ "version": "0.8.3",
"authors": [
"The Polymer Authors"
],
@@ -34,11 +34,11 @@
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.6.0",
"web-component-tester": "*"
},
- "_release": "0.8.2",
+ "_release": "0.8.3",
"_resolution": {
"type": "version",
- "tag": "v0.8.2",
- "commit": "64f95d9fe781c34efe30ec73ad93078e45857e85"
+ "tag": "v0.8.3",
+ "commit": "9361301aeb12a97f7729f0e7cd8641b7e568bc6f"
},
"_source": "git://github.com/PolymerElements/paper-button.git",
"_target": "^0.8.0",
diff --git a/third_party/polymer/v0_8/components/paper-button/paper-button.html b/third_party/polymer/v0_8/components/paper-button/paper-button.html
index 65521f0..4fdf756 100644
--- a/third_party/polymer/v0_8/components/paper-button/paper-button.html
+++ b/third_party/polymer/v0_8/components/paper-button/paper-button.html
@@ -116,44 +116,47 @@ The opacity of the ripple is not customizable via CSS.
</template>
- <script>
-
- Polymer({
-
- behaviors: [
- Polymer.PaperButtonBehavior
- ],
-
- properties: {
-
- /**
- * If true, the button should be styled with a shadow.
- *
- * @attribute raised
- * @type boolean
- * @default false
- */
- raised: {
- type: Boolean,
- reflectToAttribute: true,
- value: false,
- observer: '_buttonStateChanged'
- }
-
- },
-
- ready: function() {
- if (!this.hasAttribute('role')) {
- this.setAttribute('role', 'button');
- }
- },
-
- _buttonStateChanged: function() {
- this._calculateElevation();
+</dom-module>
+
+<script>
+
+ Polymer({
+
+ is: 'paper-button',
+
+ behaviors: [
+ Polymer.PaperButtonBehavior
+ ],
+
+ properties: {
+
+ /**
+ * If true, the button should be styled with a shadow.
+ *
+ * @attribute raised
+ * @type boolean
+ * @default false
+ */
+ raised: {
+ type: Boolean,
+ reflectToAttribute: true,
+ value: false,
+ observer: '_buttonStateChanged'
}
- });
+ },
- </script>
+ ready: function() {
+ if (!this.hasAttribute('role')) {
+ this.setAttribute('role', 'button');
+ }
+ },
+
+ _buttonStateChanged: function() {
+ this._calculateElevation();
+ }
+
+ });
+
+</script>
-</dom-module>
diff --git a/third_party/polymer/v0_8/components/paper-drawer-panel/.bower.json b/third_party/polymer/v0_8/components/paper-drawer-panel/.bower.json
index dfd4325..b09ad58 100644
--- a/third_party/polymer/v0_8/components/paper-drawer-panel/.bower.json
+++ b/third_party/polymer/v0_8/components/paper-drawer-panel/.bower.json
@@ -1,6 +1,6 @@
{
"name": "paper-drawer-panel",
- "version": "0.8.2",
+ "version": "0.8.3",
"authors": [
"The Polymer Authors"
],
@@ -27,11 +27,11 @@
"iron-doc-viewer": "PolymerElements/iron-doc-viewer#^0.8.0",
"paper-styles": "PolymerElements/paper-styles#^0.8.0"
},
- "_release": "0.8.2",
+ "_release": "0.8.3",
"_resolution": {
"type": "version",
- "tag": "v0.8.2",
- "commit": "4e4b30fe8aab07b5edd0d206728c57509d47b1f6"
+ "tag": "v0.8.3",
+ "commit": "48222bc964338c0291c21bbdf92a1b1d3d30b589"
},
"_source": "git://github.com/PolymerElements/paper-drawer-panel.git",
"_target": "^0.8.0",
diff --git a/third_party/polymer/v0_8/components/paper-drawer-panel/paper-drawer-panel.html b/third_party/polymer/v0_8/components/paper-drawer-panel/paper-drawer-panel.html
index d7d930c..20eac7e 100644
--- a/third_party/polymer/v0_8/components/paper-drawer-panel/paper-drawer-panel.html
+++ b/third_party/polymer/v0_8/components/paper-drawer-panel/paper-drawer-panel.html
@@ -283,9 +283,8 @@ To position the drawer to the right, add `rightDrawer` attribute.
/**
* Fired when the narrow layout changes.
*
- * @event paper-responsive-change
- * @param {Object} detail
- * @param {boolean} detail.narrow true if the panel is in narrow layout.
+ * @event paper-responsive-change {{narrow: boolean}} detail -
+ * narrow: true if the panel is in narrow layout.
*/
/**
@@ -295,10 +294,9 @@ To position the drawer to the right, add `rightDrawer` attribute.
* This event is fired both when a panel is selected and deselected.
* The `isSelected` detail property contains the selection state.
*
- * @event paper-select
- * @param {Object} detail
- * @param {boolean} detail.isSelected true for selection and false for deselection
- * @param {Object} detail.item the panel that the event refers to
+ * @event paper-select {{isSelected: boolean, item: Object}} detail -
+ * isSelected: True for selection and false for deselection.
+ * item: The panel that the event refers to.
*/
properties: {
@@ -336,6 +334,7 @@ To position the drawer to the right, add `rightDrawer` attribute.
// Whether the user is dragging the drawer interactively.
dragging: {
+ type: Boolean,
value: false
},
@@ -354,6 +353,7 @@ To position the drawer to the right, add `rightDrawer` attribute.
// How many pixels on the side of the screen are sensitive to edge
// swipes and peek.
edgeSwipeSensitivity: {
+ type: Number,
value: 30
},
@@ -372,6 +372,7 @@ To position the drawer to the right, add `rightDrawer` attribute.
// Whether the browser has support for the transform CSS property.
hasTransform: {
+ type: Boolean,
value: function() {
return 'transform' in this.style;
}
@@ -379,6 +380,7 @@ To position the drawer to the right, add `rightDrawer` attribute.
// Whether the browser has support for the will-change CSS property.
hasWillChange: {
+ type: Boolean,
value: function() {
return 'willChange' in this.style;
}
@@ -399,7 +401,10 @@ To position the drawer to the right, add `rightDrawer` attribute.
},
// Whether the drawer is peeking out from the edge.
- peeking: false,
+ peeking: {
+ type: Boolean,
+ value: false
+ },
/**
* Max-width when the panel changes to narrow layout.
@@ -444,19 +449,25 @@ To position the drawer to the right, add `rightDrawer` attribute.
* automatically be hidden in wide layout.
*/
drawerToggleAttribute: {
+ type: String,
value: 'paper-drawer-toggle'
},
/**
* Whether the transition is enabled.
*/
- transition: false,
+ transition: {
+ type: Boolean,
+ value: false
+ },
/**
* Starting X coordinate of a tracking gesture. It is non-null only between trackStart and
* trackEnd events.
+ * @type {?number}
*/
_startX: {
+ type: Number,
value: null
}
diff --git a/third_party/polymer/v0_8/components/paper-input/.bower.json b/third_party/polymer/v0_8/components/paper-input/.bower.json
index 9b2481a..7309e73 100644
--- a/third_party/polymer/v0_8/components/paper-input/.bower.json
+++ b/third_party/polymer/v0_8/components/paper-input/.bower.json
@@ -1,6 +1,6 @@
{
"name": "paper-input",
- "version": "0.8.1",
+ "version": "0.8.2",
"authors": [
"The Polymer Authors"
],
@@ -32,11 +32,11 @@
"web-component-tester": "Polymer/web-component-tester#^2.2.3",
"webcomponentsjs": "Polymer/webcomponentsjs#^0.6.0"
},
- "_release": "0.8.1",
+ "_release": "0.8.2",
"_resolution": {
"type": "version",
- "tag": "v0.8.1",
- "commit": "a761e0a4f9abac125d7c150e71633fd6bdc07616"
+ "tag": "v0.8.2",
+ "commit": "59028225a51c6add666503f73a32f7e2e30491e4"
},
"_source": "git://github.com/PolymerElements/paper-input.git",
"_target": "^0.8.0",
diff --git a/third_party/polymer/v0_8/components/paper-input/paper-input-behavior.html b/third_party/polymer/v0_8/components/paper-input/paper-input-behavior.html
new file mode 100644
index 0000000..50c5cb0
--- /dev/null
+++ b/third_party/polymer/v0_8/components/paper-input/paper-input-behavior.html
@@ -0,0 +1,123 @@
+<!--
+@license
+Copyright (c) 2015 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
+-->
+<link rel="import" href="../polymer/polymer.html">
+
+<!--
+Use `Polymer.PaperInputBehavior` to implement your own `<paper-input>`.
+-->
+
+<script>
+
+ Polymer.PaperInputBehavior = {
+
+ properties: {
+
+ /**
+ * The label for this input.
+ */
+ label: {
+ type: String
+ },
+
+ /**
+ * The value for this input.
+ */
+ value: {
+ notify: true,
+ type: String
+ },
+
+ /**
+ * Set to true to disable this input.
+ */
+ disabled: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * Set to true to prevent the user from entering invalid input.
+ */
+ preventInvalidInput: {
+ type: Boolean
+ },
+
+ /**
+ * The type of the input. The supported types are `text`, `number` and `password`.
+ */
+ type: {
+ type: String
+ },
+
+ /**
+ * A pattern to validate the `input` with.
+ */
+ pattern: {
+ type: String
+ },
+
+ /**
+ * Set to true to mark the input as required.
+ */
+ required: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * The maximum length of the input value.
+ */
+ maxlength: {
+ type: Number
+ },
+
+ /**
+ * The error message to display when the input is invalid.
+ */
+ errorMessage: {
+ type: String
+ },
+
+ /**
+ * Set to true to show a character counter.
+ */
+ charCounter: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * Set to true to disable the floating label.
+ */
+ noLabelFloat: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * Set to true to auto-validate the input value.
+ */
+ autoValidate: {
+ type: Boolean,
+ value: false
+ }
+
+ },
+
+ /**
+ * Returns a reference to the input element.
+ */
+ get inputElement() {
+ return this.$.input;
+ }
+
+ };
+
+</script>
diff --git a/third_party/polymer/v0_8/components/paper-input/paper-input-container.html b/third_party/polymer/v0_8/components/paper-input/paper-input-container.html
index 92e0b99..3137d6b 100644
--- a/third_party/polymer/v0_8/components/paper-input/paper-input-container.html
+++ b/third_party/polymer/v0_8/components/paper-input/paper-input-container.html
@@ -51,6 +51,11 @@ For example:
--mixin(--paper-input-container);
}
+ :host([disabled]) {
+ pointer-events: none;
+ opacity: 0.33;
+ }
+
.floated-label-placeholder {
mixin(--paper-input-container-label-font);
}
@@ -91,6 +96,12 @@ For example:
background: var(--paper-input-container-color);
}
+ :host([disabled]) .unfocused-line {
+ border-bottom: 1px dashed;
+ border-color: var(--paper-input-container-color);
+ background: transparent;
+ }
+
.input-content ::content label,
.input-content ::content .paper-input-label {
position: absolute;
@@ -166,6 +177,11 @@ For example:
color: var(--paper-input-container-focus-color);
}
+ .input-content,
+ .underline {
+ position: relative;
+ }
+
</style>
<template>
@@ -353,7 +369,7 @@ For example:
},
_computeInputContentClass: function(noLabelFloat, focused, _inputHasContent, _inputIsInvalid) {
- var cls = 'input-content relative';
+ var cls = 'input-content';
if (!noLabelFloat) {
if (_inputHasContent) {
cls += ' label-is-floating';
@@ -372,7 +388,7 @@ For example:
},
_computeUnderlineClass: function(focused, _inputIsInvalid) {
- var cls = 'relative';
+ var cls = 'underline';
if (_inputIsInvalid) {
cls += ' is-invalid';
} else if (focused) {
diff --git a/third_party/polymer/v0_8/components/paper-input/paper-input.html b/third_party/polymer/v0_8/components/paper-input/paper-input.html
index 3f80d21..c6ebb25 100644
--- a/third_party/polymer/v0_8/components/paper-input/paper-input.html
+++ b/third_party/polymer/v0_8/components/paper-input/paper-input.html
@@ -9,6 +9,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
-->
<link rel="import" href="../polymer/polymer.html">
<link rel="import" href="../iron-input/iron-input.html">
+<link rel="import" href="paper-input-behavior.html">
<link rel="import" href="paper-input-container.html">
<link rel="import" href="paper-input-error.html">
<link rel="import" href="paper-input-char-counter.html">
@@ -21,13 +22,13 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
<template>
- <paper-input-container no-label-float$="[[noLabelFloat]]" auto-validate$="[[autoValidate]]">
+ <paper-input-container no-label-float$="[[noLabelFloat]]" auto-validate$="[[autoValidate]]" disabled$="[[disabled]]">
<template is="x-if" if="[[label]]">
<label>[[parent.label]]</label>
</template>
- <input is="iron-input" id="input" bind-value="{{value}}" prevent-invalid-input="[[preventInvalidInput]]" type$="[[type]]" pattern$="[[pattern]]" maxlength$="[[maxlength]]" required$="[[required]]">
+ <input is="iron-input" id="input" bind-value="{{value}}" prevent-invalid-input="[[preventInvalidInput]]" type$="[[type]]" pattern$="[[pattern]]" maxlength$="[[maxlength]]" required$="[[required]]" disabled$="[[disabled]]">
<template is="x-if" if="[[errorMessage]]">
<paper-input-error>[[parent.errorMessage]]</paper-input-error>
@@ -51,98 +52,9 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
is: 'paper-input',
- properties: {
-
- /**
- * The label for this input.
- */
- label: {
- type: String
- },
-
- /**
- * The value for this input.
- */
- value: {
- notify: true,
- type: String
- },
-
- /**
- * Set to true to prevent the user from entering invalid input.
- */
- preventInvalidInput: {
- type: Boolean
- },
-
- /**
- * The type of the input. The supported types are `text`, `number` and `password`.
- */
- type: {
- type: String
- },
-
- /**
- * A pattern to validate the `input` with.
- */
- pattern: {
- type: String
- },
-
- /**
- * Set to true to mark the input as required.
- */
- required: {
- type: Boolean,
- value: false
- },
-
- /**
- * The maximum length of the input value.
- */
- maxlength: {
- type: Number
- },
-
- /**
- * The error message to display when the input is invalid.
- */
- errorMessage: {
- type: String
- },
-
- /**
- * Set to true to show a character counter.
- */
- charCounter: {
- type: Boolean,
- value: false
- },
-
- /**
- * Set to true to disable the floating label.
- */
- noLabelFloat: {
- type: Boolean,
- value: false
- },
-
- /**
- * Set to true to auto-validate the input value.
- */
- autoValidate: {
- type: Boolean,
- value: false
- }
-
- },
-
- /**
- * Returns a reference to the input element.
- */
- get inputElement() {
- return this.$.input;
- }
+ behaviors: [
+ Polymer.PaperInputBehavior
+ ]
})
diff --git a/third_party/polymer/v0_8/components/paper-ripple/.bower.json b/third_party/polymer/v0_8/components/paper-ripple/.bower.json
index 62815ae..1194843 100644
--- a/third_party/polymer/v0_8/components/paper-ripple/.bower.json
+++ b/third_party/polymer/v0_8/components/paper-ripple/.bower.json
@@ -1,5 +1,6 @@
{
"name": "paper-ripple",
+ "version": "0.8.3",
"private": true,
"dependencies": {
"polymer": "polymer/polymer#v0.8.0-rc.7"
@@ -14,12 +15,11 @@
"web-component-tester": "~2.2.3"
},
"homepage": "https://github.com/PolymerElements/paper-ripple",
- "version": "0.8.2",
- "_release": "0.8.2",
+ "_release": "0.8.3",
"_resolution": {
"type": "version",
- "tag": "v0.8.2",
- "commit": "7f1399055ff05cc37e3b577d97d00d664816e1d2"
+ "tag": "v0.8.3",
+ "commit": "dae4d3e1df6748aed651dfa2012121674d0b6b05"
},
"_source": "git://github.com/PolymerElements/paper-ripple.git",
"_target": "^0.8.0",
diff --git a/third_party/polymer/v0_8/components/paper-ripple/bower.json b/third_party/polymer/v0_8/components/paper-ripple/bower.json
index 5e261d5..5009035 100644
--- a/third_party/polymer/v0_8/components/paper-ripple/bower.json
+++ b/third_party/polymer/v0_8/components/paper-ripple/bower.json
@@ -1,5 +1,6 @@
{
"name": "paper-ripple",
+ "version": "0.8.3",
"private": true,
"dependencies": {
"polymer": "polymer/polymer#v0.8.0-rc.7"
diff --git a/third_party/polymer/v0_8/components/paper-ripple/paper-ripple.html b/third_party/polymer/v0_8/components/paper-ripple/paper-ripple.html
index 3b0f24b..91cac4c 100644
--- a/third_party/polymer/v0_8/components/paper-ripple/paper-ripple.html
+++ b/third_party/polymer/v0_8/components/paper-ripple/paper-ripple.html
@@ -16,21 +16,21 @@ Example:
<paper-ripple></paper-ripple>
-`paper-ripple` listens to "down" and "up" events so it would display ripple
+`paper-ripple` listens to "mousedown" and "mouseup" events so it would display ripple
effect when touches on it. You can also defeat the default behavior and
manually route the down and up actions to the ripple element. Note that it is
-important if you call downAction() you will have to make sure to call upAction()
-so that `paper-ripple` would end the animation loop.
+important if you call mousedownAction() you will have to make sure to call
+mouseupAction() so that `paper-ripple` would end the animation loop.
Example:
<paper-ripple id="ripple" style="pointer-events: none;"></paper-ripple>
...
downAction: function(e) {
- this.$.ripple.downAction({x: e.x, y: e.y});
+ this.$.ripple.mousedownAction({x: e.x, y: e.y});
},
upAction: function(e) {
- this.$.ripple.upAction();
+ this.$.ripple.mouseupAction();
}
Styling ripple effect:
@@ -84,7 +84,7 @@ animation finishes to perform some action.
/* This resolves a rendering issue in Chrome 40 where the
ripple is not properly clipped by its parent (which may have
rounded corners. See: http://jsbin.com/temexa/4 */
- -webkit-transform: translate3d(0, 0, 0);
+ -webkit-transform: translate(0, 0);
transform: translate3d(0, 0, 0);
}
@@ -366,10 +366,11 @@ animation finishes to perform some action.
dx = this.xNow - (this.containerMetrics.width / 2);
dy = this.yNow - (this.containerMetrics.height / 2);
- Polymer.Base.translate3d(this.waveContainer, dx + 'px', dy + 'px', 0);
// 2d transform for safari because of border-radius and overflow:hidden clipping bug.
// https://bugs.webkit.org/show_bug.cgi?id=98538
+ this.waveContainer.style.webkitTransform = 'translate(' + dx + 'px, ' + dy + 'px)';
+ this.waveContainer.style.transform = 'translate3d(' + dx + 'px, ' + dy + 'px, 0)';
this.wave.style.webkitTransform = 'scale(' + scale + ',' + scale + ')';
this.wave.style.transform = 'scale3d(' + scale + ',' + scale + ',1)';
},
@@ -617,4 +618,3 @@ animation finishes to perform some action.
});
})();
</script>
-
diff --git a/third_party/polymer/v0_8/reproduce.sh b/third_party/polymer/v0_8/reproduce.sh
index 4f47685..9c72cf8 100755
--- a/third_party/polymer/v0_8/reproduce.sh
+++ b/third_party/polymer/v0_8/reproduce.sh
@@ -26,6 +26,7 @@ rm -rf components/{iron-component-page,webcomponentsjs}
# Test and demo directories aren't needed.
rm -rf components/*/{test,demo}
rm -rf components/polymer/explainer
+rm -rf components/observe-js/{examples,conf,benchmark}
# Make checkperms.py happy.
find components/iron-selector -type f -exec chmod -x {} \;