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