Permalink
Browse files

Adds a pixel density monitor to the closure labs that can be queried …

…for the current pixel density of a window and dispatches events when it changes.

The pixel densities are mapped to two different modes:
- NORMAL for older screens with a ratio of less than 1.5.
- HIGH for modern screens with a bigger ratio.

Tested on Chrome and FF > 18.

R=chrishenry
DELTA=531 (513 added, 18 deleted, 0 changed)


Revision created by MOE tool push_codebase.
MOE_MIGRATION=6082


git-svn-id: http://closure-library.googlecode.com/svn/trunk@2416 0b95b8e8-c90f-11de-9d4f-f947ee5921c8
  • Loading branch information...
1 parent 23d4791 commit a8a7f25a7f960b727262ab8f033f7068b439d275 mkaeser@google.com committed Jan 5, 2013
View

Large diffs are not rendered by default.

Oops, something went wrong.
@@ -132,6 +132,7 @@
{name: 'JSON Pretty Printer', url: 'jsonprettyprinter.html'},
{name: 'Label Input', url: 'labelinput.html'},
{name: 'Offline UI', url: 'offline.html'},
+ {name: 'Pixel Density Monitor', url: 'pixeldensitymonitor.html'},
{name: 'Plain Text Spell Checker', url: 'plaintextspellchecker.html'},
{name: 'Popup', url: 'popup.html'},
{name: 'Progress Bar', url: 'progressbar.html'},
@@ -0,0 +1,50 @@
+<!doctype html>
+<html>
+<!--
+Copyright 2013 The Closure Library Authors. All Rights Reserved.
+
+Use of this source code is governed by the Apache License, Version 2.0.
+See the COPYING file for details.
+-->
+<head>
+ <title>goog.labs.style.PixelDensityMonitor</title>
+ <script src="../base.js"></script>
+ <script>
+ goog.require('goog.debug.DivConsole');
+ goog.require('goog.debug.Logger');
+ goog.require('goog.events');
+ goog.require('goog.events.EventType');
+ goog.require('goog.labs.style.PixelDensityMonitor');
+ goog.require('goog.labs.style.PixelDensityMonitor.Density');
+ </script>
+ <link rel="stylesheet" href="css/demo.css">
+</head>
+<body>
+ <h1>goog.labs.style.PixelDensityMonitor</h1>
+ <div>
+ Move between high dpi and normal screens to see density change events.
+ </div>
+ <fieldset class="goog-debug-panel">
+ <legend>Event log</legend>
+ <div class="log" id="log"></div>
+ </fieldset>
+ <script>
+ var logger = goog.debug.Logger.getLogger('PixelDensityMonitor');
+
+ new goog.debug.DivConsole(goog.dom.getElement('log')).setCapturing(true);
+
+ var monitor = new goog.labs.style.PixelDensityMonitor();
+ monitor.start();
+
+ var densityMap = goog.object.create(
+ goog.labs.style.PixelDensityMonitor.Density.NORMAL, 'NORMAL',
+ goog.labs.style.PixelDensityMonitor.Density.HIGH, 'HIGH');
+
+ goog.events.listen(monitor, goog.events.EventType.CHANGE, function() {
+ logger.info('Density change: ' + densityMap[monitor.getDensity()]);
+ });
+
+ logger.info('Starting density: ' + densityMap[monitor.getDensity()]);
+ </script>
+</body>
+</html>
View

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.
@@ -0,0 +1,179 @@
+// 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.asserts');
+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}
+ */
+goog.labs.style.PixelDensityMonitor = function(opt_domHelper) {
+ goog.base(this);
+
+ /**
+ * @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: 144dpi), (-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.base(this, 'disposeInternal');
+};
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+<!--
+Copyright 2013 The Closure Library Authors. All Rights Reserved.
+
+Use of this source code is governed by the Apache License, Version 2.0.
+See the COPYING file for details.
+-->
+<head>
+<title>Tests for goog.labs.style.PixelDensityMonitor</title>
+<script src="../../base.js"></script>
+<script>
+goog.require('goog.labs.style.PixelDensityMonitorTest');
+</script>
+<body>
+</body>
+</html>
Oops, something went wrong.

0 comments on commit a8a7f25

Please sign in to comment.