Mobile Web Appplications Development with HTML5

Lecture 1: Introduction

Claudio Riva

Aalto University March 2012

The Web is Dead!
An App for Every Task
More Time is Spent on Mobile Apps
The Apple Mobile App Economy Asymco
  • How many total apps have been downloaded on iOS ?
  • 25 billion

  • What's the gross sales from apps in Q4-11 ?
  • $1 billion

  • How much was paid to developers in Q4-11 ?
  • $700 million

  • On average how many apps were downloaded per unit sold ?
  • 75 apps

  • What's the minimum payout to developers per unit sold ?
  • $12

App Downloads on iTunes
Is the Web Dead ?
  • If you are reading this, it's not.
  • Wired article was read and discussed mostly on the web
  • HTML5 brings a lot of new cool stuff for web developers
  • Companies like Google, Apple, Adobe, Microsoft are embracing HTML5
  • Many apps are built in HTML5 and wrapped with a native shell
Evolution of the Web (Browsers)
Shifting from the "Document Web" to the "App Web"

Hyperlinked documents

Page reloading

Static pages

Web servers

Static content

Interactive web apps

Asynchronous API calls


Data hubs (web apis)

Real-time communication

Web apps are built with open standards that are refered as "Web Technologies"

The Classic Web Architecture
Towards a New Web Architecture
Shom me a "Mobile Web App"
FT Web App (more info)
  • Developed in 8 months by 3 people
  • Hugely optimized for iOS
  • Great and responsive UI design
    • Content balancing based on device type
    • Audio playing while moving to other pages
    • Continuos carousel
    • Preloading of content
    • Swipes using touch gestures
  • Offline access
  • More engagement than native app
LinkedIn App
Developing Native Apps for Multiple Platforms

We must have:

  • 2008 - iPhone Apps
  • 2009 - Android App
  • 2010 - iPad App
  • 2011 - maintain them ???
Develop, Test and Maintain
Fragmentation of OS Versions
Smartphone Platforms Shares
(units shipped Q4 2011)
Smartphone Browsers Shares
(units shipped Q4 2011)
What is HTML5 ?

1998 - W3C decided they will stop evolving HTML beyond version 4.01

2000 - W3C released XHTML 1.0 and force the world to use XML

2002 - W3C released first draft of XHTML 2.0, no backwards compatibility

2004 - WHATWG started working on HTML v5 (Opera, Mozilla and Apple)

2006 - W3C agrees to use WHATWG proposal for HTML5

2009 - W3C stops works on XHTML 2.0 and resources are diverted to HTML5

Philposphy of HTML5

Philosophy of HTML5

  • Specify undocumented features (e.g. XMLHttpRequest)
  • Browser behaviour with invalid markup
  • Support web applications
  • Define an open standard (opposed to Flash)
  • Don't break the Web


Some additional sepcs at W3C

New semantics
3D, Graphics and Effects
Offline & Storage
Device Access
Performance & Integration
New Semantics
New Semantics

section, header, footer, nav, ...

New Form Controls & Types

date, range, email, url, tel, ...

New Form Validation

by type, required, :valid, :invalid, :required

Offline Storage
Offline Usage
  • Install a package on the device
  • Buggy on some platforms
  • online/offline events
  • iOS full screen metatag
  • Persistent and Session Storage
  • key/value (strings)
  • limited to 5Mb
  • IndexDB and SQL storage

Audio and Video Tags

Javascript API & events

Some codecs supported

3D, Graphics and Effects

2D Canvas API

SVG support


Device Access

Accelerometer / gyroscope / magnetometer

Orientation change

Touch events (touchstart, touchmove, touchend)

File API and File Reader

(Media Camera API)

CSS3 and Styling
New styling

Rounded borders, shadows, opacity

2D & 3D transforms

rotate, scale, skew, translate


basic animations between 2 states

keyframe animations

prefixes (-webkit, -o, -moz, -ms)


Web Sockets

Server-sent Events

Performance & Integration

Notifications API

XMLHttpRequest 2

Web Workers

Browser Support for HTML5
Test your Browser for HTML5 support
Mobile Browsers

