85
JS Unconf 2015 ON CONNECTION LOST The life of an oine web application & war stories about generating PDFs in the browser #jsunconf #oinerst @thoughtworks @sgrewenig @jthoenes

OnConnectionLost: The life of an offline web application - JSUnconf 2015

Embed Size (px)

Citation preview

Page 1: OnConnectionLost: The life of an offline web application - JSUnconf 2015

J S U n c o n f 2 0 1 5

ON CONNECTION LOSTThe life of an offline web application &

war stories about generating PDFs in the browser

#jsunconf #offlinefirst @thoughtworks

@sgrewenig @jthoenes

Page 2: OnConnectionLost: The life of an offline web application - JSUnconf 2015

OFFLINE ??!

Page 3: OnConnectionLost: The life of an offline web application - JSUnconf 2015
Page 4: OnConnectionLost: The life of an offline web application - JSUnconf 2015

WHAT ISOFFLINE ?

Page 5: OnConnectionLost: The life of an offline web application - JSUnconf 2015

STUPIDCLIENT

Page 6: OnConnectionLost: The life of an offline web application - JSUnconf 2015

MORE LOGICCLIENT-SIDE

Page 7: OnConnectionLost: The life of an offline web application - JSUnconf 2015

“INDEPENDENT”CLIENT

Page 8: OnConnectionLost: The life of an offline web application - JSUnconf 2015

WHY ?

Page 9: OnConnectionLost: The life of an offline web application - JSUnconf 2015
Page 10: OnConnectionLost: The life of an offline web application - JSUnconf 2015
Page 11: OnConnectionLost: The life of an offline web application - JSUnconf 2015

HOW ?

Page 12: OnConnectionLost: The life of an offline web application - JSUnconf 2015

CLIENT AVAILABLE OFFLINE

2 DATA AVAILABLE OFFLINE

3 DATA CHANGES OFFLINE

1

Page 13: OnConnectionLost: The life of an offline web application - JSUnconf 2015

CLIENT AVAILABLE OFFLINE1

Page 14: OnConnectionLost: The life of an offline web application - JSUnconf 2015

YOU LEARNED ABOUT APPLICATION CACHE ALREADY, RIGHT?

14

Page 15: OnConnectionLost: The life of an offline web application - JSUnconf 2015
Page 16: OnConnectionLost: The life of an offline web application - JSUnconf 2015

APP CACHE

Page 17: OnConnectionLost: The life of an offline web application - JSUnconf 2015

APP CACHE

Page 18: OnConnectionLost: The life of an offline web application - JSUnconf 2015

APP CACHE

Page 19: OnConnectionLost: The life of an offline web application - JSUnconf 2015

INDEX.HTML

1 <!doctype html> 2 <html ... manifest="appcache.manifest"> . <!-- (...) --> 54 </html>

Page 20: OnConnectionLost: The life of an offline web application - JSUnconf 2015

APPCACHE.MANIFEST 1 CACHE MANIFEST 2 # rev 1 - 2014-10-03T13:50:18.799Z 3 4 CACHE: 5 404.html 6 favicon.ico 7 scripts/scripts.js # (...) 111 112 NETWORK: 113 * 114 115 FALLBACK: 116 / /offline.html

Page 21: OnConnectionLost: The life of an offline web application - JSUnconf 2015

APPCACHE.MANIFEST 1 CACHE MANIFEST 2 # rev 1 - 2014-10-03T13:50:18.799Z 3 4 CACHE: 5 404.html 6 favicon.ico 7 scripts/scripts.js # (...) 111 112 NETWORK: 113 * 114 115 FALLBACK: 116 / /offline.html

Page 22: OnConnectionLost: The life of an offline web application - JSUnconf 2015

APPCACHE.MANIFEST 1 CACHE MANIFEST 2 # rev 1 - 2014-10-03T13:50:18.799Z 3 4 CACHE: 5 404.html 6 favicon.ico 7 scripts/scripts.js # (...) 111 112 NETWORK: 113 * 114 115 FALLBACK: 116 / /offline.html

