+++ /dev/null
-<!DOCTYPE html>
-<!--
- Copyright 2010 Google Inc.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- Original slides: Marcin Wichary (mwichary@google.com)
- Modifications: Ernest Delgado (ernestd@google.com)
- Alex Russell (slightlyoff@chromium.org)
- Brad Neuberg
--->
-<html manifest="cache.manifest">
- <head>
- <!--[if gte IE 9]>
- <meta http-equiv="X-UA-Compatible" content="IE=edge" />
- <![endif]-->
-
- <!--[if lt IE 9]>
- <meta http-equiv="X-UA-Compatible" content="IE=edge;chrome=1" />
- <![endif]-->
-
- <meta charset="utf-8" />
- <title>Dobrica Pavlinušić: Android from source in command-line</title>
- <link href="http://fonts.googleapis.com/css?family=Droid+Sans|Droid+Sans+Mono" rel="stylesheet" type="text/css" />
-
- <style>
- body {
- font: 20px "Lucida Grande", "Trebuchet MS", Verdana, sans-serif;
- padding: 0;
- margin: 0;
- width: 100%;
- height: 100%;
- position: absolute;
- left: 0px; top: 0px;
- }
-
- .presentation {
- position: absolute;
- height: 100%;
- width: 100%;
- left: 0px;
- top: 0px;
- display: block;
- overflow: hidden;
- background: #778;
- }
-
- .slides {
- width: 100%;
- height: 100%;
- left: 0;
- top: 0;
- position: absolute;
- display: block;
- -webkit-transition: -webkit-transform 1s ease-in-out;
- -moz-transition: -moz-transform 1s ease-in-out;
- -o-transition: -o-transform 1s ease-in-out;
- transition: transform 1s ease-in-out;
-
- /* so it's visible in the iframe. */
- -webkit-transform: scale(0.8);
- -moz-transform: scale(0.8);
- -o-transform: scale(0.8);
- transform: scale(0.8);
-
- }
-
- .slide {
- display: none;
- position: absolute;
- overflow: hidden;
- width: 900px;
- height: 700px;
- left: 50%;
- top: 50%;
- margin-top: -350px;
- background-color: #eee;
- background: -webkit-gradient(linear, left bottom, left top, from(#bbd), to(#fff));
- background: -moz-linear-gradient(bottom, #bbd, #fff);
- background: linear-gradient(bottom, #bbd, #fff);
- -webkit-transition: all 0.25s ease-in-out;
- -moz-transition: all 0.25s ease-in-out;
- -o-transition: all 0.25s ease-in-out;
- transition: all 0.25s ease-in-out;
- -webkit-transform: scale(1);
- -moz-transform: scale(1);
- -o-transform: scale(1);
- transform: scale(1);
- }
-
- .slide:nth-child(even) {
- -moz-border-radius: 20px 0;
- -khtml-border-radius: 20px 0;
- border-radius: 20px 0; /* includes Opera 10.5+ */
- -webkit-border-top-left-radius: 20px;
- -webkit-border-bottom-right-radius: 20px;
- }
-
- .slide:nth-child(odd) {
- -moz-border-radius: 0 20px;
- -khtml-border-radius: 0 20px;
- border-radius: 0 20px;
- -webkit-border-top-right-radius: 20px;
- -webkit-border-bottom-left-radius: 20px;
- }
-
- .slide p, .slide textarea {
- font-size: 120%;
- }
-
- .slide .counter {
- color: #999999;
- position: absolute;
- left: 20px;
- bottom: 20px;
- display: block;
- font-size: 70%;
- }
-
- .slide.title > .counter,
- .slide.segue > .counter,
- .slide.mainTitle > .counter {
- display: none;
- }
-
- .force-render {
- display: block;
- visibility: hidden;
- }
-
- .slide.far-past {
- display: block;
- margin-left: -2400px;
- }
-
- .slide.past {
- visibility: visible;
- display: block;
- margin-left: -1400px;
- }
-
- .slide.current {
- visibility: visible;
- display: block;
- margin-left: -450px;
- }
-
- .slide.future {
- visibility: visible;
- display: block;
- margin-left: 500px;
- }
-
- .slide.far-future {
- display: block;
- margin-left: 1500px;
- }
-
- body.three-d div.slides {
- -webkit-transform: translateX(50px) scale(0.8) rotateY(10deg);
- -moz-transform: translateX(50px) scale(0.8) rotateY(10deg);
- -o-transform: translateX(50px) scale(0.8) rotateY(10deg);
- transform: translateX(50px) scale(0.8) rotateY(10deg);
- }
-
- /* Content */
-
- @font-face { font-family: 'Junction'; src: url(src/Junction02.otf); }
- @font-face { font-family: 'LeagueGothic'; src: url(src/LeagueGothic.otf); }
-
- header {
- font-family: 'Droid Sans';
- font-weight: normal;
- letter-spacing: -.05em;
- text-shadow: rgba(0, 0, 0, 0.2) 0 2px 5px;
- left: 30px;
- top: 25px;
- margin: 0;
- padding: 0;
- font-size: 140%;
- }
-
- h1 {
- font-size: 140%;
- display: inline;
- font-weight: normal;
- padding: 0;
- margin: 0;
- }
-
- h2 {
- font-family: 'Droid Sans';
- color: black;
- font-size: 120%;
- padding: 0;
- margin: 20px 0;
- }
-
- h2:first-child {
- margin-top: 0;
- }
-
- section, footer {
- font-family: 'Droid Sans';
- color: #3f3f3f;
- text-shadow: rgba(0, 0, 0, 0.2) 0 2px 5px;
- margin: 100px 30px 0;
- display: block;
- overflow: hidden;
- }
-
- footer {
- font-size: 100%;
- margin: 20px 0 0 30px;
- }
-
- a {
- color: inherit;
- display: inline-block;
- text-decoration: none;
- line-height: 110%;
- border-bottom: 2px solid #3f3f3f;
- }
-
- ul {
- margin: 0;
- padding: 0;
- }
-
- button {
- font-size: 100%;
- }
-
- pre button {
- margin: 2px;
- }
-
- section.left {
- float: left;
- width: 390px;
- }
-
- section.small {
- font-size: 24px;
- }
-
- section.small ul {
- margin: 0 0 0 15px;
- padding: 0;
- }
-
- section.small li {
- padding-bottom: 0;
- }
-
- section.middle {
- line-height: 2em;
- text-align: center;
- display: table-cell;
- vertical-align: middle;
- height: 700px;
- width: 900px;
- }
-
- pre {
- text-align: left;
- font-family: 'Droid Sans Mono', Courier;
- font-size: 80%;
- padding: 10px 20px;
- background: rgba(255, 0, 0, 0.05);
- -webkit-border-radius: 8px;
- -khtml-border-radius: 8px;
- -moz-border-radius: 8px;
- border-radius: 8px;
- border: 1px solid rgba(255, 0, 0, 0.2);
- }
-
- pre select {
- font-family: Monaco, Courier;
- border: 1px solid #c61800;
- }
-
- input {
- font-size: 100%;
- margin-right: 10px;
- font-family: Helvetica;
- padding: 3px;
- }
- input[type="range"] {
- width: 100%;
- }
-
- button {
- margin: 20px 10px 0 0;
- font-family: Verdana;
- }
-
- button.large {
- font-size: 32px;
- }
-
- pre b {
- font-weight: normal;
- color: #c61800;
- text-shadow: #c61800 0 0 1px;
- /*letter-spacing: -1px;*/
- }
- pre em {
- font-weight: normal;
- font-style: normal;
- color: #18a600;
- text-shadow: #18a600 0 0 1px;
- }
- pre input[type="range"] {
- height: 6px;
- cursor: pointer;
- width: auto;
- }
-
- div.example {
- display: block;
- padding: 10px 20px;
- color: black;
- background: rgba(255, 255, 255, 0.4);
- -webkit-border-radius: 8px;
- -khtml-border-radius: 8px;
- -moz-border-radius: 8px;
- border-radius: 8px;
- margin-bottom: 10px;
- border: 1px solid rgba(0, 0, 0, 0.2);
- }
-
- video {
- -moz-border-radius: 8px;
- -khtml-border-radius: 8px;
- -webkit-border-radius: 8px;
- border-radius: 8px;
- border: 1px solid rgba(0, 0, 0, 0.2);
- }
-
- .key {
- font-family: 'Droid Sans';
- color: black;
- display: inline-block;
- padding: 6px 10px 3px 10px;
- font-size: 100%;
- line-height: 30px;
- text-shadow: none;
- letter-spacing: 0;
- bottom: 10px;
- position: relative;
- -moz-border-radius: 10px;
- -khtml-border-radius: 10px;
- -webkit-border-radius: 10px;
- border-radius: 10px;
- background: white;
- box-shadow: rgba(0, 0, 0, 0.1) 0 2px 5px;
- -webkit-box-shadow: rgba(0, 0, 0, 0.1) 0 2px 5px;
- -moz-box-shadow: rgba(0, 0, 0, 0.1) 0 2px 5px;
- -o-box-shadow: rgba(0, 0, 0, 0.1) 0 2px 5px;
- }
-
- .key { font-family: Arial; }
-
- :not(header) > .key {
- margin: 0 5px;
- bottom: 4px;
- }
-
- .two-column {
- -webkit-column-count: 2;
- -moz-column-count: 2;
- column-count: 2;
- }
-
- .stroke {
- -webkit-text-stroke-color: red;
- -webkit-text-stroke-width: 1px;
- } /* currently webkit-only */
-
- .center {
- text-align: center;
- }
-
- #presentation-counter {
- color: #ccc;
- font-size: 70%;
- letter-spacing: 1px;
- position: absolute;
- top: 40%;
- left: 0;
- width: 100%;
- text-align: center;
- }
-
- div:not(.current).reduced {
- -webkit-transform: scale(0.8);
- -moz-transform: scale(0.8);
- -o-transform: scale(0.8);
- transform: scale(0.8);
- }
-
- .no-transitions {
- -webkit-transition: none;
- -moz-transition: none;
- -o-transition: none;
- transition: none;
- }
-
- .no-gradients {
- background: none;
- background-color: #fff;
- }
-
- ul.bulleted {
- padding-left: 30px;
- }
-
- </style>
-
- </head>
- <body>
- <div class="presentation">
- <div id="presentation-counter"></div>
- <div class="slides">
-
-<!--
-
-Android
-from
-source
-in
-command-line
-
-Android vs iPhone
-TOC
-
-Compile own ROM
-CyanogenMod
-Binary blobs from phone using adb pull
-Android-x86
-Downloads somewhat working (EeePC 701)
-USB networking broken
-http://github.com/dpavlin/android-adb-usb-tether
-
-Debug from command-line
-Do we need FLOSS app market?
-
--->
-
- <div class="slide">
- <section class="middle">
- <h2>Android from source in command-line</h2>
- <img src="android-fastboot.png">
- <p>
- Dobrica Pavlinušić
- <br><a href="http://blog.rot13.org">http://blog.rot13.org/</a>
- </p>
- </section>
- </div>
-
- <div class="slide">
- <section>
- <header>
- <h1>TOC</h1>
- </header>
- <h2>Compile Android from source code</h2>
- <h2>Command-line usage</h2>
- <h2>/system/bin</h2>
- <h2>Do we need FLOSS app market?</h2>
- </section>
- </div>
-
-<!--
- <div class="slide">
- <section class="middle">
- <h2></h2>
- </section>
- </div>
--->
- <div class="slide">
- <section>
- <header>
- <h1>Compile Android from source</h1>
- </header>
-
- <h2>Why is source important?</h2>
- <p>
- Lookup how is something implemented
- - <a href="http://github.com/dpavlin/android-adb-usb-tether">and find out why usb networking doesn't work for Google apps</a>
- </p>
- <p>Lastest Android released on abandoned hardware (Froyo on G1)</p>
-
- <h2>Ability to install your own ROM</h2>
- <p>
- severly udermined by attempts to provide full signature security from hardware to userspace
- </p>
- <p>
- SPL
- <span class="key">></span>
- recovery
- <span class="key">></span>
- system
- </p>
-
- <h2>Porting to other devices</h2>
- </div>
-
- <div class="slide">
- <section>
-
- <header>
- <h1>Compile Android from source</h1>
- </header>
-
- <h2>CyanogenMod</h2>
-
- <ul class="bulleted">
- <li>only for <b>rooted</b> phones (targets developers)
- <li>binary blobs from phone using <tt>adb pull</tt></li>
- <li><a href="http://wiki.cyanogenmod.com/index.php?title=Compile_CyanogenMod_for_Dream_%26_Sapphire">compile for your phone</a></li>
-<pre>
-dpavlin@android:/srv/cyanogen$ <b>. build/envsetup.sh</b>
-dpavlin@android:/srv/cyanogen$ <b>lunch</b>
-dpavlin@android:/srv/cyanogen$ <b>make -j8</b>
-</pre>
- <li>fastboot or sdcard <tt>update.zip</tt> flashing
- <li><a href="http://github.com/CyanogenMod/android_vendor_cyanogen/blob/froyo/CHANGELOG.mkdn">additional features</a> on top of Google release
- </ul>
- </section>
- </div>
-
- <div class="slide">
- <section>
-
- <header>
- <h1>Compile Android from source</h1>
- </header>
-
- <h2>Android-x86</h2>
-
- <ul class="bulleted">
- <li>Latest release <a href="http://android-x86.googlecode.com/files/android-x86-1.6-r2.iso">1.6r2</a> works on EeePC 701, VrtualBox and kvm</li>
- <li><a href="http://www.android-x86.org/getsourcecode">compile source</a></li>
- <li>Froyo (2.2) and Eclair (2.1) in various stages of <em>working</em>
- <li>networking in kvm: boot in <b>debug</b> mode and in first prompt load network module:
-<pre>
-# <b>modprobe 8139cp</b>
-</pre>
- <li>add <tt>vga=788</tt> to kernel line in <tt>grub</tt> to make kvm happy
- </ul>
- </section>
- </div>
-
-
-
- <div class="slide">
- <section>
- <header>
- <h1>adb</h1>
- </header>
- <h2>shell</h2>
-<pre>
-dpavlin@x200:/virtual/android$ <b>adb shell</b>
-# <b>uname -a</b>
-Linux localhost 2.6.35.4-cyanogenmod #57 PREEMPT Fri Sep 10 00:11:46 UTC 2010 armv6l GNU/Linux
-</pre>
-
- <h2>logcat</h2>
- <p>Everything your Android is storing into log, <b>multiple buffers!</b></p>
-<pre>
-dpavlin@x200:/virtual/android$ <b>adb logcat -b events</b>
-</pre>
-
- <h2>multiple devices</h2>
-<pre>
-dpavlin@x200:~$ <b>export ANDROID_SERIAL=127.0.0.1:5555</b>
-</pre>
-
- </section>
- </div>
-
-
- <div class="slide">
- <section class="middle">
- <h1>Android userland</h1>
- <h2>/system/bin</h2>
- <a href="http://github.com/dpavlin/android-command-line">http://github.com/dpavlin/android-command-line</a>
- </section>
- </div>
-
-
- <div class="slide">
- <section>
- <header>
- <h1>Dump debugging informations</h1>
- </header>
- <h2>dumpstate</h2>
- <p>Big and verbose state of your device</p>
-<pre>
-dpavlin@x200:~$ <b>adb shell dumpstate > dumpstate.txt</b>
-</pre>
-
-
- <h2>dumpsys</h2>
- <p>Who is listening to those intents?</p>
-<pre>
-dpavlin@x200:~$ <b>adb shell dumpsys > dumpsys.txt
-</pre>
-
- </section>
- </div>
-
- <div class="slide">
- <section>
- <header>
- <h1>service</h1>
- </header>
- <h2>Make phone calls from command line</h2>
-<pre>
-# <b>service call phone 2 s16 "+31611530555"</b>
-</pre>
-
- <p>
- Where did <b>2</b> came from?
- <a href="http://www.androidjavadoc.com/1.0_r1_src/constant-values.html#com.android">com.android.internal.telephony.ITelephony.Stub</a>
-
- </section>
- </div>
-
- <div class="slide">
- <section>
- <header>
- <h1>am</h1>
- </header>
- <h2>Browser</h2>
-<pre>
-# <b>am start -a android.intent.action.MAIN -n com.android.browser/.BrowserActivity</b>
-</pre>
-
- <h2>Settings</h2>
-<pre>
-# <b>am start -a android.intent.action.MAIN -n com.android.settings/.Settings</b>
-</pre>
- </section>
- </section>
- </div>
-
- <div class="slide">
- <section>
- <header>
- <h1>pm</h1>
- </header>
-
-<p>
-Install application from phone to other device
-</p>
-
-<pre>
-dpavlin@x200:~$ <b>adb shell pm list packages | grep replica</b>
-package:com.replica.replicaisland
-dpavlin@x200:~$ <b>adb shell pm path com.replica.replicaisland</b>
-package:/mnt/asec/com.replica.replicaisland-1/pkg.apk
-dpavlin@x200:~$ <b>adb pull /mnt/asec/com.replica.replicaisland-1/pkg.apk</b>
-1373 KB/s (5144485 bytes in 3.658s)
-dpavlin@x200:~$ <b>ANDROID_SERIAL=192.168.1.32:5555 adb install pkg.apk</b>
-779 KB/s (5144485 bytes in 6.446s)
- pkg: /data/local/tmp/pkg.apk
-Success
-</pre>
- </section>
- </div>
-
- <div class="slide">
- <section>
- <header>
- <h1>Do we need FLOSS app market?</h1>
- </header>
-<p>
-<a href="http://lwn.net/Articles/373128/">Jonathan Corbet of LWM fame</a> think we do and I agree.
-</p>
- <h2>Working idea</h2>
-
- <ul class="bulleted">
- <li>FLOSS licence</li>
- <li>source code repository (git)</li>
- <li>all source searchable (gitweb?)</li>
- <li>automatic builds (x86 NDK?)</li>
- <li><b>download links from web!</b></li>
- <li>backup apps to cloud (CouchDB?)</li>
- </ul>
-
- <p>Anybody interested in something like that?</p>
-
- </section>
- </div>
-
-
-<!-- extra slides -->
-
- <div class="slide">
- <section class="middle">
- <h2>The Difference Between Android And iPhone</h2>
- <p><a href="http://www.androidpolice.com/2010/09/16/comic-the-difference-between-android-and-iphone-this-pretty-much-sums-it-up/">This Pretty Much Sums It Up</a>
- </section>
- </div>
-
- <div class="slide">
- <section class="middle">
- <h2>Android</h2>
- <img src="commic-Android.png">
- </section>
- </div>
-
- <div class="slide">
- <section class="middle">
- <h2>iPhone</h2>
- <img src="commic-iPhone.png">
- </section>
- </div>
-
- <div class="slide">
- <section class="middle">
- <h1>Questions?</h1>
- <h2>Comments?</h2>
- </section>
- </div>
-
- <div class="slide">
- <section class="middle">
- <h2>Slides template</h2>
- <p>Click here, Press <span class="key">→</span> key to advance.</p>
- </section>
- </div>
-
-
- <div class="slide">
- <section class="middle">
- <h2>
- Attached Events
- </h2>
- <ul>
- <li>[arrow keys] to go next and previous</p></li>
- <li>[mouse scroll wheel] to go next and previous</p></li>
- <li>[Ctrl or Command] + [+/-] to zoom in and out</p></li>
- <li>[touch gestures] for mobile devices</p></li>
- </ul>
- </section>
- </div>
-
- <div class="slide">
- <section class="middle">
- <h2>
- Options
- </h2>
- <ul>
- <li><input type="checkbox" id="toggle-size" /><label for="toggle-size"><span>Grow</span></label></li>
- <li><input type="checkbox" id="toggle-transitions" checked /><label for="toggle-transitions"><span>Transitions</span></label></li>
- <li><input type="checkbox" id="toggle-gradients" checked /><label for="toggle-gradients"><span>Gradients</span></label></li>
- <li><input type="checkbox" id="toggle-counter" checked /><label for="toggle-counter"><span>Slide numbers</span></label></li>
- </ul>
- </section>
- </div>
-
- <div class="slide">
- <section>
- <header>
- <h2>Placeholder content</h2>
- </header>
-<pre>// some sample code
-<canvas id="canvas" width="838" height="220"></canvas>
-
-<script>
- var canvasContext = document.getElementById("canvas").<b>getContext</b>("2d");
- canvasContext.<b>fillRect</b>(250, 25, 150, 100);
-
- canvasContext.<b>beginPath</b>();
- canvasContext.<b>arc</b>(450, 110, 100, Math.PI * 1/2, Math.PI * 3/2);
- canvasContext.<b>lineWidth</b> = 15;
- canvasContext.<b>lineCap</b> = 'round';
- canvasContext.<b>strokeStyle</b> = 'rgba(255, 127, 0, 0.5)';
- canvasContext.<b>stroke</b>();
-</script>
-</pre>
- <ul class="bulleted">
- <li>point 1</li>
- <li>point 2</li>
- <li>point 3</li>
- </ul>
- </section>
- </div>
-
- </div> <!-- slides -->
-
- </div> <!-- presentation -->
-
- <script>
- (function() {
- var doc = document;
- var disableBuilds = true;
-
- var ctr = 0;
- var spaces = /\s+/, a1 = [''];
-
- var toArray = function(list) {
- return Array.prototype.slice.call(list || [], 0);
- };
-
- var byId = function(id) {
- if (typeof id == 'string') { return doc.getElementById(id); }
- return id;
- };
-
- var query = function(query, root) {
- if (!query) { return []; }
- if (typeof query != 'string') { return toArray(query); }
- if (typeof root == 'string') {
- root = byId(root);
- if(!root){ return []; }
- }
-
- root = root || document;
- var rootIsDoc = (root.nodeType == 9);
- var doc = rootIsDoc ? root : (root.ownerDocument || document);
-
- // rewrite the query to be ID rooted
- if (!rootIsDoc || ('>~+'.indexOf(query.charAt(0)) >= 0)) {
- root.id = root.id || ('qUnique' + (ctr++));
- query = '#' + root.id + ' ' + query;
- }
- // don't choke on something like ".yada.yada >"
- if ('>~+'.indexOf(query.slice(-1)) >= 0) { query += ' *'; }
-
- return toArray(doc.querySelectorAll(query));
- };
-
- var strToArray = function(s) {
- if (typeof s == 'string' || s instanceof String) {
- if (s.indexOf(' ') < 0) {
- a1[0] = s;
- return a1;
- } else {
- return s.split(spaces);
- }
- }
- return s;
- };
-
- var addClass = function(node, classStr) {
- classStr = strToArray(classStr);
- var cls = ' ' + node.className + ' ';
- for (var i = 0, len = classStr.length, c; i < len; ++i) {
- c = classStr[i];
- if (c && cls.indexOf(' ' + c + ' ') < 0) {
- cls += c + ' ';
- }
- }
- node.className = cls.trim();
- };
-
- var removeClass = function(node, classStr) {
- var cls;
- if (classStr !== undefined) {
- classStr = strToArray(classStr);
- cls = ' ' + node.className + ' ';
- for (var i = 0, len = classStr.length; i < len; ++i) {
- cls = cls.replace(' ' + classStr[i] + ' ', ' ');
- }
- cls = cls.trim();
- } else {
- cls = '';
- }
- if (node.className != cls) {
- node.className = cls;
- }
- };
-
- var toggleClass = function(node, classStr) {
- var cls = ' ' + node.className + ' ';
- if (cls.indexOf(' ' + classStr.trim() + ' ') >= 0) {
- removeClass(node, classStr);
- } else {
- addClass(node, classStr);
- }
- };
-
- var ua = navigator.userAgent;
- var isFF = parseFloat(ua.split('Firefox/')[1]) || undefined;
- var isWK = parseFloat(ua.split('WebKit/')[1]) || undefined;
- var isOpera = parseFloat(ua.split('Opera/')[1]) || undefined;
-
- var canTransition = (function() {
- var ver = parseFloat(ua.split('Version/')[1]) || undefined;
- // test to determine if this browser can handle CSS transitions.
- var cachedCanTransition =
- (isWK || (isFF && isFF > 3.6 ) || (isOpera && ver >= 10.5));
- return function() { return cachedCanTransition; }
- })();
-
- //
- // Slide class
- //
- var Slide = function(node, idx) {
- this._node = node;
- if (idx >= 0) {
- this._count = idx + 1;
- }
- if (this._node) {
- addClass(this._node, 'slide distant-slide');
- }
- this._makeCounter();
- this._makeBuildList();
- };
-
- Slide.prototype = {
- _node: null,
- _count: 0,
- _buildList: [],
- _visited: false,
- _currentState: '',
- _states: [ 'distant-slide', 'far-past',
- 'past', 'current', 'future',
- 'far-future', 'distant-slide' ],
- setState: function(state) {
- if (typeof state != 'string') {
- state = this._states[state];
- }
- if (state == 'current' && !this._visited) {
- this._visited = true;
- this._makeBuildList();
- }
- removeClass(this._node, this._states);
- addClass(this._node, state);
- this._currentState = state;
-
- // delay first auto run. Really wish this were in CSS.
- /*
- this._runAutos();
- */
- var _t = this;
- setTimeout(function(){ _t._runAutos(); } , 400);
- },
- _makeCounter: function() {
- if(!this._count || !this._node) { return; }
- var c = doc.createElement('span');
- c.innerHTML = this._count;
- c.className = 'counter';
- this._node.appendChild(c);
- },
- _makeBuildList: function() {
- this._buildList = [];
- if (disableBuilds) { return; }
- if (this._node) {
- this._buildList = query('[data-build] > *', this._node);
- }
- this._buildList.forEach(function(el) {
- addClass(el, 'to-build');
- });
- },
- _runAutos: function() {
- if (this._currentState != 'current') {
- return;
- }
- // find the next auto, slice it out of the list, and run it
- var idx = -1;
- this._buildList.some(function(n, i) {
- if (n.hasAttribute('data-auto')) {
- idx = i;
- return true;
- }
- return false;
- });
- if (idx >= 0) {
- var elem = this._buildList.splice(idx, 1)[0];
- var transitionEnd = isWK ? 'webkitTransitionEnd' : (isFF ? 'mozTransitionEnd' : 'oTransitionEnd');
- var _t = this;
- if (canTransition()) {
- var l = function(evt) {
- elem.parentNode.removeEventListener(transitionEnd, l, false);
- _t._runAutos();
- };
- elem.parentNode.addEventListener(transitionEnd, l, false);
- removeClass(elem, 'to-build');
- } else {
- setTimeout(function() {
- removeClass(elem, 'to-build');
- _t._runAutos();
- }, 400);
- }
- }
- },
- buildNext: function() {
- if (!this._buildList.length) {
- return false;
- }
- removeClass(this._buildList.shift(), 'to-build');
- return true;
- },
- };
-
- //
- // SlideShow class
- //
- var SlideShow = function(slides) {
- this._slides = (slides || []).map(function(el, idx) {
- return new Slide(el, idx);
- });
-
- var h = window.location.hash;
- try {
- this.current = parseInt(h.split('#slide')[1], 10);
- }catch (e) { /* squeltch */ }
- this.current = isNaN(this.current) ? 1 : this.current;
- var _t = this;
- doc.addEventListener('keydown',
- function(e) { _t.handleKeys(e); }, false);
- doc.addEventListener('mousewheel',
- function(e) { _t.handleWheel(e); }, false);
- doc.addEventListener('DOMMouseScroll',
- function(e) { _t.handleWheel(e); }, false);
- doc.addEventListener('touchstart',
- function(e) { _t.handleTouchStart(e); }, false);
- doc.addEventListener('touchend',
- function(e) { _t.handleTouchEnd(e); }, false);
- window.addEventListener('popstate',
- function(e) { _t.go(e.state); }, false);
- this._update();
- };
-
- SlideShow.prototype = {
- _slides: [],
- _update: function(dontPush) {
- document.querySelector('#presentation-counter').innerText = this.current;
- if (history.pushState) {
- if (!dontPush) {
- history.pushState(this.current, 'Slide ' + this.current, '#slide' + this.current);
- }
- } else {
- window.location.hash = 'slide' + this.current;
- }
- for (var x = this.current-1; x < this.current + 7; x++) {
- if (this._slides[x-4]) {
- this._slides[x-4].setState(Math.max(0, x-this.current));
- }
- }
- },
-
- current: 0,
- next: function() {
- if (!this._slides[this.current-1].buildNext()) {
- this.current = Math.min(this.current + 1, this._slides.length);
- this._update();
- }
- },
- prev: function() {
- this.current = Math.max(this.current-1, 1);
- this._update();
- },
- go: function(num) {
- if (history.pushState && this.current != num) {
- history.replaceState(this.current, 'Slide ' + this.current, '#slide' + this.current);
- }
- this.current = num;
- this._update(true);
- },
-
- _notesOn: false,
- showNotes: function() {
- var isOn = this._notesOn = !this._notesOn;
- query('.notes').forEach(function(el) {
- el.style.display = (notesOn) ? 'block' : 'none';
- });
- },
- switch3D: function() {
- toggleClass(document.body, 'three-d');
- },
- handleWheel: function(e) {
- var delta = 0;
- if (e.wheelDelta) {
- delta = e.wheelDelta/120;
- if (isOpera) {
- delta = -delta;
- }
- } else if (e.detail) {
- delta = -e.detail/3;
- }
-
- if (delta > 0 ) {
- this.prev();
- return;
- }
- if (delta < 0 ) {
- this.next();
- return;
- }
- },
- handleKeys: function(e) {
-
- if (/^(input|textarea)$/i.test(e.target.nodeName)) return;
-
- switch (e.keyCode) {
- case 37: // left arrow
- this.prev(); break;
- case 39: // right arrow
- case 32: // space
- this.next(); break;
- case 50: // 2
- this.showNotes(); break;
- case 51: // 3
- this.switch3D(); break;
- }
- },
- _touchStartX: 0,
- handleTouchStart: function(e) {
- this._touchStartX = e.touches[0].pageX;
- },
- handleTouchEnd: function(e) {
- var delta = this._touchStartX - e.changedTouches[0].pageX;
- var SWIPE_SIZE = 150;
- if (delta > SWIPE_SIZE) {
- this.next();
- } else if (delta< -SWIPE_SIZE) {
- this.prev();
- }
- },
- };
-
- // Initialize
- var slideshow = new SlideShow(query('.slide'));
-
-
-
-
-
- document.querySelector('#toggle-counter').addEventListener('click', toggleCounter, false);
- document.querySelector('#toggle-size').addEventListener('click', toggleSize, false);
- document.querySelector('#toggle-transitions').addEventListener('click', toggleTransitions, false);
- document.querySelector('#toggle-gradients').addEventListener('click', toggleGradients, false);
-
-
- var counters = document.querySelectorAll('.counter');
- var slides = document.querySelectorAll('.slide');
-
- function toggleCounter() {
- toArray(counters).forEach(function(el) {
- el.style.display = (el.offsetHeight) ? 'none' : 'block';
- });
- }
-
- function toggleSize() {
- toArray(slides).forEach(function(el) {
- if (!/reduced/.test(el.className)) {
- addClass(el, 'reduced');
- }
- else {
- removeClass(el, 'reduced');
- }
- });
- }
-
- function toggleTransitions() {
- toArray(slides).forEach(function(el) {
- if (!/no-transitions/.test(el.className)) {
- addClass(el, 'no-transitions');
- }
- else {
- removeClass(el, 'no-transitions');
- }
- });
- }
-
- function toggleGradients() {
- toArray(slides).forEach(function(el) {
- if (!/no-gradients/.test(el.className)) {
- addClass(el, 'no-gradients');
- }
- else {
- removeClass(el, 'no-gradients');
- }
- });
- }
-
-
-
-
-
- })();
-
-
-
- </script>
-
- <!--[if lt IE 9]>
- <script
- src="http://ajax.googleapis.com/ajax/libs/chrome-frame/1/CFInstall.min.js">
- </script>
- <script>CFInstall.check({ mode: "overlay" });</script>
- <![endif]-->
-
- </body>
-</html>