- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / resources / print_preview / print_preview_animations.js
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Counter used to give webkit animations unique names.
6 var animationCounter = 0;
7
8 function addAnimation(code) {
9   var name = 'anim' + animationCounter;
10   animationCounter++;
11   var rules = document.createTextNode(
12       '@-webkit-keyframes ' + name + ' {' + code + '}');
13   var el = document.createElement('style');
14   el.type = 'text/css';
15   el.appendChild(rules);
16   el.setAttribute('id', name);
17   document.body.appendChild(el);
18
19   return name;
20 }
21
22 /**
23  * Generates css code for fading in an element by animating the height.
24  * @param {number} targetHeight The desired height in pixels after the animation
25  *     ends.
26  * @return {string} The css code for the fade in animation.
27  */
28 function getFadeInAnimationCode(targetHeight) {
29   return '0% { opacity: 0; height: 0; } ' +
30       '80% { height: ' + (targetHeight + 4) + 'px; }' +
31       '100% { opacity: 1; height: ' + targetHeight + 'px; }';
32 }
33
34 /**
35  * Fades in an element. Used for both printing options and error messages
36  * appearing underneath the textfields.
37  * @param {HTMLElement} el The element to be faded in.
38  */
39 function fadeInElement(el) {
40   if (el.classList.contains('visible'))
41     return;
42   el.classList.remove('closing');
43   el.hidden = false;
44   el.style.height = 'auto';
45   var height = el.offsetHeight;
46   el.style.height = height + 'px';
47   var animName = addAnimation(getFadeInAnimationCode(height));
48   var eventTracker = new EventTracker();
49   eventTracker.add(el, 'webkitAnimationEnd',
50                    onFadeInAnimationEnd.bind(el, eventTracker),
51                    false);
52   el.style.webkitAnimationName = animName;
53   el.classList.add('visible');
54 }
55
56 /**
57  * Fades out an element. Used for both printing options and error messages
58  * appearing underneath the textfields.
59  * @param {HTMLElement} el The element to be faded out.
60  */
61 function fadeOutElement(el) {
62   if (!el.classList.contains('visible'))
63     return;
64   el.style.height = 'auto';
65   var height = el.offsetHeight;
66   el.style.height = height + 'px';
67   var animName = addAnimation('');
68   var eventTracker = new EventTracker();
69   eventTracker.add(el, 'webkitTransitionEnd',
70                    onFadeOutTransitionEnd.bind(el, animName, eventTracker),
71                    false);
72   el.classList.add('closing');
73   el.classList.remove('visible');
74 }
75
76 /**
77  * Executes when a fade out animation ends.
78  * @param {string} animationName The name of the animation to be removed.
79  * @param {EventTracker} eventTracker The |EventTracker| object that was used
80  *     for adding this listener.
81  * @param {WebkitTransitionEvent} event The event that triggered this listener.
82  * @this {HTMLElement} The element where the transition occurred.
83  */
84 function onFadeOutTransitionEnd(animationName, eventTracker, event) {
85   if (event.propertyName != 'height')
86     return;
87   fadeInOutCleanup(animationName);
88   eventTracker.remove(this, 'webkitTransitionEnd');
89   this.hidden = true;
90 }
91
92 /**
93  * Executes when a fade in animation ends.
94  * @param {EventTracker} eventTracker The |EventTracker| object that was used
95  *     for adding this listener.
96  * @param {WebkitAnimationEvent} event The event that triggered this listener.
97  * @this {HTMLElement} The element where the transition occurred.
98  */
99 function onFadeInAnimationEnd(eventTracker, event) {
100   this.style.height = '';
101   this.style.webkitAnimationName = '';
102   fadeInOutCleanup(event.animationName);
103   eventTracker.remove(this, 'webkitAnimationEnd');
104 }
105
106 /**
107  * Removes the <style> element corrsponding to |animationName| from the DOM.
108  * @param {string} animationName The name of the animation to be removed.
109  */
110 function fadeInOutCleanup(animationName) {
111   var animEl = document.getElementById(animationName);
112   if (animEl)
113     animEl.parentNode.removeChild(animEl);
114 }
115
116 /**
117  * Fades in a printing option existing under |el|.
118  * @param {HTMLElement} el The element to hide.
119  */
120 function fadeInOption(el) {
121   if (el.classList.contains('visible'))
122     return;
123
124   wrapContentsInDiv(el.querySelector('h1'), ['invisible']);
125   var rightColumn = el.querySelector('.right-column');
126   wrapContentsInDiv(rightColumn, ['invisible']);
127
128   var toAnimate = el.querySelectorAll('.collapsible');
129   for (var i = 0; i < toAnimate.length; i++)
130     fadeInElement(toAnimate[i]);
131   el.classList.add('visible');
132 }
133
134 /**
135  * Fades out a printing option existing under |el|.
136  * @param {HTMLElement} el The element to hide.
137  */
138 function fadeOutOption(el) {
139   if (!el.classList.contains('visible'))
140     return;
141
142   wrapContentsInDiv(el.querySelector('h1'), ['visible']);
143   var rightColumn = el.querySelector('.right-column');
144   wrapContentsInDiv(rightColumn, ['visible']);
145
146   var toAnimate = el.querySelectorAll('.collapsible');
147   for (var i = 0; i < toAnimate.length; i++)
148     fadeOutElement(toAnimate[i]);
149   el.classList.remove('visible');
150 }
151
152 /**
153  * Wraps the contents of |el| in a div element and attaches css classes
154  * |classes| in the new div, only if has not been already done. It is neccesary
155  * for animating the height of table cells.
156  * @param {HTMLElement} el The element to be processed.
157  * @param {array} classes The css classes to add.
158  */
159 function wrapContentsInDiv(el, classes) {
160   var div = el.querySelector('div');
161   if (!div || !div.classList.contains('collapsible')) {
162     div = document.createElement('div');
163     while (el.childNodes.length > 0)
164       div.appendChild(el.firstChild);
165     el.appendChild(div);
166   }
167
168   div.className = '';
169   div.classList.add('collapsible');
170   for (var i = 0; i < classes.length; i++)
171     div.classList.add(classes[i]);
172 }