KEMBAR78
HTML5: Building the Next Generation of Web Applications | PDF
HTML5: BUILDING THE NEXT
          GENERATION OF WEB APP
                         Features Performance Tools Compatibility


         Eric Bidelman, Google
         COSCUP / GNOME.Asia - Taipei, Taiwan
         August 14, 2010




Monday, March 21, 2011
AGENDA
    • Quick              Performance Wins

    • New            HTML5 Markup ( for web apps )

    • Web            Storage APIs

    • Web Workers               & Web Sockets

    • Compatibility

    • Tools              & Resources



Monday, March 21, 2011
PERFORMANCE WINS




Monday, March 21, 2011
DON’T UNDERESTIMATE CSS!
    •   Rounded corners, box shadows, reflection, rotations, alpha, css masks

    •   CSS animations & transitions

                                div.box {
                                  left: 40px;  
                                  -webkit-transition: left 0.3s ease-out;
                                     -moz-transition: left 0.3s ease-out;  
                                       -o-transition: left 0.3s ease-out;  
                                }
                                div.box.totheleft { left: 0px; }
                                div.box.totheright { left: 80px; }


        •   3D transforms trigger HW compositing in the GPU

                                -webkit-transform: translate3d(10px, 0, 0);

    •   pseudo-selectors are your friend ( :hover, :active, :valid, :invalid, :focus, :empty )

    •   web fonts