Too many

Some are limited

Some are too innovative

Some are proxy based

Most have little documentation

Most have little debugging support

Focus, cursor, touch or multi-touch based

Mobile HTML5 Compatibility Table
Mobile Web Challenges

Server-side detection

Responsive design

Mobile usability

Best experience based on context

Performance optimization

The viewport and pixel density

Data URI - inlining content

HTML5 Frameworks & Tools
Dev Tools
jQuery Mobile Example jQuerySimple
<!DOCTYPE html> 
  <title>Hello World</title> 
  <meta name="viewport" content="width=device-width, initial-scale=1"> 
  <link rel="stylesheet" href="" />
  <script type="text/javascript" src=""></script>
  <script type="text/javascript" src=""></script>
  <div data-role="page">
    <div data-role="header">
      <h1>List of cars</h1>
    </div><!-- /header -->
    <ul data-role="listview" data-inset="true" data-filter="true">
      <li><a href="#">Acura</a></li>
      <li><a href="#">Audi</a></li>
      <li><a href="#">BMW</a></li>
      <li><a href="#">Cadillac</a></li>
      <li><a href="#">Ferrari</a></li>
  </div><!-- /page -->
jQuerySimple on a iPhone and iPad
Sencha Example senchaSimple
<!DOCTYPE html> 
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 
        <title>Hello World</title> 
        <script src="sencha-touch.js" type="text/javascript"></script> 
        <link href="sencha-touch.css" rel="stylesheet" type="text/css" /> 
         <script type="text/javascript"> 
            new Ext.Application({
                launch: function() {
                    var cars = new{
                        model: Ext.regModel('', {fields: ['name', 'link']}),
                        data: [
                            {name: 'Acura', link:'na'},
                            {name: 'Audi', link:'sa'},
                            {name: 'BMW', link:'eu'},
                            {name: 'Cadillac', link:'eu'},
                            {name: 'Ferrari', link:'eu'}
                    new Ext.Panel({
                        fullscreen: true,
                        dockedItems: [{ xtype: 'toolbar', title: 'List of cars', }],
                        items: [{ xtype: 'list', store: cars, itemTpl: '{name}' }]
senchaSimple on a iPhone and iPad
Hey dude, native is better!
  • Is HTML5 a silver bullet ?
    No, but silver bullets don't exist.
  • HTML5 performance is not goot enough ?
    Sometimes, it is not enough.
  • HTML5 is more efficient to develop ?
    Yes, sometimes. Look at FT case.
  • HTML5 lacks good tools
    Changing fast (check Sencha)
  • HTML5 doesn't have an appstore
    Hybrid apps
  • Can HTML5 help in development cost saving ?
Organization of the course

Lectures : Introduction of key concepts, technologies and frameworks

Labs : Hands-on classes with practical exercices on selected topics

Assignment : Team work development of a mobile web app

Lectures & Labs

Lecture 1: Introduction

Lecture 2: Building a Mobile Web App

Lecture 3: Templating and MVC

Lecture 4: File and Device Access

Lecture 5: CSS3 & Canvas

Lecture 6: Websockets & Webworkers

Lecture 7: Developing native apps

Lab 1: Assignment Kick-off

Lab 2: jQuery Mobile

Lab 3: Backbone.js

Lab 4: Device Access

Lab 5: Ruby on Rails 3

Lab 6: Designing REST interfaces

Lab 7: PhoneGap

Course Material and Communication

Slides are available at

The slides are best viewed with Google Chrome

Exercises are available at GitHub

Communication channels:

The Staff

Claudio Riva , Nokia, Main Instructor

Antti Vuorela , Futurice, Course Assistant

Kimmo Karhu , Aalto University, Assignment Coordinator

Häkan Mitts , Aalto University, Program Coordinator

Mikael Blomberg , SC5, jQuery and Backbone Instructor

Matias Korhonen , Kisko Labs, Ruby On Rails Instructor

Lauri Jutila , Kisko Labs, Ruby on Rails Instructor

The Fundamentals


Javascript & Json


Ruby & Sinatra




Start using git

cd yourproject
git init
git clone

Add all files in a directory

git add .

Check status

git status -s


git commit -m "First commit"
git commit -am "First commit"

Show all branches

git branch
git branch -a

Create a new branch

git branch newfeature

Switch branch

git checkout newfeature

Add a remote

git remote add  

View the remotes

git remote -v

Link a local to a remote branch

got branch --track local remote

Fetch changes from remotes

git fetch  

Push changes to remotes

git push  

Review changes between different branches

git log origin/master ^master

Merge changes

git checkout master
git merge origin/master
Must Read: Git Reference
Javascript Event Loop
  • One thread of execution. If a function is blocked, the UI is frozen.
  • Asynchronous operations
  • Blocking I/O operations must not block the UI thread (callbacks)
  • Keep callbacks short and fast
  • Use closures for creating callbacks
Javascript: Asynchronous calls

Javascript has one thread of execution

Blocking operations (e.g. network) must use callbacks

var jqxhr = $.getJSON("example.json", function() {

$('#target').click(function() {
  alert('Handler for .click() called.');
Javascript: Lambda Functions

Lambda functions are created at runtime when the execution reaches that point of the flow. This allows functions to be defined conditionally

Function Declaration
function square(x) {
  return x * x;
var b = square(2); //b gets assigned 4
Function Statement
var square = function(x) {
  return x * x;
var b = square(2); //b gets assigned 4

Lambda functions are normal objects and can be passed as function parameters (e.g. callbacks)

$('#target').click( square );

Javascript: Iterators (jQuery)
$.each : iterates over a list
or a map
var list = [1,2,3,4,5];
var a = $.each(list, function(index, value) {
  alert(index + ": " + value);
}); //It produces 5 alerts
var map = {'a': 'b', 'c': 'd'};
var a = $.each(list, function(key, value) {
  alert(key + ": " + value);
}); //It produces 2 alerts
$.map : applies a function to each element of the array and maps the results into a new array
var list = [1,2,3,4,5];
var a = $.map(list, function(value, index) {
  return square(value);
}; // a gets [1,4,9,16,25]
Javascript: Iterators (underscore.js)
each : _.each (list, iterator, [context])
_.each([1, 2, 3], function(n){ alert(n); });
_.each({one : 1, two : 2, three : 3}, function(n, k){ alert(n); });
map :, iterator, [context]){one : 1, two : 2, three : 3}, function(n, k){ return n*3; });
=> [3, 6, 9]    
reduce : _.reduce(list, iter, memo, [context])
var sum = _.reduce([1, 2, 3], function(memo, n){ return memo + n; }, 0);
=> 6
find : _.find(list, iterator, [context])
_.find([1, 2, 3, 4, 5, 6], function(n){ return n % 2 == 0; });
=> 2
filter : _.filter(list, iterator, [context])
_.filter([1, 2, 3, 4, 5, 6], function(n){ return n % 2 == 0; });
=> [2, 4, 6]
groupBy : _.groupBy(list, iterator)
_.groupBy(['one', 'two', 'three'], 'length');
=> {3: ["one", "two"], 5: ["three"]}
Javascript: Closure

A closure is formed by returning a function object that was created within an execution context of a function call from that function call and assigning a reference to that inner function to a property of another object. Or by directly assigning a reference to such a function object to, for example, a global variable, a property of a globally accessible object or an object passed by reference as an argument to the outer function call ( Closures ).

function closureBuilder(arg1, arg2){  //outer function (builder)
    var localVar = 8;
    function exampleReturned(innerArg){  //inner function 
        return ((arg1 + arg2)/(innerArg + localVar));
    return exampleReturned;  //return a reference to the inner fucntion
var globalVar = closureBuilder(2, 4);
var secondGlobalVar = exampleClosureForm(12, 3);

globalVar(2);   //Result ?
secondGlobalVar(5);   // Result ? 
Javascript: Closure Example with Google Maps
var infoWindow = new google.maps.InfoWindow();

function addInfoWindow(marker, id, name) {
  google.maps.event.addListener(marker, 'click', function () {
      infoWindow.setContent('<p>'+ name + '</p>');, marker);

function addMarkers(json) {
  var markers = [];
  for (i=0; i<json.length; i++) {
      var place = json[i];

      var point = new google.maps.LatLng(place.coordinates[0], place.coordinates[1]);      
      var marker = new google.maps.Marker({position:point,});
      addInfoWindow(marker, place.slug,;
Javascript Object Notation (JSON)

Lightweight data-interchange format

Human readable and easy to comprehend

Easy for machines to parse

  ["first", "second", 3, 4]
Hash table
{"name":"John", "address":"London", "age":38}    
JSON.stringify( ['first', 'second', 3, 4] );
=> ["first","second",3,4]

JSON.parse( ' ["first", "second", 3, 4] ' );
=> Object
jQuery more info

Fast Javascript library for document traversing , event handling , animations and Ajax interactions

  <div id="button">Click me</div>
    $("#button").click( function(event) {
      alert("Button pressed");
Test here: Click me
Ruby Blocks
3.times { puts 'Hello' }
=> 3
array = [1, 2, 3, 4]
array.collect do |n|
  n ** 2
=> [1, 4, 9, 16]
@names = %w(John Anne Lukas)
@names.each do |name|
  puts "Hello #{name}!"
Hello John!
Hello Anne!
Hello Lukas!
=> ["John", "Anne", "Lukas"]    
#iterator for Fibonacci numbers
def fibUpTo(max)
    n1, n2 = 1, 1
    while n1 <= max
        yield n1  # invoke block with value
        n1, n2 = n2, n1+n2  # and calculate next

fibUpTo(1000) { |term| print term, " " }
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987            

a = []  
fibUpTo(1000) { |term| a << term }
=> [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987]         
Sinatra more info

Sinatra is a DSL for quickly creating web applications in Ruby

Single file web app

Runs on Rack (fast Ruby web server)

Supports many template engines

require 'sinatra'

get '/hi' do
  "Hello World!"
Sinatra - HTTP Methods (REST)
get '/' do
  .. show something ..

post '/' do
  .. create something ..

put '/' do
  .. replace something ..

delete '/' do
  .. annihilate something ..
Sinatra - Routes
Simple Routes
get '/hello' do
  'Hello World'
Named parameters
get '/hello/:name' do
  # matches "GET /hello/foo" and "GET /hello/bar"
  # params[:name] is 'foo' or 'bar'
  "Hello #{params[:name]}!"
Sinatra - Views
# erb => renders /views/index.erb (using /views/layout.erb if it exists)
get '/' do 
  erb :index
#haml => renders /views/index.haml embedded in the views/post.haml
get '/' do 
  haml :index, :layout => :post
#Inline templates
get '/' do
  haml '%div.title Hello World'
HAML more info

Template Language

  • Mix Ruby code with HAML
  • Haml generates HTML code


  • Indentation = structure
  • Tags begin with %
  • Tags close themselves
  • Use of hashes for attributes

HAML - Syntax
%tag content
%h1 Hello HAML
%p HAML is 
  %li Beautiful
  %li Easy
  %li Well-indented
<h1>Hello HAML</h1>
<p>HAML is</p>
HAML - Attributes
%a{href => "", id => "title"} 
<a href="" id="title">BBC</a>
%a(href="" id="title") 
<a href="" id="title">BBC</a>
HAML - Shortcuts
%p{class => "bio"} Hello Hello
<p class = "bio">Hello</p>
%p{id=> "title"} Hello
%p#title Hello
<p id = "title">Hello</p>
    %p Hello 
<div id = title>
  <div class = red>
HAML - Ruby Evaluation
%h1 My Blog
- for article in @articles
      %h1= article.title
    .date"%d %m %Y")
      %p= article.body

Browsers on PC with debugging capability:

Mobile Browser Emulators ( guide ):


  • iPhone/iPad: iOS browser
  • Android: native browser, Firefox 11, Chrome for Andorid, Opera Mobile
  • Nokia N9: native browser, Firefox 10, Opera Mobile

Adobe Shadow