Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Final presentation.

  • Loading branch information...
commit 5e7e2987767a2fdb3dbd1fc0290b49cc0389881c 1 parent f15c976
Seth House authored
189 oalug_2009-06-30_backups/presentation.txt
... ... @@ -0,0 +1,189 @@
  1 +===========================
  2 +Ogden Area Linux User Group
  3 +===========================
  4 +Backups
  5 +-------
  6 +
  7 +:Presenter: Seth House
  8 +:Date: 2009-06-30
  9 +
  10 +.. include:: <s5defs.txt>
  11 +.. footer:: ``rsync -a -delete --link-dest=$BACKUPDIR/`/bin/ls -t $BACKUPDIR | head -1` $HOME/ $BACKUPDIR/`date '+%FT%R'```
  12 +
  13 +Overview
  14 +========
  15 +
  16 +.. class:: handout
  17 +
  18 + Backup strategies depend highly on the specific needs of the system and the
  19 + user. There is no one-size-fits-all solution. Many talks on backups try to
  20 + cover many situations; I’m only going to discuss one. This advice should
  21 + suffice for *most* personal desktop usage.
  22 +
  23 + Again, it is up to you to think through your usage and how your computer is
  24 + set up in order to decide what works for you.
  25 +
  26 + Jamie W. Zawinski, famous for work on Mozilla, Netscape Navigator, and
  27 + currently maintains the XScreenSaver project.
  28 +
  29 +“The universe tends toward maximum irony. Don’t push it.”
  30 +— jwz
  31 +
  32 +
  33 +Where to Back Up Your Files
  34 +===========================
  35 +
  36 +.. class:: handout
  37 +
  38 + The backup method I’ll be talking about is as follows. Buy two external
  39 + hard drives. I know, there’s plenty of other things I’d rather spend $120
  40 + on too — do it anyway. Copy your files to one of the drives every single
  41 + day. Don’t forget — for the love of Pete, automate it. Keep that drive in
  42 + your home. Copy your files to the other drive once a month. Take it to the
  43 + office if you trust your desk space, or have a Backup Buddy and leave it at
  44 + your friend’s house. (I’ll talk about encrypting your drives at some later
  45 + date.)
  46 +
  47 +.. class:: incremental
  48 +
  49 + * Good: Keep a copy of your files on a separate partition.
  50 + * Better: Keep a copy of your files on a separate disk.
  51 + * Best:
  52 +
  53 + * Buy two external hard drives.
  54 + * Copy your files to one every day; keep it in your home.
  55 + * Copy your files to the other once a month; keep it somewhere not in
  56 + your home.
  57 +
  58 +
  59 +What Files to Back Up
  60 +=====================
  61 +
  62 +.. class:: handout
  63 +
  64 + Generally, there is no reason to back up your entire disk. Decide what you
  65 + want to backup by making notes as you build and configure your system. If
  66 + you make a change to your system that was time consuming or hard to figure
  67 + out, you’ll want to backup those changes. If your whole installation is
  68 + stock, you probably just want to backup your ``home`` folder.
  69 +
  70 +.. class:: incremental
  71 +
  72 + * ``/etc``
  73 + * ``/var``
  74 +
  75 + * ``/var/spool/mail``
  76 + * ``/var/logs``
  77 +
  78 + * ``/boot/config`` or ``/usr/src/linux/.config``
  79 + * ``$HOME``
  80 +
  81 +How to Back Up Your Files
  82 +=========================
  83 +
  84 +.. class:: handout
  85 +
  86 + There are a plethora of backup utilities, some free some commercial. We’re
  87 + going to talk about plain ‘ol ``rsync`` because it ships with every Unix
  88 + everywhere.
  89 +
  90 +`Amanda`, `Bacula`_, `rdiff-backup`_, `TimeVault`_
  91 +
  92 +.. class:: incremental
  93 +
  94 + ``rsync``
  95 +
  96 +.. _Amanda: http://amanda.zmanda.com/
  97 +.. _Bacula: http://www.bacula.org/en/
  98 +.. _rsnapshot: http://rsnapshot.org/
  99 +.. _rdiff-backup: http://www.nongnu.org/rdiff-backup/
  100 +.. _TimeVault: http://wiki.ubuntu.com/TimeVault
  101 +
  102 +
  103 +Behold! The Power of ``rsync``
  104 +==============================
  105 +
  106 +.. class:: handout
  107 +
  108 + We can replicate all the functionality of Apple’s Time Machine in a one line
  109 + command. (Hyperbole much?)
  110 +
  111 + How does this work? Well, we create an initial full backup of all your
  112 + files. Then we run a cronjob every two hours and rsync compares your
  113 + current files with the most recent backup, making hard links to everything
  114 + that is the same, and making full copies of everything that is different.
  115 +
  116 + Hard links have the following properties, given the file ``a`` with link
  117 + ``b``: the contents of the file are only stored once, so you don’t use
  118 + twice the space; if you change ``a``, you're changing ``b``, and
  119 + vice-versa; if you change the permissions or ownership of ``a``, you're
  120 + changing those of ``b`` as well, and vice-versa; if you overwrite ``a`` by
  121 + copying a third file on top of it, you will also overwrite ``b``.
  122 +
  123 + This command works because rsync always unlinks before overwriting. This is
  124 + referred to as creating `rsync Snapshots`_.
  125 +
  126 + We usually think of a file's name as being the file itself, but really
  127 + the name is a hard link. A given file can have more than one hard link
  128 + to itself--for example, a directory has at least two hard links: the
  129 + directory name and . (for when you're inside it). It also has one hard
  130 + link from each of its sub-directories (the .. file inside each one). If
  131 + you have the stat utility installed on your machine, you can find out
  132 + how many hard links a file has […].
  133 +
  134 + — Mike Rubel, http://www.mikerubel.org/computers/rsync_snapshots/#Incremental
  135 +
  136 + What happens if you rm one of the links? The answer is that rm is a bit of
  137 + a misnomer; it doesn't really remove a file, it just removes that one link
  138 + to it. A file's contents aren't truly removed until the number of links to
  139 + it reaches zero.
  140 +
  141 + Want a GUI? http://code.google.com/p/flyback/
  142 +
  143 + To restore the backed-up files, just copy them! Simple.
  144 +
  145 +.. _rsync Snapshots: http://www.mikerubel.org/computers/rsync_snapshots/
  146 +
  147 +.. class:: incremental
  148 +
  149 + `Apple’s Time Machine`_ in one line:
  150 +
  151 +.. _Apple’s Time Machine: http://en.wikipedia.org/wiki/Time_Machine_(Apple_software)#How_It_Works
  152 +
  153 +.. class:: incremental tiny
  154 +
  155 + ::
  156 +
  157 + 0 */2 * * * BACKUPDIR=/var/timemachine/$USER;\
  158 + rsync -a -delete\
  159 + --link-dest=$BACKUPDIR/`/bin/ls -t $BACKUPDIR | head -1`\
  160 + $HOME/ $BACKUPDIR/`date '+%FT%R'`
  161 +
  162 +.. ** vim syntax highlighting fix
  163 +
  164 +.. class:: incremental
  165 +
  166 + You have to manually create the initial backup with:
  167 +
  168 +.. class:: incremental tiny
  169 +
  170 + ::
  171 +
  172 + rsync -a $HOME/ /var/timemachine/$USER/`date '+%FT%R'`
  173 +
  174 +
  175 +Useful ``rsync`` Flags
  176 +======================
  177 +
  178 +``-x``
  179 + Avoid crossing filesystem boundries.
  180 +``--exclude``
  181 + Do not sync any files or directories that match a pattern or path.
  182 +``--dry-run``
  183 + Don’t make any actual changes to the filesystem.
  184 +``-P``
  185 + Resume partially transfered files and show a progress meter.
  186 +
  187 +
  188 +
  189 +.. vim:filetype=rst
BIN  oalug_2009-06-30_backups/ui/small-black/blank.gif
24 oalug_2009-06-30_backups/ui/small-black/framing.css
... ... @@ -0,0 +1,24 @@
  1 +/* This file has been placed in the public domain. */
  2 +/* The following styles size, place, and layer the slide components.
  3 + Edit these if you want to change the overall slide layout.
  4 + The commented lines can be uncommented (and modified, if necessary)
  5 + to help you with the rearrangement process. */
  6 +
  7 +/* target = 1024x768 */
  8 +
  9 +div#header, div#footer, .slide {width: 100%; top: 0; left: 0;}
  10 +div#footer {top: auto; bottom: 0; height: 2.5em; z-index: 5;}
  11 +.slide {top: 0; width: 92%; padding: 1em 4% 0 4%; z-index: 2;}
  12 +div#controls {left: 50%; bottom: 0; width: 50%; z-index: 100;}
  13 +div#controls form {position: absolute; bottom: 0; right: 0; width: 100%;
  14 + margin: 0;}
  15 +#currentSlide {position: absolute; width: 10%; left: 45%; bottom: 1em;
  16 + z-index: 10;}
  17 +html>body #currentSlide {position: fixed;}
  18 +
  19 +/*
  20 +div#header {background: #FCC;}
  21 +div#footer {background: #CCF;}
  22 +div#controls {background: #BBD;}
  23 +div#currentSlide {background: #FFC;}
  24 +*/
