In contrast to other posts in this series of HTML5/WinRT comparisons, this one on web sockets is relatively short. I haven’t worked too much with either set of APIs, so only have a few details to write up.

Standard WebSockets, as they’re defined in the W3C/HTML5 API, are entirely supported for Windows Store apps. However, they support only a transaction-based UDP model like DatagramSocket and only text content. The MessageWebSocket in WinRT supports both text and binary, plus you can use the StreamWebSocket for a streaming TCP model as well. The WinRT APIs also emit more detailed error information.

For all these reasons, we generally recommend using the WinRT APIs for web sockets over the HTML5 APIs.

 


Processing XML data is a common activity for web applications and will likely be employed by many Windows Store apps. For apps written in HTML, CSS, and JavaScript, two APIs are available: the XML DOM API represented by the DOMParser object, and the WinRT API in the Windows.Data.Xml.Dom namespace. This post will make a brief comparison between the two.

Note: one key difference for any comparison with WinRT APIs is that HTML and native JavaScript APIs are available in the web context whereas WinRT is not. This comparison therefore only applies to pages running in the local context. In the web context you must use the HTML5/JS APIs.

It’s also helpful to note that overlaps such as these exist (a) because of the local and web contexts, and (b) to provide the capability to Windows Store apps written in other languages where an intrinsic API is not available.

 

XML DOM API

The XML DOM API is already familiar to JavaScript developers, because the HTML DOM API is really just a specific flavor of the XML API. Functions like getElementById, for example, which every JavaScript developer can probably type in their sleep, is shared between both. The XML DOM API is compliant with the HTML5 Web DOM Core spec.

This API is the most extensive where manipulating XML is concerned. Converting XML text to an XML document is done with a simple call to DOMParser.parse; the API is then available on that document object.

As far as drawbacks are concerned, this API is synchronous and entirely based on having the XML as a string. No provision is made for loading the XML from another source. It also does not support XSLT or XPath.

For details on the implementation of DOMParser for Windows Store apps, the documentation is here.

 

WinRT API: Windows.Data.Xml.Dom

Generally speaking, the API available for an XML document in WinRT, Windows.Data.Xml.Dom, is very similar to the XML DOM API. It is compliant with the W3C DOM Core specification.

In its design, many method names match the DOM versions, such as getElementById. That said, the WinRT API isn’t quite as extensive as the DOM API. Compare, for example, the XML DOM’s API on an element to IXmlElement. Similarly, IXmlText in WinRT has a single method, SplitText, while the XML DOM Text object has quite a few more.

The WinRT API provides other functionality, however. It provides XSLT and XPath support, and can, in addition to synchronous parsing of in-memory XML, asynchronously load XML from a file or remote URL. An XML document object obtained from WinRT can also be used with other WinRT APIs.

 

Recommendations

In the end, the specific differences between these APIs will determine what’s best for you:

  1. By default, use XML DOM API (DOMParser) in an app. It is the web-friendliest API, works in the web compartment, and covers the majority of web scenarios.
  2. Use XML WinRT API where XML DOM API is insufficient. It is necessary if you need to use XSLT or XPath, need to pass XML objects to WinRT APIs, require async loading of XML from a file or remote URL, or if compliance with the W3C DOM Core spec is required.

 


HTML5 includes facilities for client-side “web storage” from within JavaScript as a great improvement over cookies. For reference, see http://en.wikipedia.org/wiki/DOM_storage for an overview, http://www.w3.org/TR/webstorage/ for the spec. In Windows Store apps written in HTML/CSS/JavaScript, these features overlap with the application storage APIs in WinRT. In this article I’ll compare and contrast the two.

Note: one key difference for any comparison with WinRT APIs is that HTML and native JavaScript APIs are available in the web context whereas WinRT is not. This comparison therefore only applies to pages running in the local context. In the web context you must use the HTML5/JS APIs.

It’s also helpful to note that overlaps such as these exist (a) because of the local and web contexts, and (b) to provide the capability to Windows Store apps written in other languages where an intrinsic API is not available.

 

In Web Storage, there is local and session storage that differ in scope and lifetime. Local storage is per-domain and persists after the browser is closed. Session storage is per-page/per-window and is cleaned up when the window is closed. If you have multiple windows open with the same site, the benefit here is that session storage is kept separate.

