Saturday, May 31, 2014

Convert a Windows Store App to the Web in Under 10 Minutes

Microsoft held an event called re//build in Atlanta and I had the opportunity to speak about what’s new with WinJS. The event used a lightning talk format so with only 30 minutes to present, I decided to make the presentation itself the demo. I wrote the re//build WinJS Windows Store app by starting with the JavaScript Grid template and customizing it to generate slides. I also included the open source animate.css library to show transitions. I purposefully went overboard on animations to show how rich the app experience can be despite using HTML.

If you run the app (don’t worry, I’ll give you a link in a minute if you don’t want to build and run it on Windows 8) you’ll see some of the more interesting announcements included future convergence of libraries (right now there are separate libraries for the phone and PC platform) and fresh support for the Xbox. Although those are both cool, what intrigued me the most was the fact that they made the WinJS library open source. What does that mean really? I originally viewed WinJS as a shim between HTML5 and the Windows Runtime, so I couldn’t imagine a scenario where it made sense on the web. Was this just a set of glorified controls? If you experiment online it looks like it might be.

Of course the first question I received during my talk was, “Do you have other versions of the app, for the web or Xbox?” No, I did not. But I was certainly determined to try. I figured it would be an interesting exercise to convert the app over to a pure web app, but assumed I’d end up stuck with a static page and wouldn’t be able to use the navigation or fancy features like Semantic Zoom.

Oh, was I wrong!

The first thing I did was copy the contents of my Windows Store app to a new folder. I deleted things like project files, security certificates and manifest files that didn’t make sense for a web app. Next, I pulled down and built the open source WinJS library. I grabbed the stylesheets and JavaScript for version 2.1 and dropped those into the folder. I updated the references in the source from this:

<!-- WinJS references -->
<link href="//Microsoft.WinJS.2.0/css/ui-light.css" rel="stylesheet" />
<script src="//Microsoft.WinJS.2.0/js/base.js"></script>
<script src="//Microsoft.WinJS.2.0/js/ui.js"></script>

To this:

<!-- WinJS references -->
<link href="/winjs/css/ui-light.css" rel="stylesheet" />
<script src="/winjs/js/base.js"></script>
<script src="/winjs/js/ui.js"></script>

I tried running the app, and it immediately aborted due to a missing reference to “Windows.” I popped open the default.js and immediately saw this:

var activation = Windows.ApplicationModel.Activation;

I know that is a projection to a Windows Runtime component, so I just hacked it. In fact, I simply removed the various references to Windows Runtime components but left the rest. What I ended up with was this:

var app = WinJS.Application;
var nav = WinJS.Navigation;
var ui = WinJS.UI;
 
app.onready = function () {
nav.history = app.sessionState.history || {};
     nav.history.current.initialPlaceholder = true;         
ui.disableAnimations();
     var p = ui.processAll().then(function () {
         document.body.onkeyup = function (e) {
             WinJS.Application.queueEvent({ type: 'keyUpTriggered', keyCode: e.keyCode,
handled: false });
         };
    return nav.navigate(nav.location || Application.navigator.home, nav.state);
     }).then(function () {
         ui.enableAnimations();
     });
}; app.start();

Thinking, “OK, how much more of this will I need to do?” I opened it up and was blown away. It’s easier to just let you see it for yourself. I suggest Internet Explorer but it will work in other browsers. This is the online version of the Windows Store App! It is fully functional, try pinching on the main page to see semantic zoom take effect. When you are in slides, use the right arrow key to bring in effects like the book on the main slide or bullets, otherwise use SPACE to advance to the next slide or BACKSPACE to go to the previous one (left arrow also works, and up arrow will take you back to the main page that previews all slides). You can also browse the source code for the converted app.

There are still a few rough edges. The size of the WinJS library (including JavaScript and CSS) is enormous (several megabytes) and the experience isn’t consistent in Chrome and FireFox. However, I still think it’s pretty amazing to see the full navigation framework and advanced controls like grid layouts and semantic zoom render faithfully in the browser, and there really wasn’t much I had to do to my app at all to make the transition. Granted, apps that rely heavily on WinRT components won’t convert as easy, but this opens up enormous possibilities for sharing code across platforms.

Because seeing is believing, I recorded a short video showing the entire conversion process. Enjoy!

2 comments:

  1. Awesome video Jeremy!

    Josh Williams here (dev lead for WinJS at Microsoft) - we're working hard on bridging the gaps for WinJS every day, in fact as of a few weeks ago even the grid app would not have worked well because the grouped-grid layout in the ListView required CSS Grid, we have since changed it to use flexbox.

    The reason semantic zoom wasn't working with touch in FF is that they have currently disabled touch events in anticipation of some changes (https://bugzilla.mozilla.org/show_bug.cgi?id=888304), our assumption is that when they come back online things should work well. There should be a button you can click (looks like a little '-') in the bottom right hand corner of the app which should zoom out and then you can click a group to zoom back in using the mouse.

    ReplyDelete
  2. Nice video! the Scheduler part in default.js could've been kept in default.js since WinJS has fallback logic so that it works when it is running in a browser.

    ReplyDelete