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.
5 // Counter used to give webkit animations unique names.
6 var animationCounter
= 0;
8 var animationEventTracker_
= new EventTracker();
10 function addAnimation(code
) {
11 var name
= 'anim' + animationCounter
;
13 var rules
= document
.createTextNode(
14 '@-webkit-keyframes ' + name
+ ' {' + code
+ '}');
15 var el
= document
.createElement('style');
17 el
.appendChild(rules
);
18 el
.setAttribute('id', name
);
19 document
.body
.appendChild(el
);
25 * Generates css code for fading in an element by animating the height.
26 * @param {number} targetHeight The desired height in pixels after the animation
28 * @return {string} The css code for the fade in animation.
30 function getFadeInAnimationCode(targetHeight
) {
31 return '0% { opacity: 0; height: 0; } ' +
32 '80% { opacity: 0.5; height: ' + (targetHeight
+ 4) + 'px; }' +
33 '100% { opacity: 1; height: ' + targetHeight
+ 'px; }';
37 * Fades in an element. Used for both printing options and error messages
38 * appearing underneath the textfields.
39 * @param {HTMLElement} el The element to be faded in.
40 * @param {boolean=} opt_justShow Whether {@code el} should be shown with no
43 function fadeInElement(el
, opt_justShow
) {
44 if (el
.classList
.contains('visible'))
46 el
.classList
.remove('closing');
48 el
.setAttribute('aria-hidden', 'false');
49 el
.style
.height
= 'auto';
50 var height
= el
.offsetHeight
;
53 el
.style
.opacity
= '';
55 el
.style
.height
= height
+ 'px';
56 var animName
= addAnimation(getFadeInAnimationCode(height
));
57 animationEventTracker_
.add(
58 el
, 'webkitAnimationEnd', onFadeInAnimationEnd
.bind(el
), false);
59 el
.style
.webkitAnimationName
= animName
;
61 el
.classList
.add('visible');
65 * Fades out an element. Used for both printing options and error messages
66 * appearing underneath the textfields.
67 * @param {HTMLElement} el The element to be faded out.
69 function fadeOutElement(el
) {
70 if (!el
.classList
.contains('visible'))
72 fadeInAnimationCleanup(el
);
73 el
.style
.height
= 'auto';
74 var height
= el
.offsetHeight
;
75 el
.style
.height
= height
+ 'px';
76 el
.offsetHeight
; // Should force an update of the computed style.
77 animationEventTracker_
.add(
78 el
, 'webkitTransitionEnd', onFadeOutTransitionEnd
.bind(el
), false);
79 el
.classList
.add('closing');
80 el
.classList
.remove('visible');
81 el
.setAttribute('aria-hidden', 'true');
85 * Executes when a fade out animation ends.
86 * @param {WebkitTransitionEvent} event The event that triggered this listener.
87 * @this {HTMLElement} The element where the transition occurred.
89 function onFadeOutTransitionEnd(event
) {
90 if (event
.propertyName
!= 'height')
92 animationEventTracker_
.remove(this, 'webkitTransitionEnd');
97 * Executes when a fade in animation ends.
98 * @param {WebkitAnimationEvent} event The event that triggered this listener.
99 * @this {HTMLElement} The element where the transition occurred.
101 function onFadeInAnimationEnd(event
) {
102 this.style
.height
= '';
103 fadeInAnimationCleanup(this);
107 * Removes the <style> element corresponding to |animationName| from the DOM.
108 * @param {HTMLElement} element The animated element.
110 function fadeInAnimationCleanup(element
) {
111 if (element
.style
.webkitAnimationName
) {
112 var animEl
= document
.getElementById(element
.style
.webkitAnimationName
);
114 animEl
.parentNode
.removeChild(animEl
);
115 element
.style
.webkitAnimationName
= '';
116 animationEventTracker_
.remove(element
, 'webkitAnimationEnd');
121 * Fades in a printing option existing under |el|.
122 * @param {HTMLElement} el The element to hide.
123 * @param {boolean=} opt_justShow Whether {@code el} should be hidden with no
126 function fadeInOption(el
, opt_justShow
) {
127 if (el
.classList
.contains('visible'))
129 // To make the option visible during the first fade in.
132 var leftColumn
= el
.querySelector('.left-column');
133 wrapContentsInDiv(leftColumn
, ['invisible']);
134 var rightColumn
= el
.querySelector('.right-column');
135 wrapContentsInDiv(rightColumn
, ['invisible']);
137 var toAnimate
= el
.querySelectorAll('.collapsible');
138 for (var i
= 0; i
< toAnimate
.length
; i
++)
139 fadeInElement(toAnimate
[i
], opt_justShow
);
140 el
.classList
.add('visible');
144 * Fades out a printing option existing under |el|.
145 * @param {HTMLElement} el The element to hide.
146 * @param {boolean=} opt_justHide Whether {@code el} should be hidden with no
149 function fadeOutOption(el
, opt_justHide
) {
150 if (!el
.classList
.contains('visible'))
153 var leftColumn
= el
.querySelector('.left-column');
154 wrapContentsInDiv(leftColumn
, ['visible']);
155 var rightColumn
= el
.querySelector('.right-column');
156 wrapContentsInDiv(rightColumn
, ['visible']);
158 var toAnimate
= el
.querySelectorAll('.collapsible');
159 for (var i
= 0; i
< toAnimate
.length
; i
++) {
161 toAnimate
[i
].hidden
= true;
162 toAnimate
[i
].classList
.add('closing');
163 toAnimate
[i
].classList
.remove('visible');
165 fadeOutElement(toAnimate
[i
]);
168 el
.classList
.remove('visible');
172 * Wraps the contents of |el| in a div element and attaches css classes
173 * |classes| in the new div, only if has not been already done. It is necessary
174 * for animating the height of table cells.
175 * @param {HTMLElement} el The element to be processed.
176 * @param {array} classes The css classes to add.
178 function wrapContentsInDiv(el
, classes
) {
179 var div
= el
.querySelector('div');
180 if (!div
|| !div
.classList
.contains('collapsible')) {
181 div
= document
.createElement('div');
182 while (el
.childNodes
.length
> 0)
183 div
.appendChild(el
.firstChild
);
188 div
.classList
.add('collapsible');
189 for (var i
= 0; i
< classes
.length
; i
++)
190 div
.classList
.add(classes
[i
]);