mirror of
https://github.com/Polymer/polymer.git
synced 2025-02-25 18:55:30 -06:00
Replace _compoundInitializationEffect with statically-initialized literals in the template for attributes & textContent, and by configuring literal values of properties in _configureAnnotationReferences.
This commit is contained in:
@@ -154,9 +154,12 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
_parseTextNodeAnnotation: function(node, list) {
|
||||
var parts = this._parseBindings(node.textContent);
|
||||
if (parts) {
|
||||
// NOTE: use a space here so the textNode remains; some browsers
|
||||
// (IE) evacipate an empty textNode.
|
||||
node.textContent = ' ';
|
||||
// Initialize the textContent with any literal parts
|
||||
// NOTE: default to a space here so the textNode remains; some browsers
|
||||
// (IE) evacipate an empty textNode following cloneNode/importNode.
|
||||
node.textContent = parts.map(function(part) {
|
||||
return part.literal;
|
||||
}).join('') || ' ';
|
||||
var annote = {
|
||||
bindings: [{
|
||||
kind: 'text',
|
||||
@@ -291,6 +294,13 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
name = name.slice(0, -1);
|
||||
kind = 'attribute';
|
||||
}
|
||||
// Initialize attribute bindings with any literal parts
|
||||
var literal = parts.map(function(part) {
|
||||
return part.literal;
|
||||
}).join('');
|
||||
if (kind == 'attribute') {
|
||||
node.setAttribute(name, literal);
|
||||
}
|
||||
// Clear attribute before removing, since IE won't allow removing
|
||||
// `value` attribute if it previously had a value (can't
|
||||
// unconditionally set '' before removing since attributes with `$`
|
||||
@@ -311,6 +321,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
kind: kind,
|
||||
name: name,
|
||||
parts: parts,
|
||||
literal: literal,
|
||||
isCompound: parts.length !== 1
|
||||
};
|
||||
}
|
||||
|
||||
@@ -21,10 +21,6 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
!effect.parts[0].negate;
|
||||
},
|
||||
|
||||
_compoundInitializationEffect: function(source, value, effect) {
|
||||
this._applyEffectValue(effect);
|
||||
},
|
||||
|
||||
_annotationEffect: function(source, value, effect) {
|
||||
if (source != effect.value) {
|
||||
value = this._get(effect.value);
|
||||
|
||||
@@ -219,42 +219,51 @@ TODO(sjmiles): this module should produce either syntactic metadata
|
||||
},
|
||||
|
||||
// push configuration references at configure time
|
||||
_configureAnnotationReferences: function() {
|
||||
this._configureTemplateContent();
|
||||
this._configureCompoundBindings();
|
||||
},
|
||||
|
||||
// nested template contents have been stored prototypically to avoid
|
||||
// unnecessary duplication, here we put references to the
|
||||
// indirected contents onto the nested template instances
|
||||
_configureTemplateContent: function() {
|
||||
this._notes.forEach(function(note, i) {
|
||||
_configureAnnotationReferences: function(config) {
|
||||
var notes = this._notes;
|
||||
var nodes = this._nodes;
|
||||
for (var i=0; i<notes.length; i++) {
|
||||
var note = notes[i];
|
||||
var node = nodes[i];
|
||||
// nested template contents have been stored prototypically to avoid
|
||||
// unnecessary duplication, here we put references to the
|
||||
// indirected contents onto the nested template instances
|
||||
if (note.templateContent) {
|
||||
// note: we can rely on _nodes being set here and having the same
|
||||
// index as _notes
|
||||
this._nodes[i]._content = note.templateContent;
|
||||
}
|
||||
}, this);
|
||||
},
|
||||
|
||||
// Compound bindings utilize private storage on the node to store
|
||||
// the current state of each value that will be concatenated to generate
|
||||
// the final property/attribute/text value
|
||||
// Here we initialize the private storage array on the node with any
|
||||
// literal parts that won't change (could get fancy and use WeakMap)
|
||||
_configureCompoundBindings: function() {
|
||||
this._notes.forEach(function(note, i) {
|
||||
var node = this._nodes[i];
|
||||
note.bindings.forEach(function(binding) {
|
||||
// Compound bindings utilize private storage on the node to store
|
||||
// the current state of each value that will be concatenated to generate
|
||||
// the final property/attribute/text value
|
||||
// Here we initialize the private storage array on the node with any
|
||||
// literal parts that won't change (could get fancy and use WeakMap),
|
||||
// and configure property bindings to children with the literal parts
|
||||
// (textContent and annotations were already initialized in the template)
|
||||
var bindings = note.bindings;
|
||||
for (var j=0; j<bindings.length; j++) {
|
||||
var binding = bindings[j];
|
||||
if (binding.isCompound) {
|
||||
var storage = node.__compoundStorage__ ||
|
||||
(node.__compoundStorage__ = {});
|
||||
storage[binding.name] = binding.parts.map(function(part) {
|
||||
return part.literal;
|
||||
});
|
||||
var parts = binding.parts;
|
||||
var literals = new Array(binding.parts);
|
||||
for (var k=0; k<parts.length; k++) {
|
||||
literals[k] = parts[k].literal;
|
||||
}
|
||||
var name = binding.name;
|
||||
storage[name] = literals;
|
||||
if (binding.kind == 'property') {
|
||||
var literal = literals.join('');
|
||||
if (node._configValue) {
|
||||
node._configValue(name, literal);
|
||||
} else {
|
||||
node[name] = literal;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}, this);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// construct `$` map (from id annotations)
|
||||
|
||||
@@ -150,14 +150,6 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
});
|
||||
}
|
||||
}
|
||||
// We need to ensure compound bindings with literals push the literals
|
||||
// through regardless of whether annotation dependencies initialized
|
||||
// this is done with a special compoundInitialization effect which simply
|
||||
// kicks _applyEffectValue to push the literals through
|
||||
if (note.isCompound) {
|
||||
note.index = index;
|
||||
this._addPropertyEffect('__static__', 'compoundInitialization', note);
|
||||
}
|
||||
},
|
||||
|
||||
_addAnnotatedComputationEffect: function(note, part, index) {
|
||||
|
||||
@@ -24,13 +24,15 @@
|
||||
computed-from-tricky-literals2='{{computeFromTrickyLiterals(3,"tricky\,'zot'" )}}'
|
||||
computed-from-no-args="{{computeFromNoArgs( )}}"
|
||||
no-computed="{{foobared(noInlineComputed)}}"
|
||||
compound1="{{cpnd1}}{{ cpnd2 }}{{cpnd3.prop}}{{ computeCompound(cpnd4, cpnd5, 'literal')}}"
|
||||
compound2="literal1 {{cpnd1}} literal2 {{cpnd2}}{{cpnd3.prop}} literal3 {{computeCompound(cpnd4, cpnd5, 'literal')}} literal4"
|
||||
compoundAttr1$="{{cpnd1}}{{ cpnd2 }}{{cpnd3.prop}}{{ computeCompound(cpnd4, cpnd5, 'literal')}}"
|
||||
compoundAttr2$="literal1 {{cpnd1}} literal2 {{cpnd2}}{{cpnd3.prop}} literal3 {{computeCompound(cpnd4, cpnd5, 'literal')}} literal4"
|
||||
>
|
||||
Test
|
||||
</div>
|
||||
<x-prop id="boundProps"
|
||||
prop1="{{cpnd1}}{{ cpnd2 }}{{cpnd3.prop}}{{ computeCompound(cpnd4, cpnd5, 'literal')}}"
|
||||
prop2="literal1 {{cpnd1}} literal2 {{cpnd2}}{{cpnd3.prop}} literal3 {{computeCompound(cpnd4, cpnd5, 'literal')}} literal4"
|
||||
></x-prop>
|
||||
<span id="boundText">{{text}}</span>
|
||||
<span idtest id="{{boundId}}"></span>
|
||||
<s id="computedContent">{{computeFromTrickyLiterals(3, 'tricky\,\'zot\'')}}</s>
|
||||
@@ -364,6 +366,26 @@
|
||||
});
|
||||
</script>
|
||||
|
||||
<script>
|
||||
Polymer({
|
||||
is: 'x-prop',
|
||||
properties: {
|
||||
prop1: {
|
||||
value: 'default',
|
||||
observer: 'prop1Changed'
|
||||
},
|
||||
prop2: {
|
||||
value: 'default',
|
||||
observer: 'prop2Changed'
|
||||
}
|
||||
},
|
||||
created: function() {
|
||||
this.prop1Changed = sinon.spy();
|
||||
this.prop2Changed = sinon.spy();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<script>
|
||||
Polymer({
|
||||
is: 'x-notifies1',
|
||||
|
||||
@@ -703,36 +703,38 @@ suite('compound binding / string interpolation', function() {
|
||||
|
||||
test('compound adjacent property bindings', function() {
|
||||
var el = document.createElement('x-basic');
|
||||
assert.equal(el.$.boundChild.compound1, '');
|
||||
assert.equal(el.$.boundProps.prop1, '');
|
||||
assert.isTrue(el.$.boundProps.prop1Changed.calledOnce);
|
||||
el.cpnd2 = 'cpnd2';
|
||||
assert.equal(el.$.boundChild.compound1, 'cpnd2');
|
||||
assert.equal(el.$.boundProps.prop1, 'cpnd2');
|
||||
el.cpnd1 = 'cpnd1';
|
||||
el.cpnd3 = {prop: 'cpnd3'};
|
||||
assert.equal(el.$.boundChild.compound1, 'cpnd1cpnd2cpnd3');
|
||||
assert.equal(el.$.boundProps.prop1, 'cpnd1cpnd2cpnd3');
|
||||
el.cpnd4 = 'cpnd4';
|
||||
assert.equal(el.$.boundChild.compound1, 'cpnd1cpnd2cpnd3');
|
||||
assert.equal(el.$.boundProps.prop1, 'cpnd1cpnd2cpnd3');
|
||||
el.cpnd5 = 'cpnd5';
|
||||
assert.equal(el.$.boundChild.compound1, 'cpnd1cpnd2cpnd3literalcpnd5cpnd4');
|
||||
assert.equal(el.$.boundProps.prop1, 'cpnd1cpnd2cpnd3literalcpnd5cpnd4');
|
||||
});
|
||||
|
||||
test('compound property bindings with literals', function() {
|
||||
var el = document.createElement('x-basic');
|
||||
assert.equal(el.$.boundChild.compound2, 'literal1 literal2 literal3 literal4');
|
||||
assert.equal(el.$.boundProps.prop2, 'literal1 literal2 literal3 literal4');
|
||||
assert.isTrue(el.$.boundProps.prop2Changed.calledOnce);
|
||||
el.cpnd1 = 'cpnd1';
|
||||
el.cpnd2 = 'cpnd2';
|
||||
el.cpnd3 = {prop: 'cpnd3'};
|
||||
el.cpnd4 = 'cpnd4';
|
||||
el.cpnd5 = 'cpnd5';
|
||||
assert.equal(el.$.boundChild.compound2, 'literal1 cpnd1 literal2 cpnd2cpnd3 literal3 literalcpnd5cpnd4 literal4');
|
||||
assert.equal(el.$.boundProps.prop2, 'literal1 cpnd1 literal2 cpnd2cpnd3 literal3 literalcpnd5cpnd4 literal4');
|
||||
el.cpnd1 = null;
|
||||
el.cpnd2 = undefined;
|
||||
el.cpnd3 = {};
|
||||
el.cpnd4 = '';
|
||||
el.cpnd5 = '';
|
||||
assert.equal(el.$.boundChild.compound2, 'literal1 literal2 literal3 literal literal4');
|
||||
assert.equal(el.$.boundProps.prop2, 'literal1 literal2 literal3 literal literal4');
|
||||
});
|
||||
|
||||
test('compound adjacent property bindings', function() {
|
||||
test('compound adjacent attribute bindings', function() {
|
||||
var el = document.createElement('x-basic');
|
||||
assert.equal(el.$.boundChild.getAttribute('compoundAttr1'), '');
|
||||
el.cpnd2 = 'cpnd2';
|
||||
@@ -746,7 +748,7 @@ suite('compound binding / string interpolation', function() {
|
||||
assert.equal(el.$.boundChild.getAttribute('compoundAttr1'), 'cpnd1cpnd2cpnd3literalcpnd5cpnd4');
|
||||
});
|
||||
|
||||
test('compound property bindings with literals', function() {
|
||||
test('compound property attribute with literals', function() {
|
||||
var el = document.createElement('x-basic');
|
||||
assert.equal(el.$.boundChild.getAttribute('compoundAttr2'), 'literal1 literal2 literal3 literal4');
|
||||
el.cpnd1 = 'cpnd1';
|
||||
@@ -765,7 +767,10 @@ suite('compound binding / string interpolation', function() {
|
||||
|
||||
test('compound adjacent textNode bindings', function() {
|
||||
var el = document.createElement('x-basic');
|
||||
assert.equal(el.$.compound1.textContent, '');
|
||||
// The single space is due to the gambit to prevent empty text nodes
|
||||
// from being evacipated on IE during importNode from the template; it will
|
||||
// only be there the when in the virgin state after cloning the template
|
||||
assert.equal(el.$.compound1.textContent, ' ');
|
||||
el.cpnd2 = 'cpnd2';
|
||||
assert.equal(el.$.compound1.textContent, 'cpnd2');
|
||||
el.cpnd1 = 'cpnd1';
|
||||
@@ -775,6 +780,14 @@ suite('compound binding / string interpolation', function() {
|
||||
assert.equal(el.$.compound1.textContent, 'cpnd1cpnd2cpnd3');
|
||||
el.cpnd5 = 'cpnd5';
|
||||
assert.equal(el.$.compound1.textContent, 'cpnd1cpnd2cpnd3literalcpnd5cpnd4');
|
||||
// Once the binding evaluates back to '', it will in fact be ''
|
||||
el.computeCompound = function() { return ''; };
|
||||
el.cpnd1 = null;
|
||||
el.cpnd2 = '';
|
||||
el.cpnd3 = {prop: null};
|
||||
el.cpnd4 = null;
|
||||
el.cpnd5 = '';
|
||||
assert.equal(el.$.compound1.textContent, '');
|
||||
});
|
||||
|
||||
test('compound textNode bindings with literals', function() {
|
||||
|
||||
Reference in New Issue
Block a user