UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

370 lines (365 loc) • 13.2 kB
/** * DevExtreme (core/devices.js) * Version: 20.1.7 * Build date: Tue Aug 25 2020 * * Copyright (c) 2012 - 2020 Developer Express Inc. ALL RIGHTS RESERVED * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/ */ "use strict"; var _renderer = require("../core/renderer"); var _renderer2 = _interopRequireDefault(_renderer); var _window = require("./utils/window"); var _window2 = _interopRequireDefault(_window); var _extend = require("./utils/extend"); var _type = require("./utils/type"); var _iterator = require("./utils/iterator"); var _errors = require("./errors"); var _errors2 = _interopRequireDefault(_errors); var _callbacks = require("./utils/callbacks"); var _callbacks2 = _interopRequireDefault(_callbacks); var _ready_callbacks = require("./utils/ready_callbacks"); var _ready_callbacks2 = _interopRequireDefault(_ready_callbacks); var _resize_callbacks = require("./utils/resize_callbacks"); var _resize_callbacks2 = _interopRequireDefault(_resize_callbacks); var _events_strategy = require("./events_strategy"); var _storage = require("./utils/storage"); var _view_port = require("./utils/view_port"); var _view_port2 = _interopRequireDefault(_view_port); var _config = require("./config"); var _config2 = _interopRequireDefault(_config); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj } } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function") } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) { descriptor.writable = true } Object.defineProperty(target, descriptor.key, descriptor) } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) { _defineProperties(Constructor.prototype, protoProps) } if (staticProps) { _defineProperties(Constructor, staticProps) } return Constructor } var navigator = _window2.default.getNavigator(); var window = _window2.default.getWindow(); var KNOWN_UA_TABLE = { iPhone: "iPhone", iPhone5: "iPhone", iPhone6: "iPhone", iPhone6plus: "iPhone", iPad: "iPad", iPadMini: "iPad Mini", androidPhone: "Android Mobile", androidTablet: "Android", msSurface: "Windows ARM Tablet PC", desktop: "desktop" }; var DEFAULT_DEVICE = { deviceType: "desktop", platform: "generic", version: [], phone: false, tablet: false, android: false, ios: false, generic: true, grade: "A", mac: false }; var uaParsers = { generic: function(userAgent) { var isPhone = /windows phone/i.test(userAgent) || userAgent.match(/WPDesktop/); var isTablet = !isPhone && /Windows(.*)arm(.*)Tablet PC/i.test(userAgent); var isDesktop = !isPhone && !isTablet && /msapphost/i.test(userAgent); var isMac = /((intel|ppc) mac os x)/.test(userAgent.toLowerCase()); if (!(isPhone || isTablet || isDesktop || isMac)) { return } return { deviceType: isPhone ? "phone" : isTablet ? "tablet" : "desktop", platform: "generic", version: [], grade: "A", mac: isMac } }, ios: function(userAgent) { if (!/ip(hone|od|ad)/i.test(userAgent)) { return } var isPhone = /ip(hone|od)/i.test(userAgent); var matches = userAgent.match(/os (\d+)_(\d+)_?(\d+)?/i); var version = matches ? [parseInt(matches[1], 10), parseInt(matches[2], 10), parseInt(matches[3] || 0, 10)] : []; var isIPhone4 = 480 === window.screen.height; var grade = isIPhone4 ? "B" : "A"; return { deviceType: isPhone ? "phone" : "tablet", platform: "ios", version: version, grade: grade } }, android: function(userAgent) { if (!/android|htc_|silk/i.test(userAgent)) { return } var isPhone = /mobile/i.test(userAgent); var matches = userAgent.match(/android (\d+)\.?(\d+)?\.?(\d+)?/i); var version = matches ? [parseInt(matches[1], 10), parseInt(matches[2] || 0, 10), parseInt(matches[3] || 0, 10)] : []; var worseThan4_4 = version.length > 1 && (version[0] < 4 || 4 === version[0] && version[1] < 4); var grade = worseThan4_4 ? "B" : "A"; return { deviceType: isPhone ? "phone" : "tablet", platform: "android", version: version, grade: grade } } }; var Devices = function() { function Devices(options) { _classCallCheck(this, Devices); this._window = (null === options || void 0 === options ? void 0 : options.window) || window; this._realDevice = this._getDevice(); this._currentDevice = void 0; this._currentOrientation = void 0; this._eventsStrategy = new _events_strategy.EventsStrategy(this); this.changed = (0, _callbacks2.default)(); if (_window2.default.hasWindow()) { _ready_callbacks2.default.add(this._recalculateOrientation.bind(this)); _resize_callbacks2.default.add(this._recalculateOrientation.bind(this)) } } _createClass(Devices, [{ key: "current", value: function(deviceOrName) { if (deviceOrName) { this._currentDevice = this._getDevice(deviceOrName); this._forced = true; this.changed.fire(); return } if (!this._currentDevice) { deviceOrName = void 0; try { deviceOrName = this._getDeviceOrNameFromWindowScope() } catch (e) { deviceOrName = this._getDeviceNameFromSessionStorage() } finally { if (!deviceOrName) { deviceOrName = this._getDeviceNameFromSessionStorage() } if (deviceOrName) { this._forced = true } } this._currentDevice = this._getDevice(deviceOrName) } return this._currentDevice } }, { key: "real", value: function(forceDevice) { return (0, _extend.extend)({}, this._realDevice) } }, { key: "orientation", value: function() { return this._currentOrientation } }, { key: "isForced", value: function() { return this._forced } }, { key: "isRippleEmulator", value: function() { return !!this._window.tinyHippos } }, { key: "_getCssClasses", value: function(device) { var result = []; var realDevice = this._realDevice; device = device || this.current(); if (device.deviceType) { result.push("dx-device-".concat(device.deviceType)); if ("desktop" !== device.deviceType) { result.push("dx-device-mobile") } } result.push("dx-device-".concat(realDevice.platform)); if (realDevice.version && realDevice.version.length) { result.push("dx-device-".concat(realDevice.platform, "-").concat(realDevice.version[0])) } if (this.isSimulator()) { result.push("dx-simulator") } if ((0, _config2.default)().rtlEnabled) { result.push("dx-rtl") } return result } }, { key: "attachCssClasses", value: function(element, device) { this._deviceClasses = this._getCssClasses(device).join(" "); (0, _renderer2.default)(element).addClass(this._deviceClasses) } }, { key: "detachCssClasses", value: function(element) { (0, _renderer2.default)(element).removeClass(this._deviceClasses) } }, { key: "isSimulator", value: function() { try { return this._isSimulator || _window2.default.hasWindow() && this._window.top !== this._window.self && this._window.top["dx-force-device"] || this.isRippleEmulator() } catch (e) { return false } } }, { key: "forceSimulator", value: function() { this._isSimulator = true } }, { key: "_getDevice", value: function(deviceName) { if ("genericPhone" === deviceName) { deviceName = { deviceType: "phone", platform: "generic", generic: true } } if ((0, _type.isPlainObject)(deviceName)) { return this._fromConfig(deviceName) } else { var ua; if (deviceName) { ua = KNOWN_UA_TABLE[deviceName]; if (!ua) { throw _errors2.default.Error("E0005") } } else { ua = navigator.userAgent } return this._fromUA(ua) } } }, { key: "_getDeviceOrNameFromWindowScope", value: function() { var result; if (_window2.default.hasWindow() && (this._window.top["dx-force-device-object"] || this._window.top["dx-force-device"])) { result = this._window.top["dx-force-device-object"] || this._window.top["dx-force-device"] } return result } }, { key: "_getDeviceNameFromSessionStorage", value: function() { var sessionStorage = (0, _storage.sessionStorage)(); if (!sessionStorage) { return } var deviceOrName = sessionStorage.getItem("dx-force-device"); try { return JSON.parse(deviceOrName) } catch (ex) { return deviceOrName } } }, { key: "_fromConfig", value: function(config) { var result = (0, _extend.extend)({}, DEFAULT_DEVICE, this._currentDevice, config); var shortcuts = { phone: "phone" === result.deviceType, tablet: "tablet" === result.deviceType, android: "android" === result.platform, ios: "ios" === result.platform, generic: "generic" === result.platform }; return (0, _extend.extend)(result, shortcuts) } }, { key: "_fromUA", value: function(ua) { var config; (0, _iterator.each)(uaParsers, function(platform, parser) { config = parser(ua); return !config }); if (config) { return this._fromConfig(config) } return DEFAULT_DEVICE } }, { key: "_changeOrientation", value: function() { var $window = (0, _renderer2.default)(this._window); var orientation = $window.height() > $window.width() ? "portrait" : "landscape"; if (this._currentOrientation === orientation) { return } this._currentOrientation = orientation; this._eventsStrategy.fireEvent("orientationChanged", [{ orientation: orientation }]) } }, { key: "_recalculateOrientation", value: function() { var windowWidth = (0, _renderer2.default)(this._window).width(); if (this._currentWidth === windowWidth) { return } this._currentWidth = windowWidth; this._changeOrientation() } }, { key: "on", value: function(eventName, eventHandler) { this._eventsStrategy.on(eventName, eventHandler); return this } }, { key: "off", value: function(eventName, eventHandler) { this._eventsStrategy.off(eventName, eventHandler); return this } }]); return Devices }(); var devices = new Devices; _view_port2.default.changeCallback.add(function(viewPort, prevViewport) { devices.detachCssClasses(prevViewport); devices.attachCssClasses(viewPort) }); module.exports = devices; module.exports.default = module.exports;