Guest User

Untitled

a guest
Feb 19th, 2012
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.79 KB | None | 0 0
  1. /* Enyo Platform encapsulation. Include this FIRST in your depends.js. The
  2. * first call you make to a function inside it will cause it to perform it's
  3. * detection (in the setup function). If you are running in PhoneGap, and your
  4. * app depends on accurate results in here, make sure that you are not running
  5. * any code that depends on this module until after the "deviceready" PhoneGap
  6. * event is fired.
  7. *
  8. * This prefers direct access to APIs whenever possible - although you CAN run
  9. * webOS and WebWorks apps with PhoneGap, I'm trying to avoid going through any
  10. * extra layers here.
  11. *
  12. * If you are deploying to iOS, set a new parameter in your appinfo.json called
  13. * iTunesAppId to your application id as found in the Apple Dev Portal, for the
  14. * getReviewURL function
  15. */
  16. enyo.kind({
  17. name: "Platform",
  18. kind: "Component",
  19. statics: {
  20. setup: function()
  21. {
  22. enyo.log("********* Setting up Platform Variables *************");
  23. enyo.log("window.PalmSystem "+ window.PalmSystem);
  24. enyo.log("window.blackberry "+ window.blackberry);
  25. enyo.log("window.PhoneGap "+ window.PhoneGap);
  26. enyo.log("window.device "+ window.device);
  27. if(window.device)
  28. enyo.log("window.device.platform "+ window.device.platform);
  29. enyo.log("window.chrome "+ window.chrome);
  30.  
  31. /* If you include PhoneGap, but you don't wait until the device var
  32. * is initialized before calling this, we're going to ignore this
  33. * until the device var is available
  34. */
  35. if(window.PhoneGap && !window.device) {
  36. enyo.log("EnyoPlatform: PhoneGap detected, device not (yet) available. Bailing until next call.");
  37. return;
  38. }
  39. /* Check for systems where we don't have PhoneGap in our
  40. * requirements first, currently webOS and BlackBerry WebWorks
  41. * Even if you use PhoneGap on BlackBerry, according to the PhoneGap
  42. * documentation, it's platform determination code doesn't work
  43. * properly for at least some models.
  44. */
  45. if(typeof window.PalmSystem !== "undefined")
  46. {
  47. var deviceInfo = enyo.fetchDeviceInfo();
  48. this.platform = "webos";
  49. this.platformVersion = deviceInfo ? deviceInfo.platformVersion : "unknown";
  50. }
  51. else if(typeof blackberry !== "undefined")
  52. {
  53. if(typeof PhoneGap !== "undefined")
  54. {
  55. this.platform = "blackberry";
  56. }
  57. else
  58. {
  59. this.platform = "webworks";
  60. }
  61. /* According to the BlackBerry docs, to get the version number,
  62. * we have to actually make an AJAX request to
  63. * http://localhost:8472/blackberry/system/get . Screw that.
  64. */
  65. this.platformVersion = "unknown";
  66. }
  67. else if(typeof PhoneGap !== "undefined")
  68. {
  69. /* See the PhoneGap Device API documentation for possible
  70. * pitfalls.
  71. */
  72. this.platform = device.platform.toLowerCase();
  73. this.platformVersion = device.version;
  74. }
  75. else
  76. {
  77. /* Someone with more time on their hands might be interested in
  78. * breaking this out to determine various web browsers and their
  79. * respective versions. Not for me at this time.
  80. */
  81. this.platform = "web";
  82. this.platformVersion = "unknown";
  83. }
  84. enyo.log("Platform detected: " + this.platform + " version " + this.platformVersion);
  85. enyo.log(" ************************************** ");
  86. },
  87. /* Should you find yourself in need of the raw platform name */
  88. getPlatformName: function() { this.platform || this.setup(); return this.platform; },
  89.  
  90. /* Platform boolean functions -- return truthy if specific platform */
  91. isWebOS: function() { this.platform || this.setup(); return this.platform == "webos"; },
  92. isAndroid: function() { this.platform || this.setup(); return this.platform == "android"; },
  93. isBlackBerry: function() { this.platform || this.setup(); return this.platform == "blackberry" || this.platform == "webworks" },
  94. isWebWorks: function() { this.platform || this.setup(); return this.platform == "webworks"; },
  95. isiOS: function() { this.platform || this.setup(); return this.platform == "iphone"; },
  96. isMobile: function() { this.platform || this.setup(); return this.platform != "web"; },
  97.  
  98. /* General screen size functions -- tablet vs phone, landscape vs portrait */
  99. isLargeScreen: function() { this.platform || this.setup(); return window.innerWidth > 480; },
  100. isWideScreen: function() { this.platform || this.setup(); return window.innerWidth > window.innerHeight; },
  101.  
  102. /* Platform-supplied UI concerns */
  103. hasBack: function()
  104. {
  105. this.platform || this.setup();
  106. return this.platform == "android" || (this.platform == "webos" && this.platformVersion < 3);
  107. },
  108. hasMenu: function()
  109. {
  110. /* You may want to include Android here if you're using a target
  111. * API of less than 14 (Ice Cream Sandwich)
  112. */
  113. /* Blackberry Tablet OS has a standard "swipe down from top bezel" gesture
  114. * that they use .. should probably consider that here, but I'm not sure
  115. * if their other platforms have any equivalent
  116. */
  117. this.platform || this.setup();
  118. return this.platform == "webos";
  119. },
  120.  
  121. /* Platform-specific Audio utility. WebWorks on PlayBook and webOS have
  122. * great support for HTML5 audio objects. Android's is terrible, so we
  123. * choose to use the PhoneGap media API there, which is encapsulated in
  124. * the PlatformSound kind
  125. */
  126. useHTMLAudio: function()
  127. {
  128. this.platform || this.setup();
  129. return this.isWebOS() || this.isWebWorks() || !this.isMobile();
  130. },
  131. /* Platform Specific Web Browser -- returns a function that should
  132. * launch the OS's web browser.
  133. * call: Platform.browser("http://www.google.com/", this)();
  134. */
  135. browser: function(url, thisObj)
  136. {
  137. this.platform || this.setup();
  138. if(this.isWebOS())
  139. {
  140. return enyo.bind(thisObj, (function(args) {
  141. var x = thisObj.createComponent({ name: "AppManService", kind: "PalmService", service: "palm://com.palm.applicationManager/", method: "open" });
  142. x.call({ target: url });
  143. }));
  144. }
  145. else if(this.platform == "web" || (this.platform == "android" && parseFloat(this.platformVersion >= 4.0)) )
  146. {
  147. /* If web, just open a new tab/window - this also works well in
  148. * Android 4.0 - suggest ChildBrowser PhoneGap plugin for other
  149. * versions of Android
  150. */
  151. return enyo.bind(thisObj, function(x) { window.open(x, '_blank'); }, url);
  152. }
  153. else if(this.isBlackBerry())
  154. {
  155. /* If BlackBerry, go through their ridiculous parsing rules */
  156. /* Make sure you have the invoke and invoke.BrowserArguments
  157. * configured in your config.xml.
  158. */
  159. var args = new blackberry.invoke.BrowserArguments(this.blackBerryURLEncode(url));
  160. return enyo.bind(thisObj, blackberry.invoke.invoke, blackberry.invoke.APP_BROWSER, args);
  161. }
  162. else if(typeof PhoneGap !== "undefined" && window.plugins && window.plugins.childBrowser)
  163. {
  164. /* If you have the popular childBrowser plugin for PhoneGap */
  165. return enyo.bind(thisObj, window.plugins.childBrowser.openExternal, url);
  166. }
  167. else
  168. {
  169. /* Fall back to something that could possibly work
  170. * One could also make a case for just setting window.location
  171. */
  172. return enyo.bind(thisObj, function(x) { window.open(x, '_blank'); }, url);
  173. }
  174. },
  175. /* A ridiculous function for parsing URLs into something that RIM's
  176. * BrowserArguments call can deal with "properly", thanks to their
  177. * forums.
  178. */
  179. blackBerryURLEncode: function(address) {
  180. var encodedAddress = "";
  181. // URL Encode all instances of ':' in the address
  182. encodedAddress = address.replace(/:/g, "%3A");
  183. // Leave the first instance of ':' in its normal form
  184. encodedAddress = encodedAddress.replace(/%3A/, ":");
  185. // Escape all instances of '&' in the address
  186. encodedAddress = encodedAddress.replace(/&/g, "\&");
  187.  
  188. if (typeof blackberry !== 'undefined') {
  189. var args = new blackberry.invoke.BrowserArguments(encodedAddress);
  190. blackberry.invoke.invoke(blackberry.invoke.APP_BROWSER, args);
  191. } else {
  192. // If I am not a BlackBerry device, open link in current browser
  193. window.location = encodedAddress;
  194. }
  195. },
  196. getReviewURL: function()
  197. {
  198. this.platform || this.setup();
  199. var url = "";
  200. switch(Platform.platform) {
  201. case "webos":
  202. url = "http://developer.palm.com/appredirect/?packageid=" + enyo.fetchAppId();
  203. break;
  204. case "android":
  205. url = "market://details?id=" + enyo.fetchAppId();
  206. break;
  207. case "blackberry": // intentional fallthrough
  208. case "webworks":
  209. url = "";
  210. break;
  211. case "iphone":
  212. var appInfo = enyo.fetchAppInfo();
  213. if(enyo.isString(appInfo))
  214. appInfo = JSON.parse(appInfo);
  215. url = "itms-apps://ax.itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?type=Purple+Software&id="+appInfo.iTunesAppId;
  216. break;
  217. }
  218. return url;
  219. }
  220. }
  221. });
  222.  
  223. /* PlatformSound is an encapsulation for both the HTML5 audio support within
  224. * webOS and WebWorks, and an extension of some of the abilities of the stock
  225. * Enyo 1.0 Sound kind.
  226. */
  227. enyo.kind({
  228. name: "PlatformSound",
  229. kind: "Sound",
  230. position: -1,
  231. /* Play our sound. If our sound is already playing, restart it */
  232. play: function() {
  233. if(!Platform.useHTMLAudio()) {
  234. if(window.PhoneGap)
  235. this.media.play();
  236. } else {
  237. if (!this.audio.paused) {
  238. this.audio.currentTime = 0;
  239. } else {
  240. this.audio.play();
  241. }
  242. }
  243. this.Paused = false;
  244. if(!Platform.useHTMLAudio())
  245. {
  246. /* The PhoneGap media API does not document it's "MediaProgress"
  247. * callback, nor does it seem to be supported universally, at least
  248. * with PhoneGap 1.4.1, so, i'm going to just run a timer to the
  249. * getCurrentPosition() asynch method, and record it regularly.
  250. */
  251. this.Timer = setInterval(enyo.bind(this, this.getMediaPos), 100);
  252. }
  253. },
  254. /* Override the function from the base Enyo 1.0 kind, to add support for
  255. * the PhoneGap Media callbacks that they provide now
  256. */
  257. srcChanged: function() {
  258. var path = enyo.path.rewrite(this.src);
  259. if(!Platform.useHTMLAudio()) {
  260. if(window.PhoneGap)
  261. this.media = new Media(path, this.MediaSuccess, this.mediaFail, this.mediaStatus, this.mediaProgress);
  262. else
  263. enyo.log("*** Don't know how to play media without HTML5 or PhoneGap!", Platform.platform);
  264. } else {
  265. this.audio = new Audio();
  266. this.audio.src = path;
  267. }
  268. },
  269. /* Internal callback functions */
  270. getMediaPos: function(x, y, z) {
  271. this.media.getCurrentPosition(enyo.bind(this, this.posReceived));
  272. },
  273. posReceived: function(x, y, z) {
  274. this.position = x;
  275. },
  276. mediaSuccess: function(x, y, z) {
  277. enyo.log("mediaSuccess "+ x+ y+ z);
  278. },
  279. mediaFail: function(x, y, z) {
  280. enyo.log("mediaFail "+ x+ y+ z);
  281. },
  282. mediaStatus: function(x, y, z) {
  283. /* Possible Media States, taken from PhoneGap 1.4.1 Android source:
  284. * Media.MEDIA_NONE = 0;
  285. * Media.MEDIA_STARTING = 1;
  286. * Media.MEDIA_RUNNING = 2;
  287. * Media.MEDIA_PAUSED = 3;
  288. * Media.MEDIA_STOPPED = 4;
  289. * not really sure what to make of them, so I just note Paused for now.
  290. */
  291. if(x == Media.MEDIA_Paused)
  292. this.Paused = true;
  293. else
  294. this.Paused = false;
  295. enyo.log("mediaStatus"+ x+ y+ z);
  296. },
  297. mediaProgress: function(x, y, z) {
  298. /* This callback specified in the Media constructor doesn't seem to
  299. * work on Android at the moment? If you see it working somewhere, you
  300. * could kill the setInterval in Play on that platform, and record the
  301. * progress here instead.
  302. */
  303. enyo.log("mediaProgress "+ x+ y+ z);
  304. },
  305. /* Return the current position of audio playback, HTML5 and PhoneGap both
  306. * seem to like it as a float down to millisecond resolution
  307. */
  308. getCurrentPosition: function() {
  309. /* I wasn't able to get PhoneGap's media._position to give me a valid
  310. * location reliably, so we record it from the callback
  311. */
  312. return Platform.useHTMLAudio() ? this.audio.currentTime : this.position; /* PhoneGap's media._position doesn't seem to load? */
  313. },
  314. /* Returns the duration of the loaded media */
  315. getDuration: function() {
  316. return !Platform.useHTMLAudio() ? this.media.getDuration() : this.audio.duration;
  317. },
  318. /* Pause playback - calling play should resume */
  319. pause: function() {
  320. this.Paused = true;
  321. clearInterval(this.Timer);
  322. !Platform.useHTMLAudio() ? this.media.pause() : this.audio.pause();
  323. },
  324. /* Forces PhoneGap to release media handles in the OS, they recommend that
  325. * you call this whenever you stop playback on Android. Also destroys
  326. * the component, so you can create a new one when you need more playback.
  327. */
  328. release: function() {
  329. this.pause();
  330. if(!Platform.useHTMLAudio()) {
  331. this.media.release();
  332. }
  333. this.destroy();
  334. },
  335. /* Reposition the media playback from the given location. HTML5 apparently
  336. * uses a float with seconds, whereas PhoneGap is looking for an int in
  337. * milliseconds
  338. */
  339. seekTo: function(loc) {
  340. if(!Platform.useHTMLAudio() ) {
  341. this.media.seekTo(loc * 1000);
  342. } else {
  343. this.audio.currentTime = loc;
  344. }
  345. },
  346. /* Stop playback. Do not destroy anything. Next call to play will restart
  347. * playback from the beginning.
  348. */
  349. stop: function() {
  350. clearInterval(this.Timer);
  351. if(!Platform.useHTMLAudio() ) {
  352. this.media.stop();
  353. } else {
  354. this.audio.pause();
  355. this.audio.currentTime = 0;
  356. }
  357. }
  358. });
Advertisement
Add Comment
Please, Sign In to add comment