1 // Copyright 2014 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 cr.define('extensions', function() { 6 'use strict'; 7 8 /** 9 * The ExtensionOptionsOverlay will show an extension's options page using 10 * an <extensionoptions> element. 11 * @constructor 12 */ 13 function ExtensionOptionsOverlay() {} 14 15 cr.addSingletonGetter(ExtensionOptionsOverlay); 16 17 ExtensionOptionsOverlay.prototype = { 18 /** 19 * The function that shows the given element in the overlay. 20 * @type {?function(HTMLDivElement)} Function that receives the element to 21 * show in the overlay. 22 * @private 23 */ 24 showOverlay_: null, 25 26 /** 27 * Initialize the page. 28 * @param {function(HTMLDivElement)} showOverlay The function to show or 29 * hide the ExtensionOptionsOverlay; this should take a single parameter 30 * which is either the overlay Div if the overlay should be displayed, 31 * or null if the overlay should be hidden. 32 */ 33 initializePage: function(showOverlay) { 34 var overlay = $('overlay'); 35 36 cr.ui.overlay.setupOverlay(overlay); 37 cr.ui.overlay.globalInitialization(); 38 overlay.addEventListener('cancelOverlay', this.handleDismiss_.bind(this)); 39 40 this.showOverlay_ = showOverlay; 41 }, 42 43 /** 44 * Handles a click on the close button. 45 * @param {Event} event The click event. 46 * @private 47 */ 48 handleDismiss_: function(event) { 49 this.setVisible_(false); 50 var extensionoptions = 51 $('extension-options-overlay-guest') 52 .querySelector('extensionoptions'); 53 54 if (extensionoptions) 55 $('extension-options-overlay-guest').removeChild(extensionoptions); 56 57 $('extension-options-overlay-icon').removeAttribute('src'); 58 59 // Remove the options query string. 60 uber.replaceState({}, ''); 61 }, 62 63 /** 64 * Associate an extension with the overlay and display it. 65 * @param {string} extensionId The id of the extension whose options page 66 * should be displayed in the overlay. 67 * @param {string} extensionName The name of the extension, which is used 68 * as the header of the overlay. 69 * @param {string} extensionIcon The URL of the extension's icon. 70 */ 71 setExtensionAndShowOverlay: function(extensionId, 72 extensionName, 73 extensionIcon) { 74 $('extension-options-overlay-title').textContent = extensionName; 75 $('extension-options-overlay-icon').src = extensionIcon; 76 77 this.setVisible_(true); 78 79 var extensionoptions = new ExtensionOptions(); 80 extensionoptions.extension = extensionId; 81 extensionoptions.autosize = 'on'; 82 83 // The <extensionoptions> content's size needs to be restricted to the 84 // bounds of the overlay window. The overlay gives a min width and 85 // max height, but the maxheight does not include our header height 86 // (title and close button), so we need to subtract that to get the 87 // max height for the extension options. 88 var headerHeight = $('extension-options-overlay-header').offsetHeight; 89 var overlayMaxHeight = 90 parseInt($('extension-options-overlay').style.maxHeight); 91 extensionoptions.maxheight = overlayMaxHeight - headerHeight; 92 93 extensionoptions.minwidth = 94 parseInt(window.getComputedStyle($('extension-options-overlay')) 95 .minWidth); 96 97 extensionoptions.setDeferAutoSize(true); 98 99 extensionoptions.onclose = function() { 100 cr.dispatchSimpleEvent($('overlay'), 'cancelOverlay'); 101 }.bind(this); 102 103 // Resize the overlay if the <extensionoptions> changes size. 104 extensionoptions.onsizechanged = function(evt) { 105 var overlayStyle = 106 window.getComputedStyle($('extension-options-overlay')); 107 var oldWidth = parseInt(overlayStyle.width); 108 var oldHeight = parseInt(overlayStyle.height); 109 110 // animationTime is the amount of time in ms that will be used to resize 111 // the overlay. It is calculated by multiplying the pythagorean distance 112 // between old and the new size (in px) with a constant speed of 113 // 0.25 ms/px. 114 var animationTime = 0.25 * Math.sqrt( 115 Math.pow(evt.newWidth - oldWidth, 2) + 116 Math.pow(evt.newHeight - oldHeight, 2)); 117 118 var player = $('extension-options-overlay').animate([ 119 {width: oldWidth + 'px', height: oldHeight + 'px'}, 120 {width: evt.newWidth + 'px', height: evt.newHeight + 'px'} 121 ], { 122 duration: animationTime, 123 delay: 0 124 }); 125 126 player.onfinish = function(e) { 127 // Allow the <extensionoptions> to autosize now that the overlay 128 // has resized, and move it back on-screen. 129 extensionoptions.resumeDeferredAutoSize(); 130 $('extension-options-overlay-guest').style.position = 'static'; 131 $('extension-options-overlay-guest').style.left = 'auto'; 132 }; 133 }.bind(this); 134 135 // Don't allow the <extensionoptions> to autosize until the overlay 136 // animation is complete. 137 extensionoptions.setDeferAutoSize(true); 138 139 // Move the <extensionoptions> off screen until the overlay is ready 140 $('extension-options-overlay-guest').style.position = 'fixed'; 141 $('extension-options-overlay-guest').style.left = 142 window.outerWidth + 'px'; 143 144 $('extension-options-overlay-guest').appendChild(extensionoptions); 145 }, 146 147 /** 148 * Toggles the visibility of the ExtensionOptionsOverlay. 149 * @param {boolean} isVisible Whether the overlay should be visible. 150 * @private 151 */ 152 setVisible_: function(isVisible) { 153 this.showOverlay_(isVisible ? 154 /** @type {HTMLDivElement} */($('extension-options-overlay')) : 155 null); 156 } 157 }; 158 159 // Export 160 return { 161 ExtensionOptionsOverlay: ExtensionOptionsOverlay 162 }; 163 }); 164