• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Mashing up JavaScript – Advanced Techniques for modern Web Apps
 

Mashing up JavaScript – Advanced Techniques for modern Web Apps

on

  • 4,668 views

My Mashing up JavaScript presentation from OSCON

My Mashing up JavaScript presentation from OSCON

Statistics

Views

Total Views
4,668
Views on SlideShare
4,538
Embed Views
130

Actions

Likes
0
Downloads
25
Comments
0

2 Embeds 130

http://www.oscon.com 70
http://lanyrd.com 60

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Mashing up JavaScript – Advanced Techniques for modern Web Apps Mashing up JavaScript – Advanced Techniques for modern Web Apps Presentation Transcript

    • Mashing up JavaScriptAdvanced techniques for modern webapplicationsBastian HofmannVZnet Netzwerke Ltd.
    • Wtf?
    • • JavaScript Apps• CORS and OAuth2• Local Storage• OEmbed and Caja• WebSockets, ActivityStrea.ms and PubsubHubbub
    • http://slideshare.net/bashofmann
    • https://github.com/bashofmann/statusnet_js_mashup
    • Let‘s write a JS App
    • History & Bookmarking
    • www.example.com#Page
    • http://sammyjs.org/
    • API Access
    • Same Origin Policy
    • Cross-Origin Resource SharingClient Backendclient.net api.twitter.com AJAX Access-Control-Allow-Origin: * http://www.w3.org/TR/cors/
    • var html="<ul>";for (var i=0; i < viewers.length; i++) {   html += "<li>" + viewers[i].displayName+ "</li>";}html += "<ul>";document.getElementById("#div").innerHTML =html; Where is the error?
    • Templates
    • Mustache.JS} https://github.com/janl/mustache.js
    • var feed = [];var app = Sammy(#main, function() { this.use(Sammy.Mustache, ms); this.get(#/, function() { this.trigger(getFeed); }); ...});jQuery(function() { app.run(#/);});
    • var feed = [];var app = Sammy(#main, function() { this.use(Sammy.Mustache, ms); this.get(#/, function() { this.trigger(getFeed); }); ...});jQuery(function() { app.run(#/);});
    • var feed = [];var app = Sammy(#main, function() { this.use(Sammy.Mustache, ms); this.get(#/, function() { this.trigger(getFeed); }); ...});jQuery(function() { app.run(#/);});
    • var feed = [];var app = Sammy(#main, function() { this.use(Sammy.Mustache, ms); this.get(#/, function() { this.trigger(getFeed); }); ...});jQuery(function() { app.run(#/);});
    • var feed = [];var app = Sammy(#main, function() { this.use(Sammy.Mustache, ms); this.get(#/, function() { this.trigger(getFeed); }); ...});jQuery(function() { app.run(#/);});
    • this.bind(getFeed, function() { var that = this; $.ajax({ url: http://..._timeline.json, success: function(response) { feed = response; that.trigger(renderFeed); } });});this.bind(renderFeed, function() { this.feed = feed; this.partial(js/templates/feed.ms);});
    • this.bind(getFeed, function() { var that = this; $.ajax({ url: http://..._timeline.json, success: function(response) { feed = response; that.trigger(renderFeed); } });});this.bind(renderFeed, function() { this.feed = feed; this.partial(js/templates/feed.ms);});
    • this.bind(getFeed, function() { var that = this; $.ajax({ url: http://..._timeline.json, success: function(response) { feed = response; that.trigger(renderFeed); } });});this.bind(renderFeed, function() { this.feed = feed; this.partial(js/templates/feed.ms);});
    • this.bind(getFeed, function() { var that = this; $.ajax({ url: http://..._timeline.json, success: function(response) { feed = response; that.trigger(renderFeed); } });});this.bind(renderFeed, function() { this.feed = feed; this.partial(js/templates/feed.ms);});
    • this.bind(getFeed, function() { var that = this; $.ajax({ url: http://..._timeline.json, success: function(response) { feed = response; that.trigger(renderFeed); } });});this.bind(renderFeed, function() { this.feed = feed; this.partial(js/templates/feed.ms);});
    • this.bind(getFeed, function() { var that = this; $.ajax({ url: http://..._timeline.json, success: function(response) { feed = response; that.trigger(renderFeed); } });});this.bind(renderFeed, function() { this.feed = feed; this.partial(js/templates/feed.ms);});
    • <ul>{{#feed}} <li> <p>{{{statusnet_html}}}</p> <p>{{created_at}} {{#user}} {{name}} {{/user}} </p> </li>{{/feed}}</ul>
    • <ul>{{#feed}} <li> <p>{{{statusnet_html}}}</p> <p>{{created_at}} {{#user}} {{name}} {{/user}} </p> </li>{{/feed}}</ul>
    • <ul>{{#feed}} <li> <p>{{{statusnet_html}}}</p> <p>{{created_at}} {{#user}} {{name}} {{/user}} </p> </li>{{/feed}}</ul>
    • <ul>{{#feed}} <li> <p>{{{statusnet_html}}}</p> <p>{{created_at}} {{#user}} {{name}} {{/user}} </p> </li>{{/feed}}</ul>
    • DEMO
    • Authorization
    • OAuth 2 +----------+ Client Identifier +----------------+ | |>---(A)-- & Redirection URI --->| | | | | |End <--+ - - - +----(B)-- User authenticates -->| Authorization |User | | | Server | | |<---(C)--- Redirect URI -------<| | | Client | with Access Token | | | in | in Fragment +----------------+ | Browser | | | +----------------+ | |>---(D)--- Redirect URI ------->| | | | without Fragment | Web Server | | | | with Client | | (F) |<---(E)--- Web Page with ------<| Resource | | Access | Script | | | Token | +----------------+ +----------+ http://tools.ietf.org/html/draft-ietf-oauth-v2
    • this.bind(getFeed, function() { oauth2.retrieveAccessToken(); if (! oauth2.store[access_token]) { this.redirect(#Login); return; } ...});
    • this.bind(getFeed, function() { oauth2.retrieveAccessToken(); if (! oauth2.store[access_token]) { this.redirect(#Login); return; } ...});
    • this.get(#Login, function() { var consumerKey = abc....; window.open(http://status.net/api/oauth2/authorize?response_toke=token&client_id= +consumerKey);});
    • this.get(#Login, function() { var consumerKey = abc....; window.open(http://status.net/api/oauth2/authorize?response_toke=token&client_id= +consumerKey);});
    • <script type="text/javascript"> var fragment = location.hash.substr(1); opener.parent.oauth2.storeToken(fragment); window.close();</script>
    • <script type="text/javascript"> var fragment = location.hash.substr(1); opener.parent.oauth2.storeToken(fragment); window.close();</script>
    • <script type="text/javascript"> var fragment = location.hash.substr(1); opener.parent.oauth2.storeToken(fragment); window.close();</script>
    • <form action="#Entry" method="post"> <textarea name="comment"></textarea> <input type="submit" value="send"/></form>
    • <form action="#Entry" method="post"> <textarea name="comment"></textarea> <input type="submit" value="send"/></form>
    • <form action="#Entry" method="post"> <textarea name="comment"></textarea> <input type="submit" value="send"/></form>
    • this.post(#Entry, function() { var that = this; $.ajax({ url: http://status.net/.../update.json?oauth_token= + oauth2.store[access_token], type: POST, data: { status: that.params[comment] }, success: function() { that.redirect(#/); } }); });
    • this.post(#Entry, function() { var that = this; $.ajax({ url: http://status.net/.../update.json?oauth_token= + oauth2.store[access_token], type: POST, data: { status: that.params[comment] }, success: function() { that.redirect(#/); } }); });
    • this.post(#Entry, function() { var that = this; $.ajax({ url: http://status.net/.../update.json?oauth_token= + oauth2.store[access_token], type: POST, data: { status: that.params[comment] }, success: function() { that.redirect(#/); } }); });
    • this.post(#Entry, function() { var that = this; $.ajax({ url: http://status.net/.../update.json?oauth_token= + oauth2.store[access_token], type: POST, data: { status: that.params[comment] }, success: function() { that.redirect(#/); } }); });
    • this.post(#Entry, function() { var that = this; $.ajax({ url: http://status.net/.../update.json?oauth_token= + oauth2.store[access_token], type: POST, data: { status: that.params[comment] }, success: function() { that.redirect(#/); } }); });
    • this.post(#Entry, function() { var that = this; $.ajax({ url: http://status.net/.../update.json?oauth_token= + oauth2.store[access_token], type: POST, data: { status: that.params[comment] }, success: function() { that.redirect(#/); } }); });
    • Storing the access token
    • Local Storage http://www.w3.org/TR/webstorage/
    • localStorage.setItem("key", value);
    • localStorage.getItem("key");
    • DEMO
    • Mash it up!
    • cool video:http://www.youtube.com/watch?v=OFzkTxiwziQ
    • OEmbed http://oembed.com/
    • http://www.youtube.com/watch?v=OyJd2qsRkNk
    • http://www.youtube.com/oembed?url=http%3A%2F %2Fwww.youtube.com%2Fwatch%3Fv %3DOyJd2qsRkNk&maxwidth=500&format=json
    • {  "provider_url":"http://www.youtube.com/",  "title":"Jupiter Jones - Das Jahr in dem ich schlief (Musik Video)",  "html":"u003cobject width="500" height="306"u003eu003cparam name="movie" value="http://www.youtube.com/v/OyJd2qsRkNk?version=3"u003eu003c/paramu003eu003cparam name="allowFullScreen" value="true"u003eu003c/paramu003eu003cparam name="allowscriptaccess" value="always"u003eu003c/paramu003eu003cembed src="http://www.youtube.com/v/OyJd2qsRkNk?version=3" type="application/x-shockwave-flash" width="500" height="306" allowscriptaccess="always" allowfullscreen="true"u003eu003c/embedu003eu003c/objectu003e",  "author_name":"St182",  "height":306,  "thumbnail_width":480,  "width":500,  "version":"1.0",  "author_url":"http://www.youtube.com/user/Stinkfist182",  "provider_name":"YouTube",  "thumbnail_url":"http://i4.ytimg.com/vi/OyJd2qsRkNk/hqdefault.jpg",  "type":"video",  "thumbnail_height":360}
    • cool video:
    • http://embed.ly/
    • Cajahttp://code.google.com/p/google-caja/
    • html_sanitize(‘<script>alert(“foo“);</script>‘)
    • DEMO
    • Instant updates without reloading
    • PubSubHubbub retrieves Atom feed with Hub URL subscribes for feed acks Hub subscription pings every posts sth subscriberhttp://code.google.com/p/pubsubhubbub/
    • <link rel="alternate"href="http://status.net.xyz:8061/index.php/api/statuses/user_timeline/3.atom"type="application/atom+xml" title="Notice feed for bastian(Atom)"/>
    • <entry> <activity:object-type>http://activitystrea.ms/schema/1.0/note</activity:object-type> <id>http://status.net.xyz:8061/index.php/notice/20</id> <title>hello from client</title> <content type="html">hello from client</content> <link rel="alternate" type="text/html" href="http://status.net.xyz:8061/index.php/notice/20"/> <activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb> <published>2011-05-23T21:07:33+00:00</published> <updated>2011-05-23T21:07:33+00:00</updated> <link rel="ostatus:conversation" href="http://status.net.xyz:8061/index.php/conversation/20"/> <georss:point>52.52437 13.41053</georss:point> <link rel="self" type="application/atom+xml"href="http://status.net.xyz:8061/index.php/api/statuses/show/20.atom"/> <link rel="edit" type="application/atom+xml"href="http://status.net.xyz:8061/index.php/api/statuses/show/20.atom"/> <statusnet:notice_info local_id="20" source="api"favorite="false"repeated="false"></statusnet:notice_info></entry>
    • http://activitystrea.ms/
    • <link href="http://status.net.xyz:8061/index.php/main/push/hub" rel="hub"/>
    • PubSubHubbub retrieves Atom feed with Hub URL subscribes for feed acks Hub subscription pings every posts sth subscriberhttp://code.google.com/p/pubsubhubbub/
    • http://nodejs.org/
    • WebSockets http://dev.w3.org/html5/websockets/
    • socket.io http://socket.io/
    • Browser Notifications
    • webkitNotifications.createNotification(image,title, text).show();
    • webkitNotifications.requestPermission();
    • Notification retrieve Stream with HubAjax: request WebSockets:Subscription new Post subscribe at hub challenge ack new post new post
    • DEMO
    • Rate and Comment http://bit.ly/oscon_js_mashup
    • h"p://twi"er.com/Bas2anHofmannh"p://profiles.google.com/bashofmannh"p://lanyrd.com/people/Bas2anHofmann/h"p://slideshare.net/bashofmannmail@bas2anhofmann.de