Page 23: OnConnectionLost: The life of an offline web application - JSUnconf 2015

APPCACHE.MANIFEST 1 CACHE MANIFEST 2 # rev 1 - 2014-10-03T13:50:18.799Z 3 4 CACHE: 5 404.html 6 favicon.ico 7 scripts/scripts.js # (...) 111 112 NETWORK: 113 * 114 115 FALLBACK: 116 / /offline.html

Page 24: OnConnectionLost: The life of an offline web application - JSUnconf 2015

APPCACHE.MANIFEST 1 CACHE MANIFEST 2 # rev 1 - 2014-10-03T13:50:18.799Z 3 4 CACHE: 5 404.html 6 favicon.ico 7 scripts/scripts.js # (...) 111 112 NETWORK: 113 * 114 115 FALLBACK: 116 / /offline.html

Page 25: OnConnectionLost: The life of an offline web application - JSUnconf 2015

EVENTS

CHECKING DOWNLOADING PROGRESS UPDATE READY

Page 26: OnConnectionLost: The life of an offline web application - JSUnconf 2015
Page 27: OnConnectionLost: The life of an offline web application - JSUnconf 2015

ADDITIONAL CACHE

Page 28: OnConnectionLost: The life of an offline web application - JSUnconf 2015
Page 29: OnConnectionLost: The life of an offline web application - JSUnconf 2015
Page 30: OnConnectionLost: The life of an offline web application - JSUnconf 2015

CLIENT AVAILABLE OFFLINE

2 DATA AVAILABLE OFFLINE

1

Page 31: OnConnectionLost: The life of an offline web application - JSUnconf 2015

31

//Store localStorage.town = “Antwerpen”

//Retrieve alert(localStorage.town)

WEBSTORAGEEasy to use key/value store Synchronous API

Page 32: OnConnectionLost: The life of an offline web application - JSUnconf 2015

INDEXED DB

Page 33: OnConnectionLost: The life of an offline web application - JSUnconf 2015

33

Page 34: OnConnectionLost: The life of an offline web application - JSUnconf 2015

10 var dbRequest = indexedDB.open('db_name', ‘1’);