42 oalug_2009-06-30_backups/ui/small-black/iepngfix.htc
... ... @@ -0,0 +1,42 @@
  1 +<public:component>
  2 +<public:attach event="onpropertychange" onevent="doFix()" />
  3 +
  4 +<script>
  5 +
  6 +// IE5.5+ PNG Alpha Fix v1.0 by Angus Turnbull http://www.twinhelix.com
  7 +// Free usage permitted as long as this notice remains intact.
  8 +
  9 +// This must be a path to a blank image. That's all the configuration you need here.
  10 +var blankImg = 'ui/small-black/blank.gif';
  11 +
  12 +var f = 'DXImageTransform.Microsoft.AlphaImageLoader';
  13 +
  14 +function filt(s, m) {
  15 + if (filters[f]) {
  16 + filters[f].enabled = s ? true : false;
  17 + if (s) with (filters[f]) { src = s; sizingMethod = m }
  18 + } else if (s) style.filter = 'progid:'+f+'(src="'+s+'",sizingMethod="'+m+'")';
  19 +}
  20 +
  21 +function doFix() {
  22 + if ((parseFloat(navigator.userAgent.match(/MSIE (\S+)/)[1]) < 5.5) ||
  23 + (event && !/(background|src)/.test(event.propertyName))) return;
  24 +
  25 + if (tagName == 'IMG') {
  26 + if ((/\.png$/i).test(src)) {
  27 + filt(src, 'image'); // was 'scale'
  28 + src = blankImg;
  29 + } else if (src.indexOf(blankImg) < 0) filt();
  30 + } else if (style.backgroundImage) {
  31 + if (style.backgroundImage.match(/^url[("']+(.*\.png)[)"']+$/i)) {
  32 + var s = RegExp.$1;
  33 + style.backgroundImage = '';
  34 + filt(s, 'crop');
  35 + } else filt();
  36 + }
  37 +}
  38 +
  39 +doFix();
  40 +
  41 +</script>
  42 +</public:component>
8 oalug_2009-06-30_backups/ui/small-black/opera.css
... ... @@ -0,0 +1,8 @@
  1 +/* This file has been placed in the public domain. */
  2 +/* DO NOT CHANGE THESE unless you really want to break Opera Show */
  3 +.slide {
  4 + visibility: visible !important;
  5 + position: static !important;
  6 + page-break-before: always;
  7 +}
  8 +#slide0 {page-break-before: avoid;}
16 oalug_2009-06-30_backups/ui/small-black/outline.css
... ... @@ -0,0 +1,16 @@
  1 +/* This file has been placed in the public domain. */
  2 +/* Don't change this unless you want the layout stuff to show up in the
  3 + outline view! */
  4 +
  5 +.layout div, #footer *, #controlForm * {display: none;}
  6 +#footer, #controls, #controlForm, #navLinks, #toggle {
  7 + display: block; visibility: visible; margin: 0; padding: 0;}
  8 +#toggle {float: right; padding: 0.5em;}
  9 +html>body #toggle {position: fixed; top: 0; right: 0;}
  10 +
  11 +/* making the outline look pretty-ish */
  12 +
  13 +#slide0 h1, #slide0 h2, #slide0 h3, #slide0 h4 {border: none; margin: 0;}
  14 +#toggle {border: 1px solid; border-width: 0 0 1px 1px; background: #FFF;}
  15 +
  16 +.outline {display: inline ! important;}
116 oalug_2009-06-30_backups/ui/small-black/pretty.css
... ... @@ -0,0 +1,116 @@
  1 +/* This file has been placed in the public domain. */
  2 +/* Following are the presentation styles -- edit away! */
  3 +
  4 +html, body {margin: 0; padding: 0;}
  5 +body {background: black; color: white;}
  6 +:link, :visited {text-decoration: none; color: cyan;}
  7 +#controls :active {color: #888 !important;}
  8 +#controls :focus {outline: 1px dotted #CCC;}
  9 +h1, h2, h3, h4 {font-size: 100%; margin: 0; padding: 0; font-weight: inherit;}
  10 +
  11 +blockquote {padding: 0 2em 0.5em; margin: 0 1.5em 0.5em;}
  12 +blockquote p {margin: 0;}
  13 +
  14 +kbd {font-weight: bold; font-size: 1em;}
  15 +sup {font-size: smaller; line-height: 1px;}
  16 +
  17 +.slide pre {padding: 0; margin-left: 0; margin-right: 0; font-size: 90%;}
  18 +.slide ul ul li {list-style: square;}
  19 +.slide img.leader {display: block; margin: 0 auto;}
  20 +.slide tt {font-size: 90%;}
  21 +
  22 +div#footer {font-family: sans-serif; color: #AAA;
  23 + font-size: 0.5em; font-weight: bold; padding: 1em 0;}
  24 +#footer h1 {display: block; padding: 0 1em;}
  25 +#footer h2 {display: block; padding: 0.8em 1em 0;}
  26 +
  27 +.slide {font-size: 1.2em;}
  28 +.slide h1 {padding-top: 0; z-index: 1; margin: 0; font: bold 150% sans-serif;}
  29 +.slide h2 {font: bold 120% sans-serif; padding-top: 0.5em;}
  30 +.slide h3 {font: bold 100% sans-serif; padding-top: 0.5em;}
  31 +h1 abbr {font-variant: small-caps;}
  32 +
  33 +div#controls {position: absolute; left: 50%; bottom: 0;
  34 + width: 50%; text-align: right; font: bold 0.9em sans-serif;}
  35 +html>body div#controls {position: fixed; padding: 0 0 1em 0; top: auto;}
  36 +div#controls form {position: absolute; bottom: 0; right: 0; width: 100%;
  37 + margin: 0; padding: 0;}
  38 +#controls #navLinks a {padding: 0; margin: 0 0.5em;
  39 + border: none; color: #888; cursor: pointer;}
  40 +#controls #navList {height: 1em;}
  41 +#controls #navList #jumplist {position: absolute; bottom: 0; right: 0;
  42 + background: black; color: #CCC;}
  43 +
  44 +#currentSlide {text-align: center; font-size: 0.5em; color: #AAA;
  45 + font-family: sans-serif; font-weight: bold;}
  46 +
  47 +#slide0 {padding-top: 0em}
  48 +#slide0 h1 {position: static; margin: 1em 0 0; padding: 0;
  49 + font: bold 2em sans-serif; white-space: normal; background: transparent;}
  50 +#slide0 h2 {font: bold italic 1em sans-serif; margin: 0.25em;}
  51 +#slide0 h3 {margin-top: 1.5em; font-size: 1.5em;}
  52 +#slide0 h4 {margin-top: 0; font-size: 1em;}
  53 +
  54 +ul.urls {list-style: none; display: inline; margin: 0;}
  55 +.urls li {display: inline; margin: 0;}
  56 +.external {border-bottom: 1px dotted gray;}
  57 +html>body .external {border-bottom: none;}
  58 +.external:after {content: " \274F"; font-size: smaller; color: #FCC;}
  59 +
  60 +.incremental, .incremental *, .incremental *:after {
  61 + color: black; visibility: visible; border: 0;}
  62 +img.incremental {visibility: hidden;}
  63 +.slide .current {color: lime;}
  64 +
  65 +.slide-display {display: inline ! important;}
  66 +
  67 +.huge {font-family: sans-serif; font-weight: bold; font-size: 150%;}
  68 +.big {font-family: sans-serif; font-weight: bold; font-size: 120%;}
  69 +.small {font-size: 75%;}
  70 +.tiny {font-size: 50% !important;}
  71 +.huge tt, .big tt, .small tt, .tiny tt {font-size: 115%;}
  72 +.huge pre, .big pre, .small pre, .tiny pre {font-size: 115%;}
  73 +
  74 +.maroon {color: maroon;}
  75 +.red {color: red;}
  76 +.magenta {color: magenta;}
  77 +.fuchsia {color: fuchsia;}
  78 +.pink {color: #FAA;}
  79 +.orange {color: orange;}
  80 +.yellow {color: yellow;}
  81 +.lime {color: lime;}
  82 +.green {color: green;}
  83 +.olive {color: olive;}
  84 +.teal {color: teal;}
  85 +.cyan {color: cyan;}
  86 +.aqua {color: aqua;}
  87 +.blue {color: blue;}
  88 +.navy {color: navy;}
  89 +.purple {color: purple;}
  90 +.black {color: black;}
  91 +.gray {color: gray;}
  92 +.silver {color: silver;}
  93 +.white {color: white;}
  94 +
  95 +.left {text-align: left ! important;}
  96 +.center {text-align: center ! important;}
  97 +.right {text-align: right ! important;}
  98 +
  99 +.animation {position: relative; margin: 1em 0; padding: 0;}
  100 +.animation img {position: absolute;}
  101 +
  102 +/* Docutils-specific overrides */
  103 +
  104 +.slide table.docinfo {margin: 1em 0 0.5em 2em;}
  105 +
  106 +div.sidebar {background-color: black;}
  107 +
  108 +pre.literal-block, pre.doctest-block {background-color: black;}
  109 +
  110 +tt.docutils {background-color: black;}
  111 +
  112 +/* diagnostics */
  113 +/*
  114 +li:after {content: " [" attr(class) "]"; color: #F88;}
  115 +div:before {content: "[" attr(class) "]"; color: #F88;}
  116 +*/
24 oalug_2009-06-30_backups/ui/small-black/print.css
... ... @@ -0,0 +1,24 @@
  1 +/* This file has been placed in the public domain. */
  2 +/* The following rule is necessary to have all slides appear in print!
  3 + DO NOT REMOVE IT! */
  4 +.slide, ul {page-break-inside: avoid; visibility: visible !important;}
  5 +h1 {page-break-after: avoid;}
  6 +
  7 +body {font-size: 12pt; background: white;}
  8 +* {color: black;}
  9 +
  10 +#slide0 h1 {font-size: 200%; border: none; margin: 0.5em 0 0.25em;}
  11 +#slide0 h3 {margin: 0; padding: 0;}
  12 +#slide0 h4 {margin: 0 0 0.5em; padding: 0;}
  13 +#slide0 {margin-bottom: 3em;}
  14 +
  15 +#header {display: none;}
  16 +#footer h1 {margin: 0; border-bottom: 1px solid; color: gray;
  17 + font-style: italic;}
  18 +#footer h2, #controls {display: none;}
  19 +
  20 +.print {display: inline ! important;}
  21 +
  22 +/* The following rule keeps the layout stuff out of print.
  23 + Remove at your own risk! */
  24 +.layout, .layout * {display: none !important;}
11 oalug_2009-06-30_backups/ui/small-black/s5-core.css
... ... @@ -0,0 +1,11 @@
  1 +/* This file has been placed in the public domain. */
  2 +/* Do not edit or override these styles!
  3 + The system will likely break if you do. */
  4 +
  5 +div#header, div#footer, div#controls, .slide {position: absolute;}
  6 +html>body div#header, html>body div#footer,
  7 + html>body div#controls, html>body .slide {position: fixed;}
  8 +.handout {display: none;}
  9 +.layout {display: block;}
  10 +.slide, .hideme, .incremental {visibility: hidden;}
  11 +#slide0 {visibility: visible;}
10 oalug_2009-06-30_backups/ui/small-black/slides.css
... ... @@ -0,0 +1,10 @@
  1 +/* This file has been placed in the public domain. */
  2 +
  3 +/* required to make the slide show run at all */
  4 +@import url(s5-core.css);
  5 +
  6 +/* sets basic placement and size of slide components */
  7 +@import url(framing.css);
  8 +
  9 +/* styles that make the slides look good */
  10 +@import url(pretty.css);
558 oalug_2009-06-30_backups/ui/small-black/slides.js
... ... @@ -0,0 +1,558 @@
  1 +// S5 v1.1 slides.js -- released into the Public Domain
  2 +// Modified for Docutils (http://docutils.sf.net) by David Goodger
  3 +//
  4 +// Please see http://www.meyerweb.com/eric/tools/s5/credits.html for
  5 +// information about all the wonderful and talented contributors to this code!
  6 +
  7 +var undef;
  8 +var slideCSS = '';
  9 +var snum = 0;
  10 +var smax = 1;
  11 +var slideIDs = new Array();
  12 +var incpos = 0;
  13 +var number = undef;
  14 +var s5mode = true;
  15 +var defaultView = 'slideshow';
  16 +var controlVis = 'visible';
  17 +
  18 +var isIE = navigator.appName == 'Microsoft Internet Explorer' ? 1 : 0;
  19 +var isOp = navigator.userAgent.indexOf('Opera') > -1 ? 1 : 0;
  20 +var isGe = navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('Safari') < 1 ? 1 : 0;
  21 +
  22 +function hasClass(object, className) {
  23 + if (!object.className) return false;
  24 + return (object.className.search('(^|\\s)' + className + '(\\s|$)') != -1);
  25 +}
  26 +
  27 +function hasValue(object, value) {
  28 + if (!object) return false;
  29 + return (object.search('(^|\\s)' + value + '(\\s|$)') != -1);
  30 +}
  31 +
  32 +function removeClass(object,className) {
  33 + if (!object) return;
  34 + object.className = object.className.replace(new RegExp('(^|\\s)'+className+'(\\s|$)'), RegExp.$1+RegExp.$2);
  35 +}
  36 +
  37 +function addClass(object,className) {
  38 + if (!object || hasClass(object, className)) return;
  39 + if (object.className) {
  40 + object.className += ' '+className;
  41 + } else {
  42 + object.className = className;
  43 + }
  44 +}
  45 +
  46 +function GetElementsWithClassName(elementName,className) {
  47 + var allElements = document.getElementsByTagName(elementName);
  48 + var elemColl = new Array();
  49 + for (var i = 0; i< allElements.length; i++) {
  50 + if (hasClass(allElements[i], className)) {
  51 + elemColl[elemColl.length] = allElements[i];
  52 + }
  53 + }
  54 + return elemColl;
  55 +}
  56 +
  57 +function isParentOrSelf(element, id) {
  58 + if (element == null || element.nodeName=='BODY') return false;
  59 + else if (element.id == id) return true;
  60 + else return isParentOrSelf(element.parentNode, id);
  61 +}
  62 +
  63 +function nodeValue(node) {
  64 + var result = "";
  65 + if (node.nodeType == 1) {
  66 + var children = node.childNodes;
  67 + for (var i = 0; i < children.length; ++i) {
  68 + result += nodeValue(children[i]);
  69 + }
  70 + }
  71 + else if (node.nodeType == 3) {
  72 + result = node.nodeValue;
  73 + }
  74 + return(result);
  75 +}
  76 +
  77 +function slideLabel() {
  78 + var slideColl = GetElementsWithClassName('*','slide');
  79 + var list = document.getElementById('jumplist');
  80 + smax = slideColl.length;
  81 + for (var n = 0; n < smax; n++) {
  82 + var obj = slideColl[n];
  83 +
  84 + var did = 'slide' + n.toString();
  85 + if (obj.getAttribute('id')) {
  86 + slideIDs[n] = obj.getAttribute('id');
  87 + }
  88 + else {
  89 + obj.setAttribute('id',did);
  90 + slideIDs[n] = did;
  91 + }
  92 + if (isOp) continue;
  93 +
  94 + var otext = '';
  95 + var menu = obj.firstChild;
  96 + if (!menu) continue; // to cope with empty slides
  97 + while (menu && menu.nodeType == 3) {
  98 + menu = menu.nextSibling;
  99 + }
  100 + if (!menu) continue; // to cope with slides with only text nodes
  101 +
  102 + var menunodes = menu.childNodes;
  103 + for (var o = 0; o < menunodes.length; o++) {
  104 + otext += nodeValue(menunodes[o]);
  105 + }
  106 + list.options[list.length] = new Option(n + ' : ' + otext, n);
  107 + }
  108 +}
  109 +
  110 +function currentSlide() {
  111 + var cs;
  112 + var footer_nodes;
  113 + var vis = 'visible';
  114 + if (document.getElementById) {
  115 + cs = document.getElementById('currentSlide');
  116 + footer_nodes = document.getElementById('footer').childNodes;
  117 + } else {
  118 + cs = document.currentSlide;
  119 + footer = document.footer.childNodes;
  120 + }
  121 + cs.innerHTML = '<span id="csHere">' + snum + '<\/span> ' +
  122 + '<span id="csSep">\/<\/span> ' +
  123 + '<span id="csTotal">' + (smax-1) + '<\/span>';
  124 + if (snum == 0) {
  125 + vis = 'hidden';
  126 + }
  127 + cs.style.visibility = vis;
  128 + for (var i = 0; i < footer_nodes.length; i++) {
  129 + if (footer_nodes[i].nodeType == 1) {
  130 + footer_nodes[i].style.visibility = vis;
  131 + }
  132 + }
  133 +}
  134 +
  135 +function go(step) {
  136 + if (document.getElementById('slideProj').disabled || step == 0) return;
  137 + var jl = document.getElementById('jumplist');
  138 + var cid = slideIDs[snum];
  139 + var ce = document.getElementById(cid);
  140 + if (incrementals[snum].length > 0) {
  141 + for (var i = 0; i < incrementals[snum].length; i++) {
  142 + removeClass(incrementals[snum][i], 'current');
  143 + removeClass(incrementals[snum][i], 'incremental');
  144 + }
  145 + }
  146 + if (step != 'j') {
  147 + snum += step;
  148 + lmax = smax - 1;
  149 + if (snum > lmax) snum = lmax;
  150 + if (snum < 0) snum = 0;
  151 + } else
  152 + snum = parseInt(jl.value);
  153 + var nid = slideIDs[snum];
  154 + var ne = document.getElementById(nid);
  155 + if (!ne) {
  156 + ne = document.getElementById(slideIDs[0]);
  157 + snum = 0;
  158 + }
  159 + if (step < 0) {incpos = incrementals[snum].length} else {incpos = 0;}
  160 + if (incrementals[snum].length > 0 && incpos == 0) {
  161 + for (var i = 0; i < incrementals[snum].length; i++) {
  162 + if (hasClass(incrementals[snum][i], 'current'))
  163 + incpos = i + 1;
  164 + else
  165 + addClass(incrementals[snum][i], 'incremental');
  166 + }
  167 + }
  168 + if (incrementals[snum].length > 0 && incpos > 0)
  169 + addClass(incrementals[snum][incpos - 1], 'current');
  170 + ce.style.visibility = 'hidden';
  171 + ne.style.visibility = 'visible';
  172 + jl.selectedIndex = snum;
  173 + currentSlide();
  174 + number = 0;
  175 +}
  176 +
  177 +function goTo(target) {
  178 + if (target >= smax || target == snum) return;
  179 + go(target - snum);
  180 +}
  181 +
  182 +function subgo(step) {
  183 + if (step > 0) {
  184 + removeClass(incrementals[snum][incpos - 1],'current');
  185 + removeClass(incrementals[snum][incpos], 'incremental');
  186 + addClass(incrementals[snum][incpos],'current');
  187 + incpos++;
  188 + } else {
  189 + incpos--;
  190 + removeClass(incrementals[snum][incpos],'current');
  191 + addClass(incrementals[snum][incpos], 'incremental');
  192 + addClass(incrementals[snum][incpos - 1],'current');
  193 + }
  194 +}
  195 +
  196 +function toggle() {
  197 + var slideColl = GetElementsWithClassName('*','slide');
  198 + var slides = document.getElementById('slideProj');
  199 + var outline = document.getElementById('outlineStyle');
  200 + if (!slides.disabled) {
  201 + slides.disabled = true;
  202 + outline.disabled = false;
  203 + s5mode = false;
  204 + fontSize('1em');
  205 + for (var n = 0; n < smax; n++) {
  206 + var slide = slideColl[n];
  207 + slide.style.visibility = 'visible';
  208 + }
  209 + } else {
  210 + slides.disabled = false;
  211 + outline.disabled = true;
  212 + s5mode = true;
  213 + fontScale();
  214 + for (var n = 0; n < smax; n++) {
  215 + var slide = slideColl[n];
  216 + slide.style.visibility = 'hidden';
  217 + }
  218 + slideColl[snum].style.visibility = 'visible';
  219 + }
  220 +}
  221 +
  222 +function showHide(action) {
  223 + var obj = GetElementsWithClassName('*','hideme')[0];
  224 + switch (action) {
  225 + case 's': obj.style.visibility = 'visible'; break;
  226 + case 'h': obj.style.visibility = 'hidden'; break;
  227 + case 'k':
  228 + if (obj.style.visibility != 'visible') {
  229 + obj.style.visibility = 'visible';
  230 + } else {
  231 + obj.style.visibility = 'hidden';
  232 + }
  233 + break;
  234 + }
  235 +}
  236 +
  237 +// 'keys' code adapted from MozPoint (http://mozpoint.mozdev.org/)
  238 +function keys(key) {
  239 + if (!key) {
  240 + key = event;
  241 + key.which = key.keyCode;
  242 + }
  243 + if (key.which == 84) {
  244 + toggle();
  245 + return;
  246 + }
  247 + if (s5mode) {
  248 + switch (key.which) {
  249 + case 10: // return
  250 + case 13: // enter
  251 + if (window.event && isParentOrSelf(window.event.srcElement, 'controls')) return;
  252 + if (key.target && isParentOrSelf(key.target, 'controls')) return;
  253 + if(number != undef) {
  254 + goTo(number);
  255 + break;
  256 + }
  257 + case 32: // spacebar
  258 + case 34: // page down
  259 + case 39: // rightkey
  260 + case 40: // downkey
  261 + if(number != undef) {
  262 + go(number);
  263 + } else if (!incrementals[snum] || incpos >= incrementals[snum].length) {
  264 + go(1);
  265 + } else {
  266 + subgo(1);
  267 + }
  268 + break;
  269 + case 33: // page up
  270 + case 37: // leftkey
  271 + case 38: // upkey
  272 + if(number != undef) {
  273 + go(-1 * number);
  274 + } else if (!incrementals[snum] || incpos <= 0) {
  275 + go(-1);
  276 + } else {
  277 + subgo(-1);
  278 + }
  279 + break;
  280 + case 36: // home
  281 + goTo(0);
  282 + break;
  283 + case 35: // end
  284 + goTo(smax-1);
  285 + break;
  286 + case 67: // c
  287 + showHide('k');
  288 + break;
  289 + }
  290 + if (key.which < 48 || key.which > 57) {
  291 + number = undef;
  292 + } else {
  293 + if (window.event && isParentOrSelf(window.event.srcElement, 'controls')) return;
  294 + if (key.target && isParentOrSelf(key.target, 'controls')) return;
  295 + number = (((number != undef) ? number : 0) * 10) + (key.which - 48);
  296 + }
  297 + }
  298 + return false;
  299 +}
  300 +
  301 +function clicker(e) {
  302 + number = undef;
  303 + var target;
  304 + if (window.event) {
  305 + target = window.event.srcElement;
  306 + e = window.event;
  307 + } else target = e.target;
  308 + if (target.href != null || hasValue(target.rel, 'external') || isParentOrSelf(target, 'controls') || isParentOrSelf(target,'embed') || isParentOrSelf(target, 'object')) return true;
  309 + if (!e.which || e.which == 1) {
  310 + if (!incrementals[snum] || incpos >= incrementals[snum].length) {
  311 + go(1);
  312 + } else {
  313 + subgo(1);
  314 + }
  315 + }
  316 +}
  317 +
  318 +function findSlide(hash) {
  319 + var target = document.getElementById(hash);
  320 + if (target) {
  321 + for (var i = 0; i < slideIDs.length; i++) {
  322 + if (target.id == slideIDs[i]) return i;
  323 + }
  324 + }
  325 + return null;
  326 +}
  327 +
  328 +function slideJump() {
  329 + if (window.location.hash == null || window.location.hash == '') {
  330 + currentSlide();
  331 + return;
  332 + }
  333 + if (window.location.hash == null) return;
  334 + var dest = null;
  335 + dest = findSlide(window.location.hash.slice(1));
  336 + if (dest == null) {
  337 + dest = 0;
  338 + }
  339 + go(dest - snum);
  340 +}
  341 +
  342 +function fixLinks() {
  343 + var thisUri = window.location.href;
  344 + thisUri = thisUri.slice(0, thisUri.length - window.location.hash.length);
  345 + var aelements = document.getElementsByTagName('A');
  346 + for (var i = 0; i < aelements.length; i++) {
  347 + var a = aelements[i].href;
  348 + var slideID = a.match('\#.+');
  349 + if ((slideID) && (slideID[0].slice(0,1) == '#')) {
  350 + var dest = findSlide(slideID[0].slice(1));
  351 + if (dest != null) {
  352 + if (aelements[i].addEventListener) {
  353 + aelements[i].addEventListener("click", new Function("e",
  354 + "if (document.getElementById('slideProj').disabled) return;" +
  355 + "go("+dest+" - snum); " +
  356 + "if (e.preventDefault) e.preventDefault();"), true);
  357 + } else if (aelements[i].attachEvent) {
  358 + aelements[i].attachEvent("onclick", new Function("",
  359 + "if (document.getElementById('slideProj').disabled) return;" +
  360 + "go("+dest+" - snum); " +
  361 + "event.returnValue = false;"));
  362 + }
  363 + }
  364 + }
  365 + }
  366 +}
  367 +
  368 +function externalLinks() {
  369 + if (!document.getElementsByTagName) return;
  370 + var anchors = document.getElementsByTagName('a');
  371 + for (var i=0; i<anchors.length; i++) {
  372 + var anchor = anchors[i];
  373 + if (anchor.getAttribute('href') && hasValue(anchor.rel, 'external')) {
  374 + anchor.target = '_blank';
  375 + addClass(anchor,'external');
  376 + }
  377 + }
  378 +}
  379 +
  380 +function createControls() {
  381 + var controlsDiv = document.getElementById("controls");
  382 + if (!controlsDiv) return;
  383 + var hider = ' onmouseover="showHide(\'s\');" onmouseout="showHide(\'h\');"';
  384 + var hideDiv, hideList = '';
  385 + if (controlVis == 'hidden') {
  386 + hideDiv = hider;
  387 + } else {
  388 + hideList = hider;
  389 + }
  390 + controlsDiv.innerHTML = '<form action="#" id="controlForm"' + hideDiv + '>' +
  391 + '<div id="navLinks">' +
  392 + '<a accesskey="t" id="toggle" href="javascript:toggle();">&#216;<\/a>' +
  393 + '<a accesskey="z" id="prev" href="javascript:go(-1);">&laquo;<\/a>' +
  394 + '<a accesskey="x" id="next" href="javascript:go(1);">&raquo;<\/a>' +
  395 + '<div id="navList"' + hideList + '><select id="jumplist" onchange="go(\'j\');"><\/select><\/div>' +
  396 + '<\/div><\/form>';
  397 + if (controlVis == 'hidden') {
  398 + var hidden = document.getElementById('navLinks');
  399 + } else {
  400 + var hidden = document.getElementById('jumplist');
  401 + }
  402 + addClass(hidden,'hideme');
  403 +}
  404 +
  405 +function fontScale() { // causes layout problems in FireFox that get fixed if browser's Reload is used; same may be true of other Gecko-based browsers
  406 + if (!s5mode) return false;
  407 + var vScale = 22; // both yield 32 (after rounding) at 1024x768
  408 + var hScale = 32; // perhaps should auto-calculate based on theme's declared value?
  409 + if (window.innerHeight) {
  410 + var vSize = window.innerHeight;
  411 + var hSize = window.innerWidth;
  412 + } else if (document.documentElement.clientHeight) {
  413 + var vSize = document.documentElement.clientHeight;
  414 + var hSize = document.documentElement.clientWidth;
  415 + } else if (document.body.clientHeight) {
  416 + var vSize = document.body.clientHeight;
  417 + var hSize = document.body.clientWidth;
  418 + } else {
  419 + var vSize = 700; // assuming 1024x768, minus chrome and such
  420 + var hSize = 1024; // these do not account for kiosk mode or Opera Show
  421 + }
  422 + var newSize = Math.min(Math.round(vSize/vScale),Math.round(hSize/hScale));
  423 + fontSize(newSize + 'px');
  424 + if (isGe) { // hack to counter incremental reflow bugs
  425 + var obj = document.getElementsByTagName('body')[0];
  426 + obj.style.display = 'none';
  427 + obj.style.display = 'block';
  428 + }
  429 +}
  430 +
  431 +function fontSize(value) {
  432 + if (!(s5ss = document.getElementById('s5ss'))) {
  433 + if (!isIE) {
  434 + document.getElementsByTagName('head')[0].appendChild(s5ss = document.createElement('style'));
  435 + s5ss.setAttribute('media','screen, projection');
  436 + s5ss.setAttribute('id','s5ss');
  437 + } else {
  438 + document.createStyleSheet();
  439 + document.s5ss = document.styleSheets[document.styleSheets.length - 1];
  440 + }
  441 + }
  442 + if (!isIE) {
  443 + while (s5ss.lastChild) s5ss.removeChild(s5ss.lastChild);
  444 + s5ss.appendChild(document.createTextNode('body {font-size: ' + value + ' !important;}'));
  445 + } else {
  446 + document.s5ss.addRule('body','font-size: ' + value + ' !important;');
  447 + }
  448 +}
  449 +
  450 +function notOperaFix() {
  451 + slideCSS = document.getElementById('slideProj').href;
  452 + var slides = document.getElementById('slideProj');
  453 + var outline = document.getElementById('outlineStyle');
  454 + slides.setAttribute('media','screen');
  455 + outline.disabled = true;
  456 + if (isGe) {
  457 + slides.setAttribute('href','null'); // Gecko fix
  458 + slides.setAttribute('href',slideCSS); // Gecko fix
  459 + }
  460 + if (isIE && document.styleSheets && document.styleSheets[0]) {
  461 + document.styleSheets[0].addRule('img', 'behavior: url(ui/small-black/iepngfix.htc)');
  462 + document.styleSheets[0].addRule('div', 'behavior: url(ui/small-black/iepngfix.htc)');
  463 + document.styleSheets[0].addRule('.slide', 'behavior: url(ui/small-black/iepngfix.htc)');
  464 + }
  465 +}
  466 +
  467 +function getIncrementals(obj) {
  468 + var incrementals = new Array();
  469 + if (!obj)
  470 + return incrementals;
  471 + var children = obj.childNodes;
  472 + for (var i = 0; i < children.length; i++) {
  473 + var child = children[i];
  474 + if (hasClass(child, 'incremental')) {
  475 + if (child.nodeName == 'OL' || child.nodeName == 'UL') {
  476 + removeClass(child, 'incremental');
  477 + for (var j = 0; j < child.childNodes.length; j++) {
  478 + if (child.childNodes[j].nodeType == 1) {
  479 + addClass(child.childNodes[j], 'incremental');
  480 + }
  481 + }
  482 + } else {
  483 + incrementals[incrementals.length] = child;
  484 + removeClass(child,'incremental');
  485 + }
  486 + }
  487 + if (hasClass(child, 'show-first')) {
  488 + if (child.nodeName == 'OL' || child.nodeName == 'UL') {
  489 + removeClass(child, 'show-first');
  490 + if (child.childNodes[isGe].nodeType == 1) {
  491 + removeClass(child.childNodes[isGe], 'incremental');
  492 + }
  493 + } else {
  494 + incrementals[incrementals.length] = child;
  495 + }
  496 + }
  497 + incrementals = incrementals.concat(getIncrementals(child));
  498 + }
  499 + return incrementals;
  500 +}
  501 +
  502 +function createIncrementals() {
  503 + var incrementals = new Array();
  504 + for (var i = 0; i < smax; i++) {
  505 + incrementals[i] = getIncrementals(document.getElementById(slideIDs[i]));
  506 + }
  507 + return incrementals;
  508 +}
  509 +
  510 +function defaultCheck() {
  511 + var allMetas = document.getElementsByTagName('meta');
  512 + for (var i = 0; i< allMetas.length; i++) {
  513 + if (allMetas[i].name == 'defaultView') {
  514 + defaultView = allMetas[i].content;
  515 + }
  516 + if (allMetas[i].name == 'controlVis') {
  517 + controlVis = allMetas[i].content;
  518 + }
  519 + }
  520 +}
  521 +
  522 +// Key trap fix, new function body for trap()
  523 +function trap(e) {
  524 + if (!e) {
  525 + e = event;
  526 + e.which = e.keyCode;
  527 + }
  528 + try {
  529 + modifierKey = e.ctrlKey || e.altKey || e.metaKey;
  530 + }
  531 + catch(e) {
  532 + modifierKey = false;
  533 + }
  534 + return modifierKey || e.which == 0;
  535 +}
  536 +
  537 +function startup() {
  538 + defaultCheck();
  539 + if (!isOp) createControls();
  540 + slideLabel();
  541 + fixLinks();
  542 + externalLinks();
  543 + fontScale();
  544 + if (!isOp) {
  545 + notOperaFix();
  546 + incrementals = createIncrementals();
  547 + slideJump();
  548 + if (defaultView == 'outline') {
  549 + toggle();
  550 + }
  551 + document.onkeyup = keys;
  552 + document.onkeypress = trap;
  553 + document.onclick = clicker;
  554 + }
  555 +}
  556 +
  557 +window.onload = startup;
  558 +window.onresize = function(){setTimeout('fontScale()', 50);}

0 comments on commit 5e7e298

Please sign in to comment.
Something went wrong with that request. Please try again.