Home | History | Annotate | Download | only in media
      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.
      4 
      5 'use strict';
      6 
      7 /**
      8  * A controller class detects mouse inactivity and hides "tool" elements.
      9  *
     10  * @param {Element} container The main DOM container.
     11  * @param {number=} opt_timeout Hide timeout in ms.
     12  * @param {function():boolean=} opt_toolsActive Function that returns |true|
     13  *     if the tools are active and should not be hidden.
     14  * @constructor
     15  */
     16 function MouseInactivityWatcher(container, opt_timeout, opt_toolsActive) {
     17   this.container_ = container;
     18   this.timeout_ = opt_timeout || MouseInactivityWatcher.DEFAULT_TIMEOUT;
     19   this.toolsActive_ = opt_toolsActive || function() { return false };
     20 
     21   this.onTimeoutBound_ = this.onTimeout_.bind(this);
     22   this.timeoutID_ = null;
     23   this.mouseOverTool_ = false;
     24 
     25   this.clientX_ = 0;
     26   this.clientY_ = 0;
     27 
     28   /**
     29    * Indicates if the inactivity watcher is enabled or disabled. Use getters
     30    * and setters.
     31    * @type {boolean}
     32    * @private
     33    **/
     34   this.disabled_ = false;
     35   this.__defineSetter__('disabled', function(value) {
     36     this.disabled_ = value;
     37     if (value)
     38       this.kick();
     39     else
     40       this.check();
     41   });
     42   this.__defineGetter__('disabled', function() {
     43     return this.disabled_;
     44   });
     45 
     46   this.container_.addEventListener('mousemove', this.onMouseMove_.bind(this));
     47   var tools = this.container_.querySelector('.tool');
     48   for (var i = 0; i < tools.length; i++) {
     49     tools[i].addEventListener('mouseover', this.onToolMouseOver_.bind(this));
     50     tools[i].addEventListener('mouseout', this.onToolMouseOut_.bind(this));
     51   }
     52 
     53   // Show tools when the user touches the screen.
     54   this.container_.addEventListener(
     55       'touchstart', this.activityStarted_.bind(this));
     56   var initiateFading = this.activityStopped_.bind(this, this.timeout_);
     57   this.container_.addEventListener('touchend', initiateFading);
     58   this.container_.addEventListener('touchcancel', initiateFading);
     59 }
     60 
     61 /**
     62  * Default inactivity timeout.
     63  */
     64 MouseInactivityWatcher.DEFAULT_TIMEOUT = 3000;
     65 
     66 /**
     67  * @param {boolean} on True if show, false if hide.
     68  */
     69 MouseInactivityWatcher.prototype.showTools = function(on) {
     70   if (on)
     71     this.container_.setAttribute('tools', 'true');
     72   else
     73     this.container_.removeAttribute('tools');
     74 };
     75 
     76 /**
     77  * To be called when the user started activity. Shows the tools
     78  * and cancels the countdown.
     79  * @private
     80  */
     81 MouseInactivityWatcher.prototype.activityStarted_ = function() {
     82   this.showTools(true);
     83 
     84   if (this.timeoutID_) {
     85     clearTimeout(this.timeoutID_);
     86     this.timeoutID_ = null;
     87   }
     88 };
     89 
     90 /**
     91  * Called when user activity has stopped. Re-starts the countdown.
     92  * @param {number=} opt_timeout Timeout.
     93  * @private
     94  */
     95 MouseInactivityWatcher.prototype.activityStopped_ = function(opt_timeout) {
     96   if (this.disabled_ || this.mouseOverTool_ || this.toolsActive_())
     97     return;
     98 
     99   if (this.timeoutID_)
    100     clearTimeout(this.timeoutID_);
    101 
    102   this.timeoutID_ = setTimeout(
    103       this.onTimeoutBound_, opt_timeout || this.timeout_);
    104 };
    105 
    106 /**
    107  * Called when a user performed a short action (such as a click or a key press)
    108  * that should show the tools if they are not visible.
    109  * @param {number=} opt_timeout Timeout.
    110  */
    111 MouseInactivityWatcher.prototype.kick = function(opt_timeout) {
    112   this.activityStarted_();
    113   this.activityStopped_(opt_timeout);
    114 };
    115 
    116 /**
    117  * Check if the tools are active and update the tools visibility accordingly.
    118  */
    119 MouseInactivityWatcher.prototype.check = function() {
    120   if (this.toolsActive_())
    121     this.activityStarted_();
    122   else
    123     this.activityStopped_();
    124 };
    125 
    126 /**
    127  * Mouse move handler.
    128  *
    129  * @param {Event} e Event.
    130  * @private
    131  */
    132 MouseInactivityWatcher.prototype.onMouseMove_ = function(e) {
    133   if (this.clientX_ == e.clientX && this.clientY_ == e.clientY) {
    134     // The mouse has not moved, must be the cursor change triggered by
    135     // some of the attributes on the root container. Ignore the event.
    136     return;
    137   }
    138   this.clientX_ = e.clientX;
    139   this.clientY_ = e.clientY;
    140 
    141   if (this.disabled_)
    142     return;
    143 
    144   this.kick();
    145 };
    146 
    147 /**
    148  * Mouse over handler on a tool element.
    149  *
    150  * @param {Event} e Event.
    151  * @private
    152  */
    153 MouseInactivityWatcher.prototype.onToolMouseOver_ = function(e) {
    154   this.mouseOverTool_ = true;
    155   if (!this.disabled_)
    156     this.kick();
    157 };
    158 
    159 /**
    160  * Mouse out handler on a tool element.
    161  *
    162  * @param {Event} e Event.
    163  * @private
    164  */
    165 MouseInactivityWatcher.prototype.onToolMouseOut_ = function(e) {
    166   this.mouseOverTool_ = false;
    167   if (!this.disabled_)
    168     this.kick();
    169 };
    170 
    171 /**
    172  * Timeout handler.
    173  * @private
    174  */
    175 MouseInactivityWatcher.prototype.onTimeout_ = function() {
    176   this.timeoutID_ = null;
    177   if (!this.disabled_ && !this.toolsActive_())
    178     this.showTools(false);
    179 };
    180