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   ...
var html="<ul>";for (var i=0; i < viewers.length; i++) {   html += "<li>" + viewers[i].displayName+ "</li>";}html += "<ul>...
Templates
Mustache.JS} https://github.com/janl/mustache.js
var feed = [];var app = Sammy(#main, function() {    this.use(Sammy.Mustache, ms);    this.get(#/, function() {        thi...
var feed = [];var app = Sammy(#main, function() {    this.use(Sammy.Mustache, ms);    this.get(#/, function() {        thi...
var feed = [];var app = Sammy(#main, function() {    this.use(Sammy.Mustache, ms);    this.get(#/, function() {        thi...
var feed = [];var app = Sammy(#main, function() {    this.use(Sammy.Mustache, ms);    this.get(#/, function() {        thi...
var feed = [];var app = Sammy(#main, function() {    this.use(Sammy.Mustache, ms);    this.get(#/, function() {        thi...
this.bind(getFeed, function() {    var that = this;    $.ajax({      url: http://..._timeline.json,      success: function...
this.bind(getFeed, function() {    var that = this;    $.ajax({      url: http://..._timeline.json,      success: function...
this.bind(getFeed, function() {    var that = this;    $.ajax({      url: http://..._timeline.json,      success: function...
this.bind(getFeed, function() {    var that = this;    $.ajax({      url: http://..._timeline.json,      success: function...
this.bind(getFeed, function() {    var that = this;    $.ajax({      url: http://..._timeline.json,      success: function...
this.bind(getFeed, function() {    var that = this;    $.ajax({      url: http://..._timeline.json,      success: function...
<ul>{{#feed}}  <li>       <p>{{{statusnet_html}}}</p>       <p>{{created_at}}            {{#user}}            {{name}}    ...
<ul>{{#feed}}  <li>       <p>{{{statusnet_html}}}</p>       <p>{{created_at}}            {{#user}}            {{name}}    ...
<ul>{{#feed}}  <li>       <p>{{{statusnet_html}}}</p>       <p>{{created_at}}            {{#user}}            {{name}}    ...
<ul>{{#feed}}  <li>       <p>{{{statusnet_html}}}</p>       <p>{{created_at}}            {{#user}}            {{name}}    ...
DEMO
Authorization
OAuth 2       +----------+          Client Identifier     +----------------+       |          |>---(A)-- & Redirection URI...
this.bind(getFeed, function() {    oauth2.retrieveAccessToken();    if (! oauth2.store[access_token]) {        this.redire...
this.bind(getFeed, function() {    oauth2.retrieveAccessToken();    if (! oauth2.store[access_token]) {        this.redire...
this.get(#Login, function() {  var consumerKey = abc....;  window.open(http://status.net/api/oauth2/authorize?response_tok...
this.get(#Login, function() {  var consumerKey = abc....;  window.open(http://status.net/api/oauth2/authorize?response_tok...
<script type="text/javascript">  var fragment = location.hash.substr(1);  opener.parent.oauth2.storeToken(fragment);  wind...
<script type="text/javascript">  var fragment = location.hash.substr(1);  opener.parent.oauth2.storeToken(fragment);  wind...
<script type="text/javascript">  var fragment = location.hash.substr(1);  opener.parent.oauth2.storeToken(fragment);  wind...
<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?o...
this.post(#Entry, function() {        var that = this;        $.ajax({            url: http://status.net/.../update.json?o...
this.post(#Entry, function() {        var that = this;        $.ajax({            url: http://status.net/.../update.json?o...
this.post(#Entry, function() {        var that = this;        $.ajax({            url: http://status.net/.../update.json?o...
this.post(#Entry, function() {        var that = this;        $.ajax({            url: http://status.net/.../update.json?o...
this.post(#Entry, function() {        var that = this;        $.ajax({            url: http://status.net/.../update.json?o...
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"...
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          ...
<link rel="alternate"href="http://status.net.xyz:8061/index.php/api/statuses/user_timeline/3.atom"type="application/atom+x...
<entry> <activity:object-type>http://activitystrea.ms/schema/1.0/note</activity:object-type> <id>http://status.net.xyz:806...
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          ...
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     ...
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.ne...
Mashing up JavaScript – Advanced Techniques for modern Web Apps
Mashing up JavaScript – Advanced Techniques for modern Web Apps
Mashing up JavaScript – Advanced Techniques for modern Web Apps
Mashing up JavaScript – Advanced Techniques for modern Web Apps
Mashing up JavaScript – Advanced Techniques for modern Web Apps
Mashing up JavaScript – Advanced Techniques for modern Web Apps
Mashing up JavaScript – Advanced Techniques for modern Web Apps
Mashing up JavaScript – Advanced Techniques for modern Web Apps
Mashing up JavaScript – Advanced Techniques for modern Web Apps
Mashing up JavaScript – Advanced Techniques for modern Web Apps
Mashing up JavaScript – Advanced Techniques for modern Web Apps
Mashing up JavaScript – Advanced Techniques for modern Web Apps
Mashing up JavaScript – Advanced Techniques for modern Web Apps
Mashing up JavaScript – Advanced Techniques for modern Web Apps
Mashing up JavaScript – Advanced Techniques for modern Web Apps
Upcoming SlideShare
Loading in...5
×

Mashing up JavaScript – Advanced Techniques for modern Web Apps

5,837

Published on

My Mashing up JavaScript presentation from OSCON

Published in: Technology, Business
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
5,837
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
26
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Mashing up JavaScript – Advanced Techniques for modern Web Apps

  1. 1. Mashing up JavaScriptAdvanced techniques for modern webapplicationsBastian HofmannVZnet Netzwerke Ltd.
  2. 2. Wtf?
  3. 3. • JavaScript Apps• CORS and OAuth2• Local Storage• OEmbed and Caja• WebSockets, ActivityStrea.ms and PubsubHubbub
  4. 4. http://slideshare.net/bashofmann
  5. 5. https://github.com/bashofmann/statusnet_js_mashup
  6. 6. Let‘s write a JS App
  7. 7. History & Bookmarking
  8. 8. www.example.com#Page
  9. 9. http://sammyjs.org/
  10. 10. API Access
  11. 11. Same Origin Policy
  12. 12. Cross-Origin Resource SharingClient Backendclient.net api.twitter.com AJAX Access-Control-Allow-Origin: * http://www.w3.org/TR/cors/
  13. 13. 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?
  14. 14. Templates
  15. 15. Mustache.JS} https://github.com/janl/mustache.js
  16. 16. var feed = [];var app = Sammy(#main, function() { this.use(Sammy.Mustache, ms); this.get(#/, function() { this.trigger(getFeed); }); ...});jQuery(function() { app.run(#/);});
  17. 17. var feed = [];var app = Sammy(#main, function() { this.use(Sammy.Mustache, ms); this.get(#/, function() { this.trigger(getFeed); }); ...});jQuery(function() { app.run(#/);});
  18. 18. var feed = [];var app = Sammy(#main, function() { this.use(Sammy.Mustache, ms); this.get(#/, function() { this.trigger(getFeed); }); ...});jQuery(function() { app.run(#/);});
  19. 19. var feed = [];var app = Sammy(#main, function() { this.use(Sammy.Mustache, ms); this.get(#/, function() { this.trigger(getFeed); }); ...});jQuery(function() { app.run(#/);});
  20. 20. var feed = [];var app = Sammy(#main, function() { this.use(Sammy.Mustache, ms); this.get(#/, function() { this.trigger(getFeed); }); ...});jQuery(function() { app.run(#/);});
  21. 21. 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);});
  22. 22. 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);});
  23. 23. 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);});
  24. 24. 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);});
  25. 25. 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);});
  26. 26. 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);});
  27. 27. <ul>{{#feed}} <li> <p>{{{statusnet_html}}}</p> <p>{{created_at}} {{#user}} {{name}} {{/user}} </p> </li>{{/feed}}</ul>
  28. 28. <ul>{{#feed}} <li> <p>{{{statusnet_html}}}</p> <p>{{created_at}} {{#user}} {{name}} {{/user}} </p> </li>{{/feed}}</ul>
  29. 29. <ul>{{#feed}} <li> <p>{{{statusnet_html}}}</p> <p>{{created_at}} {{#user}} {{name}} {{/user}} </p> </li>{{/feed}}</ul>
  30. 30. <ul>{{#feed}} <li> <p>{{{statusnet_html}}}</p> <p>{{created_at}} {{#user}} {{name}} {{/user}} </p> </li>{{/feed}}</ul>
  31. 31. DEMO
  32. 32. Authorization
  33. 33. 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
  34. 34. this.bind(getFeed, function() { oauth2.retrieveAccessToken(); if (! oauth2.store[access_token]) { this.redirect(#Login); return; } ...});
  35. 35. this.bind(getFeed, function() { oauth2.retrieveAccessToken(); if (! oauth2.store[access_token]) { this.redirect(#Login); return; } ...});
  36. 36. this.get(#Login, function() { var consumerKey = abc....; window.open(http://status.net/api/oauth2/authorize?response_toke=token&client_id= +consumerKey);});
  37. 37. this.get(#Login, function() { var consumerKey = abc....; window.open(http://status.net/api/oauth2/authorize?response_toke=token&client_id= +consumerKey);});
  38. 38. <script type="text/javascript"> var fragment = location.hash.substr(1); opener.parent.oauth2.storeToken(fragment); window.close();</script>
  39. 39. <script type="text/javascript"> var fragment = location.hash.substr(1); opener.parent.oauth2.storeToken(fragment); window.close();</script>
  40. 40. <script type="text/javascript"> var fragment = location.hash.substr(1); opener.parent.oauth2.storeToken(fragment); window.close();</script>
  41. 41. <form action="#Entry" method="post"> <textarea name="comment"></textarea> <input type="submit" value="send"/></form>
  42. 42. <form action="#Entry" method="post"> <textarea name="comment"></textarea> <input type="submit" value="send"/></form>
  43. 43. <form action="#Entry" method="post"> <textarea name="comment"></textarea> <input type="submit" value="send"/></form>
  44. 44. 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(#/); } }); });
  45. 45. 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(#/); } }); });
  46. 46. 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(#/); } }); });
  47. 47. 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(#/); } }); });
  48. 48. 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(#/); } }); });
  49. 49. 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(#/); } }); });
  50. 50. Storing the access token
  51. 51. Local Storage http://www.w3.org/TR/webstorage/
  52. 52. localStorage.setItem("key", value);
  53. 53. localStorage.getItem("key");
  54. 54. DEMO
  55. 55. Mash it up!
  56. 56. cool video:http://www.youtube.com/watch?v=OFzkTxiwziQ
  57. 57. OEmbed http://oembed.com/
  58. 58. http://www.youtube.com/watch?v=OyJd2qsRkNk
  59. 59. http://www.youtube.com/oembed?url=http%3A%2F %2Fwww.youtube.com%2Fwatch%3Fv %3DOyJd2qsRkNk&maxwidth=500&format=json
  60. 60. {  "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}
  61. 61. cool video:
  62. 62. http://embed.ly/
  63. 63. Cajahttp://code.google.com/p/google-caja/
  64. 64. html_sanitize(‘<script>alert(“foo“);</script>‘)
  65. 65. DEMO
  66. 66. Instant updates without reloading
  67. 67. PubSubHubbub retrieves Atom feed with Hub URL subscribes for feed acks Hub subscription pings every posts sth subscriberhttp://code.google.com/p/pubsubhubbub/
  68. 68. <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)"/>
  69. 69. <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>
  70. 70. http://activitystrea.ms/
  71. 71. <link href="http://status.net.xyz:8061/index.php/main/push/hub" rel="hub"/>
  72. 72. PubSubHubbub retrieves Atom feed with Hub URL subscribes for feed acks Hub subscription pings every posts sth subscriberhttp://code.google.com/p/pubsubhubbub/
  73. 73. http://nodejs.org/
  74. 74. WebSockets http://dev.w3.org/html5/websockets/
  75. 75. socket.io http://socket.io/
  76. 76. Browser Notifications
  77. 77. webkitNotifications.createNotification(image,title, text).show();
  78. 78. webkitNotifications.requestPermission();
  79. 79. Notification retrieve Stream with HubAjax: request WebSockets:Subscription new Post subscribe at hub challenge ack new post new post
  80. 80. DEMO
  81. 81. Rate and Comment http://bit.ly/oscon_js_mashup
  82. 82. h"p://twi"er.com/Bas2anHofmannh"p://profiles.google.com/bashofmannh"p://lanyrd.com/people/Bas2anHofmann/h"p://slideshare.net/bashofmannmail@bas2anhofmann.de
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×