Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / third_party / polymer / v1_0 / components-chromium / neon-animation / neon-animatable-behavior-extracted.js
blob366388eee212d2a884ca7aa23e554e29bc6350d2
3   /**
4    * `Polymer.NeonAnimatableBehavior` is implemented by elements containing animations for use with
5    * elements implementing `Polymer.NeonAnimationRunnerBehavior`.
6    * @polymerBehavior
7    */
8   Polymer.NeonAnimatableBehavior = {
10     properties: {
12       /**
13        * Animation configuration. See README for more info.
14        */
15       animationConfig: {
16         type: Object
17       },
19       /**
20        * Convenience property for setting an 'entry' animation. Do not set `animationConfig.entry`
21        * manually if using this. The animated node is set to `this` if using this property.
22        */
23       entryAnimation: {
24         observer: '_entryAnimationChanged',
25         type: String
26       },
28       /**
29        * Convenience property for setting an 'exit' animation. Do not set `animationConfig.exit`
30        * manually if using this. The animated node is set to `this` if using this property.
31        */
32       exitAnimation: {
33         observer: '_exitAnimationChanged',
34         type: String
35       }
37     },
39     _entryAnimationChanged: function() {
40       this.animationConfig = this.animationConfig || {};
41       if (this.entryAnimation !== 'fade-in-animation') {
42         // insert polyfill hack
43         this.animationConfig['entry'] = [{
44           name: 'opaque-animation',
45           node: this
46         }, {
47           name: this.entryAnimation,
48           node: this
49         }];
50       } else {
51         this.animationConfig['entry'] = [{
52           name: this.entryAnimation,
53           node: this
54         }];
55       }
56     },
58     _exitAnimationChanged: function() {
59       this.animationConfig = this.animationConfig || {};
60       this.animationConfig['exit'] = [{
61         name: this.exitAnimation,
62         node: this
63       }];
64     },
66     _copyProperties: function(config1, config2) {
67       // shallowly copy properties from config2 to config1
68       for (var property in config2) {
69         config1[property] = config2[property];
70       }
71     },
73     _cloneConfig: function(config) {
74       var clone = {
75         isClone: true
76       };
77       this._copyProperties(clone, config);
78       return clone;
79     },
81     _getAnimationConfigRecursive: function(type, map, allConfigs) {
82       if (!this.animationConfig) {
83         return;
84       }
86       // type is optional
87       var thisConfig;
88       if (type) {
89         thisConfig = this.animationConfig[type];
90       } else {
91         thisConfig = this.animationConfig;
92       }
94       if (!Array.isArray(thisConfig)) {
95         thisConfig = [thisConfig];
96       }
98       // iterate animations and recurse to process configurations from child nodes
99       if (thisConfig) {
100         for (var config, index = 0; config = thisConfig[index]; index++) {
101           if (config.animatable) {
102             config.animatable._getAnimationConfigRecursive(config.type || type, map, allConfigs);
103           } else {
104             if (config.id) {
105               var cachedConfig = map[config.id];
106               if (cachedConfig) {
107                 // merge configurations with the same id, making a clone lazily
108                 if (!cachedConfig.isClone) {
109                   map[config.id] = this._cloneConfig(cachedConfig)
110                   cachedConfig = map[config.id];
111                 }
112                 this._copyProperties(cachedConfig, config);
113               } else {
114                 // put any configs with an id into a map
115                 map[config.id] = config;
116               }
117             } else {
118               allConfigs.push(config);
119             }
120           }
121         }
122       }
123     },
125     /**
126      * An element implementing `Polymer.NeonAnimationRunnerBehavior` calls this method to configure
127      * an animation with an optional type. Elements implementing `Polymer.NeonAnimatableBehavior`
128      * should define the property `animationConfig`, which is either a configuration object
129      * or a map of animation type to array of configuration objects.
130      */
131     getAnimationConfig: function(type) {
132       var map = [];
133       var allConfigs = [];
134       this._getAnimationConfigRecursive(type, map, allConfigs);
135       // append the configurations saved in the map to the array
136       for (var key in map) {
137         allConfigs.push(map[key]);
138       }
139       return allConfigs;
140     }
142   };