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 function addAnimation(code) {
9 var name = 'anim' + animationCounter;
11 var rules = document.createTextNode(
12 '@-webkit-keyframes ' + name + ' {' + code + '}');
13 var el = document.createElement('style');
15 el.appendChild(rules);
16 el.setAttribute('id', name);
17 document.body.appendChild(el);
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
26 * @return {string} The css code for the fade in animation.
28 function getFadeInAnimationCode(targetHeight) {
29 return '0% { opacity: 0; height: 0; } ' +
30 '80% { height: ' + (targetHeight + 4) + 'px; }' +
31 '100% { opacity: 1; height: ' + targetHeight + 'px; }';
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.
39 function fadeInElement(el) {
40 if (el.classList.contains('visible'))
42 el.classList.remove('closing');
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),
52 el.style.webkitAnimationName = animName;
53 el.classList.add('visible');
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.
61 function fadeOutElement(el) {
62 if (!el.classList.contains('visible'))
64 el.style.height = 'auto';
65 var height = el.offsetHeight;
66 el.style.height = height + 'px';
67 el.offsetHeight; // Should force an update of the computed style.
68 var eventTracker = new EventTracker();
69 eventTracker.add(el, 'webkitTransitionEnd',
70 onFadeOutTransitionEnd.bind(el, eventTracker),
72 el.classList.add('closing');
73 el.classList.remove('visible');
77 * Executes when a fade out animation ends.
78 * @param {EventTracker} eventTracker The |EventTracker| object that was used
79 * for adding this listener.
80 * @param {WebkitTransitionEvent} event The event that triggered this listener.
81 * @this {HTMLElement} The element where the transition occurred.
83 function onFadeOutTransitionEnd(eventTracker, event) {
84 if (event.propertyName != 'height')
86 eventTracker.remove(this, 'webkitTransitionEnd');
91 * Executes when a fade in animation ends.
92 * @param {EventTracker} eventTracker The |EventTracker| object that was used
93 * for adding this listener.
94 * @param {WebkitAnimationEvent} event The event that triggered this listener.
95 * @this {HTMLElement} The element where the transition occurred.
97 function onFadeInAnimationEnd(eventTracker, event) {
98 this.style.height = '';
99 this.style.webkitAnimationName = '';
100 fadeInOutCleanup(event.animationName);
101 eventTracker.remove(this, 'webkitAnimationEnd');
105 * Removes the <style> element corrsponding to |animationName| from the DOM.
106 * @param {string} animationName The name of the animation to be removed.
108 function fadeInOutCleanup(animationName) {
109 var animEl = document.getElementById(animationName);
111 animEl.parentNode.removeChild(animEl);
115 * Fades in a printing option existing under |el|.
116 * @param {HTMLElement} el The element to hide.
118 function fadeInOption(el) {
119 if (el.classList.contains('visible'))
122 wrapContentsInDiv(el.querySelector('h1'), ['invisible']);
123 var rightColumn = el.querySelector('.right-column');
124 wrapContentsInDiv(rightColumn, ['invisible']);
126 var toAnimate = el.querySelectorAll('.collapsible');
127 for (var i = 0; i < toAnimate.length; i++)
128 fadeInElement(toAnimate[i]);
129 el.classList.add('visible');
133 * Fades out a printing option existing under |el|.
134 * @param {HTMLElement} el The element to hide.
136 function fadeOutOption(el) {
137 if (!el.classList.contains('visible'))
140 wrapContentsInDiv(el.querySelector('h1'), ['visible']);
141 var rightColumn = el.querySelector('.right-column');
142 wrapContentsInDiv(rightColumn, ['visible']);
144 var toAnimate = el.querySelectorAll('.collapsible');
145 for (var i = 0; i < toAnimate.length; i++)
146 fadeOutElement(toAnimate[i]);
147 el.classList.remove('visible');
151 * Wraps the contents of |el| in a div element and attaches css classes
152 * |classes| in the new div, only if has not been already done. It is neccesary
153 * for animating the height of table cells.
154 * @param {HTMLElement} el The element to be processed.
155 * @param {array} classes The css classes to add.
157 function wrapContentsInDiv(el, classes) {
158 var div = el.querySelector('div');
159 if (!div || !div.classList.contains('collapsible')) {
160 div = document.createElement('div');
161 while (el.childNodes.length > 0)
162 div.appendChild(el.firstChild);
167 div.classList.add('collapsible');
168 for (var i = 0; i < classes.length; i++)
169 div.classList.add(classes[i]);