Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Advanced JavaScript - Creating modern web applications

Advanced JavaScript - Creating modern web applications

Web Developer Conference 2012, Hamburg

8e82eb7e128a14a16d642ae55227339b?s=128

Bastian Hofmann

September 18, 2012
Tweet

Transcript

  1. Advanced JavaScript Creating Modern Web Applications @BastianHofmann

  2. Wtf?

  3. None
  4. None
  5. None
  6. None
  7. None
  8. None
  9. None
  10. None
  11. None
  12. • JavaScript Apps • CORS and OAuth2 • Local Storage

    • OEmbed and Caja • WebSockets, ActivityStrea.ms and PubsubHubbub • What‘s next?
  13. None
  14. None
  15. None
  16. None
  17. None
  18. None
  19. None
  20. None
  21. Questions? Ask!

  22. http://speakerdeck.com/u/bastianhofmann

  23. Let‘s write a JS App

  24. https://github.com/bashofmann/statusnet_js_mashup_2nd

  25. https://github.com/bashofmann/vm_js_mashup

  26. CSS Bastian

  27. http://twitter.github.com/bootstrap

  28. History & Bookmarking

  29. www.example.com#Page

  30. www.example.com/Page

  31. http://sammyjs.org/

  32. API Access

  33. None
  34. Same Origin Policy

  35. Cross-Origin Resource Sharing Backend api.twitter.com Client client.net AJAX Access-Control-Allow-Origin: *

    http://www.w3.org/TR/cors/
  36. 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?
  37. Templates

  38. Mustache.JS https://github.com/janl/mustache.js }

  39. var app = Sammy('#main', function() { var feed = [];

    this.use(Mustache, 'ms'); this.get('/', function() { this.trigger('getFeed'); }); ... }); jQuery(function() { app.run(); });
  40. 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'); });
  41. <ul> {{#feed}} <li> <p>{{{statusnet_html}}}</p> <p>{{created_at}} {{#user}} {{name}} {{/user}} </p> </li>

    {{/feed}} </ul>
  42. Authorization

  43. None
  44. http://oauth.net/

  45. User-Agent Profile

  46. http://twitter.com/authorize?&clientId=... Open Popup lanyrd.com

  47. http://twitter.com/authorize?&clientId=... Open Popup lanyrd.com HTTPS GET twitter.co m/ authorize

  48. http://twitter.com/authorize?&clientId=... Open Popup lanyrd.com Login twitter.co m/ authorize

  49. http://twitter.com/authorize?&clientId=... Open Popup lanyrd.com Grant Permission twitter.co m/ authorize

  50. lanyrd.com HTTPS Redirect RedirectURI# accessToken twitter.co m/ authorize RedirectURI# accessToken

    lanyrd.com
  51. lanyrd.com RedirectURI# accessToken Parse Access Token from Fragment Send it

    to opening window Close popup lanyrd.com
  52. Same Origin Policy

  53. lanyrd.com HTTPS Ajax Request to API Access Token twitter.com

  54. Storing the access token

  55. Local Storage http://www.w3.org/TR/webstorage/

  56. this.around(function(callback) { ... if (! oauth2.isLoggedIn()) { this.redirect('/Login'); return; }

    callback(); });
  57. this.get('/Login', function() { this.partial('login.ms'); });

  58. <form action="/Login" method="post"> <input type="submit" value="Login"/> </form>

  59. this.post('/Login', function() { var consumerKey = 'abc....'; window.open('http://status.net/api/oauth2/ authorize?response_toke=token&client_id=' +

    consumerKey); });
  60. <script type="text/javascript"> var fragment = location.hash.substr(1); opener.parent.oauth2.storeToken(fragment); window.close(); </script>

  61. <form action="/Feed" method="post"> <textarea name="status"></textarea> <inputtype="submit" value="send"/> </form>

  62. 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['status'] }, success: function() { that.redirect('/'); } }); });
  63. DEMO

  64. Mash it up!

  65. cool video: http://www.youtube.com/ watch?v=OFzkTxiwziQ

  66. OEmbed http://oembed.com/

  67. http://www.youtube.com/watch?v=OyJd2qsRkNk

  68. None
  69. http://www.youtube.com/oembed?url=http%3A%2F %2Fwww.youtube.com%2Fwatch%3Fv %3DOyJd2qsRkNk&maxwidth=500&format=json

  70. { "provider_url":"http:\/\/www.youtube.com\/", "title":"Jupiter Jones - Das Jahr in dem ich

    schlief (Musik Video)", "html":"\u003cobject width=\"500\" height=\"306\"\u003e \u003cparam name=\"movie\" value=\"http:\/\/www.youtube.com\/v\/ OyJd2qsRkNk?version=3\"\u003e\u003c\/param\u003e\u003cparam name= \"allowFullScreen\" value=\"true\"\u003e\u003c\/param\u003e \u003cparam name=\"allowscriptaccess\" value=\"always\"\u003e \u003c\/param\u003e\u003cembed src=\"http:\/\/www.youtube.com\/v\/ OyJd2qsRkNk?version=3\" type=\"application\/x-shockwave-flash \" width=\"500\" height=\"306\" allowscriptaccess=\"always \" allowfullscreen=\"true\"\u003e\u003c\/embed\u003e\u003c\/object \u003e", "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 }
  71. cool video:

  72. http://embed.ly/

  73. this.bind('changed', function() { embeds = []; $('div.feed-item h3').embedly({ key:'...', maxWidth:

    450, wmode: 'transparent', method: 'after' }); });
  74. None
  75. Caja http://code.google.com/p/google-caja/

  76. html_sanitize(result.html);

  77. DEMO

  78. Instant updates without reloading

  79. PubSubHubbub retrieves Atom feed with Hub URL Hub posts sth

    pings every subscriber subscribes for feed acks subscription http://code.google.com/p/pubsubhubbub/
  80. <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)"/>

  81. <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>
  82. http://activitystrea.ms/

  83. <link href="http://status.net.xyz:8061/ index.php/main/push/hub" rel="hub"/>

  84. PubSubHubbub retrieves Atom feed with Hub URL Hub posts sth

    pings every subscriber subscribes for feed acks subscription http://code.google.com/p/pubsubhubbub/
  85. http://nodejs.org/

  86. HTTP Server for PubsubHubbub

  87. WebSockets http://dev.w3.org/html5/websockets/

  88. socket.io http://socket.io/

  89. (Webkit) Browser Notifications

  90. retrieve Stream with Hub Ajax: request Subscription WebSockets: new Post

    subscribe at hub challenge ack new post Notification new post
  91. DEMO

  92. None
  93. Meteor http://www.meteor.com

  94. https://github.com/bashofmann/meteor_shoutbox_demo

  95. DEMO

  96. h"p://twi"er.com/Bas2anHofmann h"p://profiles.google.com/bashofmann h"p://lanyrd.com/people/Bas2anHofmann h"p://speakerdeck.com/u/bas2anhofmann h"ps://github.com/bashofmann mail@bas2anhofmann.de