PageRenderTime 61ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/prototypes/wp8/CordovaWP8_3.3.02/cordovalib/CordovaView.xaml.cs

https://github.com/diegosquid/cordova-plugin-background-download
C# | 541 lines | 346 code | 88 blank | 107 comment | 35 complexity | 1c30e69e85d4bfe066478b75d9d10c8b MD5 | raw file
Possible License(s): Apache-2.0
  1. /*
  2. Licensed under the Apache License, Version 2.0 (the "License");
  3. you may not use this file except in compliance with the License.
  4. You may obtain a copy of the License at
  5. http://www.apache.org/licenses/LICENSE-2.0
  6. Unless required by applicable law or agreed to in writing, software
  7. distributed under the License is distributed on an "AS IS" BASIS,
  8. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  9. See the License for the specific language governing permissions and
  10. limitations under the License.
  11. */
  12. using System;
  13. using System.Collections.Generic;
  14. using System.Linq;
  15. using System.Net;
  16. using System.Windows;
  17. using System.Windows.Controls;
  18. using System.Windows.Documents;
  19. using System.Windows.Input;
  20. using System.Windows.Media;
  21. using System.Windows.Media.Animation;
  22. using System.Windows.Shapes;
  23. using Microsoft.Phone.Controls;
  24. using System.IO.IsolatedStorage;
  25. using System.Windows.Resources;
  26. using System.Windows.Interop;
  27. using System.Runtime.Serialization.Json;
  28. using System.IO;
  29. using System.ComponentModel;
  30. using System.Xml.Linq;
  31. using WPCordovaClassLib.Cordova.Commands;
  32. using System.Diagnostics;
  33. using System.Text;
  34. using WPCordovaClassLib.Cordova;
  35. using System.Threading;
  36. using Microsoft.Phone.Shell;
  37. using WPCordovaClassLib.Cordova.JSON;
  38. using WPCordovaClassLib.CordovaLib;
  39. namespace WPCordovaClassLib
  40. {
  41. public partial class CordovaView : UserControl
  42. {
  43. /// <summary>
  44. /// Indicates whether web control has been loaded and no additional initialization is needed.
  45. /// Prevents data clearing during page transitions.
  46. /// </summary>
  47. private bool IsBrowserInitialized = false;
  48. /// <summary>
  49. /// Set when the user attaches a back button handler inside the WebBrowser
  50. /// </summary>
  51. private bool OverrideBackButton = false;
  52. /// <summary>
  53. /// Sentinal to keep track of page changes as a result of the hardware back button
  54. /// Set to false when the back-button is pressed, which calls js window.history.back()
  55. /// If the page changes as a result of the back button the event is cancelled.
  56. /// </summary>
  57. private bool PageDidChange = false;
  58. private static string AppRoot = "";
  59. /// <summary>
  60. /// Handles native api calls
  61. /// </summary>
  62. private NativeExecution nativeExecution;
  63. protected BrowserMouseHelper bmHelper;
  64. private ConfigHandler configHandler;
  65. private Dictionary<string, IBrowserDecorator> browserDecorators;
  66. public System.Windows.Controls.Grid _LayoutRoot
  67. {
  68. get
  69. {
  70. return ((System.Windows.Controls.Grid)(this.FindName("LayoutRoot")));
  71. }
  72. }
  73. public WebBrowser Browser
  74. {
  75. get
  76. {
  77. return CordovaBrowser;
  78. }
  79. }
  80. /*
  81. * Setting StartPageUri only has an effect if called before the view is loaded.
  82. **/
  83. protected Uri _startPageUri = null;
  84. public Uri StartPageUri
  85. {
  86. get
  87. {
  88. if (_startPageUri == null)
  89. {
  90. // default
  91. return new Uri(AppRoot + "www/index.html", UriKind.Relative);
  92. }
  93. else
  94. {
  95. return _startPageUri;
  96. }
  97. }
  98. set
  99. {
  100. if (!this.IsBrowserInitialized)
  101. {
  102. _startPageUri = value;
  103. }
  104. }
  105. }
  106. /// <summary>
  107. /// Gets or sets whether to suppress bouncy scrolling of
  108. /// the WebBrowser control;
  109. /// </summary>
  110. public bool DisableBouncyScrolling
  111. {
  112. get;
  113. set;
  114. }
  115. public CordovaView()
  116. {
  117. InitializeComponent();
  118. if (DesignerProperties.IsInDesignTool)
  119. {
  120. return;
  121. }
  122. StartupMode mode = PhoneApplicationService.Current.StartupMode;
  123. if (mode == StartupMode.Launch)
  124. {
  125. PhoneApplicationService service = PhoneApplicationService.Current;
  126. service.Activated += new EventHandler<Microsoft.Phone.Shell.ActivatedEventArgs>(AppActivated);
  127. service.Launching += new EventHandler<LaunchingEventArgs>(AppLaunching);
  128. service.Deactivated += new EventHandler<DeactivatedEventArgs>(AppDeactivated);
  129. service.Closing += new EventHandler<ClosingEventArgs>(AppClosing);
  130. }
  131. else
  132. {
  133. }
  134. // initializes native execution logic
  135. configHandler = new ConfigHandler();
  136. configHandler.LoadAppPackageConfig();
  137. if (configHandler.ContentSrc != null)
  138. {
  139. if (Uri.IsWellFormedUriString(configHandler.ContentSrc, UriKind.Absolute))
  140. {
  141. this.StartPageUri = new Uri(configHandler.ContentSrc, UriKind.Absolute);
  142. }
  143. else
  144. {
  145. this.StartPageUri = new Uri(AppRoot + "www/" + configHandler.ContentSrc, UriKind.Relative);
  146. }
  147. }
  148. browserDecorators = new Dictionary<string, IBrowserDecorator>();
  149. nativeExecution = new NativeExecution(ref this.CordovaBrowser);
  150. bmHelper = new BrowserMouseHelper(ref this.CordovaBrowser);
  151. CreateDecorators();
  152. }
  153. /*
  154. * browserDecorators are a collection of plugin-like classes (IBrowserDecorator) that add some bit of functionality to the browser.
  155. * These are somewhat different than plugins in that they are usually not async and patch a browser feature that we would
  156. * already expect to have. Essentially these are browser polyfills that are patched from the outside in.
  157. * */
  158. void CreateDecorators()
  159. {
  160. XHRHelper xhrProxy = new XHRHelper();
  161. xhrProxy.Browser = CordovaBrowser;
  162. browserDecorators.Add("XHRLOCAL", xhrProxy);
  163. OrientationHelper orientHelper = new OrientationHelper();
  164. orientHelper.Browser = CordovaBrowser;
  165. browserDecorators.Add("Orientation", orientHelper);
  166. ConsoleHelper console = new ConsoleHelper();
  167. console.Browser = CordovaBrowser;
  168. browserDecorators.Add("ConsoleLog", console);
  169. }
  170. void AppClosing(object sender, ClosingEventArgs e)
  171. {
  172. Debug.WriteLine("AppClosing");
  173. }
  174. void AppDeactivated(object sender, DeactivatedEventArgs e)
  175. {
  176. Debug.WriteLine("INFO: AppDeactivated");
  177. try
  178. {
  179. CordovaBrowser.InvokeScript("eval", new string[] { "cordova.fireDocumentEvent('pause');" });
  180. }
  181. catch (Exception)
  182. {
  183. Debug.WriteLine("ERROR: Pause event error");
  184. }
  185. }
  186. void AppLaunching(object sender, LaunchingEventArgs e)
  187. {
  188. Debug.WriteLine("INFO: AppLaunching");
  189. }
  190. void AppActivated(object sender, Microsoft.Phone.Shell.ActivatedEventArgs e)
  191. {
  192. Debug.WriteLine("INFO: AppActivated");
  193. try
  194. {
  195. CordovaBrowser.InvokeScript("eval", new string[] { "cordova.fireDocumentEvent('resume');" });
  196. }
  197. catch (Exception)
  198. {
  199. Debug.WriteLine("ERROR: Resume event error");
  200. }
  201. }
  202. void CordovaBrowser_Loaded(object sender, RoutedEventArgs e)
  203. {
  204. this.bmHelper.ScrollDisabled = this.DisableBouncyScrolling;
  205. if (DesignerProperties.IsInDesignTool)
  206. {
  207. return;
  208. }
  209. // prevents refreshing web control to initial state during pages transitions
  210. if (this.IsBrowserInitialized) return;
  211. try
  212. {
  213. // Before we possibly clean the ISO-Store, we need to grab our generated UUID, so we can rewrite it after.
  214. string deviceUUID = "";
  215. using (IsolatedStorageFile appStorage = IsolatedStorageFile.GetUserStoreForApplication())
  216. {
  217. try
  218. {
  219. IsolatedStorageFileStream fileStream = new IsolatedStorageFileStream("DeviceID.txt", FileMode.Open, FileAccess.Read, appStorage);
  220. using (StreamReader reader = new StreamReader(fileStream))
  221. {
  222. deviceUUID = reader.ReadLine();
  223. }
  224. }
  225. catch (Exception /*ex*/)
  226. {
  227. deviceUUID = Guid.NewGuid().ToString();
  228. Debug.WriteLine("Updating IsolatedStorage for APP:DeviceID :: " + deviceUUID);
  229. IsolatedStorageFileStream file = new IsolatedStorageFileStream("DeviceID.txt", FileMode.Create, FileAccess.Write, appStorage);
  230. using (StreamWriter writeFile = new StreamWriter(file))
  231. {
  232. writeFile.WriteLine(deviceUUID);
  233. writeFile.Close();
  234. }
  235. }
  236. }
  237. /*
  238. * 11/08/12 Ruslan Kokorev
  239. * Copying files to isolated storage is no more required in WP8. WebBrowser control now works with files located in XAP.
  240. */
  241. //StreamResourceInfo streamInfo = Application.GetResourceStream(new Uri("CordovaSourceDictionary.xml", UriKind.Relative));
  242. //if (streamInfo != null)
  243. //{
  244. // StreamReader sr = new StreamReader(streamInfo.Stream);
  245. // //This will Read Keys Collection for the xml file
  246. // XDocument document = XDocument.Parse(sr.ReadToEnd());
  247. // var files = from results in document.Descendants("FilePath")
  248. // select new
  249. // {
  250. // path = (string)results.Attribute("Value")
  251. // };
  252. // StreamResourceInfo fileResourceStreamInfo;
  253. // using (IsolatedStorageFile appStorage = IsolatedStorageFile.GetUserStoreForApplication())
  254. // {
  255. // foreach (var file in files)
  256. // {
  257. // fileResourceStreamInfo = Application.GetResourceStream(new Uri(file.path, UriKind.Relative));
  258. // if (fileResourceStreamInfo != null)
  259. // {
  260. // using (BinaryReader br = new BinaryReader(fileResourceStreamInfo.Stream))
  261. // {
  262. // byte[] data = br.ReadBytes((int)fileResourceStreamInfo.Stream.Length);
  263. // string strBaseDir = AppRoot + file.path.Substring(0, file.path.LastIndexOf(System.IO.Path.DirectorySeparatorChar));
  264. // if (!appStorage.DirectoryExists(strBaseDir))
  265. // {
  266. // Debug.WriteLine("INFO: Creating Directory :: " + strBaseDir);
  267. // appStorage.CreateDirectory(strBaseDir);
  268. // }
  269. // // This will truncate/overwrite an existing file, or
  270. // using (IsolatedStorageFileStream outFile = appStorage.OpenFile(AppRoot + file.path, FileMode.Create))
  271. // {
  272. // Debug.WriteLine("INFO: Writing data for " + AppRoot + file.path + " and length = " + data.Length);
  273. // using (var writer = new BinaryWriter(outFile))
  274. // {
  275. // writer.Write(data);
  276. // }
  277. // }
  278. // }
  279. // }
  280. // else
  281. // {
  282. // Debug.WriteLine("ERROR: Failed to write file :: " + file.path + " did you forget to add it to the project?");
  283. // }
  284. // }
  285. // }
  286. //}
  287. CordovaBrowser.Navigate(StartPageUri);
  288. IsBrowserInitialized = true;
  289. AttachHardwareButtonHandlers();
  290. }
  291. catch (Exception ex)
  292. {
  293. Debug.WriteLine("ERROR: Exception in CordovaBrowser_Loaded :: {0}", ex.Message);
  294. }
  295. }
  296. void AttachHardwareButtonHandlers()
  297. {
  298. PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
  299. if (frame != null)
  300. {
  301. PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
  302. if (page != null)
  303. {
  304. page.BackKeyPress += new EventHandler<CancelEventArgs>(page_BackKeyPress);
  305. // CB-2347 -jm
  306. string fullscreen = configHandler.GetPreference("fullscreen");
  307. bool bFullScreen = false;
  308. if (bool.TryParse(fullscreen, out bFullScreen) && bFullScreen)
  309. {
  310. SystemTray.SetIsVisible(page, false);
  311. }
  312. }
  313. }
  314. }
  315. void page_BackKeyPress(object sender, CancelEventArgs e)
  316. {
  317. if (OverrideBackButton)
  318. {
  319. try
  320. {
  321. CordovaBrowser.InvokeScript("eval", new string[] { "cordova.fireDocumentEvent('backbutton', {}, true);" });
  322. e.Cancel = true;
  323. }
  324. catch (Exception ex)
  325. {
  326. Console.WriteLine("Exception while invoking backbutton into cordova view: " + ex.Message);
  327. }
  328. }
  329. else
  330. {
  331. try
  332. {
  333. PageDidChange = false;
  334. Uri uriBefore = this.Browser.Source;
  335. // calling js history.back with result in a page change if history was valid.
  336. CordovaBrowser.InvokeScript("eval", new string[] { "(function(){window.history.back();})()" });
  337. Uri uriAfter = this.Browser.Source;
  338. e.Cancel = PageDidChange || (uriBefore != uriAfter);
  339. }
  340. catch (Exception)
  341. {
  342. e.Cancel = false; // exit the app ... ?
  343. }
  344. }
  345. }
  346. void CordovaBrowser_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e)
  347. {
  348. Debug.WriteLine("CordovaBrowser_LoadCompleted");
  349. string[] autoloadPlugs = this.configHandler.AutoloadPlugins;
  350. foreach (string plugName in autoloadPlugs)
  351. {
  352. //nativeExecution.ProcessCommand(commandCallParams);
  353. }
  354. string nativeReady = "(function(){ cordova.require('cordova/channel').onNativeReady.fire()})();";
  355. try
  356. {
  357. CordovaBrowser.InvokeScript("execScript", new string[] { nativeReady });
  358. }
  359. catch (Exception /*ex*/)
  360. {
  361. Debug.WriteLine("Error calling js to fire nativeReady event. Did you include cordova.js in your html script tag?");
  362. }
  363. if (this.CordovaBrowser.Opacity < 1)
  364. {
  365. FadeIn.Begin();
  366. }
  367. }
  368. void CordovaBrowser_Navigating(object sender, NavigatingEventArgs e)
  369. {
  370. if (!configHandler.URLIsAllowed(e.Uri.ToString()))
  371. {
  372. Debug.WriteLine("Whitelist exception: Stopping browser from navigating to :: " + e.Uri.ToString());
  373. e.Cancel = true;
  374. return;
  375. }
  376. this.PageDidChange = true;
  377. this.nativeExecution.ResetAllCommands();
  378. }
  379. /*
  380. * This method does the work of routing commands
  381. * NotifyEventArgs.Value contains a string passed from JS
  382. * If the command already exists in our map, we will just attempt to call the method(action) specified, and pass the args along
  383. * Otherwise, we create a new instance of the command, add it to the map, and call it ...
  384. * This method may also receive JS error messages caught by window.onerror, in any case where the commandStr does not appear to be a valid command
  385. * it is simply output to the debugger output, and the method returns.
  386. *
  387. **/
  388. void CordovaBrowser_ScriptNotify(object sender, NotifyEventArgs e)
  389. {
  390. string commandStr = e.Value;
  391. string commandName = commandStr.Split('/').FirstOrDefault();
  392. if (browserDecorators.ContainsKey(commandName))
  393. {
  394. browserDecorators[commandName].HandleCommand(commandStr);
  395. return;
  396. }
  397. CordovaCommandCall commandCallParams = CordovaCommandCall.Parse(commandStr);
  398. if (commandCallParams == null)
  399. {
  400. // ERROR
  401. Debug.WriteLine("ScriptNotify :: " + commandStr);
  402. }
  403. else if (commandCallParams.Service == "CoreEvents")
  404. {
  405. switch (commandCallParams.Action.ToLower())
  406. {
  407. case "overridebackbutton":
  408. string arg0 = JsonHelper.Deserialize<string[]>(commandCallParams.Args)[0];
  409. this.OverrideBackButton = (arg0 != null && arg0.Length > 0 && arg0.ToLower() == "true");
  410. break;
  411. }
  412. }
  413. else
  414. {
  415. if (configHandler.IsPluginAllowed(commandCallParams.Service))
  416. {
  417. nativeExecution.ProcessCommand(commandCallParams);
  418. }
  419. else
  420. {
  421. Debug.WriteLine("Error::Plugin not allowed in config.xml. " + commandCallParams.Service);
  422. }
  423. }
  424. }
  425. public void LoadPage(string url)
  426. {
  427. if (this.configHandler.URLIsAllowed(url))
  428. {
  429. this.CordovaBrowser.Navigate(new Uri(url, UriKind.RelativeOrAbsolute));
  430. }
  431. else
  432. {
  433. Debug.WriteLine("Oops, Can't load url based on config.xml :: " + url);
  434. }
  435. }
  436. private void CordovaBrowser_Unloaded(object sender, RoutedEventArgs e)
  437. {
  438. }
  439. private void CordovaBrowser_NavigationFailed(object sender, System.Windows.Navigation.NavigationFailedEventArgs e)
  440. {
  441. Debug.WriteLine("CordovaBrowser_NavigationFailed :: " + e.Uri.ToString());
  442. }
  443. private void CordovaBrowser_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
  444. {
  445. foreach (IBrowserDecorator iBD in browserDecorators.Values)
  446. {
  447. iBD.InjectScript();
  448. }
  449. }
  450. }
  451. }