The storage itself is an associative array of strings at present; there is a proposal spec for structured data.

Two such associative arrays are made available in JavaScript: localStorage and sessionStorage. You can create any property in them you want, and retrieve them as you want (checking for existence first, of course):

if (sessionStorage.insurance) { … }

if (!localStorage.pageLoadCount)
localStorage.pageLoadCount = 0;

localStorage.pageLoadCount += 1;
document.getElementById(‘count’).textContent = localStorage.pageLoadCount;

The WinRT APIs are available through the Windows.Storage.ApplicationData class, which gives you access to StorageFolder objects for Local, Temp, and Roaming areas of AppData along with localSettings and roamingSettings (containers for key-value pairs including sub-containers). The Application object in the Windows Library for JavaScript (WinJS) also contains a local, temp, and roaming objectsto simplify working with the ApplicationData APIs (it also has a sessionState object into which you can write values, but these are only restored if an app is restarted after being terminated by Windows when freeing up memory). For details, see Chapter 8 of my book (as well as sections of Chapter 3).

Comparing the APIs:

  • HTML5 sessionStorage (per window) in browsers is effectively the same as local variables in an app, because typically you use a single-page navigation model (with DOM replacement) to preserve the script context across pages. From an app’s point of view, then, In other words, sessionStorage is just a global array that had an automatic new done for it. That’s all.
  • WinRT local and HTML5 web local storage both use persistent storage that is available to the app across instances, that is, if the app runs and writes to local storage, is then closed by the user, then restarted, the local storage values are persistent.
  • HTML5 web storage has only a simple array model with strings. WinRT is much richer, with type-specific settings, hierarchical containers, composite settings (groups of settings that act as a single unit), and also supports unstructured (binary) data in arbitrary files. You’d have to encode binary data into text for web storage.
  • Web storage works on a synchronous model; WinRT is synchronous for settings, asynchronous for files.
  • WinRT and HTML5 storage are both kept in the user’s AppDatapackages<package> folder and is automatically cleaned up when the app is uninstalled.
  • WinRT supports automatic roaming through the RoamingSettings container and Roaming folder (up to 100K total data); HTML5 web storage is entirely local.
  • WinRT supports a temp folder that can be cleaned out with the Disk Cleanup tool. This makes a great place for caching data that can be restored at another time.

 

For small bits of data, an app might use HTML storage for the sake of simplicity if you’re familiar with the API. However, it means having a different (and UI-thread blocking) programming model from the roaming settings and a lack of unstructured data (file) capability. One also has to watch out for the fact that all the data are a strings and will be handled like strings. So for the code that does the launch count as above (which is pulled from the W3C spec), when you reload the pageLoadCount at a later time, the data type is actually a string, and adding 1 doesn’t increment the value, it appends “1” to the string. You have to do a parseInt on the value from localStorage to get a numerical value again.

The other comparison to make between these methods is to review the storage limits imposed by each mechanism, as summarized in the following table. For completeness, we’ve also included other storage HTML5 mechanisms like IndexedDB and AppCache as these also employ the app’s AppData area on the file system.

Storage Method Limit (up to file system capacity)
Web storage (local) 10MB
Web storage (session) 10MB
WinRT localSettings
(structured settings)
  • 8K per individual setting (1)
  • 64K per composite setting (1)
  • No limit on overall settings
WinRT localFolder
(unstructured files)
None
WinRT roamingSettings
(structured settings)
  • 8K per individual setting (1)
  • 64K per composite setting (1)
  • No limit on overall settings. Exception:   sync engine may limit total amount of roamingSettings and roamingFolder   data that will roam (2)
WinRT roamingFolder
(unstructured files)
No storage limit. However, the sync engine limits total the   amount of roamingSettings and roamingFolder data that will   actually roam. (2)
WinRT tempFolder
(unstructured files)
None (3)
Cookies 4K per cookie; no limit on total cookies
History None
Temporary Internet Files None (4)
IndexedDB 250MB per app, 12.5% of overall storage or 1TB, whichever is   less.
HTML5 Appcache None (4)

 

(1)    These are arbitrary limits and may change.