Monday, March 21, 2011
NATIVE IS BETTER!
    • Use          native methods ( not libraries )!
                         JSON.parse();       JSON.stringify();
           String.trim(‘                  too much padding       ‘);

    • Query, don’t          walk the DOM!
           document.querySelector(‘#links’);

           document.querySelectorAll(‘.myclass > span’);

    • Paint, don’t        download
                                  canvas.toDataURL();

Monday, March 21, 2011
DON’T FORGET ABOUT JAVASCRIPT 1.6+
    •   Array iterative methods: map(), filter(), forEach(), every(), some()

                         [5,6,7,8].map(function(value){ // [50,60,70,80]
                             return value * 10;
                         });

                         // Return a new array of all mathematical constants
                         under 2
                         [3.14, 2.718, 1.618].filter(function(number){
                           return number < 2;
                         });
                         // [1.618]

                         ['html5','css3','webgl'].forEach(function(value){
                           // use value
                         });



    •   Array item location methods: indexOf(‘html5’), lastIndexOf(‘webgl’)



Monday, March 21, 2011
HTML5 MARKUP FOR WEB APPS
                         ...more than just semantics




Monday, March 21, 2011
REL ATTRIBUTES
    • rel=”pingback”

        • enables           reverse linking
        • automatically           notifies original blog when other sites link to it
        <a rel="pingback" href="http://blog.blogspot.com">A Blog</a>
        •

    • rel=”prefetch”

        • hint           for the browser that the resource is likely to be used
            <link rel=”prefetch” href=”URL to top of search result”/>
           <a rel=”prefetch” href=”next_page.html”>Next page &gt;</a>



Monday, March 21, 2011
HTML5 FORMS
    • New            <input> types mean you don’t need bloated JS libraries!

        • tel, email, url, datetime, date, month, week, time, datetime-
            local, number, range, color

    • Attributes: placeholder, required, autofocus, pattern, min, max,
       step




Monday, March 21, 2011
DEMOS
                          open




Monday, March 21, 2011
WEB STORAGE
                           Not Just For Offline




Monday, March 21, 2011
WEB STORAGE APIS
       localStorage

        •   key/value pairs

        •   great for storing user preferences

            localStorage.dateOfBirth = ‘1984-07-22’;
            delete localStorage.dateOfBirth;

            localStorage[‘user’] = JSON.stringify({username: john, id: 100});
            var retrieved = JSON.parse(localStorage[‘user’]);


       sessionStorage

        •   non-persistent key/value pairs (e.g. sensitive data)

       Web SQL DB

        •   5MB of persistent storage

        •   reduces round trips to the server



Monday, March 21, 2011
EXAMPLE
                var webdb = {};

                webdb.open = function() {
                  var dbSize = 5 * 1024 * 1024; // 5MB
                  webdb.db = openDatabase('Todo', '1.0', 'todo manager', dbSize);
                }

                webdb.onError = function(tx, e) {
                  alert('Something unexpected happened: ' + e.message);
                }

                webdb.onSuccess = function(tx, r) {
                  // re-render all the data in the DOM
                }

                webdb.createTable = function() {
                  webdb.db.transaction(function(tx) {
                    tx.executeSql('CREATE TABLE IF NOT EXISTS ' +
                        'todo(ID INTEGER PRIMARY KEY ASC, todo TEXT, added_on DATETIME)', []);
                  });
                }

                webdb.addTodo = function(todoText) {
                  webdb.db.transaction(function(tx){
                    var addedOn = new Date();
                    tx.executeSql('INSERT INTO todo(todo, added_on) VALUES (?,?)',
                        [todoText, addedOn], webdb.onSuccess, webdb.onError);
                    });
                }


Monday, March 21, 2011
A 4TH STORAGE OPTION...
       Indexed DB

        •   Hybrid of localStorage/sessionStorage APIs and Web
            SQL DB.

             •   In-order retrieval

             •   Faster search - Index on any keys

        •   Browser support is still sparse

             •   Implemented in FF4

             •   landing in Chrome soon...


Monday, March 21, 2011
APPLICATION CACHE
    • Caches             entire web app locally

    • Why?

        1.HTML, CSS, and JS stay fairly consistent

        2.Native browser caching is unreliable

        3.Caching resources creates speedier apps

             • Native       iPhone & Android Gmail app uses AppCache



Monday, March 21, 2011
CACHE MANIFEST FILE
                         <html manifest="example.manifest">
                           ...
                         </html>


                         CACHE MANIFEST
                         # 2010-08-10-v0.0.1

                         # Explicitly cached entries
                         CACHE:
                         index.html
                         stylesheet.css
                         images/logo.png
                         scripts/main.js

                         # static.html will be served if the user is offline
                         FALLBACK:
                         / /static.html

                         # Resources that require the user to be online.
                         NETWORK:
                         *
                         # login.php
                         # http://api.twitter.com


Monday, March 21, 2011
JAVASCRIPT API
                         var appCache = window.applicationCache;


         if (appCache.status == window.applicationCache.UPDATEREADY) {
           appCache.swapCache();  // Fetch was successful, swap the new cache.
         }

         // Events for everything!
         appCache.addEventListener('cached', handleCacheEvent, false);

         appCache.addEventListener('checking', handleCacheEvent, false);

         appCache.addEventListener('downloading', handleCacheEvent, false);

         appCache.addEventListener('error', handleCacheError, false);

         appCache.addEventListener('noupdate', handleCacheEvent, false);

         appCache.addEventListener('obsolete', handleCacheEvent, false);

         appCache.addEventListener('progress', handleCacheEvent, false);

         appCache.addEventListener('updateready', handleCacheEvent, false);

Monday, March 21, 2011
DEBUGGING APP CACHE




Monday, March 21, 2011
DEMO
                         http://3.ly/timer




Monday, March 21, 2011
WEB WORKERS
                                      GETTING STUFF DONE
    • Take          advantage of multi-core CPUs

    • Use         cases:

        • Text           formatting of a long document

        • Syntax           highlighting

        • Audio           synthesis

        • Image           processing

        • Processing           large arrays or other computational tasks

Monday, March 21, 2011
JAVASCRIPT API
         <output id="result"></output>

         <script>
           var worker = new Worker('task.js');

           worker.addEventListener('message', function(e) {
             document.getElementById('result').textContent =
               JSON.stringify(e.data);
           }, false);

           worker.postMessage({'cmd': 'start', 'msg': 'Hi'});
         </script>


         // task.js
         self.addEventListener('message', function(e) {
           var data = e.data;
           switch (data.cmd) {
             case 'start':
               self.postMessage('WORKER STARTED: ' + data.msg);
               break;
             case 'stop':
               self.close(); // Terminates the worker.
           };
         }, false);

Monday, March 21, 2011
WEBSOCKETS
                                       REALTIME
    •   Bi-directional communication

        •   Eliminates need for XHR polling!

        •   Close as we can get to TCP/IP socket connections in JS

        •   Port 80 with scheme ws://, wss://

    •   Use cases:

        •   chat rooms

        •   white boarding

        •   games


Monday, March 21, 2011
JAVASCRIPT API
      var ws = new WebSocket("ws://www.example.com/path");

      ws.onopen = function () { // connection established
         ws.send("Hello, WebSocket");
      };

      ws.onmessage = function(evt) {
         alert(evt.data);
         ws.close();
      };

      ws.onclose = function () {
         // connection closed
      };




Monday, March 21, 2011
DEMO
                         http://mrdoob.com/projects/multiuserpad/




Monday, March 21, 2011
TOOLS & COMPATIBILITY




Monday, March 21, 2011
GOOGLE FONTS API
                         code.google.com/apis/webfonts/




Monday, March 21, 2011
Monday, March 21, 2011
Monday, March 21, 2011
GOOGLE FONTS API
        <!DOCTYPE html>
        <html>
          <head>
            <link rel="stylesheet" type="text/css"
               href="http://fonts.googleapis.com/css?family=Tangerine|Inconsolata"/>
            <style>
               h1 {
                 font-family: 'Tangerine', serif;
                 font-size: 48px;
                 text-shadow: 4px 4px 4px #aaa;
               }
            </style>
          </head>
          <body>
            <h1>Making the Web Beautiful!</h1>
          </body>
        </html>




Monday, March 21, 2011
DEMO
                         www.gobiernodechile.cl




Monday, March 21, 2011
GOOGLE CHROME FRAME
                         Compatibility




Monday, March 21, 2011
BROWSER SHARE
                                                                    JULY 2010
                                  Internet Explorer                      Firefox   Google Chrome   Safari
                                  Opera                                  Other



                                                                         5% 2%
                                                                           2%
                                                                    7%


                                                            24%
                                                                                     60%




              http://marketshare.hitslink.com/report.aspx?qprid=0




Monday, March 21, 2011
http://acid3.acidtests.org/




Monday, March 21, 2011
http://acid3.acidtests.org/




Monday, March 21, 2011
Monday, March 21, 2011
WHAT IS IT?
    •   Plug-in that brings Chrome’s OWT to IE 6,7,8

        •   V8 JS engine

        •   Chrome’s CSS/HTML rendering engine

        •   Security ( sandbox ), performance, stability benefits of Chrome

    •   If your site works in Chrome, it works in GCF

        •   New features show up when they become available in Chrome. Auto
            update!

        •   That also means the built-in plugins like Flash and PDF viewer

    •   Open source


Monday, March 21, 2011
ENABLING
    1.Add a single meta tag to your site

        • if     !installed: direct users to download

        • else: your     site ‘just works’
        <meta http-equiv="X-UA-Compatible" content="chrome=1">


    2.Add a response header
                             X-UA-Compatible: chrome=1




Monday, March 21, 2011
DETECTING
     <html>
     <body>
     <!--[if IE]>
       <script
         src="http://ajax.googleapis.com/ajax/libs/chrome-frame/1/CFInstall.min.js">
       </script>
       <style>
         .chromeFrameInstallDefaultStyle {
            width: 100%; /* default is 800px */
            border: 5px solid blue;
         }
       </style>
       <div id="prompt">
         <!-- if IE without GCF, prompt goes here -->
       </div>
       <script>
         window.attachEvent("onload", function() {
            CFInstall.check({mode: "inline", node: "prompt"});
         });
       </script>
     <![endif]-->
     </body>
     </html>



Monday, March 21, 2011
THINGS WORK THE WAY YOU EXPECT
    • Uses           IE’s network stack

        • Same           cache behavior

        • Same           cookies

        • Same           SSL behavior

    • Respects            In-Private mode

    • Respects            cache clearing



Monday, March 21, 2011
MODERNIZR LIBRARY
    •   BAD: checking navigator.userAgent

        •   Unreliable - some users change this to get around poorly
            designed sites that otherwise block certain UAs.

    •   BETTER: Feature detection!

        •   Tests 20+ HTML5/CSS3 features by:

             1. document.createElement(‘nav’)

             2. set a style

             3. retrieve that style

        •   Creates a global Modernizr object to store the test results

        •   Adds classes to the <html> element that explain precisely
            what features are (and are not) natively supported



Monday, March 21, 2011
USAGE
                         <!-- In your HTML: -->
                         <div id="audio">
                           <audio>
                             <source src="mySong.ogg" />
                             <source src="mySong.mp3" />
                           </audio>
                           <button id="play">Play</button>
                           <button id="pause">Pause</button>
                         </div>

                         /* In your CSS: */
                         .no-audio #audio {
                           display: none; /* Don't show Audio options */
                         }
                         .audio #audio button {
                           /* Style the Play and Pause buttons nicely */
                         }

                         // In your JavaScript:
                         if (Modernizr.audio) {
                           // Hook up functionality to Play and Pause buttons
                         }


