Création d’une application gérant l’offline et le stockage client
David CATUHE - @deltakoshMicrosoft – [email protected]://blogs.msdn.com/eternalcoding
David ROUSSET - @davrousMicrosoft – [email protected]://blogs.msdn.com/davrous
Du web de présentation vers le
web applicatif
Quelques fonctionnalités clés
Accélération matérielle
CSS3 grid, flexible box
Multi-columns
Stockage client
Audio/Vidéo
Accès au système de fichiers
Blobs
Mode offline
Drag’n’drop
ECMAScript 5
Geolocation
Websockets
Webworkers
Hit testing / touch / gestures
Canvas, SVG, animations
…
Démonstration
Présentation de l’application SnapX
Support du mode hors connexion
Version du site téléchargée lorsque le site est en lignePrérequis : Liste des ressources (HTML, CSS, JS, Images, etc.)Le navigateur détecte la connectivité et Si en ligne :
Télécharge les ressources Les garde synchronisées
Si hors ligne : Indique dans le DOM le statut Lève un événement si le statut change
Le navigateur ne fait pas : La sauvegarde de vos données La synchronisation lors de la reconnexion
http://www.w3.org/TR/offline-webapps/
Mode offline
Mise en œuvre : Cache Manifest File Liste des ressources
Chaque page doit pointer vers le fichier de manifeste
Attention au cache! Il faut modifier le contenu pour forcer le rafraichissement (si vous modifiez les fichiers cibles, cela ne suffit pas!)
Mode offline
<!DOCTYPE HTML> <html manifest="/cache.manifest">
<body> ... </body> </html
CACHE MANIFEST/default.htm/default.css/default.js/logo.jpg# commentaires…..
Gestion des entêtes :
NETWORK : Liste des fichiers uniquement disponible en mode connecté
CACHE : Liste des fichiers à rendre disponible hors ligne
Mode offline – mode avancé
CACHE MANIFESTNETWORK:/connect.asmxCACHE:/default.htm/default.css/default.js/logo.jpg
Mise en œuvre du mode de repli Fichiers de remplacement en cas d’erreurs:
« / » : Chaque page
Mode offline – Mode de repli
CACHE MANIFESTFALLBACK:/ /offline.htmNETWORK:/connect.asmxCACHE:/default.htm/default.css/default.js/logo.jpg
Gestion des entêtes :
« * » : Toutes les ressources qui ne sont pas dans FALLBACK et CACHE
Mode offline – Ressources externes
CACHE MANIFESTFALLBACK:/ /offline.htmlNETWORK:*
Mode offline – Cycle de vie
Manifest présent ?
[checking]
Déjà vu ?
Oui
A changé ?
Non[noupdate]
[downloading] &
[updateready]
Non
[downloading][progress]
[cached]
Window.applicationCache.status UNCACHED IDLE CHECKING DOWNLOADING UPDATEREADY OBSOLTE
Window.applicationCache.update()Window.applicationCache.abort()Window.applicationCache.swapCache()
Mode offline - Status
http://www.caniuse.com
Mode offline - Support
Démonstration
Fonctionnement hors ligne de SnapX
File API
Lecture et manipulation
File/blob
FileList
FileReader
Création et écriture
BlobBuilder
FileWriter
Répertoire et hiérarchie
DirectoryReader
FileEntry/DirectoryEntry
LocalFileSystem
File API
Démonstration
Demo File API
Stockage client
Stockage par paire clé/valeur et les propriétés sont stockées uniquement sous forme de chaîne
Chaque domaine dispose d’une zone de stockage isolée de 10 Mo
2 types : localStorage : partagé par toute l’application et
persistant sessionStorage : durée de vie par session -> pratique
pour les problématiques multi-onglets
Scénarios d’usage : sauvegarde d’un formulaire de saisie, mise en place de cache, etc.
Stockage client – DOM Storage
Comprendre par le code
<script>var lStorage = window.localStorage;function init() { if (!lStorage.score) lStorage.score = 0; document.getElementById('c1').innerText = lStorage.score; }function save() { lStorage.score = getGameScore();}</script><body onload=“init();”> <p>Votre dernier score était: <span id="c1">non défini</span> </p></body>
Démonstration
Démo DOM Storage – avec YODA
De type NoSQL : paires de clé-valeur
Les valeurs sont stockées sous forme d’objets JS Une indexation permet un filtrage et une
recherche efficace
Tout est asynchrone et tout est transaction
Les opérations classiques en SQL comme la jointure se font manuellement par code
Stockage client - IndexedDB
Comprendre via le code
var oRequestDB = window.indexedDB.open(“Library”);oRequestDB.onsuccess = function (event) { db1 = oRequestDB.result; if (db1.version == 1) { txn = db1.transaction([“Books”],IDBTransaction.READ_ONLY); var objStoreReq = txn.objectStore(“Books”); var request = objStoreReq.get("Book0"); request.onsuccess = processGet; }};
http://www.caniuse.com
IndexedDB - Support
Idées de scénarios
File System
<input type=“file” …>
Drag & Drop
File Object(Blob) XMLHttpRequest.send
Web
Canvas ou autre
élément HTML
Blob URL
File System
File Object(Blob)
IndexedDBobjectStore.add
XMLHttpRequest.send
objectStore.get
Scénario 1
Scénario 2
Démonstration
Une belle démo moche d’IndexedDB ! Démo de l’outil de debug iDBGestion d’IndexedDB dans SnapX avec driver BackBone.js
Drag’n’Drop
Gestion du glisser/déposer interne et externeRecette de cuisine : Marquer les objets [draggable] S’abonner aux événements (ondragstart,
ondragend) Définition de la dropzone
Via l’attribut [dropzone] Via les événements (ondragenter,
ondragover) S’abonner à l’événement ondrop Récupération de l’objet DataTransfer
Drag’n’Drop
<ol ondragstart="dragStartHandler(event)" ondragend="dragEndHandler(event)" >
<li draggable="true" data-value="World of Warcraft">Wow</li> <li draggable="true" data-value="Elder Scroll 5">Skyrim</li> <li draggable="true" data-value="Angry birds">Angry Birds</li> </ol>
Drag’n’Drop – les événements de départ
<div ondrop="dropHandler(event)" ondragenter="dragEnterHandler(event)" ondragover="dragOverHandler(event)"> </div>
Drag’n’Drop – les événements de réception
<div dropzone="move string:text/monformat" ondrop="dropHandler(event)"></div>
Drag’n’Drop – DropZone
Mode de drop:• Move• Link• Copy
Moniker:• File• String
Type mime
Interface utilisée pour stocker les données à transférer dropEffect : none, copy, link, move effectAllowed : none", "copy", "copyLink",
"copyMove", "link", "linkMove", "move", "all", "uninitialized“
items setDragImage addElement types getData / setData clearData files
Drag’n’Drop - DataTransfer
<script> var internalDNDType = 'text/monformat'; function dragStartHandler(event) { if (event.target instanceof HTMLLIElement) { event.dataTransfer.setData(internalDNDType, event.target.dataset.value); event.dataTransfer.effectAllowed = 'move } else { event.preventDefault(); } }</script>
Drag’n’Drop - Lancement
<script> var internalDNDType = 'text/monformat'; function dropHandler(event) { var li = document.createElement('li'); var data = event.dataTransfer.getData(internalDNDType); if (data == 'World of Warcraft') { li.textContent = 'Yeahhh'; } else { li.textContent = 'Game over'; } event.target.appendChild(li); }</script>
Drag’n’Drop - Réception
Démonstration
Gestion du drag’n’drop de SnapX
<Questions/>
palais des congrès Paris
7, 8 et 9 février 2012