(2)    The default sync engine presently imposes a 100K limit (see the roamingStorageQuota property); if the combined contents of the roamingSettings and roamingFolder exceed that limit, the settings will still only be stored locally and no data is roamed. Again, this is a limit of the sync engine: the WinRT APIs themselves don’t impose limits. Different sync engines can behave differently.

(3)    Files created in the tempFolder are subject to deletion by Windows’ Disk Cleanup utility.

(4)    Current design with Windows Store apps does not impose a storage limit for AppCache (along with any other cached files from the web); IE will continue to enforce user- and system-defined limits.

 

In the end, if you’re writing new code, I recommend using the WinRT APIs to have a consistent async programming model across local, roaming, and temp data. If you have existing code that uses HTML5 web storage, it will continue to work subject to the limits outlined above.


A few week ago I answered a question on the MSDN forums that basically asked, “I ran code in a promise, so why didn’t it run asynchronously.” It was a good opportunity to clarify the nature of a promise and the relationship between promises and asynchronous code. So here I offer an edited version of my response.

The basic thing to understand is that a promise is just a way of saying “execute this code when the promised value becomes available (that is, when the promise of that value is fulfilled).” It says nothing about how the code is actually run in the CPU scheduler. So if you take a block of code and just wrap it with WinJS.Promise.as or such, e.g.:

return new WinJS.Promise(function (complete) {  /* some code */ });

you’re just saying that /* some code */ will execute when you call the promise’s then/done methods, but all that still happens on the UI thread.

True async behavior–that is, running code on another thread–happens through three means:

  1. A JavaScript worker (web worker), which you can wrap in a promise (new WinJS.Promise to handle the worker messages) in order to chain/join the async operation to others.
  2. An async method written in a C#/VB WinRT component where the code uses the Task class.
  3. An async method written in a C++ WinRT component where the code uses the concurrency library.

In the latter two cases, async methods (including those from the built-in WinRT APIs) happen to be projected into JavaScript as promises; in #1 you use new WinJS.Promise to do the same manually. But in every case, it’s not the promise that runs code on another thread–it’s purpose is just to manage completed/error/progress handlers. It’s the underlying worker or async method that runs code on another thread.

Creating async APIs in WinRT components as well as with web workers is something I cover in Chapter 16 of my book, in the section “Implementing Async Methods,” if you want all the details.

Here’s a link to the original forum discussion where I extract some of those details.


For some, the Windows Library for JavaScript, or WinJS, seems to take on an aura of mystique, as if it’s something really special or privileged, or something that is absolutely required by a Windows Store App.

The truth is that WinJS is actually just a JavaScript library, like other libraries you might employ. It does have one unique privilege in that it’s obtained automatically via the Windows Store when a dependent app is installed, and is also serviced through the Store.

But otherwise, it’s just a bunch of JavaScript code that makes writing a Windows Store app in JavaScript a whole lot easier, but isn’t absolutely required. For example, WinJS contains the HTML/CSS/JS implementation of those standard Windows 8 controls that aren’t already covered by HTML5. These include AppBar, DatePicker, FlipView, Flyout, ListView, Rating, SemanticZoom, TimePicker, ToggleSwitch, Tooltip, and ViewBox. You can roll your own versions of these if you want, but I’d think you’d want to spend time on those things that make your app really special.

Similarly, WinJS contains an animations library with the Windows 8 personality built right it…all this is implemented on CSS animations and transitions, so you can do it all manually, but what’s the point?

WinJS contains a bunch of utilities that simplify certain tasks in JavaScript–and many of these are pure JS and have nothing to do, really, with Windows itself. For example, WinJS.Namespace.define and WinJS.Class.define provide some built-in ways to deal with module and class patterns, which I find convenient. WinJS.Binding does the same for data binding, and WinJS.Navigation and WinJS.UI.Pages (along with WinJS.UI.Fragments) does the same for implementing a page navigation (that is, DOM-replacement) mechanism so you maintain the script context within an app.

Then there’s the WinJS.Application object that simplifies your interactions with the core Windows structures provided through WinRT–basically giving you an easier way to keep track of the details. All of this is stuff you can again write yourself, but the WinJS team decided that you’d probably like to have something written for you!

