Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Advanced JavaScript - Creating modern web appli...
Search
Bastian Hofmann
September 18, 2012
Programming
670
5
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Advanced JavaScript - Creating modern web applications
Web Developer Conference 2012, Hamburg
Bastian Hofmann
September 18, 2012
More Decks by Bastian Hofmann
See All by Bastian Hofmann
Monitoring in Kubernetes with Prometheus and Grafana
bastianhofmann
0
370
Creating a fast Kubernetes Development Workflow
bastianhofmann
0
150
Highly available cross-region deployments with Kubernetes
bastianhofmann
1
180
From source to Kubernetes in 30 minutes
bastianhofmann
0
200
Introduction to Kubernetes
bastianhofmann
1
140
CI/CD with Kubernetes
bastianhofmann
0
250
Creating a fast Kubernetes Development Workflow
bastianhofmann
1
290
Deploying your first Micro-Service application to Kubernetes
bastianhofmann
2
220
Creating a fast Kubernetes Development Workflow
bastianhofmann
0
280
Other Decks in Programming
See All in Programming
DroidKaigi 2026 「個人開発という実験場: Android エンジニアが手にする4つの自由」
slashnephy
0
230
Webの地図
yosuke_furukawa
PRO
6
4.3k
Heart of Swift Concurrency
koher
0
410
Omarchy Tokyo やると聞いて UMPC 買ってセットアップしてきた
mtsmfm
0
140
アクセシビリティから考える情報設計
high_g_engineer
0
370
変化を抱擁するドキュメントの作り方 - ビジネスルール駆動開発がもたらす、コードとの新しい関係
ioki
2
170
新卒PdEのリアル
ryu1013
1
490
AI × TiDD / 2026.09.05 Redmine 大阪
tokudiro
1
140
Vibes Containers 〜AIで変わるコンテナ設計と運用〜
tkikuc
3
530
20260914 AIエージェント時代のPlatform Engineering LLM基盤とプロダクトの責務境界線
kanfab1
6
1.7k
AWS DevOps Agentで インシデント対応をAIに任せたい
honmarkhunt
7
2.8k
AHC070解法紹介
eijirou
0
110
Featured
See All Featured
Navigating the Design Leadership Dip - Product Design Week Design Leaders+ Conference 2024
apolaine
2
430
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
530
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
123
22k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
21
1.6k
The untapped power of vector embeddings
frankvandijk
2
1.9k
WCS-LA-2024
lcolladotor
0
830
How to Build an AI Search Optimization Roadmap - Criteria and Steps to Take #SEOIRL
aleyda
1
2.2k
Jamie Indigo - Trashchat’s Guide to Black Boxes: Technical SEO Tactics for LLMs
techseoconnect
PRO
0
670
Odyssey Design
rkendrick25
PRO
2
800
Leo the Paperboy
mayatellez
9
2.3k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
56
3.5k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
232
55k
Transcript
Advanced JavaScript Creating Modern Web Applications @BastianHofmann
Wtf?
None
None
None
None
None
None
None
None
None
• JavaScript Apps • CORS and OAuth2 • Local Storage
• OEmbed and Caja • WebSockets, ActivityStrea.ms and PubsubHubbub • What‘s next?
None
None
None
None
None
None
None
None
Questions? Ask!
http://speakerdeck.com/u/bastianhofmann
Let‘s write a JS App
https://github.com/bashofmann/statusnet_js_mashup_2nd
https://github.com/bashofmann/vm_js_mashup
CSS Bastian
http://twitter.github.com/bootstrap
History & Bookmarking
www.example.com#Page
www.example.com/Page
http://sammyjs.org/
API Access
None
Same Origin Policy
Cross-Origin Resource Sharing Backend api.twitter.com Client client.net 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 app = Sammy('#main', function() { var feed = [];
this.use(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'); });
<ul> {{#feed}} <li> <p>{{{statusnet_html}}}</p> <p>{{created_at}} {{#user}} {{name}} {{/user}} </p> </li>
{{/feed}} </ul>
Authorization
None
http://oauth.net/
User-Agent Profile
http://twitter.com/authorize?&clientId=... Open Popup lanyrd.com
http://twitter.com/authorize?&clientId=... Open Popup lanyrd.com HTTPS GET twitter.co m/ authorize
http://twitter.com/authorize?&clientId=... Open Popup lanyrd.com Login twitter.co m/ authorize
http://twitter.com/authorize?&clientId=... Open Popup lanyrd.com Grant Permission twitter.co m/ authorize
lanyrd.com HTTPS Redirect RedirectURI# accessToken twitter.co m/ authorize RedirectURI# accessToken
lanyrd.com
lanyrd.com RedirectURI# accessToken Parse Access Token from Fragment Send it
to opening window Close popup lanyrd.com
Same Origin Policy
lanyrd.com HTTPS Ajax Request to API Access Token twitter.com
Storing the access token
Local Storage http://www.w3.org/TR/webstorage/
this.around(function(callback) { ... if (! oauth2.isLoggedIn()) { this.redirect('/Login'); return; }
callback(); });
this.get('/Login', function() { this.partial('login.ms'); });
<form action="/Login" method="post"> <input type="submit" value="Login"/> </form>
this.post('/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>
<form action="/Feed" method="post"> <textarea name="status"></textarea> <inputtype="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['status'] }, success: function() { that.redirect('/'); } }); });
DEMO
Mash it up!
cool video: http://www.youtube.com/ watch?v=OFzkTxiwziQ
OEmbed http://oembed.com/
http://www.youtube.com/watch?v=OyJd2qsRkNk
None
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\"\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 }
cool video:
http://embed.ly/
this.bind('changed', function() { embeds = []; $('div.feed-item h3').embedly({ key:'...', maxWidth:
450, wmode: 'transparent', method: 'after' }); });
None
Caja http://code.google.com/p/google-caja/
html_sanitize(result.html);
DEMO
Instant updates without reloading
PubSubHubbub retrieves Atom feed with Hub URL Hub posts sth
pings every subscriber subscribes for feed acks subscription http://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 Hub posts sth
pings every subscriber subscribes for feed acks subscription http://code.google.com/p/pubsubhubbub/
http://nodejs.org/
HTTP Server for PubsubHubbub
WebSockets http://dev.w3.org/html5/websockets/
socket.io http://socket.io/
(Webkit) Browser Notifications
retrieve Stream with Hub Ajax: request Subscription WebSockets: new Post
subscribe at hub challenge ack new post Notification new post
DEMO
None
Meteor http://www.meteor.com
https://github.com/bashofmann/meteor_shoutbox_demo
DEMO
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
[email protected]