Home | History | Annotate | Download | only in webapp
      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 /**
      6  * @fileoverview
      7  * Apps v2 custom title bar implementation
      8  */
      9 
     10 'use strict';
     11 
     12 /** @suppress {duplicate} */
     13 var remoting = remoting || {};
     14 
     15 /**
     16  * @param {HTMLElement} titleBar The root node of the title-bar DOM hierarchy.
     17  * @constructor
     18  */
     19 remoting.WindowFrame = function(titleBar) {
     20   /**
     21    * @type {boolean}
     22    * @private
     23    */
     24   this.isConnected_ = false;
     25 
     26   /**
     27    * @type {HTMLElement}
     28    * @private
     29    */
     30   this.titleBar_ = titleBar;
     31 
     32   /**
     33    * @type {HTMLElement}
     34    * @private
     35    */
     36   this.hoverTarget_ = /** @type {HTMLElement} */
     37       (titleBar.querySelector('.window-controls-hover-target'));
     38   base.debug.assert(this.hoverTarget_ != null);
     39 
     40   /**
     41    * @type {HTMLElement}
     42    * @private
     43    */
     44   this.maximizeRestoreControl_ = /** @type {HTMLElement} */
     45       (titleBar.querySelector('.window-maximize-restore'));
     46   base.debug.assert(this.maximizeRestoreControl_ != null);
     47 
     48   /**
     49    * @type {Array.<{cls:string, fn: function()}>}
     50    */
     51   var handlers = [
     52     { cls: 'window-disconnect', fn: this.disconnectSession_.bind(this) },
     53     { cls: 'window-maximize-restore',
     54       fn: this.maximizeOrRestoreWindow_.bind(this) },
     55     { cls: 'window-minimize', fn: this.minimizeWindow_.bind(this) },
     56     { cls: 'window-close', fn: window.close.bind(window) },
     57     { cls: 'window-controls-stub', fn: this.toggleWindowControls_.bind(this) }
     58   ];
     59   for (var i = 0; i < handlers.length; ++i) {
     60     var element = titleBar.querySelector('.' + handlers[i].cls);
     61     base.debug.assert(element != null);
     62     element.addEventListener('click', handlers[i].fn, false);
     63   }
     64 
     65   // Ensure that tool-tips are always correct.
     66   this.updateMaximizeOrRestoreIconTitle_();
     67   chrome.app.window.current().onMaximized.addListener(
     68       this.updateMaximizeOrRestoreIconTitle_.bind(this));
     69   chrome.app.window.current().onRestored.addListener(
     70       this.updateMaximizeOrRestoreIconTitle_.bind(this));
     71   chrome.app.window.current().onFullscreened.addListener(
     72       this.updateMaximizeOrRestoreIconTitle_.bind(this));
     73 };
     74 
     75 /**
     76  * @param {boolean} isConnected True if there is a connection active.
     77  */
     78 remoting.WindowFrame.prototype.setConnected = function(isConnected) {
     79   this.isConnected_ = isConnected;
     80   if (this.isConnected_) {
     81     document.body.classList.add('connected');
     82   } else {
     83     document.body.classList.remove('connected');
     84   }
     85   this.updateMaximizeOrRestoreIconTitle_();
     86 };
     87 
     88 /**
     89  * @return {{width: number, height: number}} The size of the window, ignoring
     90  *     the title-bar and window borders, if visible.
     91  */
     92 remoting.WindowFrame.prototype.getClientArea = function() {
     93   if (chrome.app.window.current().isFullscreen()) {
     94     return { 'height': window.innerHeight, 'width': window.innerWidth };
     95   } else {
     96     var kBorderWidth = 1;
     97     var titleHeight = this.titleBar_.clientHeight;
     98     return {
     99       'height': window.innerHeight - titleHeight - 2 * kBorderWidth,
    100       'width': window.innerWidth - 2 * kBorderWidth
    101     };
    102   }
    103 };
    104 
    105 /**
    106  * @private
    107  */
    108 remoting.WindowFrame.prototype.disconnectSession_ = function() {
    109   // When the user disconnects, exit full-screen mode. This should not be
    110   // necessary, as we do the same thing in client_session.js when the plugin
    111   // is removed. However, there seems to be a bug in chrome.AppWindow.restore
    112   // that causes it to get stuck in full-screen mode without this.
    113   if (chrome.app.window.current().isFullscreen()) {
    114     chrome.app.window.current().restore();
    115   }
    116   remoting.disconnect();
    117 };
    118 
    119 /**
    120  * @private
    121  */
    122 remoting.WindowFrame.prototype.maximizeOrRestoreWindow_ = function() {
    123   /** @type {boolean} */
    124   var restore =
    125       chrome.app.window.current().isFullscreen() ||
    126       chrome.app.window.current().isMaximized();
    127   if (restore) {
    128     // Restore twice: once to exit full-screen and once to exit maximized.
    129     // If the app is not full-screen, or went full-screen without first
    130     // being maximized, then the second restore has no effect.
    131     chrome.app.window.current().restore();
    132   } else if (this.isConnected_) {
    133     chrome.app.window.current().fullscreen();
    134   } else {
    135     chrome.app.window.current().maximize();
    136   }
    137 };
    138 
    139 /**
    140  * @private
    141  */
    142 remoting.WindowFrame.prototype.minimizeWindow_ = function() {
    143   chrome.app.window.current().minimize();
    144 };
    145 
    146 /**
    147  * @private
    148  */
    149 remoting.WindowFrame.prototype.toggleWindowControls_ = function() {
    150   this.hoverTarget_.classList.toggle('opened');
    151 };
    152 
    153 /**
    154  * Update the tool-top for the maximize/full-screen/restore icon to reflect
    155  * its current behaviour.
    156  *
    157  * @private
    158  */
    159 remoting.WindowFrame.prototype.updateMaximizeOrRestoreIconTitle_ = function() {
    160   /** @type {string} */
    161   var tag = '';
    162   if (chrome.app.window.current().isFullscreen()) {
    163     tag = /*i18n-content*/'EXIT_FULL_SCREEN';
    164   } else if (chrome.app.window.current().isMaximized()) {
    165     tag = /*i18n-content*/'RESTORE_WINDOW';
    166   } else if (this.isConnected_) {
    167     tag = /*i18n-content*/'FULL_SCREEN';
    168   } else {
    169     tag = /*i18n-content*/'MAXIMIZE_WINDOW';
    170   }
    171   this.maximizeRestoreControl_.title = l10n.getTranslationOrError(tag);
    172 };
    173 
    174 /** @type {remoting.WindowFrame} */
    175 remoting.windowFrame = null;
    176