Create a gist now

Instantly share code, notes, and snippets.

HTML History API
#!/usr/bin/env ruby
# -*- ruby-mode -*-
=begin
An example of using the HTML5 history API to avoid page reloads.
Setup:
$ gem install sinatra haml
=end
require 'rubygems' if RUBY_VERSION < '1.9'
require 'sinatra'
require 'haml'
MAX_NUMBER = 100
get %r{^/(\d*)$} do
@number = params[ :captures ].first
@number = '1' if @number.empty?
@number = @number.to_i
@number = 1 if @number < 1
@number = MAX_NUMBER if @number > MAX_NUMBER
if request.xhr?
haml :number, :layout => false
else
haml :show
end
end
get '/history_api.js' do
content_type 'application/javascript'
<<EOT
$( document ).ready( function() {
$( '#menu a' ).click( function() {
var anchor = this;
$.get( this.href, function( data ) {
history.pushState( data, '', anchor.href );
$( '#container' ).html( data );
updateLinks( anchor.getAttribute( 'data-number' ) );
} );
return false; // Stop event bubbling
} );
} );
onpopstate = function( event ) {
$( '#container' ).html( event.state );
};
function updateLinks( number ) {
number = 1 * number;
var prev = ( number > 1 ) ? number - 1 : 1;
var next = ( number < 100 ) ? number + 1 : 100;
$( '#prev' ).attr( { href: '/' + prev, 'data-number': prev } );
$( '#next' ).attr( { href: '/' + next, 'data-number': next } );
}
EOT
end
template :layout do
<<EOT
%html
%head
%script{ :src => 'http://code.jquery.com/jquery-1.4.2.min.js' }
%script{ :src => '/history_api.js' }
%body
= yield
EOT
end
template :show do
<<EOT
%h1 HTML5 History API Example
%div#menu
!= link_to( '&lt;&lt;', 1 )
!= link_to( '&lt;', @number - 1, :id => 'prev' )
!= link_to( '&gt;', @number + 1, :id => 'next' )
!= link_to( '&gt;&gt;', MAX_NUMBER )
#container
= haml :number
%script
// Seed the initial state
!= "history.replaceState( $( '#container' ).html(), '', location.href );"
EOT
end
template :number do
'= "This is page " + @number.to_s'
end
def link_to( text, number, options = {} )
h = options.merge!( :href => "/#{ number }", :'data-number' => number ).inspect
haml "%a{ #{ h } } #{ text }"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment