Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(31)

Unified Diff: third_party/polymer/v0_8/components-chromium/polymer/src/standard/notify-path-extracted.js

Issue 1082403004: Import Polymer 0.8 and several key elements. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Also remove polymer/explainer Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/polymer/v0_8/components-chromium/polymer/src/standard/notify-path-extracted.js
diff --git a/third_party/polymer/v0_8/components-chromium/polymer/src/standard/notify-path-extracted.js b/third_party/polymer/v0_8/components-chromium/polymer/src/standard/notify-path-extracted.js
new file mode 100644
index 0000000000000000000000000000000000000000..2dc890ccfc571124dae945225bf2df9caab5ea2e
--- /dev/null
+++ b/third_party/polymer/v0_8/components-chromium/polymer/src/standard/notify-path-extracted.js
@@ -0,0 +1,240 @@
+
+
+ /**
+ * Changes to an object sub-field (aka "path") via a binding
+ * (e.g. `<x-foo value="{{item.subfield}}"`) will notify other elements bound to
+ * the same object automatically.
+ *
+ * When modifying a sub-field of an object imperatively
+ * (e.g. `this.item.subfield = 42`), in order to have the new value propagated
+ * to other elements, a special `setPathValue(path, value)` API is provided.
+ * `setPathValue` sets the object field at the path specified, and then notifies the
+ * binding system so that other elements bound to the same path will update.
+ *
+ * Example:
+ *
+ * Polymer({
+ *
+ * is: 'x-date',
+ *
+ * properties: {
+ * date: {
+ * type: Object,
+ * notify: true
+ * }
+ * },
+ *
+ * attached: function() {
+ * this.date = {};
+ * setInterval(function() {
+ * var d = new Date();
+ * // Required to notify elements bound to date of changes to sub-fields
+ * // this.date.seconds = d.getSeconds(); <-- Will not notify
+ * this.setPathValue('date.seconds', d.getSeconds());
+ * this.setPathValue('date.minutes', d.getMinutes());
+ * this.setPathValue('date.hours', d.getHours() % 12);
+ * }.bind(this), 1000);
+ * }
+ *
+ * });
+ *
+ * Allows bindings to `date` sub-fields to update on changes:
+ *
+ * <x-date date="{{date}}"></x-date>
+ *
+ * Hour: <span>{{date.hours}}</span>
+ * Min: <span>{{date.minutes}}</span>
+ * Sec: <span>{{date.seconds}}</span>
+ *
+ * @class data feature: path notification
+ */
+
+ Polymer.Base._addFeature({
+ /**
+ Notify that a path has changed. For example:
+
+ this.item.user.name = 'Bob';
+ this.notifyPath('item.user.name', this.item.user.name);
+
+ Returns true if notification actually took place, based on
+ a dirty check of whether the new value was already known
+ */
+ notifyPath: function(path, value, fromAbove) {
+ var old = this._propertySet(path, value);
+ // manual dirty checking for now...
+ if (old !== value) {
+ // console.group((this.localName || this.dataHost.id + '-' + this.dataHost.dataHost.index) + '#' + (this.id || this.index) + ' ' + path, value);
+ // Take path effects at this level for exact path matches,
+ // and notify down for any bindings to a subset of this path
+ this._pathEffector(path, value);
+ // Send event to notify the path change upwards
+ // Optimization: don't notify up if we know the notification
+ // is coming from above already (avoid wasted event dispatch)
+ if (!fromAbove) {
+ // TODO(sorvell): should only notify if notify: true?
+ this._notifyPath(path, value);
+ }
+ // console.groupEnd((this.localName || this.dataHost.id + '-' + this.dataHost.dataHost.index) + '#' + (this.id || this.index) + ' ' + path, value);
+ }
+ },
+
+ /**
+ Convienence method for setting a value to a path and calling
+ notify path
+ */
+ setPathValue: function(path, value) {
+ var parts = path.split('.');
+ if (parts.length > 1) {
+ var last = parts.pop();
+ var prop = this;
+ while (parts.length) {
+ prop = prop[parts.shift()];
+ if (!prop) {
+ return;
+ }
+ }
+ // TODO(kschaaf): want dirty-check here?
+ // if (prop[last] !== value) {
+ prop[last] = value;
+ this.notifyPath(path, value);
+ // }
+ } else {
+ this[path] = value;
+ }
+ },
+
+ getPathValue: function(path, root) {
+ var parts = path.split('.');
+ var last = parts.pop();
+ var prop = root || this;
+ while (parts.length) {
+ prop = prop[parts.shift()];
+ if (!prop) {
+ return;
+ }
+ }
+ return prop[last];
+ },
+
+ // TODO(kschaaf): This machine can be optimized to memoize compiled path
+ // effectors as new paths are notified for performance, since it involves
+ // a fair amount of runtime lookup
+ _pathEffector: function(path, value) {
+ // get root property
+ var model = this._modelForPath(path);
+ // search property effects of the root property for 'annotation' effects
+ var fx$ = this._propertyEffects[model];
+ if (fx$) {
+ fx$.forEach(function(fx) {
+ var fxFn = this[fx.kind + 'PathEffect'];
+ if (fxFn) {
+ fxFn.call(this, path, value, fx.effect);
+ }
+ }, this);
+ }
+ // notify runtime-bound paths
+ if (this._boundPaths) {
+ this._notifyBoundPaths(path, value);
+ }
+ },
+
+ annotationPathEffect: function(path, value, effect) {
+ if (effect.value === path || effect.value.indexOf(path + '.') === 0) {
+ // TODO(sorvell): ideally the effect function is on this prototype
+ // so we don't have to call it like this.
+ Polymer.Bind.annotationEffect.call(this, path, value, effect);
+ } else if ((path.indexOf(effect.value + '.') === 0) && !effect.negate) {
+ // locate the bound node
+ var node = this._nodes[effect.index];
+ if (node && node.notifyPath) {
+ var p = this._fixPath(effect.name , effect.value, path);
+ node.notifyPath(p, value, true);
+ }
+ }
+ },
+
+ complexObserverPathEffect: function(path, value, effect) {
+ if (this._pathMatchesEffect(path, effect)) {
+ Polymer.Bind.complexObserverEffect.call(this, path, value, effect);
+ }
+ },
+
+ computePathEffect: function(path, value, effect) {
+ if (this._pathMatchesEffect(path, effect)) {
+ Polymer.Bind.computeEffect.call(this, path, value, effect);
+ }
+ },
+
+ annotatedComputationPathEffect: function(path, value, effect) {
+ if (this._pathMatchesEffect(path, effect)) {
+ Polymer.Bind.annotatedComputationEffect.call(this, path, value, effect);
+ }
+ },
+
+ _pathMatchesEffect: function(path, effect) {
+ var effectArg = effect.arg.name;
+ return (effectArg == path) ||
+ (effectArg.indexOf(path + '.') === 0) ||
+ (effect.arg.wildcard && path.indexOf(effectArg) === 0);
+ },
+
+ bindPaths: function(to, from) {
+ this._boundPaths = this._boundPaths || {};
+ if (from) {
+ this._boundPaths[to] = from;
+ // this.setPathValue(to, this.getPathValue(from));
+ } else {
+ this.unbindPath(to);
+ // this.setPathValue(to, from);
+ }
+ },
+
+ unbindPaths: function(path) {
+ if (this._boundPaths) {
+ delete this._boundPaths[path];
+ }
+ },
+
+ _notifyBoundPaths: function(path, value) {
+ var from, to;
+ for (var a in this._boundPaths) {
+ var b = this._boundPaths[a];
+ if (path.indexOf(a + '.') == 0) {
+ from = a;
+ to = b;
+ break;
+ }
+ if (path.indexOf(b + '.') == 0) {
+ from = b;
+ to = a;
+ break;
+ }
+ }
+ if (from && to) {
+ var p = this._fixPath(to, from, path);
+ this.notifyPath(p, value);
+ }
+ },
+
+ _fixPath: function(property, root, path) {
+ return property + path.slice(root.length);
+ },
+
+ _notifyPath: function(path, value) {
+ var rootName = this._modelForPath(path);
+ var dashCaseName = Polymer.CaseMap.camelToDashCase(rootName);
+ var eventName = dashCaseName + this._EVENT_CHANGED;
+ this.fire(eventName, {
+ path: path,
+ value: value
+ }, {bubbles: false});
+ },
+
+ _modelForPath: function(path) {
+ return path.split('.').shift();
+ },
+
+ _EVENT_CHANGED: '-changed',
+
+ });
+

Powered by Google App Engine
This is Rietveld 408576698