31 var trans = database.transaction(['name'], ‘readonly'); 32 var store = trans.objectStore('name'); 33 var getRequest = store.get('4'); 34 getRequest.onsuccess = // …

42 var index = store.index('stockAmount'); 43 var cursorRequest = index.openCursor(IDBKeyRange.lower(15)); 44 cursorRequest.onsuccess = // ...

THE API

Page 35: OnConnectionLost: The life of an offline web application - JSUnconf 2015

10 var dbRequest = indexedDB.open('db_name', ‘1’);

31 var trans = database.transaction(['name'], ‘readonly'); 32 var store = trans.objectStore('name'); 33 var getRequest = store.get('4'); 34 getRequest.onsuccess = // …

42 var index = store.index('stockAmount'); 43 var cursorRequest = index.openCursor(IDBKeyRange.lower(15)); 44 cursorRequest.onsuccess = // ...

THE API

Page 36: OnConnectionLost: The life of an offline web application - JSUnconf 2015

10 var dbRequest = indexedDB.open('db_name', ‘1’);

31 var trans = database.transaction(['name'], ‘readonly'); 32 var store = trans.objectStore('name'); 33 var getRequest = store.get('4'); 34 getRequest.onsuccess = // …

42 var index = store.index('stockAmount'); 43 var cursorRequest = index.openCursor(IDBKeyRange.lower(15)); 44 cursorRequest.onsuccess = // ...

THE API

Page 37: OnConnectionLost: The life of an offline web application - JSUnconf 2015

10 var dbRequest = indexedDB.open('db_name', ‘1’);

31 var trans = database.transaction(['name'], ‘readonly'); 32 var store = trans.objectStore('name'); 33 var getRequest = store.get('4'); 34 getRequest.onsuccess = // …

42 var index = store.index('stockAmount'); 43 var cursorRequest = index.openCursor(IDBKeyRange.lower(15)); 44 cursorRequest.onsuccess = // ...

THE API

Page 38: OnConnectionLost: The life of an offline web application - JSUnconf 2015

10 var dbRequest = indexedDB.open('db_name', ‘1’);

31 var trans = database.transaction(['name'], ‘readonly'); 32 var store = trans.objectStore('name'); 33 var getRequest = store.get('4'); 34 getRequest.onsuccess = // …

42 var index = store.index('stockAmount'); 43 var cursorRequest = index.openCursor(IDBKeyRange.lower(15)); 44 cursorRequest.onsuccess = // ...

THE API

Page 39: OnConnectionLost: The life of an offline web application - JSUnconf 2015

10 var dbRequest = indexedDB.open('db_name', ‘1’);

31 var trans = database.transaction(['name'], ‘readonly'); 32 var store = trans.objectStore('name'); 33 var getRequest = store.get('4'); 34 getRequest.onsuccess = // …

42 var index = store.index('stockAmount'); 43 var cursorRequest = index.openCursor(IDBKeyRange.lower(15)); 44 cursorRequest.onsuccess = // ...

THE API

Page 40: OnConnectionLost: The life of an offline web application - JSUnconf 2015
Page 41: OnConnectionLost: The life of an offline web application - JSUnconf 2015

MIGRATIONS

Page 42: OnConnectionLost: The life of an offline web application - JSUnconf 2015

ONUPGRADE

NEEDED

Page 43: OnConnectionLost: The life of an offline web application - JSUnconf 2015

FILESYSTEM APIFILE API

Page 44: OnConnectionLost: The life of an offline web application - JSUnconf 2015

44

ADD IMAGE

filesystem:http://thedomain/persistent/xyz.jpg

Page 45: OnConnectionLost: The life of an offline web application - JSUnconf 2015

45

GET IMAGE

Page 46: OnConnectionLost: The life of an offline web application - JSUnconf 2015

IE 106.1YES YEShttp://caniuse.com/#search=fileapi

Page 47: OnConnectionLost: The life of an offline web application - JSUnconf 2015

YES NONONOhttp://caniuse.com/#search=filesystem

Page 48: OnConnectionLost: The life of an offline web application - JSUnconf 2015

CLIENT AVAILABLE OFFLINE

2 DATA AVAILABLE OFFLINE

3 DATA CHANGES OFFLINE

1

Page 49: OnConnectionLost: The life of an offline web application - JSUnconf 2015

DATA SYNCHRONISATION

Page 50: OnConnectionLost: The life of an offline web application - JSUnconf 2015

CAPTURING1 CHANGES

Page 51: OnConnectionLost: The life of an offline web application - JSUnconf 2015

QUEUE2

Page 52: OnConnectionLost: The life of an offline web application - JSUnconf 2015

PROCESSING3

Page 53: OnConnectionLost: The life of an offline web application - JSUnconf 2015

<<<<<<< HEAD

Hamburger is better than Berliner.=======

Berlin is better than Hamburger.>>>>>>> d237ef28dc3fab5dcccc63f580bfa7780f

Page 54: OnConnectionLost: The life of an offline web application - JSUnconf 2015

OR

Page 55: OnConnectionLost: The life of an offline web application - JSUnconf 2015

SIZE OF DATA ?

Page 56: OnConnectionLost: The life of an offline web application - JSUnconf 2015

STRUCTURE OF DATA ?

Page 57: OnConnectionLost: The life of an offline web application - JSUnconf 2015

SENSITIVE DATA ?

Page 58: OnConnectionLost: The life of an offline web application - JSUnconf 2015

POTENTIAL FOR DATA CONFLICTS ?

Page 59: OnConnectionLost: The life of an offline web application - JSUnconf 2015

BROWSER SUPPORT ?

Page 60: OnConnectionLost: The life of an offline web application - JSUnconf 2015

AMOUNT OF FUNCTIONALITY TO WORK OFFLINE ?

Page 61: OnConnectionLost: The life of an offline web application - JSUnconf 2015

61

CHALLENGE REQUIREMENTS

Page 62: OnConnectionLost: The life of an offline web application - JSUnconf 2015

OFFLINE FIRST & EARLY

Page 63: OnConnectionLost: The life of an offline web application - JSUnconf 2015

63

EXPLORE THE POSSIBILITIES

Page 64: OnConnectionLost: The life of an offline web application - JSUnconf 2015

PDF IN THE BROWSER

Page 65: OnConnectionLost: The life of an offline web application - JSUnconf 2015
Page 66: OnConnectionLost: The life of an offline web application - JSUnconf 2015

"sections": [{ "blocks": [{ "contentItems": [ { "uid": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee", "wysiwyg": "<p>Decorative <i>deer</i> figures in a set of 2<\/p><img our-src=“aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee.png”>” }, { "libraryItemUid": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee", "uid": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee", "wysiwyg": "<p>There may be <strong>no sign</strong> of a seam in the material. [FT-PLACEHOLDER]<\/p>" }, { "libraryItemUid": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee", "uid": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee", "wysiwyg": "<p>Set comprises a large deer and a small deer [FT-PLACEHOLDER]<\/p>" },

Page 67: OnConnectionLost: The life of an offline web application - JSUnconf 2015

HAVE A LOOK !

67

Page 68: OnConnectionLost: The life of an offline web application - JSUnconf 2015

USE THE BROWSER TO PRINT?

68

Page 69: OnConnectionLost: The life of an offline web application - JSUnconf 2015

var doc = new jsPDF();doc.text(20, 20, 'Hello world.');doc.save('Test.pdf');

https://github.com/MrRio/jsPDF

Page 70: OnConnectionLost: The life of an offline web application - JSUnconf 2015

PDFDocument = require 'pdfkit'

doc = new PDFDocumentdoc.pipe fs.createWriteStream('output.pdf')doc.font('fonts/PalatinoBold.ttf') .fontSize(25) .text('Some text with an embedded font!', 100, 100)

doc.addPage() .fontSize(25) .text('Here is some vector graphics...', 100, 100)

doc.end()https://github.com/devongovett/pdfkit

Page 71: OnConnectionLost: The life of an offline web application - JSUnconf 2015

pdfMake.createPdf({ content: [ { text: 'This paragraph will have a bigger font', fontSize: 15 }, { text: [ { text: 'restyle part of it and make it bigger ', fontSize: 15 }, 'than the rest.' ] } ]}).open();

https://github.com/bpampuch/pdfmake

Page 72: OnConnectionLost: The life of an offline web application - JSUnconf 2015
Page 73: OnConnectionLost: The life of an offline web application - JSUnconf 2015

SHORT DEMO?

73

Page 74: OnConnectionLost: The life of an offline web application - JSUnconf 2015

74

Page 75: OnConnectionLost: The life of an offline web application - JSUnconf 2015

HTML -> PDF PARSER

75

Page 76: OnConnectionLost: The life of an offline web application - JSUnconf 2015

PAGE BREAKS

76

Page 77: OnConnectionLost: The life of an offline web application - JSUnconf 2015

LANDSCAPE

77

Page 78: OnConnectionLost: The life of an offline web application - JSUnconf 2015

95 CHARACTERS

78

Page 79: OnConnectionLost: The life of an offline web application - JSUnconf 2015

IMAGE WRAPPING

79

Page 80: OnConnectionLost: The life of an offline web application - JSUnconf 2015

https://github.com/TW-QEN/pdfmake#develop

Page 81: OnConnectionLost: The life of an offline web application - JSUnconf 2015

THANKS@SGREWENIG @JTHOENES@THOUGHTWORKS

Page 82: OnConnectionLost: The life of an offline web application - JSUnconf 2015
Page 83: OnConnectionLost: The life of an offline web application - JSUnconf 2015

IE 10YESYES YEShttp://caniuse.com/#search=appcache

Page 84: OnConnectionLost: The life of an offline web application - JSUnconf 2015

IE 107.1YES YEShttp://caniuse.com/#search=indexeddb

Page 85: OnConnectionLost: The life of an offline web application - JSUnconf 2015

YESYESYES YEShttp://caniuse.com/#search=webstorage