Monday, March 21, 2011
CANIUSE.COM
Monday, March 21, 2011
CHROME DEVELOPER TOOLS



Monday, March 21, 2011
HTML5ROCKS.COM
   • Step-by-Step Tutorials
   • Code                Playground
   • Interactive             Presentation
   • Studio              / Gallery




Monday, March 21, 2011
THANKS!
    •   Tools

        •   Google Fonts API: code.google.com/apis/webfonts/

        •   html5rocks.com

    •   Compatibility:

        •   Google Chrome Frame: http://code.google.com/chrome/chromeframe/

        •   caniuse.com

        •   modernizr.com

    •   File bugs against Chrome: crbug.com

    •   Stay in Touch!

        •   Twitter: @ChromiumDev

        •   groups.google.com/a/chromium.org/group/chromium-html5/



Monday, March 21, 2011
Monday, March 21, 2011

HTML5: Building the Next Generation of Web Applications

  • 1.
    HTML5: BUILDING THENEXT GENERATION OF WEB APP Features Performance Tools Compatibility Eric Bidelman, Google COSCUP / GNOME.Asia - Taipei, Taiwan August 14, 2010 Monday, March 21, 2011
  • 2.
    AGENDA • Quick Performance Wins • New HTML5 Markup ( for web apps ) • Web Storage APIs • Web Workers & Web Sockets • Compatibility • Tools & Resources Monday, March 21, 2011
  • 3.
  • 4.
    DON’T UNDERESTIMATE CSS! • Rounded corners, box shadows, reflection, rotations, alpha, css masks • CSS animations & transitions div.box {   left: 40px;     -webkit-transition: left 0.3s ease-out;      -moz-transition: left 0.3s ease-out;          -o-transition: left 0.3s ease-out;   } div.box.totheleft { left: 0px; } div.box.totheright { left: 80px; } • 3D transforms trigger HW compositing in the GPU -webkit-transform: translate3d(10px, 0, 0); • pseudo-selectors are your friend ( :hover, :active, :valid, :invalid, :focus, :empty ) • web fonts Monday, March 21, 2011
  • 5.
    NATIVE IS BETTER! • Use native methods ( not libraries )! JSON.parse(); JSON.stringify(); String.trim(‘ too much padding ‘); • Query, don’t walk the DOM! document.querySelector(‘#links’); document.querySelectorAll(‘.myclass > span’); • Paint, don’t download canvas.toDataURL(); Monday, March 21, 2011
  • 6.
    DON’T FORGET ABOUTJAVASCRIPT 1.6+ • Array iterative methods: map(), filter(), forEach(), every(), some() [5,6,7,8].map(function(value){ // [50,60,70,80] return value * 10; }); // Return a new array of all mathematical constants under 2 [3.14, 2.718, 1.618].filter(function(number){   return number < 2; }); // [1.618] ['html5','css3','webgl'].forEach(function(value){ // use value }); • Array item location methods: indexOf(‘html5’), lastIndexOf(‘webgl’) Monday, March 21, 2011
  • 7.
    HTML5 MARKUP FORWEB APPS ...more than just semantics Monday, March 21, 2011
  • 8.
    REL ATTRIBUTES • rel=”pingback” • enables reverse linking • automatically notifies original blog when other sites link to it <a rel="pingback" href="http://blog.blogspot.com">A Blog</a> • • rel=”prefetch” • hint for the browser that the resource is likely to be used <link rel=”prefetch” href=”URL to top of search result”/> <a rel=”prefetch” href=”next_page.html”>Next page &gt;</a> Monday, March 21, 2011
  • 9.
    HTML5 FORMS • New <input> types mean you don’t need bloated JS libraries! • tel, email, url, datetime, date, month, week, time, datetime- local, number, range, color • Attributes: placeholder, required, autofocus, pattern, min, max, step Monday, March 21, 2011
  • 10.
    DEMOS open Monday, March 21, 2011
  • 11.
    WEB STORAGE Not Just For Offline Monday, March 21, 2011
  • 12.
    WEB STORAGE APIS localStorage • key/value pairs • great for storing user preferences localStorage.dateOfBirth = ‘1984-07-22’; delete localStorage.dateOfBirth; localStorage[‘user’] = JSON.stringify({username: john, id: 100}); var retrieved = JSON.parse(localStorage[‘user’]); sessionStorage • non-persistent key/value pairs (e.g. sensitive data) Web SQL DB • 5MB of persistent storage • reduces round trips to the server Monday, March 21, 2011
  • 13.
    EXAMPLE var webdb = {}; webdb.open = function() {   var dbSize = 5 * 1024 * 1024; // 5MB   webdb.db = openDatabase('Todo', '1.0', 'todo manager', dbSize); } webdb.onError = function(tx, e) {   alert('Something unexpected happened: ' + e.message); } webdb.onSuccess = function(tx, r) {   // re-render all the data in the DOM } webdb.createTable = function() {   webdb.db.transaction(function(tx) {     tx.executeSql('CREATE TABLE IF NOT EXISTS ' +     'todo(ID INTEGER PRIMARY KEY ASC, todo TEXT, added_on DATETIME)', []);   }); } webdb.addTodo = function(todoText) { webdb.db.transaction(function(tx){     var addedOn = new Date();     tx.executeSql('INSERT INTO todo(todo, added_on) VALUES (?,?)',         [todoText, addedOn], webdb.onSuccess, webdb.onError);     }); } Monday, March 21, 2011
  • 14.
    A 4TH STORAGEOPTION... Indexed DB • Hybrid of localStorage/sessionStorage APIs and Web SQL DB. • In-order retrieval • Faster search - Index on any keys • Browser support is still sparse • Implemented in FF4 • landing in Chrome soon... Monday, March 21, 2011
  • 15.
    APPLICATION CACHE • Caches entire web app locally • Why? 1.HTML, CSS, and JS stay fairly consistent 2.Native browser caching is unreliable 3.Caching resources creates speedier apps • Native iPhone & Android Gmail app uses AppCache Monday, March 21, 2011
  • 16.
    CACHE MANIFEST FILE <html manifest="example.manifest">   ... </html> CACHE MANIFEST # 2010-08-10-v0.0.1 # Explicitly cached entries CACHE: index.html stylesheet.css images/logo.png scripts/main.js # static.html will be served if the user is offline FALLBACK: / /static.html # Resources that require the user to be online. NETWORK: * # login.php # http://api.twitter.com Monday, March 21, 2011
  • 17.
    JAVASCRIPT API var appCache = window.applicationCache; if (appCache.status == window.applicationCache.UPDATEREADY) {   appCache.swapCache();  // Fetch was successful, swap the new cache. } // Events for everything! appCache.addEventListener('cached', handleCacheEvent, false); appCache.addEventListener('checking', handleCacheEvent, false); appCache.addEventListener('downloading', handleCacheEvent, false); appCache.addEventListener('error', handleCacheError, false); appCache.addEventListener('noupdate', handleCacheEvent, false); appCache.addEventListener('obsolete', handleCacheEvent, false); appCache.addEventListener('progress', handleCacheEvent, false); appCache.addEventListener('updateready', handleCacheEvent, false); Monday, March 21, 2011
  • 18.
  • 19.
    DEMO http://3.ly/timer Monday, March 21, 2011
  • 20.
    WEB WORKERS GETTING STUFF DONE • Take advantage of multi-core CPUs • Use cases: • Text formatting of a long document • Syntax highlighting • Audio synthesis • Image processing • Processing large arrays or other computational tasks Monday, March 21, 2011
  • 21.
    JAVASCRIPT API <output id="result"></output> <script>   var worker = new Worker('task.js');   worker.addEventListener('message', function(e) {     document.getElementById('result').textContent = JSON.stringify(e.data);   }, false); worker.postMessage({'cmd': 'start', 'msg': 'Hi'}); </script> // task.js self.addEventListener('message', function(e) {   var data = e.data;   switch (data.cmd) {     case 'start':       self.postMessage('WORKER STARTED: ' + data.msg);       break;     case 'stop':       self.close(); // Terminates the worker.   }; }, false); Monday, March 21, 2011
  • 22.
    WEBSOCKETS REALTIME • Bi-directional communication • Eliminates need for XHR polling! • Close as we can get to TCP/IP socket connections in JS • Port 80 with scheme ws://, wss:// • Use cases: • chat rooms • white boarding • games Monday, March 21, 2011
  • 23.
    JAVASCRIPT API var ws = new WebSocket("ws://www.example.com/path"); ws.onopen = function () { // connection established ws.send("Hello, WebSocket"); }; ws.onmessage = function(evt) { alert(evt.data); ws.close(); }; ws.onclose = function () { // connection closed }; Monday, March 21, 2011
  • 24.
    DEMO http://mrdoob.com/projects/multiuserpad/ Monday, March 21, 2011
  • 25.
  • 26.
    GOOGLE FONTS API code.google.com/apis/webfonts/ Monday, March 21, 2011
  • 27.
  • 28.
  • 29.
    GOOGLE FONTS API <!DOCTYPE html> <html> <head> <link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?family=Tangerine|Inconsolata"/> <style> h1 { font-family: 'Tangerine', serif; font-size: 48px; text-shadow: 4px 4px 4px #aaa; } </style> </head> <body> <h1>Making the Web Beautiful!</h1> </body> </html> Monday, March 21, 2011
  • 30.
    DEMO www.gobiernodechile.cl Monday, March 21, 2011
  • 31.
    GOOGLE CHROME FRAME Compatibility Monday, March 21, 2011
  • 32.
    BROWSER SHARE JULY 2010 Internet Explorer Firefox Google Chrome Safari Opera Other 5% 2% 2% 7% 24% 60% http://marketshare.hitslink.com/report.aspx?qprid=0 Monday, March 21, 2011
  • 33.
  • 34.
  • 35.
  • 36.
    WHAT IS IT? • Plug-in that brings Chrome’s OWT to IE 6,7,8 • V8 JS engine • Chrome’s CSS/HTML rendering engine • Security ( sandbox ), performance, stability benefits of Chrome • If your site works in Chrome, it works in GCF • New features show up when they become available in Chrome. Auto update! • That also means the built-in plugins like Flash and PDF viewer • Open source Monday, March 21, 2011
  • 37.
    ENABLING 1.Add a single meta tag to your site • if !installed: direct users to download • else: your site ‘just works’ <meta http-equiv="X-UA-Compatible" content="chrome=1"> 2.Add a response header X-UA-Compatible: chrome=1 Monday, March 21, 2011
  • 38.
    DETECTING <html> <body> <!--[if IE]> <script src="http://ajax.googleapis.com/ajax/libs/chrome-frame/1/CFInstall.min.js"> </script> <style> .chromeFrameInstallDefaultStyle { width: 100%; /* default is 800px */ border: 5px solid blue; } </style> <div id="prompt"> <!-- if IE without GCF, prompt goes here --> </div> <script> window.attachEvent("onload", function() {   CFInstall.check({mode: "inline", node: "prompt"}); }); </script> <![endif]--> </body> </html> Monday, March 21, 2011
  • 39.
    THINGS WORK THEWAY YOU EXPECT • Uses IE’s network stack • Same cache behavior • Same cookies • Same SSL behavior • Respects In-Private mode • Respects cache clearing Monday, March 21, 2011
  • 40.
    MODERNIZR LIBRARY • BAD: checking navigator.userAgent • Unreliable - some users change this to get around poorly designed sites that otherwise block certain UAs. • BETTER: Feature detection! • Tests 20+ HTML5/CSS3 features by: 1. document.createElement(‘nav’) 2. set a style 3. retrieve that style • Creates a global Modernizr object to store the test results • Adds classes to the <html> element that explain precisely what features are (and are not) natively supported Monday, March 21, 2011
  • 41.
    USAGE <!-- In your HTML: --> <div id="audio"> <audio> <source src="mySong.ogg" /> <source src="mySong.mp3" /> </audio> <button id="play">Play</button> <button id="pause">Pause</button> </div> /* In your CSS: */ .no-audio #audio { display: none; /* Don't show Audio options */ } .audio #audio button { /* Style the Play and Pause buttons nicely */ } // In your JavaScript: if (Modernizr.audio) { // Hook up functionality to Play and Pause buttons } Monday, March 21, 2011
  • 42.
  • 43.
  • 44.
    HTML5ROCKS.COM • Step-by-Step Tutorials • Code Playground • Interactive Presentation • Studio / Gallery Monday, March 21, 2011
  • 45.
    THANKS! • Tools • Google Fonts API: code.google.com/apis/webfonts/ • html5rocks.com • Compatibility: • Google Chrome Frame: http://code.google.com/chrome/chromeframe/ • caniuse.com • modernizr.com • File bugs against Chrome: crbug.com • Stay in Touch! • Twitter: @ChromiumDev • groups.google.com/a/chromium.org/group/chromium-html5/ Monday, March 21, 2011
  • 46.