Windows 8 – Using jQuery for app development

Windows 8 – Using jQuery for app development

The incredibly practical Javascript-library jQuery is the favored tool for lots of web developers. Since Windows 8 supports app development using the standard webtechniques, jQuery immediatly suggests itself. But because Microsoft has integrated a new security model in Windows 8, jQuery has to be modified slightly in order to be usable for app development.

The background

Microsofts security model comes into play when one of the standard Javascript functions innerHTML, outerHTML or document.write are used. Try the following code

1
2
3
4
<div id=„test“></div>
<script>
document.querySelector(„#test“).innerHTML = „<a onclick=’document.body.style.backgroundColor=\“#F00\“‚>Something evil</a>“;
</script>

You will see a Javascript runtime error that terminates the app, because dynamic content is injected via Javascript.

The solution

Microsoft provides the method execUnsafeLocalFunction with which you can explicitly disable the security model and tell Windows “I know what I’m doing”. Of course, this should only be done when you control the executed code and are sure that no security problems could potentially happen. You have to wrap the code within the execUnsafeLocalFunction construct and let it execute for you. The following code works without problems:

1
2
3
4
5
<script>
MSApp.execUnsafeLocalFunction(function () {
document.querySelector(„#test“).innerHTML = „<a onclick=’document.body.style.backgroundColor=\“#F00\“‚>Something evil</a>“;
});
</script>

When pulling in potentially unsafe content from an external source, you might want to consider using the toStaticHTML method (further documentation here) or creating your nodes via DOM – but this is another topic, we don’t want to cover in this post.

The problem with jQuery

jQuery itself comes with lots of checks for the sake of browser compatibility. These checks contain code, that is considered to be potentially malicious and Visual Studio shows 3 warnings when using jQuery 1.8 (at the time of this post, version 1.8 is the latest).

Even if these are “only” warnings, we are going to get rid of them when using jQuery with Windows 8.

Making jQuery ready for Windows 8 – step by step

We will use the development version of jQuery 1.8 for this blogpost that can be found here.

Starting from the bottom of the file, the first necessary change is to wrap the contents of the assert block starting at line 5025 up to line 5040 within a execUnsafeLocalFunction block:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
assert(function( div ) {MSApp.execUnsafeLocalFunction(function () {
// Opera 10-12/IE9 – ^= $= *= and empty values
// Should not select anything
div.innerHTML = „<p test=“></p>“;
if (div.querySelectorAll(„[test^=“]“).length) {
rbuggyQSA.push(„[*^$]=“ + whitespace + „*(?:\“\“|“)“);
}// FF 3.5 – :enabled/:disabled and hidden elements (hidden elements are still enabled)
// IE8 throws error here (do not put tests after this one)
div.innerHTML = „<input type=’hidden’/>“;
if (!div.querySelectorAll(„:enabled“).length) {
rbuggyQSA.push(„:enabled“, „:disabled“);
}
});
});

The next target is the assertUsableName function – same principle as above. Change lines 3808 to 3826 to this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
assertUsableName = assert(function( div ) {return MSApp.execUnsafeLocalFunction(function () {
// Inject content
div.id = expando + 0;
div.innerHTML = „<a name='“ + expando + „‚></a><div name='“ + expando + „‚></div>“;
docElem.insertBefore(div, docElem.firstChild);// Test
var pass = document.getElementsByName &&
// buggy browsers will return fewer than the correct 2
document.getElementsByName(expando).length ===
// buggy browsers will return more than the correct 0
2 + document.getElementsByName(expando + 0).length;
assertGetIdNotName = !document.getElementById(expando);// Cleanup
docElem.removeChild(div);

return pass;
});
}),

The next and last necessary change is the jQuery.support function that starts at line 1239 and goes all the way down to line 1507. The stripped down function looks like this:

1
2
3
4
5
6
jQuery.support = (function() {//…return support;
})();

This self executing function has to be wrapped like this:

1
2
3
4
5
6
jQuery.support = MSApp.execUnsafeLocalFunction(function() {//…return support;
});

Be sure to remove the last paranthesis because execUnsafeLocalFunction already executes the function for you – no need for a self executing function any more.

Further optimization

When you know what you are doing and can be sure that all the executed code is controlled by you, it makes sense to apply one last change to the core of jQuery which is handling the html() method among some others like append. After having applied the modification, you will be able to execute code like this without an error:

1
$(„#test“).html(„<a onclick=’document.body.style.backgroundColor=\“#F00\“‚>Something evil</a>“);

Change line 6115 from

1
div.innerHTML = wrap[1] + elem + wrap[2];

to our new favourite contruct

1
2
3
MSApp.execUnsafeLocalFunction(function() {
div.innerHTML = wrap[1] + elem + wrap[2];
});

$(“windows8″).ready();

All the modifications have been included in this modified version of jquery-1.8.0. Download, include in your Windows 8 App and have fun! If a new jQuery version has come out in the meantime, you know where to apply your changes. Watch out for innerHTML and maybe some time, the jQuery team will release a Windows 8 ready version. Let’s hope together!

Update 2012-10-02: Eric pointed out an encoding issue with the original file causing applications with the modified, old jQuery version contained to fail the WACK test. This has now been fixed, the links are updated accordingly. Thanks Eric!

Weiterempfehlen

 

Über den Autor

David Müller

David ist CTO bei Incloud. Er fungiert als technischer Direktor, trifft Technologieentscheidungen und ist für die Entwicklungsprozesse verantwortlich. Im Blog schreibt er über Technologien, Trends und Entwicklungsprozesse.

Darf ich Ihnen helfen?

Lassen Sie uns kurz und unverbindlich über Ihr Projekt sprechen:

06151 4936456

Gerade keine Zeit?

Wir melden uns gerne später bei Ihnen: