1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006 |
- (function (factory) {
- if (typeof module === "object" && typeof module.exports === "object") {
- var v = factory(require, exports);
- if (v !== undefined) module.exports = v;
- }
- else if (typeof define === "function" && define.amd) {
- define(["require", "exports", "@angular/core", "../util/dom", "./query-params", "../util/util"], factory);
- }
- })(function (require, exports) {
- "use strict";
- Object.defineProperty(exports, "__esModule", { value: true });
- var core_1 = require("@angular/core");
- var dom_1 = require("../util/dom");
- var query_params_1 = require("./query-params");
- var util_1 = require("../util/util");
- /**
- * @name Platform
- * @description
- * The Platform service can be used to get information about your current device.
- * You can get all of the platforms associated with the device using the [platforms](#platforms)
- * method, including whether the app is being viewed from a tablet, if it's
- * on a mobile device or browser, and the exact platform (iOS, Android, etc).
- * You can also get the orientation of the device, if it uses right-to-left
- * language direction, and much much more. With this information you can completely
- * customize your app to fit any device.
- *
- * @usage
- * ```ts
- * import { Platform } from 'ionic-angular';
- *
- * @Component({...})
- * export MyPage {
- * constructor(public platform: Platform) {
- *
- * }
- * }
- * ```
- * @demo /docs/demos/src/platform/
- */
- var Platform = (function () {
- function Platform() {
- var _this = this;
- this._versions = {};
- this._qp = new query_params_1.QueryParams();
- this._bbActions = [];
- this._pW = 0;
- this._pH = 0;
- this._lW = 0;
- this._lH = 0;
- this._isPortrait = null;
- this._uiEvtOpts = false;
- /** @internal */
- this._platforms = [];
- // Events meant to be triggered by the engine
- // **********************************************
- /**
- * @hidden
- */
- this.backButton = new core_1.EventEmitter();
- /**
- * The pause event emits when the native platform puts the application
- * into the background, typically when the user switches to a different
- * application. This event would emit when a Cordova app is put into
- * the background, however, it would not fire on a standard web browser.
- */
- this.pause = new core_1.EventEmitter();
- /**
- * The resume event emits when the native platform pulls the application
- * out from the background. This event would emit when a Cordova app comes
- * out from the background, however, it would not fire on a standard web browser.
- */
- this.resume = new core_1.EventEmitter();
- /**
- * The resize event emits when the browser window has changed dimensions. This
- * could be from a browser window being physically resized, or from a device
- * changing orientation.
- */
- this.resize = new core_1.EventEmitter();
- this._readyPromise = new Promise(function (res) { _this._readyResolve = res; });
- this.backButton.subscribe(function () {
- // the hardware back button event has been fired
- (void 0) /* console.debug */;
- // decide which backbutton action should run
- _this.runBackButtonAction();
- });
- }
- /**
- * @hidden
- */
- Platform.prototype.setWindow = function (win) {
- this._win = win;
- };
- /**
- * @hidden
- */
- Platform.prototype.win = function () {
- return this._win;
- };
- /**
- * @hidden
- */
- Platform.prototype.setDocument = function (doc) {
- this._doc = doc;
- };
- /**
- * @hidden
- */
- Platform.prototype.doc = function () {
- return this._doc;
- };
- /**
- * @hidden
- */
- Platform.prototype.setZone = function (zone) {
- this.zone = zone;
- };
- /**
- * @hidden
- */
- Platform.prototype.setCssProps = function (docElement) {
- this.Css = dom_1.getCss(docElement);
- };
- // Methods
- // **********************************************
- /**
- * @returns {boolean} returns true/false based on platform.
- * @description
- * Depending on the platform the user is on, `is(platformName)` will
- * return `true` or `false`. Note that the same app can return `true`
- * for more than one platform name. For example, an app running from
- * an iPad would return `true` for the platform names: `mobile`,
- * `ios`, `ipad`, and `tablet`. Additionally, if the app was running
- * from Cordova then `cordova` would be true, and if it was running
- * from a web browser on the iPad then `mobileweb` would be `true`.
- *
- * ```
- * import { Platform } from 'ionic-angular';
- *
- * @Component({...})
- * export MyPage {
- * constructor(public platform: Platform) {
- * if (this.platform.is('ios')) {
- * // This will only print when on iOS
- * console.log('I am an iOS device!');
- * }
- * }
- * }
- * ```
- *
- * | Platform Name | Description |
- * |-----------------|------------------------------------|
- * | android | on a device running Android. |
- * | cordova | on a device running Cordova. |
- * | core | on a desktop device. |
- * | ios | on a device running iOS. |
- * | ipad | on an iPad device. |
- * | iphone | on an iPhone device. |
- * | mobile | on a mobile device. |
- * | mobileweb | in a browser on a mobile device. |
- * | phablet | on a phablet device. |
- * | tablet | on a tablet device. |
- * | windows | on a device running Windows. |
- *
- * @param {string} platformName
- */
- Platform.prototype.is = function (platformName) {
- return (this._platforms.indexOf(platformName) > -1);
- };
- /**
- * @returns {array} the array of platforms
- * @description
- * Depending on what device you are on, `platforms` can return multiple values.
- * Each possible value is a hierarchy of platforms. For example, on an iPhone,
- * it would return `mobile`, `ios`, and `iphone`.
- *
- * ```
- * import { Platform } from 'ionic-angular';
- *
- * @Component({...})
- * export MyPage {
- * constructor(public platform: Platform) {
- * // This will print an array of the current platforms
- * console.log(this.platform.platforms());
- * }
- * }
- * ```
- */
- Platform.prototype.platforms = function () {
- // get the array of active platforms, which also knows the hierarchy,
- // with the last one the most important
- return this._platforms;
- };
- /**
- * Returns an object containing version information about all of the platforms.
- *
- * ```
- * import { Platform } from 'ionic-angular';
- *
- * @Component({...})
- * export MyPage {
- * constructor(public platform: Platform) {
- * // This will print an object containing
- * // all of the platforms and their versions
- * console.log(platform.versions());
- * }
- * }
- * ```
- *
- * @returns {object} An object containing all of the platforms and their versions.
- */
- Platform.prototype.versions = function () {
- // get all the platforms that have a valid parsed version
- return this._versions;
- };
- /**
- * @hidden
- */
- Platform.prototype.version = function () {
- for (var platformName in this._versions) {
- if (this._versions[platformName]) {
- return this._versions[platformName];
- }
- }
- return {};
- };
- /**
- * Returns a promise when the platform is ready and native functionality
- * can be called. If the app is running from within a web browser, then
- * the promise will resolve when the DOM is ready. When the app is running
- * from an application engine such as Cordova, then the promise will
- * resolve when Cordova triggers the `deviceready` event.
- *
- * The resolved value is the `readySource`, which states which platform
- * ready was used. For example, when Cordova is ready, the resolved ready
- * source is `cordova`. The default ready source value will be `dom`. The
- * `readySource` is useful if different logic should run depending on the
- * platform the app is running from. For example, only Cordova can execute
- * the status bar plugin, so the web should not run status bar plugin logic.
- *
- * ```
- * import { Component } from '@angular/core';
- * import { Platform } from 'ionic-angular';
- *
- * @Component({...})
- * export MyApp {
- * constructor(public platform: Platform) {
- * this.platform.ready().then((readySource) => {
- * console.log('Platform ready from', readySource);
- * // Platform now ready, execute any required native code
- * });
- * }
- * }
- * ```
- * @returns {promise}
- */
- Platform.prototype.ready = function () {
- return this._readyPromise;
- };
- /**
- * @hidden
- * This should be triggered by the engine when the platform is
- * ready. If there was no custom prepareReady method from the engine,
- * such as Cordova or Electron, then it uses the default DOM ready.
- */
- Platform.prototype.triggerReady = function (readySource) {
- var _this = this;
- this.zone.run(function () {
- _this._readyResolve(readySource);
- });
- };
- /**
- * @hidden
- * This is the default prepareReady if it's not replaced by an engine,
- * such as Cordova or Electron. If there was no custom prepareReady
- * method from an engine then it uses the method below, which triggers
- * the platform ready on the DOM ready event, and the default resolved
- * value is `dom`.
- */
- Platform.prototype.prepareReady = function () {
- var self = this;
- if (self._doc.readyState === 'complete' || self._doc.readyState === 'interactive') {
- self.triggerReady('dom');
- }
- else {
- self._doc.addEventListener('DOMContentLoaded', completed, false);
- self._win.addEventListener('load', completed, false);
- }
- function completed() {
- self._doc.removeEventListener('DOMContentLoaded', completed, false);
- self._win.removeEventListener('load', completed, false);
- self.triggerReady('dom');
- }
- };
- /**
- * Set the app's language direction, which will update the `dir` attribute
- * on the app's root `<html>` element. We recommend the app's `index.html`
- * file already has the correct `dir` attribute value set, such as
- * `<html dir="ltr">` or `<html dir="rtl">`. This method is useful if the
- * direction needs to be dynamically changed per user/session.
- * [W3C: Structural markup and right-to-left text in HTML](http://www.w3.org/International/questions/qa-html-dir)
- * @param {DocumentDirection} dir Examples: `rtl`, `ltr`
- * @param {boolean} updateDocument
- */
- Platform.prototype.setDir = function (dir, updateDocument) {
- this._dir = dir;
- this.isRTL = (dir === 'rtl');
- if (updateDocument !== false) {
- this._doc['documentElement'].setAttribute('dir', dir);
- }
- };
- /**
- * Returns app's language direction.
- * We recommend the app's `index.html` file already has the correct `dir`
- * attribute value set, such as `<html dir="ltr">` or `<html dir="rtl">`.
- * [W3C: Structural markup and right-to-left text in HTML](http://www.w3.org/International/questions/qa-html-dir)
- * @returns {DocumentDirection}
- */
- Platform.prototype.dir = function () {
- return this._dir;
- };
- /**
- * Set the app's language and optionally the country code, which will update
- * the `lang` attribute on the app's root `<html>` element.
- * We recommend the app's `index.html` file already has the correct `lang`
- * attribute value set, such as `<html lang="en">`. This method is useful if
- * the language needs to be dynamically changed per user/session.
- * [W3C: Declaring language in HTML](http://www.w3.org/International/questions/qa-html-language-declarations)
- * @param {string} language Examples: `en-US`, `en-GB`, `ar`, `de`, `zh`, `es-MX`
- * @param {boolean} updateDocument Specifies whether the `lang` attribute of `<html>` should be updated
- */
- Platform.prototype.setLang = function (language, updateDocument) {
- this._lang = language;
- if (updateDocument !== false) {
- this._doc['documentElement'].setAttribute('lang', language);
- }
- };
- /**
- * Returns app's language and optional country code.
- * We recommend the app's `index.html` file already has the correct `lang`
- * attribute value set, such as `<html lang="en">`.
- * [W3C: Declaring language in HTML](http://www.w3.org/International/questions/qa-html-language-declarations)
- * @returns {string}
- */
- Platform.prototype.lang = function () {
- return this._lang;
- };
- // Methods meant to be overridden by the engine
- // **********************************************
- // Provided NOOP methods so they do not error when
- // called by engines (the browser)that do not provide them
- /**
- * @hidden
- */
- Platform.prototype.exitApp = function () { };
- /**
- * The back button event is triggered when the user presses the native
- * platform's back button, also referred to as the "hardware" back button.
- * This event is only used within Cordova apps running on Android and
- * Windows platforms. This event is not fired on iOS since iOS doesn't come
- * with a hardware back button in the same sense an Android or Windows device
- * does.
- *
- * Registering a hardware back button action and setting a priority allows
- * apps to control which action should be called when the hardware back
- * button is pressed. This method decides which of the registered back button
- * actions has the highest priority and should be called.
- *
- * @param {Function} fn Called when the back button is pressed,
- * if this registered action has the highest priority.
- * @param {number} priority Set the priority for this action. Only the highest priority will execute. Defaults to `0`.
- * @returns {Function} A function that, when called, will unregister
- * the back button action.
- */
- Platform.prototype.registerBackButtonAction = function (fn, priority) {
- var _this = this;
- if (priority === void 0) { priority = 0; }
- var action = { fn: fn, priority: priority };
- this._bbActions.push(action);
- // return a function to unregister this back button action
- return function () {
- util_1.removeArrayItem(_this._bbActions, action);
- };
- };
- /**
- * @hidden
- */
- Platform.prototype.runBackButtonAction = function () {
- // decide which one back button action should run
- var winner = null;
- this._bbActions.forEach(function (action) {
- if (!winner || action.priority >= winner.priority) {
- winner = action;
- }
- });
- // run the winning action if there is one
- winner && winner.fn && winner.fn();
- };
- // Getter/Setter Methods
- // **********************************************
- /**
- * @hidden
- */
- Platform.prototype.setUserAgent = function (userAgent) {
- this._ua = userAgent;
- };
- /**
- * @hidden
- */
- Platform.prototype.setQueryParams = function (url) {
- this._qp.parseUrl(url);
- };
- /**
- * Get the query string parameter
- */
- Platform.prototype.getQueryParam = function (key) {
- return this._qp.get(key);
- };
- /**
- * Get the current url.
- */
- Platform.prototype.url = function () {
- return this._win['location']['href'];
- };
- /**
- * @hidden
- */
- Platform.prototype.userAgent = function () {
- return this._ua || '';
- };
- /**
- * @hidden
- */
- Platform.prototype.setNavigatorPlatform = function (navigatorPlt) {
- this._nPlt = navigatorPlt;
- };
- /**
- * @hidden
- */
- Platform.prototype.navigatorPlatform = function () {
- return this._nPlt || '';
- };
- /**
- * Gets the width of the platform's viewport using `window.innerWidth`.
- * Using this method is preferred since the dimension is a cached value,
- * which reduces the chance of multiple and expensive DOM reads.
- */
- Platform.prototype.width = function () {
- this._calcDim();
- return this._isPortrait ? this._pW : this._lW;
- };
- /**
- * Gets the height of the platform's viewport using `window.innerHeight`.
- * Using this method is preferred since the dimension is a cached value,
- * which reduces the chance of multiple and expensive DOM reads.
- */
- Platform.prototype.height = function () {
- this._calcDim();
- return this._isPortrait ? this._pH : this._lH;
- };
- /**
- * @hidden
- */
- Platform.prototype.getElementComputedStyle = function (ele, pseudoEle) {
- return this._win['getComputedStyle'](ele, pseudoEle);
- };
- /**
- * @hidden
- */
- Platform.prototype.getElementFromPoint = function (x, y) {
- return this._doc['elementFromPoint'](x, y);
- };
- /**
- * @hidden
- */
- Platform.prototype.getElementBoundingClientRect = function (ele) {
- return ele['getBoundingClientRect']();
- };
- /**
- * Returns `true` if the app is in portait mode.
- */
- Platform.prototype.isPortrait = function () {
- this._calcDim();
- return this._isPortrait;
- };
- /**
- * Returns `true` if the app is in landscape mode.
- */
- Platform.prototype.isLandscape = function () {
- return !this.isPortrait();
- };
- Platform.prototype._calcDim = function () {
- // we're caching window dimensions so that
- // we're not forcing many layouts
- // if _isPortrait is null then that means
- // the dimensions needs to be looked up again
- // this also has to cover an edge case that only
- // happens on iOS 10 (not other versions of iOS)
- // where window.innerWidth is always bigger than
- // window.innerHeight when it is first measured,
- // even when the device is in portrait but
- // the second time it is measured it is correct.
- // Hopefully this check will not be needed in the future
- if (this._isPortrait === null || this._isPortrait === false && this._win['innerWidth'] < this._win['innerHeight']) {
- var win = this._win;
- var innerWidth = win['innerWidth'];
- var innerHeight = win['innerHeight'];
- // we're keeping track of portrait and landscape dimensions
- // separately because the virtual keyboard can really mess
- // up accurate values when the keyboard is up
- if (win.screen.width > 0 && win.screen.height > 0) {
- if (innerWidth < innerHeight) {
- // the device is in portrait
- // we have to do fancier checking here
- // because of the virtual keyboard resizing
- // the window
- if (this._pW <= innerWidth) {
- (void 0) /* console.debug */;
- this._isPortrait = true;
- this._pW = innerWidth;
- }
- if (this._pH <= innerHeight) {
- (void 0) /* console.debug */;
- this._isPortrait = true;
- this._pH = innerHeight;
- }
- }
- else {
- // the device is in landscape
- if (this._lW !== innerWidth) {
- (void 0) /* console.debug */;
- this._isPortrait = false;
- this._lW = innerWidth;
- }
- if (this._lH !== innerHeight) {
- (void 0) /* console.debug */;
- this._isPortrait = false;
- this._lH = innerHeight;
- }
- }
- }
- }
- };
- /**
- * @hidden
- * This requestAnimationFrame will NOT be wrapped by zone.
- */
- Platform.prototype.raf = function (callback) {
- var win = this._win;
- return win['__zone_symbol__requestAnimationFrame'](callback);
- };
- /**
- * @hidden
- */
- Platform.prototype.cancelRaf = function (rafId) {
- var win = this._win;
- return win['__zone_symbol__cancelAnimationFrame'](rafId);
- };
- /**
- * @hidden
- * This setTimeout will NOT be wrapped by zone.
- */
- Platform.prototype.timeout = function (callback, timeout) {
- var win = this._win;
- return win['__zone_symbol__setTimeout'](callback, timeout);
- };
- /**
- * @hidden
- * This setTimeout will NOT be wrapped by zone.
- */
- Platform.prototype.cancelTimeout = function (timeoutId) {
- var win = this._win;
- win['__zone_symbol__clearTimeout'](timeoutId);
- };
- /**
- * @hidden
- * Built to use modern event listener options, like "passive".
- * If options are not supported, then just return a boolean which
- * represents "capture". Returns a method to remove the listener.
- */
- Platform.prototype.registerListener = function (ele, eventName, callback, opts, unregisterListenersCollection) {
- // use event listener options when supported
- // otherwise it's just a boolean for the "capture" arg
- var listenerOpts = this._uiEvtOpts ? {
- 'capture': !!opts.capture,
- 'passive': !!opts.passive,
- } : !!opts.capture;
- var unReg;
- if (!opts.zone && ele['__zone_symbol__addEventListener']) {
- // do not wrap this event in zone and we've verified we can use the raw addEventListener
- ele['__zone_symbol__addEventListener'](eventName, callback, listenerOpts);
- unReg = function unregisterListener() {
- ele['__zone_symbol__removeEventListener'](eventName, callback, listenerOpts);
- };
- }
- else {
- // use the native addEventListener, which is wrapped with zone
- ele['addEventListener'](eventName, callback, listenerOpts);
- unReg = function unregisterListener() {
- ele['removeEventListener'](eventName, callback, listenerOpts);
- };
- }
- if (unregisterListenersCollection) {
- unregisterListenersCollection.push(unReg);
- }
- return unReg;
- };
- /**
- * @hidden
- */
- Platform.prototype.transitionEnd = function (el, callback, zone) {
- if (zone === void 0) { zone = true; }
- var unRegs = [];
- function unregister() {
- unRegs.forEach(function (unReg) {
- unReg();
- });
- }
- function onTransitionEnd(ev) {
- if (el === ev.target) {
- unregister();
- callback(ev);
- }
- }
- if (el) {
- this.registerListener(el, 'webkitTransitionEnd', onTransitionEnd, { zone: zone }, unRegs);
- this.registerListener(el, 'transitionend', onTransitionEnd, { zone: zone }, unRegs);
- }
- return unregister;
- };
- /**
- * @hidden
- */
- Platform.prototype.windowLoad = function (callback) {
- var win = this._win;
- var doc = this._doc;
- var unreg;
- if (doc.readyState === 'complete') {
- callback(win, doc);
- }
- else {
- unreg = this.registerListener(win, 'load', function () {
- unreg && unreg();
- callback(win, doc);
- }, { zone: false });
- }
- };
- /**
- * @hidden
- */
- Platform.prototype.isActiveElement = function (ele) {
- return !!(ele && (this.getActiveElement() === ele));
- };
- /**
- * @hidden
- */
- Platform.prototype.getActiveElement = function () {
- return this._doc['activeElement'];
- };
- /**
- * @hidden
- */
- Platform.prototype.hasFocus = function (ele) {
- return !!((ele && (this.getActiveElement() === ele)) && (ele.parentElement.querySelector(':focus') === ele));
- };
- /**
- * @hidden
- */
- Platform.prototype.hasFocusedTextInput = function () {
- var ele = this.getActiveElement();
- if (dom_1.isTextInput(ele)) {
- return (ele.parentElement.querySelector(':focus') === ele);
- }
- return false;
- };
- /**
- * @hidden
- */
- Platform.prototype.focusOutActiveElement = function () {
- var activeElement = this.getActiveElement();
- activeElement && activeElement.blur && activeElement.blur();
- };
- Platform.prototype._initEvents = function () {
- var _this = this;
- // Test via a getter in the options object to see if the passive property is accessed
- try {
- var opts = Object.defineProperty({}, 'passive', {
- get: function () {
- _this._uiEvtOpts = true;
- }
- });
- this._win.addEventListener('optsTest', null, opts);
- }
- catch (e) { }
- // add the window resize event listener XXms after
- this.timeout(function () {
- var timerId;
- _this.registerListener(_this._win, 'resize', function () {
- clearTimeout(timerId);
- timerId = setTimeout(function () {
- // setting _isPortrait to null means the
- // dimensions will need to be looked up again
- if (_this.hasFocusedTextInput() === false) {
- _this._isPortrait = null;
- }
- _this.zone.run(function () { return _this.resize.emit(); });
- }, 200);
- }, { passive: true, zone: false });
- }, 2000);
- };
- // Platform Registry
- // **********************************************
- /**
- * @hidden
- */
- Platform.prototype.setPlatformConfigs = function (platformConfigs) {
- this._registry = platformConfigs || {};
- };
- /**
- * @hidden
- */
- Platform.prototype.getPlatformConfig = function (platformName) {
- return this._registry[platformName] || {};
- };
- /**
- * @hidden
- */
- Platform.prototype.registry = function () {
- return this._registry;
- };
- /**
- * @hidden
- */
- Platform.prototype.setDefault = function (platformName) {
- this._default = platformName;
- };
- /**
- * @hidden
- */
- Platform.prototype.testQuery = function (queryValue, queryTestValue) {
- var valueSplit = queryValue.toLowerCase().split(';');
- return valueSplit.indexOf(queryTestValue) > -1;
- };
- /**
- * @hidden
- */
- Platform.prototype.testNavigatorPlatform = function (navigatorPlatformExpression) {
- var rgx = new RegExp(navigatorPlatformExpression, 'i');
- return rgx.test(this._nPlt);
- };
- /**
- * @hidden
- */
- Platform.prototype.matchUserAgentVersion = function (userAgentExpression) {
- if (this._ua && userAgentExpression) {
- var val = this._ua.match(userAgentExpression);
- if (val) {
- return {
- major: val[1],
- minor: val[2]
- };
- }
- }
- };
- Platform.prototype.testUserAgent = function (expression) {
- if (this._ua) {
- return this._ua.indexOf(expression) >= 0;
- }
- return false;
- };
- /**
- * @hidden
- */
- Platform.prototype.isPlatformMatch = function (queryStringName, userAgentAtLeastHas, userAgentMustNotHave) {
- if (userAgentMustNotHave === void 0) { userAgentMustNotHave = []; }
- var queryValue = this._qp.get('ionicplatform');
- if (queryValue) {
- return this.testQuery(queryValue, queryStringName);
- }
- userAgentAtLeastHas = userAgentAtLeastHas || [queryStringName];
- var userAgent = this._ua.toLowerCase();
- for (var i = 0; i < userAgentAtLeastHas.length; i++) {
- if (userAgent.indexOf(userAgentAtLeastHas[i]) > -1) {
- for (var j = 0; j < userAgentMustNotHave.length; j++) {
- if (userAgent.indexOf(userAgentMustNotHave[j]) > -1) {
- return false;
- }
- }
- return true;
- }
- }
- return false;
- };
- /** @hidden */
- Platform.prototype.init = function () {
- this._initEvents();
- var rootPlatformNode;
- var enginePlatformNode;
- // figure out the most specific platform and active engine
- var tmpPlt;
- for (var platformName in this._registry) {
- tmpPlt = this.matchPlatform(platformName);
- if (tmpPlt) {
- // we found a platform match!
- // check if its more specific than the one we already have
- if (tmpPlt.isEngine) {
- // because it matched then this should be the active engine
- // you cannot have more than one active engine
- enginePlatformNode = tmpPlt;
- }
- else if (!rootPlatformNode || tmpPlt.depth > rootPlatformNode.depth) {
- // only find the root node for platforms that are not engines
- // set this node as the root since we either don't already
- // have one, or this one is more specific that the current one
- rootPlatformNode = tmpPlt;
- }
- }
- }
- if (!rootPlatformNode) {
- rootPlatformNode = new PlatformNode(this._registry, this._default);
- }
- // build a Platform instance filled with the
- // hierarchy of active platforms and settings
- if (rootPlatformNode) {
- // check if we found an engine node (cordova/node-webkit/etc)
- if (enginePlatformNode) {
- // add the engine to the first in the platform hierarchy
- // the original rootPlatformNode now becomes a child
- // of the engineNode, which is not the new root
- enginePlatformNode.child = rootPlatformNode;
- rootPlatformNode.parent = enginePlatformNode;
- rootPlatformNode = enginePlatformNode;
- }
- var platformNode = rootPlatformNode;
- while (platformNode) {
- insertSuperset(this._registry, platformNode);
- platformNode = platformNode.child;
- }
- // make sure the root noot is actually the root
- // incase a node was inserted before the root
- platformNode = rootPlatformNode.parent;
- while (platformNode) {
- rootPlatformNode = platformNode;
- platformNode = platformNode.parent;
- }
- platformNode = rootPlatformNode;
- while (platformNode) {
- platformNode.initialize(this);
- // extra check for ipad pro issue
- // https://forums.developer.apple.com/thread/25948
- if (platformNode.name === 'iphone' && this.navigatorPlatform() === 'iPad') {
- // this is an ipad pro so push ipad and tablet to platforms
- // and then return as we are done
- this._platforms.push('tablet');
- this._platforms.push('ipad');
- return;
- }
- // set the array of active platforms with
- // the last one in the array the most important
- this._platforms.push(platformNode.name);
- // get the platforms version if a version parser was provided
- this._versions[platformNode.name] = platformNode.version(this);
- // go to the next platform child
- platformNode = platformNode.child;
- }
- }
- if (this._platforms.indexOf('mobile') > -1 && this._platforms.indexOf('cordova') === -1) {
- this._platforms.push('mobileweb');
- }
- };
- /**
- * @hidden
- */
- Platform.prototype.matchPlatform = function (platformName) {
- // build a PlatformNode and assign config data to it
- // use it's getRoot method to build up its hierarchy
- // depending on which platforms match
- var platformNode = new PlatformNode(this._registry, platformName);
- var rootNode = platformNode.getRoot(this);
- if (rootNode) {
- rootNode.depth = 0;
- var childPlatform = rootNode.child;
- while (childPlatform) {
- rootNode.depth++;
- childPlatform = childPlatform.child;
- }
- }
- return rootNode;
- };
- return Platform;
- }());
- exports.Platform = Platform;
- function insertSuperset(registry, platformNode) {
- var supersetPlaformName = platformNode.superset();
- if (supersetPlaformName) {
- // add a platform in between two exist platforms
- // so we can build the correct hierarchy of active platforms
- var supersetPlatform = new PlatformNode(registry, supersetPlaformName);
- supersetPlatform.parent = platformNode.parent;
- supersetPlatform.child = platformNode;
- if (supersetPlatform.parent) {
- supersetPlatform.parent.child = supersetPlatform;
- }
- platformNode.parent = supersetPlatform;
- }
- }
- /**
- * @hidden
- */
- var PlatformNode = (function () {
- function PlatformNode(registry, platformName) {
- this.registry = registry;
- this.c = registry[platformName];
- this.name = platformName;
- this.isEngine = this.c.isEngine;
- }
- PlatformNode.prototype.settings = function () {
- return this.c.settings || {};
- };
- PlatformNode.prototype.superset = function () {
- return this.c.superset;
- };
- PlatformNode.prototype.isMatch = function (p) {
- return this.c.isMatch && this.c.isMatch(p) || false;
- };
- PlatformNode.prototype.initialize = function (plt) {
- this.c.initialize && this.c.initialize(plt);
- };
- PlatformNode.prototype.version = function (plt) {
- if (this.c.versionParser) {
- var v = this.c.versionParser(plt);
- if (v) {
- var str = v.major + '.' + v.minor;
- return {
- str: str,
- num: parseFloat(str),
- major: parseInt(v.major, 10),
- minor: parseInt(v.minor, 10)
- };
- }
- }
- };
- PlatformNode.prototype.getRoot = function (plt) {
- if (this.isMatch(plt)) {
- var parents = this.getSubsetParents(this.name);
- if (!parents.length) {
- return this;
- }
- var platformNode = null;
- var rootPlatformNode = null;
- for (var i = 0; i < parents.length; i++) {
- platformNode = new PlatformNode(this.registry, parents[i]);
- platformNode.child = this;
- rootPlatformNode = platformNode.getRoot(plt);
- if (rootPlatformNode) {
- this.parent = platformNode;
- return rootPlatformNode;
- }
- }
- }
- return null;
- };
- PlatformNode.prototype.getSubsetParents = function (subsetPlatformName) {
- var parentPlatformNames = [];
- var pltConfig = null;
- for (var platformName in this.registry) {
- pltConfig = this.registry[platformName];
- if (pltConfig.subsets && pltConfig.subsets.indexOf(subsetPlatformName) > -1) {
- parentPlatformNames.push(platformName);
- }
- }
- return parentPlatformNames;
- };
- return PlatformNode;
- }());
- /**
- * @hidden
- */
- function setupPlatform(doc, platformConfigs, zone) {
- var plt = new Platform();
- plt.setDefault('core');
- plt.setPlatformConfigs(platformConfigs);
- plt.setZone(zone);
- // set values from "document"
- var docElement = doc.documentElement;
- plt.setDocument(doc);
- var dir = docElement.dir;
- plt.setDir(dir === 'rtl' ? 'rtl' : 'ltr', !dir);
- plt.setLang(docElement.lang, false);
- // set css properties
- plt.setCssProps(docElement);
- // set values from "window"
- var win = doc.defaultView;
- plt.setWindow(win);
- plt.setNavigatorPlatform(win.navigator.platform);
- plt.setUserAgent(win.navigator.userAgent);
- // set location values
- plt.setQueryParams(win.location.href);
- plt.init();
- // add the platform obj to the window
- win['Ionic'] = win['Ionic'] || {};
- win['Ionic']['platform'] = plt;
- return plt;
- }
- exports.setupPlatform = setupPlatform;
- });
- //# sourceMappingURL=platform.js.map
|