APIs HTML5 HTML5 JavaScript APIs jsconf.eu 2009
2022
2022 = two completely interoperable implementations
CSS 2.1
HTML5
Web Forms Audio/Video Canvas Offline Drag & Drop Editable History API Undo X-Domain Messaging HTML5
“HTML5”
“HTML5” •Web Forms 2.0 •Audio & Video •Canvas •Offline •Storage •Geolocation •Workers
“HTML5” •Web Forms 2.0 •Audio & Video •Canvas •Offline •Storage •Geolocation •Workers
“HTML5” •Web Forms 2.0 •Audio & Video •Canvas •Offline •Storage •Geolocation •Workers
Web Forms 2.0 Actual search for "web forms", wtf? http://tr.im/webforms_pic ➙
"JavaScript is only good for image roll overs & form validation"
"JavaScript is only good for image roll overs & form validation" :hover
"JavaScript is only good for image roll overs & form validation" .hasFeature('WebForms', '2.0')
"JavaScript is only good for image roll overs & form validation" awesome shit" .hasFeature('WebForms', '2.0')
var f = document.querySelector('form'); f.onsubmit = function () { if ( this.checkValidity() ) { alert("It's all okay"); } else { alert("Something's gone wrong..."); return false; } };
Less JavaScript on donkey work == more JavaScript on awesome work.
Native Media Elements
<object classid="clsid:d27cdb6e-a height="344" codebase="http://dow flash/swflash.cab#version=6,0,40, <param name="allowFullScreen" val <param name="allowscriptaccess" v <param name="src" value="http://w <param name="allowfullscreen" val <embed type="application/x-shockw src="http://www.youtube.com/v/oHg allowscriptaccess="always" allowf </embed> </object>
<video src="dizzy.ogv" />
<video> <source src="dizzy.ogv" /> <source src="dizzy.mp4" /> </video>
?
<video> <source src="dizzy.ogv" /> <source src="dizzy.mp4" /> </video>
<video> <source src="dizzy.ogv" /> <source src="dizzy.mp4" /> <!-- QuickTime support --> <object><param></object> </video>
<video> <source src="dizzy.ogv" /> <source src="dizzy.mp4" /> <!-- QuickTime support --> <object><param></object> <!-- down to flash --> <object><param></object> </video>
<video> <source src="dizzy.ogv" /> <source src="dizzy.mp4" /> </video>
if (video.paused) { if (video.ended) { video.currentTime = 0; } video.play(); } else { video.pause(); }
if (video.paused) { if (video.ended) { video.currentTime = 0; } video.play(); } else { video.pause(); }
if (video.paused) { if (video.ended) { video.currentTime = 0; } video.play(); } else { video.pause(); }
if (video.paused) { if (video.ended) { video.currentTime = 0; } video.play(); } else { video.pause(); }
addEvent( video, 'timeupdate', function () { positon.innerHTML = ➥ asTime(this.currentTime); } );
addEvent( video, 'timeupdate', function () { positon.innerHTML = ➥ asTime(this.currentTime); } );
addEvent( video, 'timeupdate', function () { positon.innerHTML = ➥ asTime(this.currentTime); } );
•play(), pause() •paused, ended, currentTime •canplay, timeupdate, ended •and a bunch more.
•Bugs tend to be rather quiet...shhh... •Firefox needs the right content-type •Safari will plough ahead
Accessibility?
http://open.bbc.co.uk/rad/demos/html5/rdtv/episode2/
Canvas (+ excanvas.js)
<!DOCTYPE html> <html> <head> <title>Canvas</title> </head> <body> <canvas></canvas> </body> </html>
var ctx = canvas.getContext('2d');
var ctx = canvas.getContext('2d'); // Create radial gradient var grad = ctx.createRadialGradient(0,0,0,0,0,600);
var ctx = canvas.getContext('2d'); // Create radial gradient var grad = ctx.createRadialGradient(0,0,0,0,0,600); grad.addColorStop(0, '#E4E4E4'); grad.addColorStop(1, '#000');
var ctx = canvas.getContext('2d'); // Create radial gradient var grad = ctx.createRadialGradient(0,0,0,0,0,600); grad.addColorStop(0, '#E4E4E4'); grad.addColorStop(1, '#000'); // assign gradients to fill ctx.fillStyle = grad;
var ctx = canvas.getContext('2d'); // Create radial gradient var grad = ctx.createRadialGradient(0,0,0,0,0,600); grad.addColorStop(0, '#E4E4E4'); grad.addColorStop(1, '#000'); // assign gradients to fill ctx.fillStyle = grad; // draw 600x600 fill ctx.fillRect(0,0,600,600);
ctx.toDataURL("image/png");
ctx.toDataURL("image/png"); data:image/ png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAYAAACtWK6eAAAFxUlEQVR4Ae3dQW5jORAEUXvQ97+yez CzNQpNyPwdIp+XJkVlRTKgheGvz69/fz78IIDAtwT+ +fa3fokAAv8RIIiLgMBAgCADHEsIEMQdQGAgQJABjiUECOIOIDAQIMgAxxICBHEHEBgIEGSAYwkBgrgDCAwECDLAs YQAQdwBBAYCBBngWEKAIO4AAgMBggxwLCFAEHcAgYEAQQY4lhAgiDuAwECAIAMcSwj8+nEEn58/ fuQfHehf6/8Ik01rBHyCrPGy+zICBLmscOOuESDIGi+7LyNAkMsKN +4aAYKs8bL7MgIEuaxw464RIMgaL7svI0CQywo37hoBgqzxsvsyAgS5rHDjrhEgyBovuy8jQJDLCjfuGgGCrPGy +zICBLmscOOuESDIGi+7LyNAkMsKN +4aAYKs8bL7MgIEuaxw464RIMgaL7svI0CQywo37hoBgqzxsvsyAgS5rHDjrhEgyBovuy8jQJDLCjfuGgGCrPGy +zICBLmscOOuESDIGi+7LyNAkMsKN+4aAYKs8bL7MgI//3R3T1m/ 7AqdPa5PkLP7Nd2LBAjyIkAvP5sAQc7u13QvEiDIiwC9/ GwCBDm7X9O9SIAgLwL08rMJEOTsfk33IgGCvAjQy88mQJCz+zXdiwR+/i/pLwba/fLPj7/zPe5fH1+7R3P+BgI +QTZAdeQ5BAhyTpcm2UCAIBugOvIcAgQ5p0uTbCBAkA1QHXkOAYKc06VJNhAgyAaojjyHAEHO6dIkGwgQZANUR55D gCDndGmSDQQIsgGqI88hQJBzujTJBgIE2QDVkecQIMg5XZpkAwGCbIDqyHMIEOScLk2ygQBBNkB15DkECHJOlybZQ IAgG6A68hwCBDmnS5NsIECQDVAdeQ4BgpzTpUk2ECDIBqiOPIcAQc7p0iQbCBBkA1RHnkOAIOd0aZINBAiyAaojzy FAkHO6NMkGAgTZANWR5xC47ununrJ+zuV9YhKfIE9Q9h5vS4Agb1ud4E8QIMgTlL3H2xIgyNtWJ/ gTBAjyBGXv8bYECPK21Qn+BAGCPEHZe7wtAYK8bXWCP0GAIE9Q9h5vS+C6v6TXm/r8O1/j/vHla9y/vRo +Qb7F4pcI/E +AIG4CAgMBggxwLCFAEHcAgYEAQQY4lhAgiDuAwECAIAMcSwgQxB1AYCBAkAGOJQQI4g4gMBAgyADHEgIEcQcQGAg QZIBjCQGCuAMIDAQIMsCxhABB3AEEBgIEGeBYQoAg7gACAwGCDHAsIUAQdwCBgQBBBjiWECCIO4DAQIAgAxxLCBDE HUBgIECQAY4lBAjiDiAwECDIAMcSAgRxBxAYCBBkgGMJAU93j90BT1lvFeITpNWHNDECBIkVIk6LAEFafUgTI0CQW CHitAgQpNWHNDECBIkVIk6LAEFafUgTI0CQWCHitAgQpNWHNDECBIkVIk6LAEFafUgTI0CQWCHitAgQpNWHNDECBI kVIk6LAEFafUgTI0CQWCHitAgQpNWHNDECBIkVIk6LAEFafUgTI0CQWCHitAgQpNWHNDECBIkVIk6LAEFafUgTI0C QWCHitAgQpNWHNDECBIkVIk6LAEFafUgTI0CQWCHitAgQpNWHNDECBIkVIk6LAEFafUgTI0CQWCHitAgQpNWHNDEC BIkVIk6LAEFafUgTI0CQWCHitAgQpNWHNDECBIkVIk6LAEFafUgTI0CQWCHitAgQpNWHNDECBIkVIk6LAEFafUgTI 0CQWCHitAgQpNWHNDECBIkVIk6LAEFafUgTI0CQWCHitAgQpNWHNDECBIkVIk6LAEFafUgTI0CQWCHitAgQpNWHND ECBIkVIk6LAEFafUgTI0CQWCHitAgQpNWHNDECBIkVIk6LAEFafUgTI0CQWCHitAgQpNWHNDECBIkVIk6LAEFafUg TI0CQWCHitAgQpNWHNDECBIkVIk6LAEFafUgTI0CQWCHitAgQpNWHNDECvwHnaxGSkEUPVAAAAABJRU5ErkJggg== data:image/png;base64,...
Canvas + drawImage + Video =
ctx.getImageData() http://blog.mozbox.org/post/2009/04/12/Firefox-35%3A-a-new-experiment-with-Canvas-Video
frame = ctx.getImageData(0, 0, w, h); i = 0; // or via loop r = frame.data[i + 0]; g = frame.data[i + 1]; b = frame.data[i + 2];
ctx.translate(canvas.width/2, canvas.height/2); ctx.scale(-1, 1); ctx.translate(-canvas.width/2, -canvas.height/2); ctx.drawImage( video, 0, 0, video.width, video.height, 0, 0, canvas.width, canvas.height);
Don't use for evil
Offline Applications
Offline Applications
Offline Apps •Application cache •Events: offline, online •navigator.onLine property
http://icanhaz.com/rubiks
Enable <!DOCTYPE html> <html manifest="my.manifest"> <body> <!-- my page --> </body> </html>
CACHE MANIFEST images/shade.jpg images/bin.jpg #version 13 my.manifest
Cache •First line: CACHE MANIFEST •Requires text/cache-manifest •Recommend using versioning •window.applicationCache •Add it last!
The process
Browser: request Server: serve all Browser: I have a manifest, cache assets Server: serve manifest assets Browser: applicationCache updated Browser: reload Browser: only request manifest file Server: 304 Not Modified Browser: serve locally
Storage (giant cookies)
SQLite key/val
key/value sessionStorage localStorage .setItem(key, value); .getItem(key); window based
key/value sessionStorage localStorage .setItem(key, value); .getItem(key); window based domain based
SQLite "User agents must implement the SQL dialect supported by Sqlite 3.6.19" Another one that fails super silently :(
db = openDatabase("demo", "1.0", "sample", 200000); db.transaction(function (tx) { tx.executeSql('SELECT * FROM tweets WHERE mention = ?', [mention], function (tx, results) { // do something with results }); });
db = openDatabase("demo", "1.0", "sample", 200000); db.transaction(function (tx) { tx.executeSql('SELECT * FROM tweets WHERE mention = ?', [mention], function (tx, results) { // do something with results }); });
db = openDatabase("demo", "1.0", "sample", 200000); db.transaction(function (tx) { tx.executeSql('SELECT * FROM tweets WHERE mention = ?', [mention], function (tx, results) { // do something with results }); });
db = openDatabase("demo", "1.0", "sample", 200000); db.transaction(function (tx) { tx.executeSql('SELECT * FROM tweets WHERE mention = ?', [mention], function (tx, results) { // do something with results }); });
Geolocation
Geolocation
Not always accurate!
navigator .geolocation .getCurrentPosition( success, err );
Web Workers
•"Threads" •Native or via Gears (or setTimeout hack?) •Sandboxed •Debugging?
http://html5demos.com/worker
•importScripts •postMessage •onmessage •onconnect
var w = new Worker('worker.js'); w.onmessage = function (event) { alert("msg: " + event.data); }; w.postMessage('run'); app.html
importScripts('xhr.js', 'db.js'); onmessage = function (event) { if (event.data == 'run') { run(); } }; function run() { var data = doCrazyNumberCrunch(); postMessage(data); } worker.js
importScripts('xhr.js', 'db.js'); onmessage = function (event) { if (event.data == 'run') { run(); } }; function run() { var data = doCrazyNumberCrunch(); postMessage(data); } worker.js
importScripts('xhr.js', 'db.js'); onmessage = function (event) { if (event.data == 'run') { run(); } }; function run() { var data = doCrazyNumberCrunch(); postMessage(data); } worker.js
And a lot more...
Attributes: data-*, itemProp, sandbox (on iframes) Microdata API, datagrid, XHR2 & upload progress Drag & Drop, History manager ARIA overlap querySelector <progress> <meter> <datalist> <ruby>
http://www.whatwg.org/html5/ http://tr.im/whatwg_complete irc://irc.freenode.net/#whatwg
Remy Sharp @rem JavaScript Conference: full-frontal.org http://html5demos.com Links: http://tr.im/rs_jsconfeu (another) Pro tip: cats can't code for crap

HTML5 JavaScript APIs