mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
435 lines
13 KiB
JavaScript
435 lines
13 KiB
JavaScript
(function(window, document, ionic) {
|
|
|
|
function getParameterByName(name) {
|
|
name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
|
|
var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
|
|
results = regex.exec(location.search);
|
|
return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
|
|
}
|
|
|
|
var IOS = 'ios';
|
|
var ANDROID = 'android';
|
|
var WINDOWS_PHONE = 'windowsphone';
|
|
var requestAnimationFrame = ionic.requestAnimationFrame;
|
|
|
|
/**
|
|
* @ngdoc utility
|
|
* @name ionic.Platform
|
|
* @module ionic
|
|
* @description
|
|
* A set of utility methods that can be used to retrieve the device ready state and
|
|
* various other information such as what kind of platform the app is currently installed on.
|
|
*
|
|
* @usage
|
|
* ```js
|
|
* angular.module('PlatformApp', ['ionic'])
|
|
* .controller('PlatformCtrl', function($scope) {
|
|
*
|
|
* ionic.Platform.ready(function(){
|
|
* // will execute when device is ready, or immediately if the device is already ready.
|
|
* });
|
|
*
|
|
* var deviceInformation = ionic.Platform.device();
|
|
*
|
|
* var isWebView = ionic.Platform.isWebView();
|
|
* var isIPad = ionic.Platform.isIPad();
|
|
* var isIOS = ionic.Platform.isIOS();
|
|
* var isAndroid = ionic.Platform.isAndroid();
|
|
* var isWindowsPhone = ionic.Platform.isWindowsPhone();
|
|
*
|
|
* var currentPlatform = ionic.Platform.platform();
|
|
* var currentPlatformVersion = ionic.Platform.version();
|
|
*
|
|
* ionic.Platform.exit(); // stops the app
|
|
* });
|
|
* ```
|
|
*/
|
|
var self = ionic.Platform = {
|
|
|
|
// Put navigator on platform so it can be mocked and set
|
|
// the browser does not allow window.navigator to be set
|
|
navigator: window.navigator,
|
|
|
|
/**
|
|
* @ngdoc property
|
|
* @name ionic.Platform#isReady
|
|
* @returns {boolean} Whether the device is ready.
|
|
*/
|
|
isReady: false,
|
|
/**
|
|
* @ngdoc property
|
|
* @name ionic.Platform#isFullScreen
|
|
* @returns {boolean} Whether the device is fullscreen.
|
|
*/
|
|
isFullScreen: false,
|
|
/**
|
|
* @ngdoc property
|
|
* @name ionic.Platform#platforms
|
|
* @returns {Array(string)} An array of all platforms found.
|
|
*/
|
|
platforms: null,
|
|
/**
|
|
* @ngdoc property
|
|
* @name ionic.Platform#grade
|
|
* @returns {string} What grade the current platform is.
|
|
*/
|
|
grade: null,
|
|
ua: navigator.userAgent,
|
|
|
|
/**
|
|
* @ngdoc method
|
|
* @name ionic.Platform#ready
|
|
* @description
|
|
* Trigger a callback once the device is ready, or immediately
|
|
* if the device is already ready. This method can be run from
|
|
* anywhere and does not need to be wrapped by any additonal methods.
|
|
* When the app is within a WebView (Cordova), it'll fire
|
|
* the callback once the device is ready. If the app is within
|
|
* a web browser, it'll fire the callback after `window.load`.
|
|
* Please remember that Cordova features (Camera, FileSystem, etc) still
|
|
* will not work in a web browser.
|
|
* @param {function} callback The function to call.
|
|
*/
|
|
ready: function(cb) {
|
|
// run through tasks to complete now that the device is ready
|
|
if (self.isReady) {
|
|
cb();
|
|
} else {
|
|
// the platform isn't ready yet, add it to this array
|
|
// which will be called once the platform is ready
|
|
readyCallbacks.push(cb);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
detect: function() {
|
|
self._checkPlatforms();
|
|
|
|
requestAnimationFrame(function() {
|
|
// only add to the body class if we got platform info
|
|
for (var i = 0; i < self.platforms.length; i++) {
|
|
document.body.classList.add('platform-' + self.platforms[i]);
|
|
}
|
|
});
|
|
},
|
|
|
|
/**
|
|
* @ngdoc method
|
|
* @name ionic.Platform#setGrade
|
|
* @description Set the grade of the device: 'a', 'b', or 'c'. 'a' is the best
|
|
* (most css features enabled), 'c' is the worst. By default, sets the grade
|
|
* depending on the current device.
|
|
* @param {string} grade The new grade to set.
|
|
*/
|
|
setGrade: function(grade) {
|
|
var oldGrade = self.grade;
|
|
self.grade = grade;
|
|
requestAnimationFrame(function() {
|
|
if (oldGrade) {
|
|
document.body.classList.remove('grade-' + oldGrade);
|
|
}
|
|
document.body.classList.add('grade-' + grade);
|
|
});
|
|
},
|
|
|
|
/**
|
|
* @ngdoc method
|
|
* @name ionic.Platform#device
|
|
* @description Return the current device (given by cordova).
|
|
* @returns {object} The device object.
|
|
*/
|
|
device: function() {
|
|
return window.device || {};
|
|
},
|
|
|
|
_checkPlatforms: function() {
|
|
self.platforms = [];
|
|
var grade = 'a';
|
|
|
|
if (self.isWebView()) {
|
|
self.platforms.push('webview');
|
|
self.platforms.push('cordova');
|
|
} else {
|
|
self.platforms.push('browser');
|
|
}
|
|
if (self.isIPad()) self.platforms.push('ipad');
|
|
|
|
var platform = self.platform();
|
|
if (platform) {
|
|
self.platforms.push(platform);
|
|
|
|
var version = self.version();
|
|
if (version) {
|
|
var v = version.toString();
|
|
if (v.indexOf('.') > 0) {
|
|
v = v.replace('.', '_');
|
|
} else {
|
|
v += '_0';
|
|
}
|
|
self.platforms.push(platform + v.split('_')[0]);
|
|
self.platforms.push(platform + v);
|
|
|
|
if (self.isAndroid() && version < 4.4) {
|
|
grade = (version < 4 ? 'c' : 'b');
|
|
} else if (self.isWindowsPhone()) {
|
|
grade = 'b';
|
|
}
|
|
}
|
|
}
|
|
|
|
self.setGrade(grade);
|
|
},
|
|
|
|
/**
|
|
* @ngdoc method
|
|
* @name ionic.Platform#isWebView
|
|
* @returns {boolean} Check if we are running within a WebView (such as Cordova).
|
|
*/
|
|
isWebView: function() {
|
|
return !(!window.cordova && !window.PhoneGap && !window.phonegap);
|
|
},
|
|
/**
|
|
* @ngdoc method
|
|
* @name ionic.Platform#isIPad
|
|
* @returns {boolean} Whether we are running on iPad.
|
|
*/
|
|
isIPad: function() {
|
|
if (/iPad/i.test(self.navigator.platform)) {
|
|
return true;
|
|
}
|
|
return /iPad/i.test(self.ua);
|
|
},
|
|
/**
|
|
* @ngdoc method
|
|
* @name ionic.Platform#isIOS
|
|
* @returns {boolean} Whether we are running on iOS.
|
|
*/
|
|
isIOS: function() {
|
|
return self.is(IOS);
|
|
},
|
|
/**
|
|
* @ngdoc method
|
|
* @name ionic.Platform#isAndroid
|
|
* @returns {boolean} Whether we are running on Android.
|
|
*/
|
|
isAndroid: function() {
|
|
return self.is(ANDROID);
|
|
},
|
|
/**
|
|
* @ngdoc method
|
|
* @name ionic.Platform#isWindowsPhone
|
|
* @returns {boolean} Whether we are running on Windows Phone.
|
|
*/
|
|
isWindowsPhone: function() {
|
|
return self.is(WINDOWS_PHONE);
|
|
},
|
|
|
|
/**
|
|
* @ngdoc method
|
|
* @name ionic.Platform#platform
|
|
* @returns {string} The name of the current platform.
|
|
*/
|
|
platform: function() {
|
|
// singleton to get the platform name
|
|
if (platformName === null) self.setPlatform(self.device().platform);
|
|
return platformName;
|
|
},
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
setPlatform: function(n) {
|
|
if (typeof n != 'undefined' && n !== null && n.length) {
|
|
platformName = n.toLowerCase();
|
|
} else if (getParameterByName('ionicplatform')) {
|
|
platformName = getParameterByName('ionicplatform');
|
|
} else if (self.ua.indexOf('Android') > 0) {
|
|
platformName = ANDROID;
|
|
} else if (/iPhone|iPad|iPod/.test(self.ua)) {
|
|
platformName = IOS;
|
|
} else if (self.ua.indexOf('Windows Phone') > -1) {
|
|
platformName = WINDOWS_PHONE;
|
|
} else {
|
|
platformName = self.navigator.platform && navigator.platform.toLowerCase().split(' ')[0] || '';
|
|
}
|
|
},
|
|
|
|
/**
|
|
* @ngdoc method
|
|
* @name ionic.Platform#version
|
|
* @returns {number} The version of the current device platform.
|
|
*/
|
|
version: function() {
|
|
// singleton to get the platform version
|
|
if (platformVersion === null) self.setVersion(self.device().version);
|
|
return platformVersion;
|
|
},
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
setVersion: function(v) {
|
|
if (typeof v != 'undefined' && v !== null) {
|
|
v = v.split('.');
|
|
v = parseFloat(v[0] + '.' + (v.length > 1 ? v[1] : 0));
|
|
if (!isNaN(v)) {
|
|
platformVersion = v;
|
|
return;
|
|
}
|
|
}
|
|
|
|
platformVersion = 0;
|
|
|
|
// fallback to user-agent checking
|
|
var pName = self.platform();
|
|
var versionMatch = {
|
|
'android': /Android (\d+).(\d+)?/,
|
|
'ios': /OS (\d+)_(\d+)?/,
|
|
'windowsphone': /Windows Phone (\d+).(\d+)?/
|
|
};
|
|
if (versionMatch[pName]) {
|
|
v = self.ua.match(versionMatch[pName]);
|
|
if (v && v.length > 2) {
|
|
platformVersion = parseFloat(v[1] + '.' + v[2]);
|
|
}
|
|
}
|
|
},
|
|
|
|
// Check if the platform is the one detected by cordova
|
|
is: function(type) {
|
|
type = type.toLowerCase();
|
|
// check if it has an array of platforms
|
|
if (self.platforms) {
|
|
for (var x = 0; x < self.platforms.length; x++) {
|
|
if (self.platforms[x] === type) return true;
|
|
}
|
|
}
|
|
// exact match
|
|
var pName = self.platform();
|
|
if (pName) {
|
|
return pName === type.toLowerCase();
|
|
}
|
|
|
|
// A quick hack for to check userAgent
|
|
return self.ua.toLowerCase().indexOf(type) >= 0;
|
|
},
|
|
|
|
/**
|
|
* @ngdoc method
|
|
* @name ionic.Platform#exitApp
|
|
* @description Exit the app.
|
|
*/
|
|
exitApp: function() {
|
|
self.ready(function() {
|
|
navigator.app && navigator.app.exitApp && navigator.app.exitApp();
|
|
});
|
|
},
|
|
|
|
/**
|
|
* @ngdoc method
|
|
* @name ionic.Platform#showStatusBar
|
|
* @description Shows or hides the device status bar (in Cordova).
|
|
* @param {boolean} shouldShow Whether or not to show the status bar.
|
|
*/
|
|
showStatusBar: function(val) {
|
|
// Only useful when run within cordova
|
|
self._showStatusBar = val;
|
|
self.ready(function() {
|
|
// run this only when or if the platform (cordova) is ready
|
|
requestAnimationFrame(function() {
|
|
if (self._showStatusBar) {
|
|
// they do not want it to be full screen
|
|
window.StatusBar && window.StatusBar.show();
|
|
document.body.classList.remove('status-bar-hide');
|
|
} else {
|
|
// it should be full screen
|
|
window.StatusBar && window.StatusBar.hide();
|
|
document.body.classList.add('status-bar-hide');
|
|
}
|
|
});
|
|
});
|
|
},
|
|
|
|
/**
|
|
* @ngdoc method
|
|
* @name ionic.Platform#fullScreen
|
|
* @description
|
|
* Sets whether the app is fullscreen or not (in Cordova).
|
|
* @param {boolean=} showFullScreen Whether or not to set the app to fullscreen. Defaults to true.
|
|
* @param {boolean=} showStatusBar Whether or not to show the device's status bar. Defaults to false.
|
|
*/
|
|
fullScreen: function(showFullScreen, showStatusBar) {
|
|
// showFullScreen: default is true if no param provided
|
|
self.isFullScreen = (showFullScreen !== false);
|
|
|
|
// add/remove the fullscreen classname to the body
|
|
ionic.DomUtil.ready(function() {
|
|
// run this only when or if the DOM is ready
|
|
requestAnimationFrame(function() {
|
|
// fixing pane height before we adjust this
|
|
var panes = document.getElementsByClassName('pane');
|
|
for (var i = 0; i < panes.length; i++) {
|
|
panes[i].style.height = panes[i].offsetHeight + "px";
|
|
}
|
|
if (self.isFullScreen) {
|
|
document.body.classList.add('fullscreen');
|
|
} else {
|
|
document.body.classList.remove('fullscreen');
|
|
}
|
|
});
|
|
// showStatusBar: default is false if no param provided
|
|
self.showStatusBar((showStatusBar === true));
|
|
});
|
|
}
|
|
|
|
};
|
|
|
|
var platformName = null, // just the name, like iOS or Android
|
|
platformVersion = null, // a float of the major and minor, like 7.1
|
|
readyCallbacks = [],
|
|
windowLoadListenderAttached;
|
|
|
|
// setup listeners to know when the device is ready to go
|
|
function onWindowLoad() {
|
|
if (self.isWebView()) {
|
|
// the window and scripts are fully loaded, and a cordova/phonegap
|
|
// object exists then let's listen for the deviceready
|
|
document.addEventListener("deviceready", onPlatformReady, false);
|
|
} else {
|
|
// the window and scripts are fully loaded, but the window object doesn't have the
|
|
// cordova/phonegap object, so its just a browser, not a webview wrapped w/ cordova
|
|
onPlatformReady();
|
|
}
|
|
if (windowLoadListenderAttached) {
|
|
window.removeEventListener("load", onWindowLoad, false);
|
|
}
|
|
}
|
|
if (document.readyState === 'complete') {
|
|
onWindowLoad();
|
|
} else {
|
|
windowLoadListenderAttached = true;
|
|
window.addEventListener("load", onWindowLoad, false);
|
|
}
|
|
|
|
window.addEventListener("load", onWindowLoad, false);
|
|
|
|
function onPlatformReady() {
|
|
// the device is all set to go, init our own stuff then fire off our event
|
|
self.isReady = true;
|
|
self.detect();
|
|
for (var x = 0; x < readyCallbacks.length; x++) {
|
|
// fire off all the callbacks that were added before the platform was ready
|
|
readyCallbacks[x]();
|
|
}
|
|
readyCallbacks = [];
|
|
ionic.trigger('platformready', { target: document });
|
|
|
|
requestAnimationFrame(function() {
|
|
document.body.classList.add('platform-ready');
|
|
});
|
|
}
|
|
|
|
})(this, document, ionic);
|