Home | History | Annotate | Download | only in extensions
      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