Path: blob/trunk/third_party/closure/goog/labs/dom/pagevisibilitymonitor.js
2868 views
// Copyright 2013 The Closure Library Authors. All Rights Reserved.1//2// Licensed under the Apache License, Version 2.0 (the "License");3// you may not use this file except in compliance with the License.4// You may obtain a copy of the License at5//6// http://www.apache.org/licenses/LICENSE-2.07//8// Unless required by applicable law or agreed to in writing, software9// distributed under the License is distributed on an "AS-IS" BASIS,10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.11// See the License for the specific language governing permissions and12// limitations under the License.1314/**15* @fileoverview This event monitor wraps the Page Visibility API.16* @see http://www.w3.org/TR/page-visibility/17*/1819goog.provide('goog.labs.dom.PageVisibilityEvent');20goog.provide('goog.labs.dom.PageVisibilityMonitor');21goog.provide('goog.labs.dom.PageVisibilityState');2223goog.require('goog.dom');24goog.require('goog.dom.vendor');25goog.require('goog.events');26goog.require('goog.events.Event');27goog.require('goog.events.EventTarget');28goog.require('goog.events.EventType');29goog.require('goog.memoize');303132/**33* The different visibility states.34* @enum {string}35*/36goog.labs.dom.PageVisibilityState = {37HIDDEN: 'hidden',38VISIBLE: 'visible',39PRERENDER: 'prerender',40UNLOADED: 'unloaded'41};42434445/**46* This event handler allows you to catch page visibility change events.47* @param {!goog.dom.DomHelper=} opt_domHelper48* @constructor49* @extends {goog.events.EventTarget}50* @final51*/52goog.labs.dom.PageVisibilityMonitor = function(opt_domHelper) {53goog.labs.dom.PageVisibilityMonitor.base(this, 'constructor');5455/**56* @private {!goog.dom.DomHelper}57*/58this.domHelper_ = opt_domHelper || goog.dom.getDomHelper();5960/**61* @private {?string}62*/63this.eventType_ = this.getBrowserEventType_();6465// Some browsers do not support visibilityChange and therefore we don't bother66// setting up events.67if (this.eventType_) {68/**69* @private {goog.events.Key}70*/71this.eventKey_ = goog.events.listen(72this.domHelper_.getDocument(), this.eventType_,73goog.bind(this.handleChange_, this));74}75};76goog.inherits(goog.labs.dom.PageVisibilityMonitor, goog.events.EventTarget);777879/**80* @return {?string} The visibility change event type, or null if not supported.81* Memoized for performance.82* @private83*/84goog.labs.dom.PageVisibilityMonitor.prototype85.getBrowserEventType_ = goog.memoize(function() {86var isSupported =87/** @type {!goog.labs.dom.PageVisibilityMonitor} */ (this).isSupported();88var isPrefixed =89/** @type {!goog.labs.dom.PageVisibilityMonitor} */ (this).isPrefixed_();9091if (isSupported) {92return isPrefixed ?93goog.dom.vendor.getPrefixedEventType(94goog.events.EventType.VISIBILITYCHANGE) :95goog.events.EventType.VISIBILITYCHANGE;96} else {97return null;98}99});100101102/**103* @return {?string} The browser-specific document.hidden property. Memoized104* for performance.105* @private106*/107goog.labs.dom.PageVisibilityMonitor.prototype.getHiddenPropertyName_ =108goog.memoize(function() {109return goog.dom.vendor.getPrefixedPropertyName(110'hidden',111/** @type {!goog.labs.dom.PageVisibilityMonitor} */112(this).domHelper_.getDocument());113});114115116/**117* @return {boolean} Whether the visibility API is prefixed.118* @private119*/120goog.labs.dom.PageVisibilityMonitor.prototype.isPrefixed_ = function() {121return this.getHiddenPropertyName_() != 'hidden';122};123124125/**126* @return {?string} The browser-specific document.visibilityState property.127* Memoized for performance.128* @private129*/130goog.labs.dom.PageVisibilityMonitor.prototype.getVisibilityStatePropertyName_ =131goog.memoize(function() {132return goog.dom.vendor.getPrefixedPropertyName(133'visibilityState',134/** @type {!goog.labs.dom.PageVisibilityMonitor} */135(this).domHelper_.getDocument());136});137138139/**140* @return {boolean} Whether the visibility API is supported.141*/142goog.labs.dom.PageVisibilityMonitor.prototype.isSupported = function() {143return !!this.getHiddenPropertyName_();144};145146147/**148* @return {boolean} Whether the page is visible.149*/150goog.labs.dom.PageVisibilityMonitor.prototype.isHidden = function() {151return !!this.domHelper_.getDocument()[this.getHiddenPropertyName_()];152};153154155/**156* @return {?goog.labs.dom.PageVisibilityState} The page visibility state, or157* null if not supported.158*/159goog.labs.dom.PageVisibilityMonitor.prototype.getVisibilityState = function() {160if (!this.isSupported()) {161return null;162}163return this.domHelper_.getDocument()[this.getVisibilityStatePropertyName_()];164};165166167/**168* Handles the events on the element.169* @param {goog.events.BrowserEvent} e The underlying browser event.170* @private171*/172goog.labs.dom.PageVisibilityMonitor.prototype.handleChange_ = function(e) {173var state = this.getVisibilityState();174var visibilityEvent = new goog.labs.dom.PageVisibilityEvent(175this.isHidden(),176/** @type {goog.labs.dom.PageVisibilityState} */ (state));177this.dispatchEvent(visibilityEvent);178};179180181/** @override */182goog.labs.dom.PageVisibilityMonitor.prototype.disposeInternal = function() {183goog.events.unlistenByKey(this.eventKey_);184goog.labs.dom.PageVisibilityMonitor.base(this, 'disposeInternal');185};186187188189/**190* A page visibility change event.191* @param {boolean} hidden Whether the page is hidden.192* @param {goog.labs.dom.PageVisibilityState} visibilityState A more detailed193* visibility state.194* @constructor195* @extends {goog.events.Event}196* @final197*/198goog.labs.dom.PageVisibilityEvent = function(hidden, visibilityState) {199goog.labs.dom.PageVisibilityEvent.base(200this, 'constructor', goog.events.EventType.VISIBILITYCHANGE);201202/**203* Whether the page is hidden.204* @type {boolean}205*/206this.hidden = hidden;207208/**209* A more detailed visibility state.210* @type {goog.labs.dom.PageVisibilityState}211*/212this.visibilityState = visibilityState;213};214goog.inherits(goog.labs.dom.PageVisibilityEvent, goog.events.Event);215216217