readOnly & observer effects (no compat yet)

This commit is contained in:
Kevin Schaaf
2016-02-17 19:19:06 -08:00
parent bdd7d85720
commit 5a5422e93c
3 changed files with 196 additions and 1 deletions

View File

@@ -4,7 +4,8 @@
"no-console": 0
},
"env": {
"browser": true
"browser": true,
"es6": true
},
"plugins": [
"html"

View File

@@ -0,0 +1,107 @@
<!--
@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
-->
<script>
(function() {
'use strict';
var Properties = {
createReadOnlyProperty: function(model, property) {
this._ensureAccessor(model, property, true);
},
createObserver: function(model, property, methodName, context) {
var effects = this._ensureAccessor(model, property);
effects.push({
fn: this._runObserver,
info: {
methodName: methodName,
context: context || model
}
});
},
_runObserver: function(property, value, old, info) {
var fn = info.context[info.methodName];
if (fn) {
fn.call(info.context, value, old);
} else {
// this._warn(this._logf('_observerEffect', 'observer method `' +
// effect.method + '` not defined'));
}
},
_ensureAccessor: function(model, property, readOnly) {
if (!model._propertyEffects) {
model._propertyEffects = {};
}
var effects = model._propertyEffects[property];
if (!effects) {
effects = model._propertyEffects[property] = [];
this._createAccessor(model, property, readOnly, effects);
}
return effects;
},
_createAccessor: function(model, property, readOnly, effects) {
var self = this;
var defun = {
get: function() {
// TODO(sjmiles): elide delegation for performance, good ROI?
return model.__data__[property];
}
};
var setter = function(value) {
self._propertySetter(property, value, effects);
};
if (readOnly) {
model['_set' + this._upper(property)] = setter;
} else {
defun.set = setter;
}
Object.defineProperty(model, property, defun);
},
_upper: function(name) {
return name[0].toUpperCase() + name.substring(1);
},
_propertySetter: function(property, value, effects, fromAbove) {
if (!this.__data__) {
this.__data__ = {};
}
var old = this.__data__[property];
if (this.isPropertyDirty(value, old)) {
this.__data__[property] = value;
if (effects) {
this._runEffects(property, value, old, effects, fromAbove);
}
}
return old;
},
_runEffects: function(property, value, old, effects, fromAbove) {
for (var i=0, l=effects.length, fx; (i<l) && (fx=effects[i]); i++) {
fx.fn.call(this, property, value, old, fx.info, fromAbove);
}
},
isPropertyDirty: function(value, old) {
return (old !== value && (old === old || value === value));
}
};
// export
Polymer.Properties = Properties;
})();
</script>

View File

@@ -0,0 +1,87 @@
<!doctype html>
<!--
@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
-->
<html>
<head>
<title>Polymer - template</title>
<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="../../src/utils/boot.html">
<link rel="import" href="../../src/properties/properties.html">
</head>
<body>
<template id="x-template">
<style>
:host {
display: block;
background: beige;
padding: 8px;
}
</style>
<div id="content" on-tap="_tap">I was stamped from x-base template (click me)!</div>
<template id="subTemplate">sub</template>
</template>
<script>
(function() {
'use strict';
// var template = document.querySelector('template#x-template');
// var notes = Polymer.Annotations.parseAnnotations(template);
class XProperties extends HTMLElement {
createdCallback() {
// var dom = document.importNode(template.content, true);
// this.attachShadow({mode: 'open'}).appendChild(dom);
// Polymer.Bindings.setupBindings(dom, notes);
}
zizChanged(value, old) {
console.log('ziz', value, old);
}
fooChanged(value, old) {
console.log('foo', value, old);
}
}
Polymer.Properties.createReadOnlyProperty(XProperties.prototype, 'ziz');
Polymer.Properties.createObserver(XProperties.prototype, 'ziz',
'zizChanged');
Polymer.Properties.createObserver(XProperties.prototype, 'foo',
'fooChanged');
// Polymer.Properties.createComputedProperty(XProperties.prototype, 'bar',
// 'computeBar(foo, zot)');
// Polymer.Properties.createNotifyProperty(XProperties.prototype, 'zot');
// Polymer.Bindings.createBindings(XProperties.prototype, notes);
document.registerElement('x-properties', XProperties);
})();
</script>
<x-properties id="el"></x-properties>
<script>
var el = document.getElementById('el');
el.foo = 'foo';
el._setZiz('ziz');
</script>
</body>
</html>