PageRenderTime 76ms CodeModel.GetById 20ms app.highlight 51ms RepoModel.GetById 1ms app.codeStats 0ms

/templates/dzslides-aapw.html

http://txt2tags.googlecode.com/
HTML | 428 lines | 366 code | 47 blank | 15 comment | 0 complexity | e7c2b784a921a5f16166aee20c3b7b72 MD5 | raw file
  1<style>
  2  html { background-color: black; }
  3  body { background-color: white; }
  4  /* A section is a slide. It's size is 800x600, and this will never change */
  5  section {
  6      font-family: monospace;
  7      font-size: 18px;
  8  }
  9
 10/*  footer {
 11    position: absolute;
 12    bottom: 10px;
 13    right: 20px;
 14  } */
 15
 16  /* Transition effect */
 17  /* Feel free to change the transition effect for original
 18     animations. See here:
 19     https://developer.mozilla.org/en/CSS/CSS_transitions
 20     How to use CSS3 Transitions: */
 21  section {
 22      -moz-transition: top 400ms linear 0s;
 23      -webkit-transition: top 400ms linear 0s;
 24      -ms-transition: top 400ms linear 0s;
 25      transition: top 400ms linear 0s;
 26  }
 27
 28  /* Before */
 29  section { left: -150%; }
 30  /* Now */
 31  section[aria-selected] { left: 0; }
 32  /* After */
 33  section[aria-selected] ~ section { left: +150%; }
 34
 35  /* Incremental elements */
 36
 37  /* By default, visible */
 38  .incremental > * { opacity: 1; }
 39
 40  /* The current item */
 41  .incremental > *[aria-selected] { color: red; opacity: 1; }
 42
 43  /* The items to-be-selected */
 44  .incremental > *[aria-selected] ~ * { opacity: 0.2; }
 45
 46</style>
 47
 48 <!-- {{{{ dzslides core
 49#
 50#
 51#     __  __  __       .  __   ___  __
 52#    |  \  / /__` |    | |  \ |__  /__`
 53#    |__/ /_ .__/ |___ | |__/ |___ .__/ core :€
 54#
 55#
 56# The following block of code is not supposed to be edited.
 57# But if you want to change the behavior of these slides,
 58# feel free to hack it!
 59#
 60-->
 61
 62<!-- Default Style -->
 63<style>
 64  * { margin: 0; padding: 0; }
 65  details { display: none; }
 66  body {
 67    width: 800px; height: 600px;
 68    margin-left: -400px; margin-top: -300px;
 69    position: absolute; top: 50%; left: 50%;
 70    overflow: hidden;
 71  }
 72  section {
 73    position: absolute;
 74    pointer-events: none;
 75    width: 100%; height: 100%;
 76  }
 77  section[aria-selected] { pointer-events: auto; }
 78  html { overflow: hidden; }
 79  body { display: none; }
 80  body.loaded { display: block; }
 81  .incremental {visibility: hidden; }
 82  .incremental[active] {visibility: visible; }
 83</style>
 84
 85<script>
 86  var Dz = {
 87    remoteWindows: [],
 88    idx: -1,
 89    step: 0,
 90    slides: null,
 91    params: {
 92      autoplay: "1"
 93    }
 94  };
 95
 96  Dz.init = function() {
 97    document.body.className = "loaded";
 98    this.slides = $$("body > section");
 99    this.setupParams();
100    this.onhashchange();
101    this.setupTouchEvents();
102    this.onresize();
103  }
104  
105  Dz.setupParams = function() {
106    var p = window.location.search.substr(1).split('&');
107    p.forEach(function(e, i, a) {
108      var keyVal = e.split('=');
109      Dz.params[keyVal[0]] = decodeURIComponent(keyVal[1]);
110    });
111  }
112
113  Dz.onkeydown = function(aEvent) {
114    // Don't intercept keyboard shortcuts
115    if (aEvent.altKey
116      || aEvent.ctrlKey
117      || aEvent.metaKey
118      || aEvent.shiftKey) {
119      return;
120    }
121    if ( aEvent.keyCode == 37 // left arrow
122      || aEvent.keyCode == 38 // up arrow
123      || aEvent.keyCode == 33 // page up
124    ) {
125      aEvent.preventDefault();
126      this.back();
127    }
128    if ( aEvent.keyCode == 39 // right arrow
129      || aEvent.keyCode == 40 // down arrow
130      || aEvent.keyCode == 34 // page down
131    ) {
132      aEvent.preventDefault();
133      this.forward();
134    }
135    if (aEvent.keyCode == 35) { // end
136      aEvent.preventDefault();
137      this.goEnd();
138    }
139    if (aEvent.keyCode == 36) { // home
140      aEvent.preventDefault();
141      this.goStart();
142    }
143    if (aEvent.keyCode == 32) { // space
144      aEvent.preventDefault();
145      this.toggleContent();
146    }
147  }
148
149  /* Touch Events */
150
151  Dz.setupTouchEvents = function() {
152    var orgX, newX;
153    var tracking = false;
154
155    var db = document.body;
156    db.addEventListener("touchstart", start.bind(this), false);
157    db.addEventListener("touchmove", move.bind(this), false);
158
159    function start(aEvent) {
160      aEvent.preventDefault();
161      tracking = true;
162      orgX = aEvent.changedTouches[0].pageX;
163    }
164
165    function move(aEvent) {
166      if (!tracking) return;
167      newX = aEvent.changedTouches[0].pageX;
168      if (orgX - newX > 100) {
169        tracking = false;
170        this.forward();
171      } else {
172        if (orgX - newX < -100) {
173          tracking = false;
174          this.back();
175        }
176      }
177    }
178  }
179
180  /* Adapt the size of the slides to the window */
181
182  Dz.onresize = function() {
183    var db = document.body;
184    var sx = db.clientWidth / window.innerWidth;
185    var sy = db.clientHeight / window.innerHeight;
186    var transform = "scale(" + (1/Math.max(sx, sy)) + ")";
187
188    db.style.MozTransform = transform;
189    db.style.WebkitTransform = transform;
190    db.style.OTransform = transform;
191    db.style.msTransform = transform;
192    db.style.transform = transform;
193  }
194
195
196  Dz.getDetails = function(aIdx) {
197    var s = $("section:nth-of-type(" + aIdx + ")");
198    var d = s.$("details");
199    return d ? d.innerHTML : "";
200  }
201
202  Dz.onmessage = function(aEvent) {
203    var argv = aEvent.data.split(" "), argc = argv.length;
204    argv.forEach(function(e, i, a) { a[i] = decodeURIComponent(e) });
205    var win = aEvent.source;
206    if (argv[0] === "REGISTER" && argc === 1) {
207      this.remoteWindows.push(win);
208      this.postMsg(win, "REGISTERED", document.title, this.slides.length);
209      this.postMsg(win, "CURSOR", this.idx + "." + this.step);
210      return;
211    }
212    if (argv[0] === "BACK" && argc === 1)
213      this.back();
214    if (argv[0] === "FORWARD" && argc === 1)
215      this.forward();
216    if (argv[0] === "START" && argc === 1)
217      this.goStart();
218    if (argv[0] === "END" && argc === 1)
219      this.goEnd();
220    if (argv[0] === "TOGGLE_CONTENT" && argc === 1)
221      this.toggleContent();
222    if (argv[0] === "SET_CURSOR" && argc === 2)
223      window.location.hash = "#" + argv[1];
224    if (argv[0] === "GET_CURSOR" && argc === 1)
225      this.postMsg(win, "CURSOR", this.idx + "." + this.step);
226    if (argv[0] === "GET_NOTES" && argc === 1)
227      this.postMsg(win, "NOTES", this.getDetails(this.idx));
228  }
229
230  Dz.toggleContent = function() {
231    // If a Video is present in this new slide, play it.
232    // If a Video is present in the previous slide, stop it.
233    var s = $("section[aria-selected]");
234    if (s) {
235      var video = s.$("video");
236      if (video) {
237        if (video.ended || video.paused) {
238          video.play();
239        } else {
240          video.pause();
241        }
242      }
243    }
244  }
245
246  Dz.setCursor = function(aIdx, aStep) {
247    // If the user change the slide number in the URL bar, jump
248    // to this slide.
249    aStep = (aStep != 0 && typeof aStep !== "undefined") ? "." + aStep : ".0";
250    window.location.hash = "#" + aIdx + aStep;
251  }
252
253  Dz.onhashchange = function() {
254    var cursor = window.location.hash.split("#"),
255        newidx = 1,
256        newstep = 0;
257    if (cursor.length == 2) {
258      newidx = ~~cursor[1].split(".")[0];
259      newstep = ~~cursor[1].split(".")[1];
260      if (newstep > Dz.slides[newidx - 1].$$('.incremental > *').length) {
261        newstep = 0;
262        newidx++;
263      }
264    }
265    if (newidx != this.idx) {
266      this.setSlide(newidx);
267    }
268    if (newstep != this.step) {
269      this.setIncremental(newstep);
270    }
271    for (var i = 0; i < this.remoteWindows.length; i++) {
272      this.postMsg(this.remoteWindows[i], "CURSOR", this.idx + "." + this.step);
273    }
274  }
275
276  Dz.back = function() {
277    if (this.idx == 1 && this.step == 0) {
278      return;
279    }
280    if (this.step == 0) {
281      this.setCursor(this.idx - 1,
282                     this.slides[this.idx - 2].$$('.incremental > *').length);
283    } else {
284      this.setCursor(this.idx, this.step - 1);
285    }
286  }
287
288  Dz.forward = function() {
289    if (this.idx >= this.slides.length &&
290        this.step >= this.slides[this.idx - 1].$$('.incremental > *').length) {
291        return;
292    }
293    if (this.step >= this.slides[this.idx - 1].$$('.incremental > *').length) {
294      this.setCursor(this.idx + 1, 0);
295    } else {
296      this.setCursor(this.idx, this.step + 1);
297    }
298  }
299
300  Dz.goStart = function() {
301    this.setCursor(1, 0);
302  }
303
304  Dz.goEnd = function() {
305    var lastIdx = this.slides.length;
306    var lastStep = this.slides[lastIdx - 1].$$('.incremental > *').length;
307    this.setCursor(lastIdx, lastStep);
308  }
309
310  Dz.setSlide = function(aIdx) {
311    this.idx = aIdx;
312    var old = $("section[aria-selected]");
313    var next = $("section:nth-of-type("+ this.idx +")");
314    if (old) {
315      old.removeAttribute("aria-selected");
316      var video = old.$("video");
317      if (video) {
318        video.pause();
319      }
320    }
321    if (next) {
322      next.setAttribute("aria-selected", "true");
323      var video = next.$("video");
324      if (video && !!+this.params.autoplay) {
325        video.play();
326      }
327    } else {
328      // That should not happen
329      this.idx = -1;
330      // console.warn("Slide doesn't exist.");
331    }
332  }
333
334  Dz.setIncremental = function(aStep) {
335    this.step = aStep;
336    var old = this.slides[this.idx - 1].$('.incremental > *[aria-selected]');
337    if (old) {
338      old.removeAttribute('aria-selected');
339    }
340    var incrementals = this.slides[this.idx - 1].$$('.incremental');
341    if (this.step <= 0) {
342      incrementals.forEach(function(aNode) {
343        aNode.removeAttribute('active');
344      });
345      return;
346    }
347    var next = this.slides[this.idx - 1].$$('.incremental > *')[this.step - 1];
348    if (next) {
349      next.setAttribute('aria-selected', true);
350      next.parentNode.setAttribute('active', true);
351      var found = false;
352      incrementals.forEach(function(aNode) {
353        if (aNode != next.parentNode)
354          if (found)
355            aNode.removeAttribute('active');
356          else
357            aNode.setAttribute('active', true);
358        else
359          found = true;
360      });
361    } else {
362      setCursor(this.idx, 0);
363    }
364    return next;
365  }
366  
367  Dz.postMsg = function(aWin, aMsg) { // [arg0, [arg1...]]
368    aMsg = [aMsg];
369    for (var i = 2; i < arguments.length; i++)
370      aMsg.push(encodeURIComponent(arguments[i]));
371    aWin.postMessage(aMsg.join(" "), "*");
372  }
373
374  function init() {
375    Dz.init();
376    window.onkeydown = Dz.onkeydown.bind(Dz);
377    window.onresize = Dz.onresize.bind(Dz);
378    window.onhashchange = Dz.onhashchange.bind(Dz);
379    window.onmessage = Dz.onmessage.bind(Dz);
380  }
381
382  window.onload = init;
383</script>
384
385
386<script> // Helpers
387  if (!Function.prototype.bind) {
388    Function.prototype.bind = function (oThis) {
389
390      // closest thing possible to the ECMAScript 5 internal IsCallable
391      // function 
392      if (typeof this !== "function")
393      throw new TypeError(
394        "Function.prototype.bind - what is trying to be fBound is not callable"
395      );
396
397      var aArgs = Array.prototype.slice.call(arguments, 1),
398          fToBind = this,
399          fNOP = function () {},
400          fBound = function () {
401            return fToBind.apply( this instanceof fNOP ? this : oThis || window,
402                   aArgs.concat(Array.prototype.slice.call(arguments)));
403          };
404
405      fNOP.prototype = this.prototype;
406      fBound.prototype = new fNOP();
407
408      return fBound;
409    };
410  }
411
412  var $ = (HTMLElement.prototype.$ = function(aQuery) {
413    return this.querySelector(aQuery);
414  }).bind(document);
415
416  var $$ = (HTMLElement.prototype.$$ = function(aQuery) {
417    return this.querySelectorAll(aQuery);
418  }).bind(document);
419
420  NodeList.prototype.forEach = function(fun) {
421    if (typeof fun !== "function") throw new TypeError();
422    for (var i = 0; i < this.length; i++) {
423      fun.call(this, this[i]);
424    }
425  }
426
427</script>
428<!-- vim: set fdm=marker: }}} -->