mirror of
https://github.com/Polymer/polymer.git
synced 2026-08-19 01:14:44 -05:00
- actually iterate behaviors in reverse order for mixing in
- iterate `behaviors` in natural order for prepping - aggregate hostAttributes at prep-time for proper override behavior - fix/add tests - remove vestigial mixins.html file
This commit is contained in:
+10
-6
@@ -23,6 +23,8 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
_registerFeatures: function() {
|
||||
// identity
|
||||
this._prepIs();
|
||||
// attributes
|
||||
this._prepAttributes();
|
||||
// shared behaviors
|
||||
this._prepBehaviors();
|
||||
// inheritance
|
||||
@@ -31,18 +33,20 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
this._prepConstructor();
|
||||
},
|
||||
|
||||
_prepBehavior: function() {},
|
||||
_prepBehavior: function(b) {
|
||||
this._addHostAttributes(b.hostAttributes);
|
||||
},
|
||||
|
||||
_marshalBehavior: function(b) {
|
||||
},
|
||||
|
||||
_initFeatures: function() {
|
||||
// install host attributes
|
||||
this._marshalHostAttributes();
|
||||
// setup debouncers
|
||||
this._setupDebouncers();
|
||||
// acquire behaviors
|
||||
this._marshalBehaviors();
|
||||
},
|
||||
|
||||
_marshalBehavior: function(b) {
|
||||
// publish attributes to instance
|
||||
this._installHostAttributes(b.hostAttributes);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
+7
-3
@@ -24,6 +24,8 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
_registerFeatures: function() {
|
||||
// identity
|
||||
this._prepIs();
|
||||
// attributes
|
||||
this._prepAttributes();
|
||||
// shared behaviors
|
||||
this._prepBehaviors();
|
||||
// inheritance
|
||||
@@ -36,7 +38,9 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
this._prepShady();
|
||||
},
|
||||
|
||||
_prepBehavior: function() {},
|
||||
_prepBehavior: function(b) {
|
||||
this._addHostAttributes(b.hostAttributes);
|
||||
},
|
||||
|
||||
_initFeatures: function() {
|
||||
// manage local dom
|
||||
@@ -47,6 +51,8 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
this._stampTemplate();
|
||||
// host stack
|
||||
this._popHost();
|
||||
// install host attributes
|
||||
this._marshalHostAttributes();
|
||||
// setup debouncers
|
||||
this._setupDebouncers();
|
||||
// instance shared behaviors
|
||||
@@ -56,8 +62,6 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
},
|
||||
|
||||
_marshalBehavior: function(b) {
|
||||
// publish attributes to instance
|
||||
this._installHostAttributes(b.hostAttributes);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
+6
-3
@@ -28,6 +28,8 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
_registerFeatures: function() {
|
||||
// identity
|
||||
this._prepIs();
|
||||
// attributes
|
||||
this._prepAttributes();
|
||||
// inheritance
|
||||
this._prepExtends();
|
||||
// factory
|
||||
@@ -51,8 +53,9 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
},
|
||||
|
||||
_prepBehavior: function(b) {
|
||||
this._addPropertyEffects(b.properties || b.accessors);
|
||||
this._addPropertyEffects(b.properties);
|
||||
this._addComplexObserverEffects(b.observers);
|
||||
this._addHostAttributes(b.hostAttributes);
|
||||
},
|
||||
|
||||
_initFeatures: function() {
|
||||
@@ -70,6 +73,8 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
this._popHost();
|
||||
// concretize template references
|
||||
this._marshalAnnotationReferences();
|
||||
// install host attributes
|
||||
this._marshalHostAttributes();
|
||||
// setup debouncers
|
||||
this._setupDebouncers();
|
||||
// concretize effects on instance
|
||||
@@ -83,8 +88,6 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
},
|
||||
|
||||
_marshalBehavior: function(b) {
|
||||
// publish attributes to instance
|
||||
this._installHostAttributes(b.hostAttributes);
|
||||
// establish listeners on instance
|
||||
this._listenListeners(b.listeners);
|
||||
}
|
||||
|
||||
@@ -60,21 +60,25 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
|
||||
Polymer.Base._addFeature({
|
||||
|
||||
_marshalAttributes: function() {
|
||||
this._takeAttributes();
|
||||
_prepAttributes: function() {
|
||||
this._aggregatedAttributes = {};
|
||||
},
|
||||
|
||||
_installHostAttributes: function(attributes) {
|
||||
_addHostAttributes: function(attributes) {
|
||||
if (attributes) {
|
||||
this._applyAttributes(this, attributes);
|
||||
this.mixin(this._aggregatedAttributes, attributes);
|
||||
}
|
||||
},
|
||||
|
||||
_marshalHostAttributes: function() {
|
||||
this._applyAttributes(this, this._aggregatedAttributes);
|
||||
},
|
||||
|
||||
/* apply attributes to node but avoid overriding existing values */
|
||||
_applyAttributes: function(node, attr$) {
|
||||
for (var n in attr$) {
|
||||
// NOTE: never allow 'class' to be set in hostAttributes
|
||||
// since shimming classes would make it work
|
||||
// since shimming classes would make it work
|
||||
// inconsisently under native SD
|
||||
if (!this.hasAttribute(n) && (n !== 'class')) {
|
||||
this.serializeValueToAttribute(attr$[n], n, this);
|
||||
@@ -82,7 +86,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
}
|
||||
},
|
||||
|
||||
_takeAttributes: function() {
|
||||
_marshalAttributes: function() {
|
||||
this._takeAttributesToModel(this);
|
||||
},
|
||||
|
||||
@@ -106,6 +110,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
},
|
||||
|
||||
_serializing: false,
|
||||
|
||||
reflectPropertyToAttribute: function(name) {
|
||||
this._serializing = true;
|
||||
this.serializeValueToAttribute(this[name],
|
||||
|
||||
+22
-16
@@ -46,7 +46,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
if (this.behaviors.length) {
|
||||
this.behaviors = this._flattenBehaviorsList(this.behaviors);
|
||||
}
|
||||
this._prepAllBehaviors();
|
||||
this._prepAllBehaviors(this.behaviors);
|
||||
},
|
||||
|
||||
_flattenBehaviorsList: function(behaviors) {
|
||||
@@ -54,36 +54,42 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
behaviors.forEach(function(b) {
|
||||
if (b instanceof Array) {
|
||||
flat = flat.concat(this._flattenBehaviorsList(b));
|
||||
} else {
|
||||
}
|
||||
// filter out null entries so other iterators don't need to check
|
||||
else if (b) {
|
||||
flat.push(b);
|
||||
} else {
|
||||
this._warn(this._logf('_flattenBehaviorsList', 'behavior is null, check for missing or 404 import'));
|
||||
}
|
||||
}, this);
|
||||
return flat;
|
||||
},
|
||||
|
||||
_prepAllBehaviors: function() {
|
||||
// filter so other iterators don't need null check
|
||||
this.behaviors = this.behaviors.filter(function(b) {
|
||||
if (b) {
|
||||
this._mixinBehavior(b);
|
||||
this._prepBehavior(b);
|
||||
return true;
|
||||
}
|
||||
this._warn(this._logf('_prepAllBehaviors', 'behavior is null, check for missing or 404 import'));
|
||||
}, this);
|
||||
_prepAllBehaviors: function(behaviors) {
|
||||
// traverse the behaviors in _reverse_ order (youngest first) because
|
||||
// `_mixinBehavior` has _first property wins_ behavior, this is done
|
||||
// to optimize # of calls to `_copyOwnProperty`
|
||||
for (var i=behaviors.length-1; i>=0; i--) {
|
||||
this._mixinBehavior(behaviors[i]);
|
||||
}
|
||||
// we iterate a second time so that `_prepBehavior` goes in natural order
|
||||
// otherwise, it's a tricky detail for implementors of `_prepBehavior`
|
||||
for (var i=0, l=behaviors.length; i<l; i++) {
|
||||
this._prepBehavior(behaviors[i]);
|
||||
}
|
||||
// prep our prototype-as-behavior
|
||||
this._prepBehavior(this);
|
||||
},
|
||||
|
||||
_mixinBehavior: function(b) {
|
||||
var names = Object.getOwnPropertyNames(b);
|
||||
for (var i=names.length-1, n; i >= 0 && (n=names[i]); i--) {
|
||||
Object.getOwnPropertyNames(b).forEach(function(n) {
|
||||
switch (n) {
|
||||
case 'hostAttributes':
|
||||
case 'registered':
|
||||
case 'properties':
|
||||
case 'observers':
|
||||
case 'listeners':
|
||||
case 'keyPresses':
|
||||
case 'hostAttributes':
|
||||
case 'created':
|
||||
case 'attached':
|
||||
case 'detached':
|
||||
@@ -97,7 +103,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}, this);
|
||||
},
|
||||
|
||||
_doBehavior: function(name, args) {
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
<!--
|
||||
@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>
|
||||
|
||||
/**
|
||||
* Automatically extend using objects referenced in `mixins` array.
|
||||
*
|
||||
* Polymer({
|
||||
*
|
||||
* mixins: [
|
||||
* someMixinObject
|
||||
* ]
|
||||
*
|
||||
* ...
|
||||
*
|
||||
* });
|
||||
*
|
||||
* @class base feature: mixins
|
||||
*/
|
||||
|
||||
Polymer.Base._addFeature({
|
||||
|
||||
_prepMixins: function() {
|
||||
if (this.mixins) {
|
||||
this.mixins.forEach(function(m) {
|
||||
Polymer.Base.extend(this, m);
|
||||
}, this);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
@@ -35,7 +35,13 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
hasBehaviorA: {
|
||||
value: true
|
||||
}
|
||||
},
|
||||
|
||||
_simpleProperty: 'A',
|
||||
|
||||
hostAttributes: {
|
||||
behavior: 'A',
|
||||
user: 'A'
|
||||
},
|
||||
|
||||
listeners: {
|
||||
@@ -84,10 +90,17 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
|
||||
overridablePropertyB: {
|
||||
value: true
|
||||
}
|
||||
},
|
||||
|
||||
},
|
||||
|
||||
hostAttributes: {
|
||||
behavior: 'B',
|
||||
user: 'B'
|
||||
},
|
||||
|
||||
_simpleProperty: 'B',
|
||||
|
||||
_disabledChanged: function(disabled) {
|
||||
this.__disabled = disabled
|
||||
},
|
||||
@@ -126,6 +139,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
|
||||
behaviors: [
|
||||
Polymer.BehaviorA,
|
||||
null,
|
||||
Polymer.BehaviorB
|
||||
],
|
||||
|
||||
@@ -166,7 +180,9 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
value: true
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
_simpleProperty: 'C'
|
||||
|
||||
};
|
||||
|
||||
@@ -178,7 +194,9 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
value: true
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
_simpleProperty: 'D'
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -59,7 +59,9 @@ suite('multi-behaviors element', function() {
|
||||
var el;
|
||||
|
||||
setup(function() {
|
||||
el = document.createElement('multi-behaviors');
|
||||
var div = document.createElement('div');
|
||||
div.innerHTML = '<multi-behaviors user="user"></multi-behaviors>';
|
||||
el = div.firstElementChild;
|
||||
document.body.appendChild(el);
|
||||
});
|
||||
|
||||
@@ -103,15 +105,21 @@ suite('multi-behaviors element', function() {
|
||||
assert.equal(typeof el._setHasOptionsB, 'function');
|
||||
});
|
||||
|
||||
test('behavior overrides are last', function() {
|
||||
test('multi-behavior overrides ordering', function() {
|
||||
assert.equal(el._toOverride, Polymer._toOverride, 'Behavior method was not overridden by prototype');
|
||||
assert(el.overridableProperty, 'Behavior property was not overridden by prototype');
|
||||
assert(el.overridablePropertyB, 'Behavior property was not overridden by sub-behavior');
|
||||
assert(el.overridablePropertyB, 'Behavior config-property was not overridden by sub-behavior');
|
||||
});
|
||||
|
||||
test('hostAttributes ordering', function() {
|
||||
assert.equal(el.attributes.behavior.value, 'B', 'Behavior hostAttribute not overridden by subclass');
|
||||
assert.equal(el.attributes.user.value, 'user', 'Behavior hostAttribute overrode user attribute');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
suite('nexted-behaviors element', function() {
|
||||
suite('nested-behaviors element', function() {
|
||||
|
||||
var el;
|
||||
|
||||
@@ -124,11 +132,12 @@ suite('nexted-behaviors element', function() {
|
||||
document.body.removeChild(el);
|
||||
});
|
||||
|
||||
test('properties from nested behaviors', function() {
|
||||
test('nested-behavior overrides ordering', function() {
|
||||
assert.ok(el.hasBehaviorA, "missing BehaviorA");
|
||||
assert.ok(el.hasBehaviorB, "missing BehaviorB");
|
||||
assert.ok(el.hasBehaviorC, "missing BehaviorC");
|
||||
assert.ok(el.hasBehaviorD, "missing BehaviorD");
|
||||
assert.equal(el._simpleProperty, 'D', 'Behavior simple property was not overridden by sub-behavior');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user