| // Copyright 2013 The Closure Library Authors. All Rights Reserved. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS-IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| /** |
| * @fileoverview Utility class that monitors pixel density ratio changes. |
| * |
| * @see ../demos/pixeldensitymonitor.html |
| */ |
| |
| goog.provide('goog.labs.style.PixelDensityMonitor'); |
| goog.provide('goog.labs.style.PixelDensityMonitor.Density'); |
| goog.provide('goog.labs.style.PixelDensityMonitor.EventType'); |
| |
| goog.require('goog.events'); |
| goog.require('goog.events.EventTarget'); |
| |
| |
| |
| /** |
| * Monitors the window for changes to the ratio between device and screen |
| * pixels, e.g. when the user moves the window from a high density screen to a |
| * screen with normal density. Dispatches |
| * goog.labs.style.PixelDensityMonitor.EventType.CHANGE events when the density |
| * changes between the two predefined values NORMAL and HIGH. |
| * |
| * This class uses the window.devicePixelRatio value which is supported in |
| * WebKit and FF18. If the value does not exist, it will always return a |
| * NORMAL density. It requires support for MediaQueryList to detect changes to |
| * the devicePixelRatio. |
| * |
| * @param {!goog.dom.DomHelper=} opt_domHelper The DomHelper which contains the |
| * document associated with the window to listen to. Defaults to the one in |
| * which this code is executing. |
| * @constructor |
| * @extends {goog.events.EventTarget} |
| * @final |
| */ |
| goog.labs.style.PixelDensityMonitor = function(opt_domHelper) { |
| goog.labs.style.PixelDensityMonitor.base(this, 'constructor'); |
| |
| /** |
| * @type {Window} |
| * @private |
| */ |
| this.window_ = opt_domHelper ? opt_domHelper.getWindow() : window; |
| |
| /** |
| * The last density that was reported so that changes can be detected. |
| * @type {goog.labs.style.PixelDensityMonitor.Density} |
| * @private |
| */ |
| this.lastDensity_ = this.getDensity(); |
| |
| /** |
| * @type {function (MediaQueryList)} |
| * @private |
| */ |
| this.listener_ = goog.bind(this.handleMediaQueryChange_, this); |
| |
| /** |
| * The media query list for a query that detects high density, if supported |
| * by the browser. Because matchMedia returns a new object for every call, it |
| * needs to be saved here so the listener can be removed when disposing. |
| * @type {?MediaQueryList} |
| * @private |
| */ |
| this.mediaQueryList_ = this.window_.matchMedia ? this.window_.matchMedia( |
| goog.labs.style.PixelDensityMonitor.HIGH_DENSITY_QUERY_) : null; |
| }; |
| goog.inherits(goog.labs.style.PixelDensityMonitor, goog.events.EventTarget); |
| |
| |
| /** |
| * The two different pixel density modes on which the various ratios between |
| * physical and device pixels are mapped. |
| * @enum {number} |
| */ |
| goog.labs.style.PixelDensityMonitor.Density = { |
| /** |
| * Mode for older portable devices and desktop screens, defined as having a |
| * device pixel ratio of less than 1.5. |
| */ |
| NORMAL: 1, |
| |
| /** |
| * Mode for newer portable devices with a high resolution screen, defined as |
| * having a device pixel ratio of more than 1.5. |
| */ |
| HIGH: 2 |
| }; |
| |
| |
| /** |
| * The events fired by the PixelDensityMonitor. |
| * @enum {string} |
| */ |
| goog.labs.style.PixelDensityMonitor.EventType = { |
| /** |
| * Dispatched when density changes between NORMAL and HIGH. |
| */ |
| CHANGE: goog.events.getUniqueId('change') |
| }; |
| |
| |
| /** |
| * Minimum ratio between device and screen pixel needed for high density mode. |
| * @type {number} |
| * @private |
| */ |
| goog.labs.style.PixelDensityMonitor.HIGH_DENSITY_RATIO_ = 1.5; |
| |
| |
| /** |
| * Media query that matches for high density. |
| * @type {string} |
| * @private |
| */ |
| goog.labs.style.PixelDensityMonitor.HIGH_DENSITY_QUERY_ = |
| '(min-resolution: 1.5dppx), (-webkit-min-device-pixel-ratio: 1.5)'; |
| |
| |
| /** |
| * Starts monitoring for changes in pixel density. |
| */ |
| goog.labs.style.PixelDensityMonitor.prototype.start = function() { |
| if (this.mediaQueryList_) { |
| this.mediaQueryList_.addListener(this.listener_); |
| } |
| }; |
| |
| |
| /** |
| * @return {goog.labs.style.PixelDensityMonitor.Density} The density for the |
| * window. |
| */ |
| goog.labs.style.PixelDensityMonitor.prototype.getDensity = function() { |
| if (this.window_.devicePixelRatio >= |
| goog.labs.style.PixelDensityMonitor.HIGH_DENSITY_RATIO_) { |
| return goog.labs.style.PixelDensityMonitor.Density.HIGH; |
| } else { |
| return goog.labs.style.PixelDensityMonitor.Density.NORMAL; |
| } |
| }; |
| |
| |
| /** |
| * Handles a change to the media query and checks whether the density has |
| * changed since the last call. |
| * @param {MediaQueryList} mql The list of changed media queries. |
| * @private |
| */ |
| goog.labs.style.PixelDensityMonitor.prototype.handleMediaQueryChange_ = |
| function(mql) { |
| var newDensity = this.getDensity(); |
| if (this.lastDensity_ != newDensity) { |
| this.lastDensity_ = newDensity; |
| this.dispatchEvent(goog.labs.style.PixelDensityMonitor.EventType.CHANGE); |
| } |
| }; |
| |
| |
| /** @override */ |
| goog.labs.style.PixelDensityMonitor.prototype.disposeInternal = function() { |
| if (this.mediaQueryList_) { |
| this.mediaQueryList_.removeListener(this.listener_); |
| } |
| goog.labs.style.PixelDensityMonitor.base(this, 'disposeInternal'); |
| }; |