Consider something like promises as well. A promise is basically an object that has .then and .done methods on it. Even if you didn’t use WinJS, you’d get promise objects back from async WinRT APIs thanks to the JavaScript language projection. What the code in WinJS.Promises does, then, is give you a set of utilities for doing more with these basic promises, like joining them or creating new ones from scratch. Again, all stuff you might end up writing on your own, just like the wrapper for XmlHttpRequests in WinJS.xhr that makes that async JS API look like a promise such that it can be easily integrated in with other async code using WinRT.

The short of it is that WinJS is a library full of all kinds of stuff for which people inside Microsoft figured a standard implementation would be really, really helpful.

Now along these lines, questions about the nature of WinJS sometimes arise in the context of whether it’s possible to write a Windows Store app using HTML, CSS, and JavaScript and have that app run within other browsers or other frameworks that also use these standards.

You can certainly write code that can be used in both an app and a site, and they can use common services, but an app written in HTML, CSS, and JavaScript has specific structures that are distinctly different from the structure of a web site/web app.

In particular, an app ties into various platform features such as the WinRT API, many parts of WinJS, and the fact that it’s running inside the WWAHost process instead of a browser. Apps are also generally written in an AJAX style (a single HTML page wherein parts of the DOM are swapped in and out) rather than using <a> navigation (which is again why WinJS provides many utilities here).

So again if you modularize your app code to separate pure app logic that can run in a browser (and doesn’t have any Windows-specific dependencies) from that which is platform-specific, then you can achieve some amount of code-sharing. But those apps won’t just run in a browser. They aren’t web apps: they are Windows Store apps that just so happen to be written with the same technologies as web apps.

Is it possible to use WinJS code in a web app, then? Originally, WinJS wasn’t licensed for this purpose, but as of April 2014, WinJS is an open source project so that you can use it anywhere. See http://try.buildwinjs.com/. It’s important to note that WinJS will take advantage of WinRT APIs when they’re available, but it was written to adapt when WinRT isn’t there.

In short, WinJS is a very useful library with many different controls and other capabilities, and now that it’s open source it’s really helpful for creating a Windows-like experience in apps and on the web.


HTML5 contains a geolocation API to find the user’s location, something that used to be accomplished by analyzing IP addresses. As shown in the specification, http://www.w3.org/TR/geolocation-API/, the API itself is fairly simple. For Windows Store apps written in HTML/CSS/JavaScript, then, there is an overlap with the Windows.Devices.Geolocation API in WinRT. So which one should you use?

Note: one key difference for any comparison with WinRT APIs is that HTML5 and native JavaScript APIs are available in the web context whereas WinRT is not. This comparison therefore only applies to pages running in the local context; in the web context you’ll want to use the HTML5/JS APIs.

It’s also helpful to note that overlaps such as these exist (a) because of the local and web contexts, and (b) to provide the capability to Windows Store apps written in other languages where an intrinsic API is not available.

With that, let’s look at both APIs in turn.

Geolocation in HTML5

HTML5’s geolocation is available through the navigator.gelocation object in JavaScript. With this you can obtain a single reading, which is useful to present location-relevant content for a visitor, and also watch the position for ongoing readings.

A single reading is retrieved through the navigator.geolocation.getCurrentPosition method, to which you pass a function that receives a position object:

navigator.geolocation.getCurrentPosition(function(position) {
     var lat = position.coords.latitude;
     var long = position.coords.longitude;
     …
});

Additional parameters to getCurrentPosition include an error function and an object containing the options enableHighAccuracy (bool), maximumAge (maximum age of cached data in milliseconds), and timeout (in milliseconds).

Ongoing (asynchronous) readings are taken by passing a callback function to navigator.geolocation.watchPosition that takes the same parameters as getCurrentPosition. watchPosition returns an ID for the operation which can be passed to clearWatch to end the readings.

The timeout option value is important as it determines the maximum length of time that can elapse between a call to getCurrentPosition and watchPosition and a callback with a position value. If that timeout is exceeded, the error function is called with a TIMEOUT error. Other error conditions are PERMISSION_DENIED (see below) and POSITION_UNAVAILABLE (no geolocation capability is available, or there’s an error in determining the location). Note that a watch will remain in place when an error occurs.

The position object passed to the callback in both cases contains a timestamp member as well as a coords object. The latter contains latitude, longitude, altitude, accuracy, altitudeAccuracy, heading, and speed (all doubles). Complete details are, of course, in the specification.

