As you may have guessed by the title of this post, I've been looking at adding Windows Phone 7 support to PhoneGap.
For those that are interested, the code can be found at http://github.com/mrlacey/phonegap-wp7. I know that others have started some work on this also. (Most notably at http://github.com/filmaj/phonegap-winphone.) I thought I would share what I've been doing to help the project. I'd already got further than the version by filmaj when I became aware of and have solved some issues they haven't dealt with yet.
So what is implemented?
In theory the easiest way to show what is implmented is show some test results. So here we are:
It passes 76 of 98 tests. Not bad. (Even if I say so myself).
As it's a shorter list, the tests that fail are the ones which relate to: HTML5 Storage, Contacts, File IO, Maps and methods which require objects being passed in their callback functions.
It's probably a good time to point out that all I've done has only been tested in the Beta emulator. (I'd love to have a real device to test this on. Hint, hint!) Because some functionality requires can't be tested in the emulator, some of it is untested (e.g. navigator.notification.vibrate()) while other code always returns the same default values in the emulator.
How much functionality is implemented?
The following functionality is documented as supported across all platforms which PhoneGap supports:
Accelerometer: GetCurrentAccelleration is implemented but the watcher functions are not as these cannot be tested in the emulator.
Supporting tombstoning is the biggest issue with the current code. This could probably be worked around by storing all relevant callback details natively so they could be kept in state across deactivation/activation but I'd like to get some feedback on what I've done so far before spending more time on this.Device: All features are implemented in JS, but limitations of the WP7 API currently mean that not all details are populated. It should be possible to get theses details with the release version of the API.
Events: deviceReady is not implemented as I have been unable to find a way to create events in the browser. It seems this can't be done, so I have implemented the PhoneGap.available property as a test for confirming loading.
Geolocation: getCurrentPosition is implemented (but returning a hardcoded vallue in the emulator). The watcher functions are not implemented as these cannot be tested in the emulator.
Network: this is implemented
Notification: this is fully implemented.
Additionally, the following other features are also implemented:
DebugConsole: log, warn and error methods
Orientation: getCurrentLocation and the watcher functions (as these can be tested in the emulator)
SMS: Send - triggers the compose functionality
Telephony: Call - triggers the request to make a call
To enable demonstration and testing of the implemented functionality I've created a simple app which demonstrates all the implemented features.
Other points of note in the code:
- While it's possible to load a file included in the project (in the webbrowsercontrol) any files loaded this way can't reference other files (JS, CSS, image or ohter HTML files) A partial work around is to try and merge all content into a single file but this can't deal with images. The browser doesn't currenlty support the data protocol but will in the next version (according to an email I've had from the team) so we would have to live without images if we went that route. The alternative is to load all content into Isolated Storage and view it from there. This is what I've done. Also rather than specify all the files to load manually (I couldn't find a way to query these from the XAP) I'm using a T4 template to generate the list of files to load.
- I'm using a command pattern to handle the different feature implementations. I'm using an abstract base class (PhoneGapCommand) for the commands and two optional interfaces to manage the variations in types of command (IAsyncCommand & IWatcherCommand). This works pretty well but feels like it could be better. I'm keen to discuss/explore alternatives to this.
- I've implemented a custom back stack to support navigation between pages. This recreates the behaviour you'd see elsewhere if navigating between XAML pages or html pages in IE.
- Because of the time it can take to load all the files to Isolated Storage and to prevent the webbrowser control being shown before the content has all loaded correctly I've had to implement my own version of the splash screen image. To use this the image must be set to a resource. In my code I have renamed the sample image to make this more obvious.
Ideally I'd like to contribute this code to the core project but I guess that will depend on what else others have done in terms of WP7 support.
Please feel free to leave any feedback in the comments below, or in the discussion I'm about to start in the Google Group.