PageRenderTime 46ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/platforms/wp8/cordovalib/XHRHelper.cs

https://gitlab.com/adamlwalker/phonegap-nfc-reader
C# | 270 lines | 255 code | 14 blank | 1 comment | 5 complexity | 997fe3d2650bb7e2470d5e97ea5c75ef MD5 | raw file
  1. using Microsoft.Phone.Controls;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Diagnostics;
  5. using System.IO;
  6. using System.IO.IsolatedStorage;
  7. using System.Linq;
  8. using System.Text;
  9. using System.Windows;
  10. namespace WPCordovaClassLib.CordovaLib
  11. {
  12. public class XHRHelper : IBrowserDecorator
  13. {
  14. public WebBrowser Browser { get; set; }
  15. public PhoneApplicationPage Page { get; set; }
  16. public void InjectScript()
  17. {
  18. string script = @"(function(win, doc) {
  19. var docDomain = null;
  20. try {
  21. docDomain = doc.domain;
  22. } catch (err) {}
  23. if (!docDomain || docDomain.length === 0) {
  24. var aliasXHR = win.XMLHttpRequest;
  25. var XHRShim = function() {};
  26. win.XMLHttpRequest = XHRShim;
  27. XHRShim.noConflict = aliasXHR;
  28. XHRShim.UNSENT = 0;
  29. XHRShim.OPENED = 1;
  30. XHRShim.HEADERS_RECEIVED = 2;
  31. XHRShim.LOADING = 3;
  32. XHRShim.DONE = 4;
  33. XHRShim.prototype = {
  34. isAsync: false,
  35. onreadystatechange: null,
  36. readyState: 0,
  37. _url: '',
  38. timeout: 0,
  39. withCredentials: false,
  40. _requestHeaders: null,
  41. open: function (reqType, uri, isAsync, user, password) {
  42. if (uri && uri.indexOf('http') === 0) {
  43. if (!this.wrappedXHR) {
  44. this.wrappedXHR = new aliasXHR();
  45. var self = this;
  46. if (this.timeout > 0) {
  47. this.wrappedXHR.timeout = this.timeout;
  48. }
  49. Object.defineProperty(this, 'timeout', {
  50. set: function(val) {
  51. this.wrappedXHR.timeout = val;
  52. },
  53. get: function() {
  54. return this.wrappedXHR.timeout;
  55. }
  56. });
  57. if (this.withCredentials) {
  58. this.wrappedXHR.withCredentials = this.withCredentials;
  59. }
  60. Object.defineProperty(this, 'withCredentials', {
  61. set: function(val) {
  62. this.wrappedXHR.withCredentials = val;
  63. },
  64. get: function() {
  65. return this.wrappedXHR.withCredentials;
  66. }
  67. });
  68. Object.defineProperty(this, 'status', {
  69. get: function() {
  70. return this.wrappedXHR.status;
  71. }
  72. });
  73. Object.defineProperty(this, 'responseText', {
  74. get: function() {
  75. return this.wrappedXHR.responseText;
  76. }
  77. });
  78. Object.defineProperty(this, 'statusText', {
  79. get: function() {
  80. return this.wrappedXHR.statusText;
  81. }
  82. });
  83. Object.defineProperty(this, 'responseXML', {
  84. get: function() {
  85. return this.wrappedXHR.responseXML;
  86. }
  87. });
  88. this.getResponseHeader = function(header) {
  89. return this.wrappedXHR.getResponseHeader(header);
  90. };
  91. this.getAllResponseHeaders = function() {
  92. return this.wrappedXHR.getAllResponseHeaders();
  93. };
  94. this.wrappedXHR.onreadystatechange = function() {
  95. self.changeReadyState(self.wrappedXHR.readyState);
  96. };
  97. }
  98. return this.wrappedXHR.open(reqType, uri, isAsync, user, password);
  99. }
  100. else
  101. {
  102. this.isAsync = isAsync;
  103. this.reqType = reqType;
  104. this._url = uri;
  105. }
  106. },
  107. statusText: '',
  108. changeReadyState: function(newState) {
  109. this.readyState = newState;
  110. if (this.onreadystatechange) {
  111. this.onreadystatechange();
  112. }
  113. if (this.readyState == XHRShim.DONE){
  114. this.onload && this.onload();
  115. }
  116. },
  117. setRequestHeader: function(header, value) {
  118. if (this.wrappedXHR) {
  119. this.wrappedXHR.setRequestHeader(header, value);
  120. }
  121. },
  122. getResponseHeader: function(header) {
  123. return this.wrappedXHR ? this.wrappedXHR.getResponseHeader(header) : '';
  124. },
  125. getAllResponseHeaders: function() {
  126. return this.wrappedXHR ? this.wrappedXHR.getAllResponseHeaders() : '';
  127. },
  128. overrideMimeType: function(mimetype) {
  129. return this.wrappedXHR ? this.wrappedXHR.overrideMimeType(mimetype) : '';
  130. },
  131. responseText: '',
  132. responseXML: '',
  133. onResult: function(res) {
  134. this.status = 200;
  135. if (typeof res == 'object') {
  136. res = JSON.stringify(res);
  137. }
  138. this.responseText = res;
  139. this.responseXML = res;
  140. this.changeReadyState(XHRShim.DONE);
  141. },
  142. onError: function(err) {
  143. this.status = 404;
  144. this.changeReadyState(XHRShim.DONE);
  145. },
  146. abort: function() {
  147. if (this.wrappedXHR) {
  148. return this.wrappedXHR.abort();
  149. }
  150. },
  151. send: function(data) {
  152. if (this.wrappedXHR) {
  153. return this.wrappedXHR.send(data);
  154. }
  155. else {
  156. this.changeReadyState(XHRShim.OPENED);
  157. var alias = this;
  158. var root = window.location.href.split('#')[0]; // remove hash
  159. var basePath = root.substr(0,root.lastIndexOf('/')) + '/';
  160. var resolvedUrl = this._url.split('//').join('/').split('#')[0]; // remove hash
  161. var wwwFolderPath = navigator.userAgent.indexOf('MSIE 9.0') > -1 ? 'app/www/' : 'www/';
  162. if(resolvedUrl.indexOf('/') == 0) {
  163. //console.log('removing leading /');
  164. resolvedUrl = resolvedUrl.substr(1);
  165. }
  166. // handle special case where url is of form app/www but we are loaded just from /www
  167. if( resolvedUrl.indexOf('app/www') == 0 ) {
  168. resolvedUrl = window.location.protocol + wwwFolderPath + resolvedUrl.substr(7);
  169. }
  170. else if( resolvedUrl.indexOf('www') == 0) {
  171. resolvedUrl = window.location.protocol + wwwFolderPath + resolvedUrl.substr(4);
  172. }
  173. if(resolvedUrl.indexOf(':') < 0) {
  174. resolvedUrl = basePath + resolvedUrl; // consider it relative
  175. }
  176. var funk = function () {
  177. window.__onXHRLocalCallback = function (responseCode, responseText) {
  178. alias.status = responseCode;
  179. if (responseCode == '200') {
  180. alias.responseText = responseText;
  181. }
  182. else {
  183. alias.onerror && alias.onerror(responseCode);
  184. }
  185. alias.changeReadyState(XHRShim.DONE);
  186. }
  187. alias.changeReadyState(XHRShim.LOADING);
  188. window.external.Notify('XHRLOCAL/' + resolvedUrl);
  189. }
  190. if (this.isAsync) {
  191. setTimeout(funk, 0);
  192. }
  193. else {
  194. funk();
  195. }
  196. }
  197. },
  198. status: 404
  199. };
  200. }
  201. })(window, document); ";
  202. Browser.InvokeScript("execScript", new string[] { script });
  203. }
  204. public bool HandleCommand(string commandStr)
  205. {
  206. if (commandStr.IndexOf("XHRLOCAL") == 0)
  207. {
  208. string url = commandStr.Replace("XHRLOCAL/", "");
  209. Uri uri = new Uri(url, UriKind.RelativeOrAbsolute);
  210. using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
  211. {
  212. if (isoFile.FileExists(uri.AbsolutePath))
  213. {
  214. using (TextReader reader = new StreamReader(isoFile.OpenFile(uri.AbsolutePath, FileMode.Open, FileAccess.Read)))
  215. {
  216. string text = reader.ReadToEnd();
  217. Browser.InvokeScript("__onXHRLocalCallback", new string[] { "200", text });
  218. return true;
  219. }
  220. }
  221. }
  222. Uri relUri = new Uri(uri.AbsolutePath, UriKind.Relative);
  223. var resource = Application.GetResourceStream(relUri);
  224. if (resource == null)
  225. {
  226. // 404 ?
  227. Browser.InvokeScript("__onXHRLocalCallback", new string[] { "404" });
  228. return true;
  229. }
  230. else
  231. {
  232. using (StreamReader streamReader = new StreamReader(resource.Stream))
  233. {
  234. string text = streamReader.ReadToEnd();
  235. Browser.InvokeScript("__onXHRLocalCallback", new string[] { "200", text });
  236. return true;
  237. }
  238. }
  239. }
  240. return false;
  241. }
  242. }
  243. }