This page is the collection point for errata in my book, Programming Windows Store Apps with HTML, CSS, and JavaScript, Second Edition. If you find an error, please check the know error list below. If you've found a new error, please leave a comment with the details and I'll migrate into the body of this post. Thank you!

Page numbers given here refer to the PDF, but I also try to give the name of the nearest section header or sidebar title.

Multiple Chapters:

  • The website http://dev.windows.com has been revamped to include Windows Phone, Desktop, Hardware, and IE, so a "Dashboard" link no longer appears at this URI. To get to the right page, use the drop down along the top of the page to select "Windows Store Apps". This takes you to http://msdn.microsoft.com/en-US/windows/apps/ where "Dashboard" is visible.

 

Chapter 1:

  • Page 41: As of Windows 8.1 Update 1 (released shortly after the book was complete), local loopback and "brokered WinRT components" allow for inter-process communication between side-loaded apps and desktop processes. These capabilities are specifically designed for side-loaded apps in enterprise scenarios, and are not supported for apps installed via the Store. For more information, see Brokered WinRT component project templates now available (Building Apps for Windows Blog) for all the details.
     

Chapter 8:

  • Page 432: In the footnote I mention that WinJS.UI.ViewBox was removed for WinJS 2.0. Apparently it made it back in late in the game, so you can use it directly instead of writing your own code as shown in the book.
  • Page 453. I mention that the WinJS.UI.Hub control is only present in WinJS 2.0 for Windows 8.1. On Windows Phone 8.1 and WinJS 2.1 you have the WinJS.UI.Pivot control instead. The two are supposed to have virtually identical interfaces, so you should be able to replace WinJS.UI.Hub with WinJS.UI.Pivot and WinJS.UI.HubSection with WinJS.UI.PivotItem section in your HTML and be in business. I have not tested all this, however.

 

Chapter 11:

  • Page 612, last "Hint" under the section, "KnownFolders and the StorageLibrary Object" (or just above "Removable Storage")–the Library management sample now shows the proper use of removeEventListener for definitionChanged. (Got that bug fixed!)

 

Chapter 13:

  • Page 707: numbering in the list should start at 1.

 

Appendix D:

  • Page 1303: The AppointmentProviders example in the companion content has a bug on line 60 of html/manageAppointment.html, where the method call should be reportCompleted (it's missing the "d" at the end) and will throw an exception as it currently exists.

In the Here My Am! app of my book, one problem I didn’t get around to solving was scaling of captured images to fit the display area. Typically this isn’t a problem when you capture an image large enough for that area, but when you have a low-res camera (or a high-res camera set to a low res output), or when you change view states, the image can become distorted.

As I’m working through the book now for a  second edition, I fixed this particular problem in Chapter 2’s version of the app, and fortunately the solution turns out to be pretty simple. The trick is to first wrap the img element in a div where that div contains a 1×1 CSS grid. The img element, as a child, is then centered within that cell. So in default.html I replaced the <img> element line with these:

<divid=”photo”class=”graphic”>
<imgid=”photoImg”src=”#”alt=”Tap to capture image from camera”role=”img”/>
</div>

And added these bits to default.css:

#photo {
    display: -ms-grid;
    -ms-grid-columns: 1fr;
    -ms-grid-rows: 1fr;
}

#photoImg {
    -ms-grid-column-align: center;
    -ms-grid-row-align: center;
}

Within photoImg, then, we can style that element to be 100% width or 100% height depending on whether the picture’s aspect ration is greater than or smaller than the parent div, photo. The original image size can be easily obtained from StorageFile.properties.getImagePropertiesAsync. So in this added function, imgElement is photoImg, parentDiv is photo, and file is the captured StorageFile object:

function scaleImageToFit(imgElement, parentDiv, file) {
    file.properties.getImagePropertiesAsync().done(function (props) {
        var scaleToWidth = (props.width / props.height > parentDiv.clientWidth / parentDiv.clientHeight);
        imgElement.style.width = scaleToWidth ? “100%” : “”;
        imgElement.style.height = scaleToWidth ? “” : “100%”;
}, function (e) {
        console.log(“getImageProperties error: “ + e.message);
    });
}

I then call this function from within the completed handler of captureUI.captureFileAsync, after setting the img.src URI. I also have a window.onresize handler to call this again with the most recently captured file, which handles scaling the image again for new view states.

With this approach, specifically centering the image in the parent div’s one grid cell, we get automatic letterboxing around the image.

