So, Microsoft created what really turned out to be an amazing set of HTML/JS/CSS controls when they released the WinJS library. Not to go too much into the history, but honestly I hated it when I first had to use it. But, let me clarify. It wasn't until this last year when I learned that I didn't hate the WinJS controls by themselves, but I despised the way you declared their usage using the specialized win-* html attributes. It felt like a total hack to get an app up and running by littering semantic html with these attributes.

Then along comes a little toy project they created called react-winjs and all of a sudden the WinJS "Components" made total sense. When looking at them through the lense of WinJS through ReactJS components was the first time that I not only clicked with WinJS, but I actually fell in lov... (well I won't go that far), but was excited enough about them to pick them as the primary U.I. control suite while building out a little side-project.

Fast forward a year of development, and Microsoft essentially bailed on WinJS but at least they left it out in the open so I could hack on it and continue to depend on my own fork for the time being.

Then, they announce a NEW & SHINY library that can be used to help develop UWP and TV/Xbox One apps which is great. Except, WinJS doesn't work with this new library out-of-the-box, and since Microsoft isn't adding new features to WinJS, they likely never will build-in compatibility with the new & shiny library.

Guess that means we (I) have to figure it out on my own. And although I write this knowing that I'm probably the ONLY developer on the planet using this combination of libraries, I wanted to put out some of the hacks/code I've thrown together to get some WinJS controls to play nice with TVJS with regards to focus management.

What is focus management you say?

In the context of an Xbox app, the idea is to take your'e web-page-app and get rid of the ugly mouse-like-cursor you'd see if you didn't do this and replace it with a controller navigable approach - so up/down/left/right on the controller moves the visible "focus" around the application and the A button "presses enter" (or invokes) the control/button/etc.

What IS provided by TVJS

The TVJS library has a helper within it called DirectionalNavigation and is great in that it provides a focused and specific API to enable focus management while developing a Xbox App UWP Javascript (& C#) apps.

Just dropping the library in is enough to get much of the basics to work with most web apps.

However, the conflict between this and WinJS comes into play because WinJS also tried to implement some of their own focus management and the mix of these two just doesn't quite cut it.

Get rid of mouse cursor

Well, this isn't really a hack:

If you're looking at building a UWP JavaScript app for the Xbox, and tried to run your app on the Xbox (in dev mode), you may have noticed that your app behaves almost like it was just another web-page and doesn't default the cursor focus the way other xbox apps work. You're app just has a mouse-like cursor.

The way to deal with this is just by accessing the browser's gamepad api. Now, the Microsoft TVJS TVHelpers DirectionalNavigation library automatically does this for you, but for a better experience if you don't want to wait for the browser to download this library, you can manually access the api to hide the mouse cursor by throwing this at the top of your start page EX: index.html

By not allowing WinJS to add it's XYFocus handlers, we can avoid many of the issues that I worked through below...

Dealing with a WinJS Pivot control

For my app, the first control I ran into trouble with was the WinJS Pivot control. This control already does some focus management all by itself, and it's own management style contradicts the way the DirectionalNavigation helper works. So we basically have to detect focus on it, turn of TVJS focus management and handle it internally (until we leave focus of the Pivot).

Now when I navigate around using an Xbox controller I can properly navigate around the WinJS Pivot.

Next up are ItemContainers.

UPDATE:

With the added (remove XYFocus above - I removed the below hack)

This one is a total hack, and I look forward to a better solution, but for now it's been working.

The issue I was seeing was with WinJS ItemContainers and the TVJS library applying a separate forced "click" on the element when the control itself has already "clicked/invoked" the element.

The real fix would likely to figure out how to get the ItemContainer to event.preventDefault() and/or event.stopPropagation() and avoid the bubbling up to the documentkeyup event handler that DirectionalNavigation has under it's control, but WinJS ItemControl management is just so complicated that this hack was easier to figure out at the time I threw it together.

So what does this do?

It's basically hijacking the DirectionalNavigation._handleKeyUpEvent function, and re-writing it with one that ignores the keyup event if the currently focused element is an ItemContainer.

ItemContainers within a ContentDialog

UPDATE

That's just a big mess from what I could figure out. I was able to get it working by using the ContentDialog but manually creat my own buttons as the ItemContainer in combination with the dialog kept swallowing events that didn't allow focus navigation to be sucessful. The internals of what was holding me back didn't appear to be monkey-patch-able from what I could tell... ugh...

One big improvement could be to consider setting up a unit-test that could take the original "string" value of the entire function code, and comparing it to the current version of WinJS library you're using and fail if they're even one character different. This would allow you to detect if say a fix were applied, or you need to update our local hacked version with some remote changes... It's not pretty, but one way to avoid over-writing possible working WinJS code with our potentially not-so-future-proof hacked version.

Next one is the WinJS [ToggleSwitch].

This control just seemed to have all behavior wrong for me. So I hacked the keyDownHandler and simplified it's implementation which seems to have really made it more usable (for me).

The original had up/down/left/right configured to toggle the switch on/off which meant focus in/out was nearly impossible, it also only listened to space as a toggle option. So by removing the up/down/left/right we can navigate in/around the control and we wanted to listen to space, GamepadA, and enter to toggle the control on/off.

What else?

The WinJS control set is quite large, and I certainly haven't worked with each control in this manor, however, it's a step forward eh and if you managed to come across this random post on the interweb I hope it was useful?

I've been playing with WinJS a bit lately, specifically the React-WinJS and wanted the native WinJS Navigation to play a little nicer with a web browser. The original/default environment for WinJS app is within a WinRT/Metro application where there is no "url/address" bar to be seen.

My uneducated guess is that the WinJS team decided not to worry about how WinJS.Navigation would integrate with a normal browser's history as there doesn't appear to be native integration or documentation about how to do it so far.

I asked the team if they had plans to work on any integration options, but only asked that last night so don't expect to hear back from over the weekend.

So I spent a moment and prototyped one possible solution which works for this simple test using the browser's history api since I'm not looking to support browsers older than IE 10.

Ideally we could leverage WinJS controls without worrying about how to "integrate" the WinJS.Navigation with anything, but sadly some of the WinJS controls take a dependency on WinJS.Navigation (like the BackButton) so finding a way to play nice with this can be challenging.

The map section in the System.config defines a pointer to a fork of react-winjs I have that supports React 0.14 (so if you find this in the future and need it, try to use the native react-winjs if they've merged in my pull request instead.)

As a simple demonstration on in-app unit tests I've thrown together a little plunk that shows in-app tests within the a WinJSPivot. And add to the layers of abstraction I'm using react-winjs which I'm LOVING over normal WinJS development.

If you like this starter, I have it and a few more linked here: for re-use

I'd like to highlight this particular starter at bit more in this post, not only because there are a few more concepts to this basic plunk, but also because I'm fairly happy with the MochaJS React component that I've now copied around and re-used a few times in some small projects where use In App Unit Tests.

Plunker file overview

index.html - The index file is a very basic JSPM bootstrap page that loads the app.jsx react component.

app.jsx - Defines a WinJS Pivot control where we render the in-app MochaTests.jsx React component. This also defines the test file(s) and using MochaJS's global detection we can tell the react MochaTests component what test files to load and run as well as what globals are allowed to exist.

config.js - This is JSPM's config that defines what version of React we're using and to use babel for transpilation.

tests.js - is our Mocha set of unit tests. We can have multiple test files if we want, just have to define what files to load in app.jsx.

Lastly the MochaTests.jsx which I'll include the full component below:

I'm not expecting to see a large up-tick in WinJS apps out there with in-app unit tests that run in the browser, however hopefully the MochaTests.jsx React Component is of value to you and can be utilized outside of WinJS within almost any React app.

Please drop a line if you end up using it or if it can be adapted. If there's value in the component, maybe

Known Issue

If the number of tests starts to go beyond the height of the pivot in this sample, it has an issue where the WinJS Pivot cuts off at the bottom not allowing you to scroll and see the rest of the test output. I haven't dug into it yet because I've been clicking the failures: X link and it filters the U.I. to just the erroring tests.

If you happen to come up with a good solution, drop me a note - I'd love it. Thanks in advance!

I described a while back a scenario about running in-app unit tests. So if you'd like some background on the subject have a look there before reading here.

This post is going to give some specifics about how to run MochaJS tests within a Microsoft Windows JavaScript application (WinJS).

Prerequisites

These steps assume you already have a WinJS application, possibly using the universal template or other. In the end it doesn't matter. As long as you have a project that probably has a default.html file and the ability to add js & css files to.

Get Mocha

You can acquire the mocha library however you want, Bower, Npm, or download it manually from the site (mochajs.org).

Reference Mocha Within Project & App

However you get the mocha source, you need to both add references to the mocha js and css files into your project file either in a *.jsproj file or if using a universal shared app, in the shared project.

Then you need to include a reference to the code in your default.html file.

In my example below you can see I used bower to download the MochaJS library.

The mocha.setup('bdd') tells mocha to use the BDD style of tests which defines the describe(...), it(...), etc functions.

Create a WinJS Control for hosting Mocha reporting.

Below is a sample WinJS control that can be used to host the mocha html report.

<!DOCTYPE html><html><head><style>#mocha{
height:800px;
width:600px;
overflow: scroll;
}</style></head><body><divclass="fragment section1page"><sectionaria-label="Main content"role="main"><!-- define a button that we can use to manually run or re-run tests --><buttonid="mochaTestsRun">Run Tests</button><!-- define a checkbox that allow us to toggle auto-run
of the tests when we start up the app -->
Auto start <inputtype="checkbox"id="mochaTestsRunOnStart" /><!-- this is a blank div we use to inject U.I. related tests --><divid="testElementContainer"></div><!-- mocha throws the html output in the below div --><divid="mocha"></div></section></div></body></html>

(function () {
"use strict";
var runMochaTests = function() {
// clear any current test results since mocha just appends.
element.querySelector('#mocha').innerHTML = "";
// If you want your tests to verify nothing is leaked globally...
mocha.checkLeaks();
// specify any globals that you are OK with your tests leaking
mocha.globals([
'someGlobalIAmExpecting'
]);
// start the test run
mocha.run();
}
var ControlConstructor = WinJS.UI.Pages.define("/js/tests/tests.html", {
// This function is called after the page control contents// have been loaded, controls have been activated, and// the resulting elements have been parented to the DOM.
ready: function (element, options) {
options = options || {};
// get our possibly already cached value of whether to run the tests on startup.var runOnStart = (JSON.parse(localStorage.getItem("mochaTestsRunOnStart") || "true"));
// checkbox to manage auto-run statevar runOnStartCheckbox = element.querySelector('#mochaTestsRunOnStart');
runOnStartCheckbox.addEventListener('change', function () {
localStorage.setItem("mochaTestsRunOnStart", runOnStartCheckbox.checked);
});
// button to manually trigger a test runvar mochaTestsRunButton = element.querySelector('#mochaTestsRun');
mochaTestsRunButton.addEventListener('click', function(){
runMochaTests();
})
runOnStartCheckbox.checked = runOnStart;
if (runOnStart && !window.hasRunMochaTestsAtLeastOnce) {
// this value is used to avoid extra test runs as we navigation around the app.// EX: if the test control is on a home pivot - we nav away and come back home// we probably don't want to auto-run the tests again. (use the menu button// instead if you want another test run)window.hasRunMochaTestsAtLeastOnce = true;
runMochaTests();
}
},
});
// The following lines expose this control constructor as a global.// This lets you use the control as a declarative control inside the// data-win-control attribute.
WinJS.Namespace.define("MyApp.Testing.Controls", {
TestsControl: ControlConstructor
});
})();

Handle global exceptions

If you write any async code (difficult not to these days) an exception or assertion failure will not be trapped by the internal try/catch mechanism's of Mocha in a Windows WinJS environment.

We have to give Mocha a hint on how to hook into global exceptions.

Mocha tries to attach to the browser's global window.onerror method, and since a WinJS app doesn't use this same handler, we have to forward the exceptions and to mocha's attached window.onerror handler.

In your default.js or wherever you configure the app you can attach to the WinJS.Application.onerror and after some exception massaging we can hand the exceptions to mocha so when a test fails it can be reported correctly.

If you’re unfamiliar with TypeScript, I’d highly recommend checking it out. It’s my new preferred way to write JavaScript based applications.

If you write an application in TypeScript and need to interact with an external set of either JavaScript or C++/CX dependencies then you will quickly find that you are going to be mucking with some TypeScript Definition files and the more you take a dependency on the WinRT runtime the more type definitions you probably need to manually create.

It’s true that the TypeScript team has created a set of TypeScript Definition files for WinRT and WinJS, but I couldn’t get any comment as to how they were generated. And the more I looked into what was provided, the more I realized that there were inconsistencies and inaccuracies that were not good. Which led me to believe that they weren’t working on a super-secret tool to automatically generate these for us.

ToTypeScriptD is a quick little attempt at automatically taking the type system provided to us by a C++/CX winmd or .Net assembly file and projecting that into a set of TypeScript Definition files. This tool can basically take anything that is Ecma 355 Common Language Infrastructure (CLI) and spit out a .d.ts file for you automatically.

Why would I need this?

In the project readme I describe two use-cases that I know of (so far).

If you build a 'Modern' (come on, we still call it Metro) Windows 8 app with WinJS and want to leverage TypeScript, wouldn't it be nice to get a set of TypeScript Definition files that reflect the native API's you're calling in the platform without manually creating the definition files?

Say your building an MVC/WebAPI server application. It would be useful if your C.I./Build system could generate a set of TypeScript interfaces that were based on the server objects used to render your JSON API. This can be useful for client side JavaScript/TypeScript libraries that need to consume these objects and also provide a simple way to document the format of the input and output API response objects.

How do I get the project and start using it?

Before you install the tool and dive in head first, I would like warn you that I have only been working on this for about 2 weeks (in my off-hours) and there is going to be lots of room for improvement. But it’s currently generating a solid set of .d.ts files for .winmd files.