You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
897 lines
27 KiB
HTML
897 lines
27 KiB
HTML
<!--
|
|
Google IO 2012/2013 HTML5 Slide Template
|
|
|
|
Authors: Eric Bidelman <ebidel@gmail.com>
|
|
Luke Mahé <lukem@google.com>
|
|
|
|
URL: https://code.google.com/p/io-2012-slides
|
|
-->
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title></title>
|
|
<meta charset="utf-8">
|
|
<meta http-equiv="X-UA-Compatible" content="chrome=1">
|
|
<!--<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">-->
|
|
<!--<meta name="viewport" content="width=device-width, initial-scale=1.0">-->
|
|
<!--This one seems to work all the time, but really small on ipad-->
|
|
<!--<meta name="viewport" content="initial-scale=0.4">-->
|
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
|
<link rel="stylesheet" media="all" href="theme/css/default.css">
|
|
<link rel="stylesheet" media="only screen and (max-device-width: 480px)" href="theme/css/phone.css">
|
|
<base target="_blank"> <!-- This amazingness opens all links in a new tab. -->
|
|
<script data-main="js/slides" src="js/require-1.0.8.min.js"></script>
|
|
</head>
|
|
<body style="opacity: 0">
|
|
|
|
<slides class="layout-widescreen">
|
|
|
|
<!-- <slide class="logoslide nobackground">
|
|
<article class="flexbox vcenter">
|
|
<span><img src="images/angularjs.png"></span>
|
|
</article>
|
|
</slide>
|
|
-->
|
|
<slide class="title-slide segue nobackground fill" style="background-image: url(images/promises.jpg)">
|
|
<!-- <aside class="gdbar"><img src="images/angularjs.png"></aside> -->
|
|
<!-- The content of this hgroup is replaced programmatically through the slide_config.json. -->
|
|
<hgroup class="auto-fadein">
|
|
<h1 class="yellow" data-config-title><!-- populated from slide_config.json --></h1>
|
|
<h2 data-config-subtitle><!-- populated from slide_config.json --></h2>
|
|
<p class="yellow2" data-config-presenter><!-- populated from slide_config.json --></p>
|
|
</hgroup>
|
|
</slide>
|
|
|
|
<slide class="segue dark nobackground">
|
|
<!-- <aside class="gdbar"><img src="images/google_developers_icon_128.png"></aside> -->
|
|
<hgroup>
|
|
<h2 class="yellow">Why Promises ?</h2>
|
|
<h3 class="yellow">Let's step back to the basics</h3>
|
|
</hgroup>
|
|
</slide>
|
|
|
|
<slide>
|
|
<hgroup class="centered">
|
|
<h3>Single thread synchronous model aka. blocking</h3>
|
|
</hgroup>
|
|
<br><br>
|
|
<article style="float: left">
|
|
<br>
|
|
<br>
|
|
<br>
|
|
<br>
|
|
<ul>
|
|
<li>Suppose a program consisting of 3 distinct tasks</li>
|
|
<li>Tasks are performed one at a time</li>
|
|
<li>Always in a defined order</li>
|
|
<li>Simplest style of programming</li>
|
|
</ul>
|
|
</article>
|
|
<article class="centered">
|
|
<img src="images/sync.png" class="auto-fade-in" alt="Description" title="Description">
|
|
<footer class="source">source: <a href="http://krondo.com/?p=1209">krondo.com</a></footer>
|
|
</article>
|
|
</slide>
|
|
|
|
|
|
<slide>
|
|
<hgroup class="centered">
|
|
<h3>Multi threaded model</h3>
|
|
</hgroup>
|
|
<br><br>
|
|
<article style="float: left; width: 60%">
|
|
<br>
|
|
<br>
|
|
<br>
|
|
<br>
|
|
<ul>
|
|
<li>Tasks run in separate threads</li>
|
|
<li>Threads are handled by the OS</li>
|
|
<li>Threads can run concurrently</li>
|
|
<li>They often <b>end up just waiting</b></li>
|
|
<li>Or interleaved together in single CPU</li>
|
|
<li>Tasks might get suspended arbitrarily by OS</li>
|
|
<li>Thread communication and synchronisation is a diffcult topic</li>
|
|
</ul>
|
|
</article>
|
|
<article class="centered">
|
|
<br>
|
|
<br>
|
|
<br>
|
|
<br>
|
|
<br>
|
|
<img src="images/threaded.png" class="auto-fade-in" alt="Description" title="Description">
|
|
<footer class="source">source: <a href="http://krondo.com/?p=1209">krondo.com</a></footer>
|
|
</article>
|
|
</slide>
|
|
|
|
<slide class="fill nobackground" style="background-image: url(images/ihavenoidea.jpg)">
|
|
<!-- <hgroup>
|
|
<h2 class="white">Full Image (with Optional Header)</h2>
|
|
</hgroup>
|
|
--> <!-- <footer class="source white">www.flickr.com/photos/25797459@N06/5438799763/</footer> -->
|
|
</slide>
|
|
|
|
<slide>
|
|
<hgroup class="centered">
|
|
<h3>Single thread asynchronous model = <b>Javascript</b></h3>
|
|
</hgroup>
|
|
<br><br>
|
|
<article style="float: left">
|
|
<br>
|
|
<br>
|
|
<br>
|
|
<br>
|
|
<ul>
|
|
<li>Tasks interleaved inside the same Thread</li>
|
|
<li>Goodness of synchronous + multithreaded </li>
|
|
<li>Programmer in control, not the OS</li>
|
|
<li>Tasks are not suspended arbitrarily</li>
|
|
</ul>
|
|
</article>
|
|
<article class="centered">
|
|
<img src="images/async.png" class="auto-fade-in" alt="Description" title="Description">
|
|
<footer class="source">source: <a href="http://krondo.com/?p=1209">krondo.com</a></footer>
|
|
</article>
|
|
</slide>
|
|
|
|
<slide>
|
|
<hgroup class="centered">
|
|
<h3>Single thread asynchronous model = <b>Javascript</b></h3>
|
|
</hgroup>
|
|
<br><br>
|
|
<article style="float: left">
|
|
<br>
|
|
<h4>The <b class="blue">event loop</b> handles task scheduling</h4>
|
|
<br><br>
|
|
<pre class="prettyprint" data-lang="javascript" >
|
|
// Event loop pseudo code
|
|
for(;;) {
|
|
if (endOfProgram)
|
|
quit();
|
|
<b>if(eventToHandle) { // task waiting, task finished ...
|
|
handleEvent(eventToHandle); // Callback </b>
|
|
}
|
|
}
|
|
</pre>
|
|
</article>
|
|
<article class="centered">
|
|
<img src="images/eventloop.png" class="auto-fade-in" alt="Description" title="Description" style="height:350px">
|
|
<footer class="source">source: <a href="http://krondo.com/?p=1209">krondo.com</a></footer>
|
|
</article>
|
|
</slide>
|
|
|
|
|
|
<slide>
|
|
<hgroup class="centered">
|
|
<h3>Single thread asynchronous model = <b>Javascript</b></h3>
|
|
</hgroup>
|
|
<br><br>
|
|
<article style="float: left">
|
|
<br>
|
|
<h3 class="red">Therefore</h3>
|
|
<br><br>
|
|
<ul>
|
|
<li>Each task must be <b>non blocking</b></li>
|
|
<li>Otherwise you get freezes and lags</li>
|
|
</ul>
|
|
</article>
|
|
<article class="centered">
|
|
<img src="images/async.png" class="auto-fade-in" alt="Description" title="Description">
|
|
<footer class="source">source: <a href="http://krondo.com/?p=1209">krondo.com</a></footer>
|
|
</article>
|
|
</slide>
|
|
|
|
<slide>
|
|
<hgroup>
|
|
<h2>Stupid Asynchronous API: <b>Callbacks</b></h2>
|
|
<h3>Asynchronous = Non Blocking</h3>
|
|
</hgroup>
|
|
<article class="">
|
|
<h3 class="centered"> <b>Callbacks</b> are a way to make tasks non blocking</h3>
|
|
<br>
|
|
<pre class="prettyprint" data-lang="javascript" >
|
|
task1(function task2(task1Result) {
|
|
// do something with task 1 result
|
|
})
|
|
|
|
var task1 = function(callback) {
|
|
result = longRunningTask(); // Blocking call
|
|
callback(result); // Calling a passed callback
|
|
}
|
|
</pre>
|
|
</article>
|
|
</slide>
|
|
|
|
<slide>
|
|
<hgroup>
|
|
<h2>Stupid Asynchronous API: <b>Callbacks</b></h2>
|
|
<h3>Asynchronous = Non Blocking</h3>
|
|
</hgroup>
|
|
<article class="">
|
|
<h3 class="centered"> <b>Callbacks</b> are messy </h3>
|
|
<br>
|
|
<pre class="prettyprint" data-lang="javascript" >
|
|
$('#button').click(function () {
|
|
askForTwitterHandle(function(twitterHandle) {
|
|
twitterHandle.getTweets(function (tweets) {
|
|
processTweets(function (processedTweets) {
|
|
ui.show(processedTweets);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
</pre>
|
|
</article>
|
|
</slide>
|
|
|
|
<slide>
|
|
<article class="smaller">
|
|
<h3 class="centered"> <b>Callbacks</b> error handling is worse, no exception propagation </h3>
|
|
<pre class="prettyprint" data-lang="javascript" >
|
|
$('#button').click(function () {
|
|
askForTwitterHandle(function(twitterHandle) {
|
|
twitterHandle.getTweets(function (tweets) {
|
|
...
|
|
});
|
|
}, function onFailure(error) {
|
|
handleError(error);
|
|
});
|
|
});
|
|
</pre>
|
|
<h3 class="centered">In the synchronous model we have <b>try/catch</b></h3>
|
|
<pre class="prettyprint" data-lang="javascript" >
|
|
try {
|
|
handle = askForTwitterHandle();
|
|
tweets = handle.getTweets();
|
|
...
|
|
} catch (errorMessage) {
|
|
console.log('I messed up');
|
|
}
|
|
</pre>
|
|
</article>
|
|
</slide>
|
|
|
|
<slide class="fill nobackground" style="background-image: url(images/callbacks-hack.jpg); background-position: center; background-size: auto 100%;">
|
|
<!-- <hgroup>
|
|
<h2 class="white">Full Image (with Optional Header)</h2>
|
|
</hgroup>
|
|
--> <!-- <footer class="source white">www.flickr.com/photos/25797459@N06/5438799763/</footer> -->
|
|
</slide>
|
|
|
|
<slide>
|
|
<hgroup>
|
|
<h2>Promises are the right abstraction</h2>
|
|
</hgroup>
|
|
<article>
|
|
</pre>
|
|
<h4 class="centered">Instead of calling a passed callback, we return a promise</h4>
|
|
<br><br>
|
|
<pre class="prettyprint" data-lang="javascript" >
|
|
ajax('template.html', function(err, template) {
|
|
if (err)
|
|
handleError();
|
|
|
|
render(template);
|
|
})
|
|
|
|
// Becomes
|
|
|
|
<b>var promiseForTemplate = $http.get('template.html');
|
|
promiseForTemplate.then(render, handleError)</b>
|
|
</pre>
|
|
</article>
|
|
</slide>
|
|
|
|
<slide>
|
|
<hgroup>
|
|
<h2>Promises guarantees</h2>
|
|
</hgroup>
|
|
<article>
|
|
</pre>
|
|
<pre class="prettyprint" data-lang="javascript" >
|
|
promiseForTemplate.then(onFulfilled, onFailed);
|
|
</pre>
|
|
<br><br>
|
|
<ul>
|
|
<li>Only one of <b>onFulfilled</b> or <b>onFailed</b> will be called</li>
|
|
<li><b>onFulfilled</b> will be called with a single value (return value)</li>
|
|
<li><b>onFailed</b> will be called with a single rejection reason (thrown exception) </li>
|
|
<li>If the promise if already settled, the handlers are guaranteed to be called anyway</li>
|
|
<li>The handlers will always be called asynchronousy</li>
|
|
</ul>
|
|
</article>
|
|
</slide>
|
|
|
|
<slide>
|
|
<hgroup>
|
|
<h2>Promises can be chained</h2>
|
|
</hgroup>
|
|
<article>
|
|
</pre>
|
|
<pre class="prettyprint" data-lang="javascript" >
|
|
//
|
|
var transformedPromise = promiseForTemplate.then(onFulfilled, onFailed);
|
|
</pre>
|
|
<br><br>
|
|
<ul>
|
|
<li>If <b>onFulfilled</b> returns a value</li>
|
|
<ul>
|
|
<li><b>transformedPromise</b> is <u>resolved</u> with that value</li>
|
|
</ul>
|
|
<li>If <b>onFulfilled</b> returns a promise</li>
|
|
<ul>
|
|
<li><b>transformedPromise</b> will adapt it's state</li>
|
|
</ul>
|
|
<li>If <b>onFailed</b> throws an exception</li>
|
|
<ul>
|
|
<li><b>transformedPromise</b> will be rejected with that exception</li>
|
|
</ul>
|
|
</ul>
|
|
</article>
|
|
</slide>
|
|
|
|
|
|
<slide>
|
|
<article class="">
|
|
<hgroup>
|
|
<h2>Example</h2>
|
|
</hgroup>
|
|
<br><br>
|
|
<h3>Sync</h3>
|
|
<pre class="prettyprint" data-lang="javascript" >
|
|
var user = getUser(); // blocking, ie, prompt for password
|
|
var username = user.name;
|
|
</pre>
|
|
<br><br>
|
|
<h3>Async with Promise</h3>
|
|
<pre class="prettyprint" data-lang="javascript" >
|
|
var userNamePromise = getUser().then(function (user){
|
|
return user.name;
|
|
})</pre>
|
|
</article>
|
|
</slide>
|
|
|
|
<slide>
|
|
<article class="">
|
|
<hgroup>
|
|
<h2>Example: throwing an exception</h2>
|
|
</hgroup>
|
|
<br><br>
|
|
<h3>Sync</h3>
|
|
<pre class="prettyprint" data-lang="javascript" >
|
|
var user = getUser(); // blocking, ie, prompt for password
|
|
if (user === null)
|
|
throw new Error('null user');
|
|
</pre>
|
|
<br><br>
|
|
<h3>Async with Promise</h3>
|
|
<pre class="prettyprint" data-lang="javascript" >
|
|
var userPromise = getUser().then(function (user){
|
|
if (user === null)
|
|
throw new Error('null user');
|
|
return user;
|
|
})
|
|
</pre>
|
|
</article>
|
|
</slide>
|
|
|
|
<slide>
|
|
<article class="">
|
|
<hgroup>
|
|
<h2>Example: handling an exception</h2>
|
|
</hgroup>
|
|
<br><br>
|
|
<h3>Sync</h3>
|
|
<pre class="prettyprint" data-lang="javascript" >
|
|
try {
|
|
updateUser(data);
|
|
} <b>catch (exp) {
|
|
console.log('There was an error', exp);
|
|
}</b></pre>
|
|
<br>
|
|
<h3>Async with Promise: exception propagation</h3>
|
|
<pre class="prettyprint" data-lang="javascript" >
|
|
|
|
var updateUserPromise = updateUser(data).then(undefined, <b>function(exp) {
|
|
console.log('There was an error', exp);
|
|
}</b>)
|
|
</pre>
|
|
</article>
|
|
</slide>
|
|
|
|
<slide>
|
|
<article class="">
|
|
<hgroup>
|
|
<h2>Example: rethrowing an exception</h2>
|
|
</hgroup>
|
|
<br><br>
|
|
<h3>Sync</h3>
|
|
<pre class="prettyprint" data-lang="javascript" >
|
|
try {
|
|
updateUser(data);
|
|
} <b>catch (exp) {
|
|
throw new Error('UpdateUserError: ' + exp.message)
|
|
}</b></pre>
|
|
<br>
|
|
<h3>Async with Promise: exception propagation</h3>
|
|
<pre class="prettyprint" data-lang="javascript" >
|
|
|
|
var updateUserPromise = updateUser(data).then(undefined, <b>function(exp) {
|
|
throw new Error('UpdateUserError: ' + exp.message)
|
|
}</b>)
|
|
</pre>
|
|
</article>
|
|
</slide>
|
|
|
|
<slide>
|
|
<article class="">
|
|
<hgroup>
|
|
<h2>Example: exception propagation</h2>
|
|
</hgroup>
|
|
<h3>Callbacks</h3>
|
|
<pre class="prettyprint" data-lang="javascript" >
|
|
getUser('spike', function(err, user){
|
|
<b>if(err) {
|
|
ui.error(err);
|
|
}</b> else {
|
|
getBestFriend(user, function(err, friend){
|
|
<b>if (err) {
|
|
ui.error(err);
|
|
}</b> else {
|
|
ui.showBestFriend(friend, function(err, friend){
|
|
<b>if (err) {
|
|
ui.error(err);
|
|
}</b>
|
|
})
|
|
}
|
|
})
|
|
}
|
|
})</pre>
|
|
<br>
|
|
</article>
|
|
</slide>
|
|
|
|
<slide>
|
|
<article class="">
|
|
<hgroup>
|
|
<h2>Example: exception propagation</h2>
|
|
</hgroup>
|
|
<br>
|
|
<br>
|
|
<br>
|
|
<h3>Promises</h3>
|
|
<pre class="prettyprint" data-lang="javascript" >
|
|
getUser()
|
|
.then(getBestFriend)
|
|
.then(ui.showBestFriend)
|
|
<b>.then(undefined, ui.error)</b>
|
|
</pre>
|
|
<br>
|
|
</article>
|
|
</slide>
|
|
|
|
<slide>
|
|
<hgroup>
|
|
<h2>Promises in <span class="red3">Angular</span></h2>
|
|
</hgroup>
|
|
<article class="">
|
|
<ul>
|
|
<li>Provided by <b class="blue">$q</b> service</li>
|
|
<li>Inspired by the the promise/deferred <code><a href="https://github.com/kriskowal/q">Q library</a></code></li>
|
|
<li>Is a lightweight implementation of Promises (Q is much more complete)</li>
|
|
<li>Promises are used everywhere Angular needs async</li>
|
|
<ul>
|
|
<li>$http</li>
|
|
<li>$resource</li>
|
|
<li>$routeProvider</li>
|
|
<li>Controller properties</li>
|
|
<li>Response Interceptors</li>
|
|
<li>...</li>
|
|
</ul>
|
|
<li>Optimized for the Angular <b class="blue2">run loop</b></li>
|
|
</ul>
|
|
</article>
|
|
</slide>
|
|
|
|
<slide>
|
|
<hgroup>
|
|
<h2>Angular Run Loop</h2>
|
|
<br><br>
|
|
<article class="centered">
|
|
<img src="images/runloop.png" alt="" style="height: 455px">
|
|
</article>
|
|
</hgroup>
|
|
</slide>
|
|
|
|
<slide>
|
|
<hgroup>
|
|
<h2>How to use Promises in Angular</h2>
|
|
</hgroup>
|
|
<article>
|
|
<pre class="prettyprint" data-lang="javascript" >
|
|
|
|
.controller('testCtrl', function($scope, $q) { // inject the service
|
|
|
|
var promiseOfTask = function () {
|
|
|
|
var deferredTask = $q.defer(); // create a deferred object
|
|
|
|
var result = blockingTask(); // long running task
|
|
deferredTask.<b>resolve(result)</b> // resolve the future promise with the result
|
|
|
|
return deferredTask.promise // return the promise
|
|
}
|
|
|
|
//using the promise
|
|
<b>promiseOfTask().then(function(result){
|
|
$scope.updateSomeModel(result);
|
|
})</b>
|
|
})
|
|
</pre>
|
|
</article>
|
|
</slide>
|
|
|
|
<slide class="segue dark nobackground">
|
|
<aside class="gdbar"><img src="images/angularjs.png"></aside>
|
|
<hgroup>
|
|
<h2 class="yellow">Demonstration</h2>
|
|
<h3 class="yellow">Handling failovers for api calls</h3>
|
|
</hgroup>
|
|
</slide>
|
|
|
|
<slide>
|
|
<hgroup>
|
|
<h2>Slide with Bullets that Build</h2>
|
|
<h3>Subtitle Placeholder</h3>
|
|
</hgroup>
|
|
<article>
|
|
<p>A list where items build:</p>
|
|
<ul class="build">
|
|
<li>Pressing 'h' highlights code snippets</li>
|
|
<li>Pressing 'p' toggles speaker notes (if they're on the current slide)</li>
|
|
<li>Pressing 'f' toggles fullscreen viewing</li>
|
|
<li>Pressing 'w' toggles widescreen</li>
|
|
<li>Pressing 'o' toggles overview mode</li>
|
|
<li>Pressing 'ESC' toggles off these goodies</li>
|
|
</ul>
|
|
<p>Another list, but items fade as they build:</p>
|
|
<ul class="build fade">
|
|
<li>Hover over me!</li>
|
|
<li>Hover over me!</li>
|
|
<li>Hover over me!</li>
|
|
</ul>
|
|
</article>
|
|
</slide>
|
|
|
|
<slide>
|
|
<hgroup>
|
|
<h2>Slide with (Smaller Font)</h2>
|
|
</hgroup>
|
|
<article class="smaller">
|
|
<ul>
|
|
<li>All <a href="http://google.com">links</a> open in new tabs.</li>
|
|
<li>To change that this, add <code>target="_self"</code> to the link.</li>
|
|
</ul>
|
|
</article>
|
|
</slide>
|
|
|
|
<slide hidden>
|
|
Hidden slides are left out of the presentation.
|
|
</slide>
|
|
|
|
<slide>
|
|
<hgroup>
|
|
<h2>Code Slide (with Subtitle Placeholder)</h2>
|
|
<h3>Subtitle Placeholder</h3>
|
|
</hgroup>
|
|
<article>
|
|
<p>Press 'h' to highlight important sections of code (wrapped in <code><b></code>).</p>
|
|
<pre class="prettyprint" data-lang="javascript">
|
|
<script type='text/javascript'>
|
|
// Say hello world until the user starts questioning
|
|
// the meaningfulness of their existence.
|
|
function helloWorld(world) {
|
|
<b>for (var i = 42; --i >= 0;) {
|
|
alert('Hello ' + String(world));
|
|
}</b>
|
|
}
|
|
</script>
|
|
</pre>
|
|
</article>
|
|
</slide>
|
|
|
|
<slide>
|
|
<hgroup>
|
|
<h2>Code Slide (Smaller Font)</h2>
|
|
</hgroup>
|
|
<article class="smaller">
|
|
<pre class="prettyprint" data-lang="javascript">
|
|
// Say hello world until the user starts questioning
|
|
// the meaningfulness of their existence.
|
|
function helloWorld(world) {
|
|
for (var i = 42; --i >= 0;) {
|
|
alert('Hello ' + String(world));
|
|
}
|
|
}
|
|
</pre>
|
|
<pre class="prettyprint" data-lang="css">
|
|
<style>
|
|
p { color: pink }
|
|
b { color: blue }
|
|
</style>
|
|
</pre>
|
|
<pre class="prettyprint" data-lang="html">
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>My Awesome Page</title>
|
|
</head>
|
|
<body>
|
|
<p>Hello world</p>
|
|
<body>
|
|
</html>
|
|
</pre>
|
|
</article>
|
|
</slide>
|
|
|
|
<slide>
|
|
<aside class="note">
|
|
<section>
|
|
<ul>
|
|
<li>Point I wanted to make #1</li>
|
|
<li>Point I wanted to make #2</li>
|
|
<li>Point I wanted to make #3</li>
|
|
<li>Example <a href="#">link</a> in notes.</li>
|
|
</ul>
|
|
<p><b>Remember to say this tag line!</b></p>
|
|
</section>
|
|
</aside>
|
|
<hgroup>
|
|
<h2>Slide with Speaker Notes</h2>
|
|
</hgroup>
|
|
<article>
|
|
<p>Press 'p' to toggle speaker notes.</p>
|
|
</article>
|
|
</slide>
|
|
|
|
<slide>
|
|
<aside class="note">
|
|
<section>
|
|
<ul>
|
|
<li>See this amazing link: <a href="http://www.google.com">link</a>.</li>
|
|
</ul>
|
|
<p><b>Remember to say this tag line!</b></p>
|
|
</section>
|
|
</aside>
|
|
<hgroup>
|
|
<h2>Presenter Mode</h2>
|
|
</hgroup>
|
|
<article>
|
|
<p>Add <code><a href="?presentme=true" target="_self">?presentme=true</a></code> to the URL to enabled presenter mode.
|
|
This setting is sticky, meaning refreshing the page will persist presenter
|
|
mode.</p>
|
|
<p>Hit <code><a href="?presentme=false" target="_self">?presentme=false</a></code> to disable presenter mode.</p>
|
|
</article>
|
|
</slide>
|
|
|
|
<slide>
|
|
<hgroup>
|
|
<h2>Slide with Image</h2>
|
|
</hgroup>
|
|
<article>
|
|
<img src="images/chart.png" class="reflect" alt="Description" title="Description">
|
|
<footer class="source">source: place source info here</footer>
|
|
</article>
|
|
</slide>
|
|
|
|
<slide>
|
|
<hgroup>
|
|
<h2>Slide with Image (Centered horz/vert)</h2>
|
|
</hgroup>
|
|
<article class="flexbox vcenter">
|
|
<img src="images/barchart.png" alt="Description" title="Description">
|
|
<footer class="source">source: place source info here</footer>
|
|
</article>
|
|
</slide>
|
|
|
|
<slide>
|
|
<hgroup>
|
|
<h2>Table Option A</h2>
|
|
<h3>Subtitle Placeholder</h3>
|
|
</hgroup>
|
|
<article>
|
|
<table>
|
|
<tr>
|
|
<th></th><th>Column 1</th><th>Column 2</th><th>Column 3</th><th>Column 4</th>
|
|
</tr>
|
|
<tr>
|
|
<td>Row 1</td><td>placeholder</td><td class="highlight">placeholder</td><td>placeholder</td><td>placeholder</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Row 2</td><td>placeholder</td><td>placeholder</td><td>placeholder</td><td>placeholder</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Row 3</td><td>placeholder</td><td>placeholder</td><td>placeholder</td><td>placeholder</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Row 4</td><td>placeholder</td><td>placeholder</td><td>placeholder</td><td>placeholder</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Row 5</td><td>placeholder</td><td>placeholder</td><td>placeholder</td><td>placeholder</td>
|
|
</tr>
|
|
</table>
|
|
</article>
|
|
</slide>
|
|
|
|
<slide>
|
|
<hgroup>
|
|
<h2>Table Option A (Smaller Text)</h2>
|
|
<h3>Subtitle Placeholder</h3>
|
|
</hgroup>
|
|
<article class="smaller">
|
|
<table>
|
|
<tr>
|
|
<th></th><th>Column 1</th><th>Column 2</th><th>Column 3</th><th>Column 4</th>
|
|
</tr>
|
|
<tr>
|
|
<td>Row 1</td><td>placeholder</td><td class="highlight">placeholder</td><td>placeholder</td><td>placeholder</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Row 2</td><td>placeholder</td><td>placeholder</td><td>placeholder</td><td>placeholder</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Row 3</td><td>placeholder</td><td>placeholder</td><td>placeholder</td><td>placeholder</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Row 4</td><td>placeholder</td><td>placeholder</td><td>placeholder</td><td>placeholder</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Row 5</td><td>placeholder</td><td>placeholder</td><td>placeholder</td><td>placeholder</td>
|
|
</tr>
|
|
</table>
|
|
</article>
|
|
</slide>
|
|
|
|
<slide>
|
|
<hgroup>
|
|
<h2>Table Option B</h2>
|
|
<h3>Subtitle Placeholder</h3>
|
|
</hgroup>
|
|
<article>
|
|
<table class="rows">
|
|
<tr>
|
|
<th>Header 1</th><td>placeholder</td><td class="highlight">placeholder</td><td>placeholder</td>
|
|
</tr>
|
|
<tr>
|
|
<th>Header 2</th><td>placeholder</td><td>placeholder</td><td>placeholder</td>
|
|
</tr>
|
|
<tr>
|
|
<th>Header 3</th><td>placeholder</td><td>placeholder</td><td>placeholder</td>
|
|
</tr>
|
|
<tr>
|
|
<th>Header 4</th><td>placeholder</td><td>placeholder</td><td>placeholder</td>
|
|
</tr>
|
|
<tr>
|
|
<th>Header 5</th><td>placeholder</td><td>placeholder</td><td>placeholder</td>
|
|
</tr>
|
|
</table>
|
|
</article>
|
|
</slide>
|
|
|
|
<slide>
|
|
<hgroup>
|
|
<h2>Slide Styles</h2>
|
|
</hgroup>
|
|
<article class="smaller">
|
|
<div class="columns-2">
|
|
<ul>
|
|
<li class="red">class="red"</li>
|
|
<li class="red2">class="red2"</li>
|
|
<li class="red3">class="red3"</li>
|
|
<li class="blue">class="blue"</li>
|
|
<li class="blue2">class="blue2"</li>
|
|
<li class="blue3">class="blue3"</li>
|
|
<li class="green">class="green"</li>
|
|
<li class="green2">class="green2"</li>
|
|
</ul>
|
|
<ul>
|
|
<li class="green3">class="green3"</li>
|
|
<li class="yellow">class="yellow"</li>
|
|
<li class="yellow2">class="yellow2"</li>
|
|
<li class="yellow3">class="yellow3"</li>
|
|
<li class="gray">class="gray"</li>
|
|
<li class="gray2">class="gray2"</li>
|
|
<li class="gray3">class="gray3"</li>
|
|
<li class="gray4">class="gray4"</li>
|
|
</ul>
|
|
</div>
|
|
<div class="centered" style="margin-top:2em">
|
|
I am centered text with a <button>Button</button> and <button disabled>Disabled</button> button.
|
|
</div>
|
|
</article>
|
|
</slide>
|
|
|
|
<slide class="segue dark nobackground">
|
|
<aside class="gdbar"><img src="images/google_developers_icon_128.png"></aside>
|
|
<hgroup class="auto-fadein">
|
|
<h2>Segue Slide</h2>
|
|
<h3>Subtitle Placeholder</h3>
|
|
</hgroup>
|
|
</slide>
|
|
|
|
<slide class="fill nobackground" style="background-image: url(images/sky.jpg)">
|
|
<hgroup>
|
|
<h2 class="white">Full Image (with Optional Header)</h2>
|
|
</hgroup>
|
|
<footer class="source white">www.flickr.com/photos/25797459@N06/5438799763/</footer>
|
|
</slide>
|
|
|
|
<slide class="segue dark quote nobackground">
|
|
<aside class="gdbar right bottom"><img src="images/google_developers_icon_128.png"></aside>
|
|
<article class="flexbox vleft auto-fadein">
|
|
<q>
|
|
This is an example of quote text.
|
|
</q>
|
|
<div class="author">
|
|
Name<br>
|
|
Company
|
|
</div>
|
|
</article>
|
|
</slide>
|
|
|
|
<slide>
|
|
<hgroup>
|
|
<h2>Slide with Iframe</h2>
|
|
</hgroup>
|
|
<article>
|
|
<iframe data-src="http://www.google.com/doodle4google/history.html"></iframe>
|
|
</article>
|
|
</slide>
|
|
|
|
<slide>
|
|
<article>
|
|
<iframe data-src="http://www.google.com/doodle4google/history.html"></iframe>
|
|
</article>
|
|
</slide>
|
|
|
|
<slide class="thank-you-slide segue nobackground">
|
|
<aside class="gdbar right"><img src="images/google_developers_icon_128.png"></aside>
|
|
<article class="flexbox vleft auto-fadein">
|
|
<h2><Thank You!></h2>
|
|
<p>Important contact information goes here.</p>
|
|
</article>
|
|
<p class="auto-fadein" data-config-contact>
|
|
<!-- populated from slide_config.json -->
|
|
</p>
|
|
</slide>
|
|
|
|
<slide class="logoslide dark nobackground">
|
|
<article class="flexbox vcenter">
|
|
<span><img src="images/angularjs_white.png"></span>
|
|
</article>
|
|
</slide>
|
|
|
|
<slide class="backdrop"></slide>
|
|
|
|
</slides>
|
|
|
|
<script>
|
|
var _gaq = _gaq || [];
|
|
_gaq.push(['_setAccount', 'UA-XXXXXXXX-1']);
|
|
_gaq.push(['_trackPageview']);
|
|
|
|
(function() {
|
|
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
|
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
|
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
|
|
})();
|
|
</script>
|
|
|
|
<!--[if IE]>
|
|
<script src="http://ajax.googleapis.com/ajax/libs/chrome-frame/1/CFInstall.min.js"></script>
|
|
<script>CFInstall.check({mode: 'overlay'});</script>
|
|
<![endif]-->
|
|
</body>
|
|
</html>
|