Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Mashing up JavaScript
Search
Bastian Hofmann
July 19, 2012
Programming
770
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Mashing up JavaScript
Bastian Hofmann
July 19, 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
170
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
210
Creating a fast Kubernetes Development Workflow
bastianhofmann
0
280
Other Decks in Programming
See All in Programming
夏だ!祭りだ!祭りとはドメインモデリングでは?
ryugen04
0
340
ソフトウェアエンジニアにとっての生成AI - 特性を知って使い倒す / generative ai for software enginner
kishida
7
2k
為什麼你並不需要ViewModel / No, you don't need a ViewModel
lovee
1
500
片田舎のおっさん、 Swift Buildのダイアモンド問題解決の不具合修正PRを出すが、解決方法がキャッシュをしないようにすることであり、ビルド時間が伸びると言われてマージされないので高速化もする/swiftbuild
yimajo
0
200
自動化したのに回らないテスト運用の壁ーAI時代の品質責任と生産性
mfunaki
1
140
全PRの83%がAIレビューだけでマージできるようになった開発組織はその後どうなったか
athug
1
1.9k
リアルな遅延を測る仕様
kota_yata
1
120
楽しそうなつよつよエンジニアと目が死んでる僕/A brilliant engineer having a blast, and dead-eyed me.
3l4l5
2
200
Dockerfile CMD for Node.js
grazie1999
0
110
<title><a id="</title>君はこのHTMLをパースできるか"></a></title> #雑LT_study
pizzacat83
0
160
freee が目指す データ マネジメント戦略 AI-Ready 時代を支える 攻めのガバナンスとは
freee
PRO
0
440
React本体のコードリーディング
high_g_engineer
1
150
Featured
See All Featured
<Decoding/> the Language of Devs - We Love SEO 2024
nikkihalliwell
1
290
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
230
23k
Agile that works and the tools we love
rasmusluckow
331
22k
Measuring & Analyzing Core Web Vitals
bluesmoon
9
970
How to Grow Your eCommerce with AI & Automation
katarinadahlin
PRO
1
250
New Earth Scene 8
popppiees
3
2.5k
Believing is Seeing
oripsolob
1
190
The Director’s Chair: Orchestrating AI for Truly Effective Learning
tmiket
1
270
Bridging the Design Gap: How Collaborative Modelling removes blockers to flow between stakeholders and teams @FastFlow conf
baasie
0
660
DBのスキルで生き残る技術 - AI時代におけるテーブル設計の勘所
soudai
PRO
68
57k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
508
140k
How STYLIGHT went responsive
nonsquared
100
6.2k
Transcript
Mashing up JavaScript @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
http://speakerdeck.com/u/bastianhofmann
Let‘s write a JS App
https://github.com/bashofmann/statusnet_js_mashup_2nd
None
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
Did you like this talk? http://bit.ly/oscon12_js_mashup 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]