Privacy is a concern with geolocation. The W3C specification places the responsibility for insuring privacy on the agent that implements the API. Internet Explorer, for instance, pops up an alert to the user asking their permission on behalf of sites that use the API. This can be seen with the IE9 TestDrive site’s Geolocation page, http://ie.microsoft.com/testdrive/HTML5/Geolocation/Default.html.

If the user disallows geolocation, the error function given to getCurrentPosition or watchPosition is called with a PERMISSION_DENIED error.

Note that when using HTML5 geolocation in a Windows Store app (including any web content in iframes and pages within navigation domains), it is necessary to declare the Location capability in the app manifest. Without this declaration, the APIs will fail with PERMISSION_DENIED errors.

Note also that if a Windows Store app navigates to any additional websites (e.g. uses navigation domains or includes content in iframes) that utilize geolocation, it must also include the domain in the ApplicationContentUris list.

Geolocation in WinRT

In WinRT, geolocation is provided through the Windows.Devices.Geolocation API. In WinRT you create (with new) a Windows.Devices.Geolocation.Geolocator object, which you then configure with various properties if desired: desiredAccuracy (default or high), movementThreshold (double), and reportInterval (double).

Obtaining a one-time position reading is done through the getGeopositionAsync method that produces a Windows.Devices.Geolocation.Geoposition object. Its properties are civicAddress and coordinate, where the properties of the latter are accuracy, altitude, altitudeAccuracy, heading, latitude, longitude, speed, and timestamp.
var gl = new Windows.Devices.Geolocation.Geolocator();
gl.getGeopositionAsync().then(function (posOp) {
     var position = posOp.getResults();
     var lat = position.coordinate.latitude;
     var long = position.coordinate.longitude;
     …
});

A variation of getPositionAsync lets you specify maximumAge and timeout parameters.

You can also assign functions to the positionChanged and statusChanged members of the Geolocator object for ongoing readings. positionChanged will be called within the reportInterval setting, and statusChanged is called when the device status changes between the following states:

  • ready: location data is available.
  • initializing: the location provider is initializing (e.g. a GPS receiver is still acquiring satellites).
  • noData: no location data is available from any location provider (like POSITION_UNAVAILABLE in HTML5).
  • disabled: the application doesn’t have permission to access location (like PERMISSION_DENIED in HTML5).
  • notInitialized: an operation to retrieve location has not yet been initialized (i.e. the app has not called getGeopositionAsync or registered for the positionChanged event).
  • notAvailable: the Windows Sensor and Location Platform is not available on this version of Windows.

Where privacy is concerned, this API will fail unless the app has declared the Location capability in its manifest. At runtime, Windows will also prompt the user for consent.

API Differences and Distinctions

As with other overlapping parts of WinRT and HTML5/JavaScript, the Geolocation APIs in WinRT are primarily there for apps written in C++ and .NET languages, where no other option is available. For written in HTML/CSS/JS, the two alternatives are more or less equal, with a few distinctions:

  • Geolocation options: The movementThreshold option is unique to WinRT, which is used for system power management and which allows an app to only receive readings there has been enough of a change. This is helpful for geo-fencing apps that only want to update themselves when the user has moved far enough away from a given point. To do the same with the HTML5 API requires more frequent location polling and calculating distance to filter out events.
  • Position information: When address information is supported by a location provider, WinRT provides for surfacing that data through the civicAddress property (and its individual sub-propeities).

Thus, developers with existing HTML5 geolocation code, or those who want to maintain as much platform-neutral code in their apps as possible, will likely use the HTML5 API. On the other hand, the convenience of movementThreshold and its positive effect on power management is a significant benefit of the WinRT API.


Thanks to my teammate Kyle Marsh for this one:

var freeSpaceProperty = "System.FreeSpace";
var applicationData = Windows.Storage.ApplicationData.current;
var localFolder = applicationData.localFolder;

localFolder.getBasicPropertiesAsync().then(function (basicProperties) {
    // Get extra properties
    return basicProperties.retrievePropertiesAsync([freeSpaceProperty]);
}).done(function (extraProperties) {
    var propValue = extraProperties[freeSpaceProperty];
    if (propValue !== null) {
        outputDiv.innerText = "Free Space: " + propValue;
}
}, function (error) {
    // Handle errors encountered while retrieving properties
});