I believe it would also be possible to solve this with a WinJS FlexBox control, which effectively does the same thing. I don’t think it would mean any less code, however. The solution here, of course, depends on the WinRT APIs and having a StorageFile object. For use with pure HTML/CSS, you can create a new Image and assign its src, and once loaded that object’s width and height properties will be available. When you have those values, you can then use the same calculation as above to scale the image without changing the aspect ratio.

 

 


I received this reader comment for a note on page 210 of my book:

On page 210 you mention, “…I’m building most of the element by using the root div.innerHTML property instead of calling create element and appendChild and setting individual properties explicitly. Except for very simply structures, setting innerHTML on the root element is more efficient because we minimize the number of DOM API calls.” This sounded a little strange to me so I ran some tests in IE10 desktop mode since Win8 Apps run on IE and I found the opposite seemed to be true. Performing an equivalent operation using innerHTML and the createElement/appendChild, I found on my own computer that for IE10 innerHTML took almost 60 times as long. Am I missing something?

The reader also shared the test code, which looped through some test functions using both the DOM API and innerHTML assignments, which indeed showed a clear advantage of teh DOM API over innerHTML. What made the difference, however, was that the tests were making additions to innerHTML using += rather than straight assignments using =.

Here’s what I wrote for the response (edited a little)

This note about optimization is aimed specifically at rendering an item in a ListView, where the rendering function as a whole might be called thousands of times over, each time building up a specificc DOM structure for that item. As such, we want to minimize the execution time of that particular function.

In your test, the timing differences you’re seeing are entirely due to the fact that you’re using element.innerHTML += rather than just element.innerHTML =. The effect of this is that there is that the whole of innerHTML is reparsed each time through your loop, because the code keeps adding to the overall string. This is entirely the reason for the apparently slow performance. If, on the other hand, you simply do an assignment (=) with a string that contains around three to four elements, you’ll find that innerHTML performs faster than the equivalent series of createElement/appendChild calls.

The simple reason for this is that in that one assignment to innerHTML you’re having a piece of highly-optimized C++ code parse the string and effectively make the same createElement/appendChild calls internally as you’d make from JavaScript. For just a few elements, the difference is hardly noticeable. However, once you get above about 4 element—as our performance testing has shown—those extra round trips between the JS engine and the DOM API start to add up and become significant. For instance, if you’re building up a ListView item with, say, 20 items, we’ve definitely seen that building up a string and making a single assignment to innerHTML performs much better than lots of distinct calls from JavaScript.

Be clear, again, that you want to make a single assignment to innerHTML rather than doing a bunch of += assignments, as the latter will, as you’ve found, perform slower. I’ll make sure to clarify this in the next rev of the book and on my blog (as I’m doing here).

Again, the optimization here is primarily aimed at ListView item rendering. For building up DOM dynamically (e.g. trying to render a complex page), then using the DOM API is better than repeatedly making innerHTML += calls.


Thanks to M. Dirksma on the Building Windows Store Apps with HTML5/JS Forum for this one. It applies to the first edition of Programming Windows 8 Apps in HTML, CSS, and JavaScript.

When running versions of Here My Am! that use an iframe element to host the Bing Maps web control (Chapters 2-7; in Chapter 8 this is replaced with the Bing Maps SDK control), there is a possibility that the iframe isn’t instantiated before the app attempts to set the geolocation. This can throw an exception.

The solution to this–a good practice for any situation where you might depend on iframe content being loaded, is to place that dependent code inside a handler for the iframe’s load event. M. Dirksma’s solution is as follows:

document.getElementById("map").addEventListener("load", function () {
    var gl = new Windows.Devices.Geolocation.Geolocator();
    gl.getGeopositionAsync().done(function (position) {
        lastPosition = { latitude: position.coordinate.latitude,
            longitude: position.coordinate.longitude };
        callFrameScript(document.frames["map"], "pinLocation",
            [position.coordinate.latitude, position.coordinate.longitude]);
    }, function (error) { console.log("Unable to get location."); })
    ;
}, false);

This should prevent the error and avoid any odd timing issues.


A couple of links in my first edition book (out of 1400+) managed to get past my process for checking and validating them. Pages numbers are in the PDF:

For checking links, I found a very helpful add-in for Microsoft Word (2010…now waiting for one that works with Office 2013!) from ablebits.com. See http://www.ablebits.com/word-links-manager/index.php for details. The product as a 15-day free trial, and a license costs $9.95. This was well worth it for how much time it saved me in the last weeks of production!