Dans cet article, on va parler d’une subtilité assez surprenante mais légitime du comportement des composants WinJS. On l’a vu dans l’article précédent, les composants WinJS peuvent être créés directement en HTML:
Windows Metro – Les composants WinJS : DatePicker, TimePicker, Rating, Tooltip, ToggleSwitch
Et référencer directement des fonctions en réponse à des évènements comme ici la fonction « changeRating » en réaction à l’évènement de type onchange:
<div id="rating1" data-win-control="WinJS.UI.Rating" data-win-options="{averageRating: 3.4, userRating: 4, onchange: changeRating}"> </div>
Si vous importez ce bout de code tel quel dans votre application, votre composant ne va pas être créer, à cause de cette référence à changeRating directement dans le DOM HTML.
Les attributs « data-win-* » qui se trouvent dans votre markup vont être lus et interprétés par des méthodes du framework WinJS, WinJS.UI.processAll() dans le cas de data-win-control. Il existe 2 autres méthodes qui vont parcourir le DOM de manière transversalle que l’on verra dans d’autres articles: WinJS.Binding.processAll() et WinJS.Resources.processAll().
Ces différentes « pré-processeurs » vont interpréter le markup HTML et notamment créer des Binding (liaison dynamique) entre des variables ou bien assigner un handler d’évènement comme on l’a vu dans l’exemple plus haut.
Ce genre d’interprétation peut introduire des risques d’injection de contenu HTML qui pourraient venir compromettre votre code. En effet, si vous ajoutez dans votre DOM, un contenu HTML issu d’une saisie utilisateur, celui-ci pourrait intégrer du code et lier ce code directement avec le votre par binding par exemple.
Pour éviter ce genre d’attaque, Microsoft vous oblige à marquer les fonctions de votre code qui peuvent être appelées à partir du markup HTML. Pour que les fonctions soient marquées comme « OK », il faut que leur propriété « supportedForProcessing » soit à true. Cette propriété est à « false » par défaut, il faut donc bien faire attention à le faire systématiquement.
Marker une fonction comme « supportedForProcessing »
Pour cela, plusieurs manières d’y arriver, suivant si vous avez affaire à une fonction, à un event handler ou à une fonction de Binding:
WinJS.Utilities.markSupportedForProcessing(myfunction); WinJS.UI.eventHandler(myHandler); WinJS.Binding.initializer(myInitializer); //Also OK <namespace>.myfunction = WinJS.UI.eventHandler(function () { });
Précision sur les cas d’application
Cette notion de « supportedForProcessing » semble être assez génante mais il faut bien voir qu’elle ne couvre qu’un cas particulier d’une application WinJS. Quelques précisions:
- Cette restriction ne concerne que les fonctions déclarées dans du markup HTML. Les fonctions qui sont référencées par « addEventListener » en JavaScript ne sont pas concernées
- Les fonctions issues des packages WinJS.UI.* et WinJS.Binding.* ne sont pas concernées car marquées par défaut
- Les fonctions renvoyées depuis une instruction WinJS.Class.define, WinJS.Class.derive, WinJS.UI.Pages.define et WinJS.Binding.converter sont automatiquement marquées par défaut. Donc si vous définissez vos classes et vos pages avec les fonctions du framework WinJS, vous ne devriez jamais tomber sur ce problème.