Mozilla has introduced two simple methods to the DOM API for encrypting and decrypting base64 values. These are btoa, which converts binary (or string) data to a base64 ASCII-encoded string, and atob, which will do the opposite.  These APIs are being adopted by Internet Explorer 10 and are thus also available to Metro style apps written in JavaScript.

The basic functionality of these methods overlaps with the WinRT APIs found in the Windows.Security.Cryptography.CryptographicBuffer class, with the results being entirely interchangeable as you would expect. This means that base64-encrypted data created in one app using the DOM APIs can be passed to and successfully decrypted by an app using the WinRT APIs, and vice versa. This is shown in the code example below.

The difference between the two APIs thus rests in their structure and scope. As seen in the code example below, the btoa and atob methods are the simplest and most concise, but they work only with binary or basic string data, and cannot handle raw Unicode. As Mozilla’s btoa docs point out, Unicode strings will cause an exception in both methods and must be worked around with additional code. These methods are also focused solely on base64.

The WinRT APIs, on the other hand, are a little more complicated for basic usage but are much more flexible overall. For one, they handle Unicode strings just fine, with support for UTF-8, UTF-16LE, and UTF-16BE. Second, these APIs work with an intermediary buffer that can be created from a string, a byte array, or filled with random data. Finally, such buffers can then be encoded to base64 or hexadecimal, or copied to a separate byte array.

In short, the two can be used interchangeably for basic base64 operations, but developers might find it more consistent to use WinRT for other kinds of encoding.

Code example

This example simply shows the equivalence of the APIs and their cross compatibility. Create a new JavaScript project using the Blank template and drop in the code below. When you run the app and press the Run Test button, you’ll see the original string, the base64 encryption, and the decrypted values, using WinRT exclusively, using HTML APIs exclusively, then intermixing the two. As you’ll see, the results are entirely as expected.

HTML (body of default.html)

<body>
     <h1>Encryption Comparison</h1>
     <button<span >id="btnRun">Run Test</button>
     <p>Input Text: <spanid="txtInput">A text string for encyption</span></p>
     <p>Encrypted String (WinRT): <spanid="txtEncryptedWinRT"></span></p>
     <p>Decrypted String (WinRT): <spanid="txtDecryptedWinRT"></span></p>
     <p>Encrypted String (btoa): <spanid="txtEncryptedJS"></span></p>
     <p>Decrypted String (atob): <spanid="txtDecryptedJS"></span></p>
     <p>Decrypted String (WinRT using btoa output): <spanid="txtDecryptedCross1"></span></p>
     <p>Decrypted String (atob using WinRT output): <spanid="txtDecryptedCross2"></span></p>
</body>

 

JavaScript (entire contents of default.js)

(function () {
    "use strict";
    var app = WinJS.Application;
    app.onactivated = function (e) {
        if (e.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.launch) {
            WinJS.UI.processAll();
            var btn = btnRun;
            btnRun.addEventListener("click", runTest);
        }
    }


    function runTest() {
        var wsc = Windows.Security.Cryptography;
        var input = document.getElementById("txtInput").innerText;
        var buffer1a = wsc.CryptographicBuffer.convertStringToBinary(input,
        wsc.BinaryStringEncoding.utf8);
        var encrypt1 = wsc.CryptographicBuffer.encodeToBase64String(buffer1a);
        document.getElementById("txtEncryptedWinRT").innerText = encrypt1;
        var buffer1b = wsc.CryptographicBuffer.decodeFromBase64String(encrypt1);
        document.getElementById("txtDecryptedWinRT").innerText =
        wsc.CryptographicBuffer.convertBinaryToString(wsc.BinaryStringEncoding.utf8, buffer1b);
        var encrypt2 = btoa(input);
        document.getElementById("txtEncryptedJS").innerText = encrypt2.toString();
        document.getElementById("txtDecryptedJS").innerText = atob(encrypt2);
        document.getElementById("txtDecryptedCross1").innerText = wsc.CryptographicBuffer.convertBinaryToString(wsc.BinaryStringEncoding.utf8,
        wsc.CryptographicBuffer.decodeFromBase64String(encrypt2));
        document.getElementById("txtDecryptedCross2").innerText = atob(encrypt1);
    }


    app.start();
})();