API Docs for: 0.2.7
Show:

File: lib/helpers/devicePixelRatio.js

'use strict';

var logMethods = require('../log');
var type = require('../type');
var when = require('../when');

var devicePixelRatioScripts = require('../scripts/devicePixelRatio');

var PNGImage = require('pngjs-image');

module.exports = DevicePixelRatio;

/**
 * Device-Pixel-Ratio object
 *
 * @constructor
 * @class DevicePixelRatio
 * @module WebDriver
 * @submodule Helpers
 * @param {Driver} driver
 */
function DevicePixelRatio (driver) {
	this._driver = driver;
}


/////////////////////
// Private Methods //
/////////////////////

/**
 * Logs a method call by an event
 *
 * @param {object} event
 * @method _logMethodCall
 * @private
 */
DevicePixelRatio.prototype._logMethodCall = function (event) {
	event.target = 'DevicePixelRatio';
	this._driver._logMethodCall(event);
};


/**
 * Performs a context dependent JSON request for the current session.
 * The result is parsed for errors.
 *
 * @method _requestJSON
 * @private
 * @param {String} method
 * @param {String} path
 * @param {*} [body]
 * @return {*}
 */
DevicePixelRatio.prototype._requestJSON = function (method, path, body) {
	return this._driver._requestJSON(method, path, body);
};


////////////////////
// Public Methods //
////////////////////

/**
 * Gets the driver object.
 * Direct-access. No need to wait.
 *
 * @return {Driver}
 */
DevicePixelRatio.prototype.getDriver = function () {
	return this._driver;
};


/**
 * Gets the device-pixel-ratio of the browser.
 * If this info is not available yet, then it will determine it.
 * It will then be cached for each driver instance, determining this
 * only once per instance.
 *
 * Note:
 * ```horizontalPadding``` is any element that extents horizontally
 * outside of the document, i.e. negative absolute position.
 *
 * @method getDevicePixelRatio
 * @param {object} [options]
 * @param {int} [options.horizontalPadding=0] Padding of the document
 * @return {number}
 */
DevicePixelRatio.prototype.getDevicePixelRatio = function (options) {
	var devicePixelRatio = this.getDriver().getValue('devicePixelRatio');

	if (devicePixelRatio === null) {
		return when(this._determineDevicePixelRatio(options), function (value) {
			this.getDriver().setValue('devicePixelRatio', value); // Cache value
			return value;
		}.bind(this));
	} else {
		return this.getDriver().utils().resolve(devicePixelRatio);
	}
};

/**
 * Determines the device-pixel-ratio of the browser.
 *
 * @method _determineDevicePixelRatio
 * @param {object} [options]
 * @param {int} [options.horizontalPadding=0] Padding of the document
 * @return {number}
 * @private
 */
DevicePixelRatio.prototype._determineDevicePixelRatio = function (options) {

	var Screenshot = require('./screenshot'),
		screenshot = new Screenshot(this.getDriver());

	options = options || {};

	// Reduce size of document to get a small screenshot for ratio determination
	return when(this._execute(devicePixelRatioScripts.init, [options.horizontalPadding || 0]), function (initData) {
		initData = JSON.parse(initData);

		// Take screenshot (hopefully very small, but big enough to get the ratio right)
		return when(screenshot.takeProcessedScreenshot(), function (image) {

			// Revert document size
			return when(this._execute(devicePixelRatioScripts.revert, [initData]), function () {

				// Determine best ratio: browser delivered or calculated ratio
				var devicePixelRatio = image.getWidth() / initData.documentWidth;

				// Rounding
				if (Math.abs(devicePixelRatio - (Math.round(devicePixelRatio * 10) / 10)) < 0.1) {
					devicePixelRatio = Math.round(devicePixelRatio * 10) / 10;
				}

				if (Math.abs(devicePixelRatio - initData.devicePixelRatio) <= 0.1) {
					return initData.devicePixelRatio;
				} else {
					return devicePixelRatio;
				}

			}.bind(this));
		}.bind(this));
	}.bind(this));
};

/**
 * Executes a script in the browser and returns the result.
 *
 * This is a convenience method for accessing the execute method.
 *
 * @method _execute
 * @param {String|Function} script
 * @param {Array} [args]
 * @return {*}
 * @private
 */
DevicePixelRatio.prototype._execute = function (script, args) {
	if (script) {
		return this.getDriver().browser().activeWindow().execute(script, args);

	} else { // Ignore script if there is nothing
		return this.getDriver().utils().resolve(undefined);
	}
};

logMethods(DevicePixelRatio.prototype);