| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Counter used to give animations unique names. | 5 // Counter used to give animations unique names. |
| 6 var animationCounter = 0; | 6 var animationCounter = 0; |
| 7 | 7 |
| 8 var animationEventTracker_ = new EventTracker(); | 8 var animationEventTracker = new EventTracker(); |
| 9 | 9 |
| 10 function addAnimation(code) { | 10 function addAnimation(code) { |
| 11 var name = 'anim' + animationCounter; | 11 var name = 'anim' + animationCounter; |
| 12 animationCounter++; | 12 animationCounter++; |
| 13 var rules = document.createTextNode( | 13 var rules = document.createTextNode( |
| 14 '@keyframes ' + name + ' {' + code + '}'); | 14 '@keyframes ' + name + ' {' + code + '}'); |
| 15 var el = document.createElement('style'); | 15 var el = document.createElement('style'); |
| 16 el.type = 'text/css'; | 16 el.type = 'text/css'; |
| 17 el.appendChild(rules); | 17 el.appendChild(rules); |
| 18 el.setAttribute('id', name); | 18 el.setAttribute('id', name); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 47 el.hidden = false; | 47 el.hidden = false; |
| 48 el.setAttribute('aria-hidden', 'false'); | 48 el.setAttribute('aria-hidden', 'false'); |
| 49 el.style.height = 'auto'; | 49 el.style.height = 'auto'; |
| 50 var height = el.offsetHeight; | 50 var height = el.offsetHeight; |
| 51 if (opt_justShow) { | 51 if (opt_justShow) { |
| 52 el.style.height = ''; | 52 el.style.height = ''; |
| 53 el.style.opacity = ''; | 53 el.style.opacity = ''; |
| 54 } else { | 54 } else { |
| 55 el.style.height = height + 'px'; | 55 el.style.height = height + 'px'; |
| 56 var animName = addAnimation(getFadeInAnimationCode(height)); | 56 var animName = addAnimation(getFadeInAnimationCode(height)); |
| 57 animationEventTracker_.add( | 57 animationEventTracker.add( |
| 58 el, 'animationend', onFadeInAnimationEnd.bind(el), false); | 58 el, 'animationend', onFadeInAnimationEnd.bind(el), false); |
| 59 el.style.animationName = animName; | 59 el.style.animationName = animName; |
| 60 } | 60 } |
| 61 el.classList.add('visible'); | 61 el.classList.add('visible'); |
| 62 } | 62 } |
| 63 | 63 |
| 64 /** | 64 /** |
| 65 * Fades out an element. Used for both printing options and error messages | 65 * Fades out an element. Used for both printing options and error messages |
| 66 * appearing underneath the textfields. | 66 * appearing underneath the textfields. |
| 67 * @param {HTMLElement} el The element to be faded out. | 67 * @param {HTMLElement} el The element to be faded out. |
| 68 */ | 68 */ |
| 69 function fadeOutElement(el) { | 69 function fadeOutElement(el) { |
| 70 if (!el.classList.contains('visible')) | 70 if (!el.classList.contains('visible')) |
| 71 return; | 71 return; |
| 72 fadeInAnimationCleanup(el); | 72 fadeInAnimationCleanup(el); |
| 73 el.style.height = 'auto'; | 73 el.style.height = 'auto'; |
| 74 var height = el.offsetHeight; | 74 var height = el.offsetHeight; |
| 75 el.style.height = height + 'px'; | 75 el.style.height = height + 'px'; |
| 76 /** @suppress {suspiciousCode} */ |
| 76 el.offsetHeight; // Should force an update of the computed style. | 77 el.offsetHeight; // Should force an update of the computed style. |
| 77 animationEventTracker_.add( | 78 animationEventTracker.add( |
| 78 el, 'transitionend', onFadeOutTransitionEnd.bind(el), false); | 79 el, 'transitionend', onFadeOutTransitionEnd.bind(el), false); |
| 79 el.classList.add('closing'); | 80 el.classList.add('closing'); |
| 80 el.classList.remove('visible'); | 81 el.classList.remove('visible'); |
| 81 el.setAttribute('aria-hidden', 'true'); | 82 el.setAttribute('aria-hidden', 'true'); |
| 82 } | 83 } |
| 83 | 84 |
| 84 /** | 85 /** |
| 85 * Executes when a fade out animation ends. | 86 * Executes when a fade out animation ends. |
| 86 * @param {Event} event The event that triggered this listener. | 87 * @param {Event} event The event that triggered this listener. |
| 87 * @this {HTMLElement} The element where the transition occurred. | 88 * @this {HTMLElement} The element where the transition occurred. |
| 88 */ | 89 */ |
| 89 function onFadeOutTransitionEnd(event) { | 90 function onFadeOutTransitionEnd(event) { |
| 90 if (event.propertyName != 'height') | 91 if (event.propertyName != 'height') |
| 91 return; | 92 return; |
| 92 animationEventTracker_.remove(this, 'transitionend'); | 93 animationEventTracker.remove(this, 'transitionend'); |
| 93 this.hidden = true; | 94 this.hidden = true; |
| 94 } | 95 } |
| 95 | 96 |
| 96 /** | 97 /** |
| 97 * Executes when a fade in animation ends. | 98 * Executes when a fade in animation ends. |
| 98 * @param {Event} event The event that triggered this listener. | 99 * @param {Event} event The event that triggered this listener. |
| 99 * @this {HTMLElement} The element where the transition occurred. | 100 * @this {HTMLElement} The element where the transition occurred. |
| 100 */ | 101 */ |
| 101 function onFadeInAnimationEnd(event) { | 102 function onFadeInAnimationEnd(event) { |
| 102 this.style.height = ''; | 103 this.style.height = ''; |
| 103 fadeInAnimationCleanup(this); | 104 fadeInAnimationCleanup(this); |
| 104 } | 105 } |
| 105 | 106 |
| 106 /** | 107 /** |
| 107 * Removes the <style> element corresponding to |animationName| from the DOM. | 108 * Removes the <style> element corresponding to |animationName| from the DOM. |
| 108 * @param {HTMLElement} element The animated element. | 109 * @param {HTMLElement} element The animated element. |
| 109 */ | 110 */ |
| 110 function fadeInAnimationCleanup(element) { | 111 function fadeInAnimationCleanup(element) { |
| 111 if (element.style.animationName) { | 112 if (element.style.animationName) { |
| 112 var animEl = document.getElementById(element.style.animationName); | 113 var animEl = document.getElementById(element.style.animationName); |
| 113 if (animEl) | 114 if (animEl) |
| 114 animEl.parentNode.removeChild(animEl); | 115 animEl.parentNode.removeChild(animEl); |
| 115 element.style.animationName = ''; | 116 element.style.animationName = ''; |
| 116 animationEventTracker_.remove(element, 'animationend'); | 117 animationEventTracker.remove(element, 'animationend'); |
| 117 } | 118 } |
| 118 } | 119 } |
| 119 | 120 |
| 120 /** | 121 /** |
| 121 * Fades in a printing option existing under |el|. | 122 * Fades in a printing option existing under |el|. |
| 122 * @param {HTMLElement} el The element to hide. | 123 * @param {HTMLElement} el The element to hide. |
| 123 * @param {boolean=} opt_justShow Whether {@code el} should be hidden with no | 124 * @param {boolean=} opt_justShow Whether {@code el} should be hidden with no |
| 124 * animation. | 125 * animation. |
| 125 */ | 126 */ |
| 126 function fadeInOption(el, opt_justShow) { | 127 function fadeInOption(el, opt_justShow) { |
| 127 if (el.classList.contains('visible')) | 128 if (el.classList.contains('visible')) |
| 128 return; | 129 return; |
| 129 // To make the option visible during the first fade in. | 130 // To make the option visible during the first fade in. |
| 130 el.hidden = false; | 131 el.hidden = false; |
| 131 | 132 |
| 132 var leftColumn = el.querySelector('.left-column'); | 133 var leftColumn = assertInstanceof(el.querySelector('.left-column'), |
| 134 HTMLElement); |
| 133 wrapContentsInDiv(leftColumn, ['invisible']); | 135 wrapContentsInDiv(leftColumn, ['invisible']); |
| 134 var rightColumn = el.querySelector('.right-column'); | 136 var rightColumn = assertInstanceof(el.querySelector('.right-column'), |
| 137 HTMLElement); |
| 135 wrapContentsInDiv(rightColumn, ['invisible']); | 138 wrapContentsInDiv(rightColumn, ['invisible']); |
| 136 | 139 |
| 137 var toAnimate = el.querySelectorAll('.collapsible'); | 140 var toAnimate = el.querySelectorAll('.collapsible'); |
| 138 for (var i = 0; i < toAnimate.length; i++) | 141 for (var i = 0; i < toAnimate.length; i++) |
| 139 fadeInElement(toAnimate[i], opt_justShow); | 142 fadeInElement(assertInstanceof(toAnimate[i], HTMLElement), opt_justShow); |
| 140 el.classList.add('visible'); | 143 el.classList.add('visible'); |
| 141 } | 144 } |
| 142 | 145 |
| 143 /** | 146 /** |
| 144 * Fades out a printing option existing under |el|. | 147 * Fades out a printing option existing under |el|. |
| 145 * @param {HTMLElement} el The element to hide. | 148 * @param {HTMLElement} el The element to hide. |
| 146 * @param {boolean=} opt_justHide Whether {@code el} should be hidden with no | 149 * @param {boolean=} opt_justHide Whether {@code el} should be hidden with no |
| 147 * animation. | 150 * animation. |
| 148 */ | 151 */ |
| 149 function fadeOutOption(el, opt_justHide) { | 152 function fadeOutOption(el, opt_justHide) { |
| 150 if (!el.classList.contains('visible')) | 153 if (!el.classList.contains('visible')) |
| 151 return; | 154 return; |
| 152 | 155 |
| 153 var leftColumn = el.querySelector('.left-column'); | 156 var leftColumn = assertInstanceof(el.querySelector('.left-column'), |
| 157 HTMLElement); |
| 154 wrapContentsInDiv(leftColumn, ['visible']); | 158 wrapContentsInDiv(leftColumn, ['visible']); |
| 155 var rightColumn = el.querySelector('.right-column'); | 159 var rightColumn = assertInstanceof(el.querySelector('.right-column'), |
| 156 wrapContentsInDiv(rightColumn, ['visible']); | 160 HTMLElement); |
| 161 if (rightColumn) |
| 162 wrapContentsInDiv(rightColumn, ['visible']); |
| 157 | 163 |
| 158 var toAnimate = el.querySelectorAll('.collapsible'); | 164 var toAnimate = el.querySelectorAll('.collapsible'); |
| 159 for (var i = 0; i < toAnimate.length; i++) { | 165 for (var i = 0; i < toAnimate.length; i++) { |
| 160 if (opt_justHide) { | 166 if (opt_justHide) { |
| 161 toAnimate[i].hidden = true; | 167 toAnimate[i].hidden = true; |
| 162 toAnimate[i].classList.add('closing'); | 168 toAnimate[i].classList.add('closing'); |
| 163 toAnimate[i].classList.remove('visible'); | 169 toAnimate[i].classList.remove('visible'); |
| 164 } else { | 170 } else { |
| 165 fadeOutElement(toAnimate[i]); | 171 fadeOutElement(assertInstanceof(toAnimate[i], HTMLElement)); |
| 166 } | 172 } |
| 167 } | 173 } |
| 168 el.classList.remove('visible'); | 174 el.classList.remove('visible'); |
| 169 } | 175 } |
| 170 | 176 |
| 171 /** | 177 /** |
| 172 * Wraps the contents of |el| in a div element and attaches css classes | 178 * 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 | 179 * |classes| in the new div, only if has not been already done. It is necessary |
| 174 * for animating the height of table cells. | 180 * for animating the height of table cells. |
| 175 * @param {HTMLElement} el The element to be processed. | 181 * @param {!HTMLElement} el The element to be processed. |
| 176 * @param {array} classes The css classes to add. | 182 * @param {!Array} classes The css classes to add. |
| 177 */ | 183 */ |
| 178 function wrapContentsInDiv(el, classes) { | 184 function wrapContentsInDiv(el, classes) { |
| 179 var div = el.querySelector('div'); | 185 var div = el.querySelector('div'); |
| 180 if (!div || !div.classList.contains('collapsible')) { | 186 if (!div || !div.classList.contains('collapsible')) { |
| 181 div = document.createElement('div'); | 187 div = document.createElement('div'); |
| 182 while (el.childNodes.length > 0) | 188 while (el.childNodes.length > 0) |
| 183 div.appendChild(el.firstChild); | 189 div.appendChild(el.firstChild); |
| 184 el.appendChild(div); | 190 el.appendChild(div); |
| 185 } | 191 } |
| 186 | 192 |
| 187 div.className = ''; | 193 div.className = ''; |
| 188 div.classList.add('collapsible'); | 194 div.classList.add('collapsible'); |
| 189 for (var i = 0; i < classes.length; i++) | 195 for (var i = 0; i < classes.length; i++) |
| 190 div.classList.add(classes[i]); | 196 div.classList.add(classes[i]); |
| 191 } | 197 } |
| OLD | NEW |