1 2 (function() { 3 4 var ANIMATION_GROUPS = { 5 'par': AnimationGroup, 6 'seq': AnimationSequence 7 }; 8 9 Polymer('core-animation-group',{ 10 11 publish: { 12 /** 13 * If target is set, any children without a target will be assigned the group's 14 * target when this property is set. 15 * 16 * @property target 17 * @type HTMLElement|Node|Array|Array<HTMLElement|Node> 18 */ 19 20 /** 21 * For a `core-animation-group`, a duration of "auto" means the duration should 22 * be the specified duration of its children. If set to anything other than 23 * "auto", any children without a set duration will be assigned the group's duration. 24 * 25 * @property duration 26 * @type number 27 * @default "auto" 28 */ 29 duration: {value: 'auto', reflect: true}, 30 31 /** 32 * The type of the animation group. 'par' creates a parallel group and 'seq' creates 33 * a sequential group. 34 * 35 * @property type 36 * @type String 37 * @default 'par' 38 */ 39 type: {value: 'par', reflect: true} 40 }, 41 42 typeChanged: function() { 43 this.apply(); 44 }, 45 46 targetChanged: function() { 47 // Only propagate target to children animations if it's defined. 48 if (this.target) { 49 this.doOnChildren(function(c) { 50 c.target = this.target; 51 }.bind(this)); 52 } 53 }, 54 55 durationChanged: function() { 56 if (this.duration && this.duration !== 'auto') { 57 this.doOnChildren(function(c) { 58 // Propagate to children that is not a group and has no 59 // duration specified. 60 if (!c.type && (!c.duration || c.duration === 'auto')) { 61 c.duration = this.duration; 62 } 63 }.bind(this)); 64 } 65 }, 66 67 doOnChildren: function(inFn) { 68 var children = this.children; 69 if (!children.length) { 70 children = this.shadowRoot ? this.shadowRoot.childNodes : []; 71 } 72 Array.prototype.forEach.call(children, function(c) { 73 // TODO <template> in the way 74 c.apply && inFn(c); 75 }, this); 76 }, 77 78 makeAnimation: function() { 79 return new ANIMATION_GROUPS[this.type](this.childAnimations, this.timingProps); 80 }, 81 82 hasTarget: function() { 83 var ht = this.target !== null; 84 if (!ht) { 85 this.doOnChildren(function(c) { 86 ht = ht || c.hasTarget(); 87 }.bind(this)); 88 } 89 return ht; 90 }, 91 92 apply: function() { 93 // Propagate target and duration to child animations first. 94 this.durationChanged(); 95 this.targetChanged(); 96 this.doOnChildren(function(c) { 97 c.apply(); 98 }); 99 return this.super(); 100 }, 101 102 get childAnimationElements() { 103 var list = []; 104 this.doOnChildren(function(c) { 105 if (c.makeAnimation) { 106 list.push(c); 107 } 108 }); 109 return list; 110 }, 111 112 get childAnimations() { 113 var list = []; 114 this.doOnChildren(function(c) { 115 if (c.animation) { 116 list.push(c.animation); 117 } 118 }); 119 return list; 120 } 121 }); 122 123 })(); 124