Start on adding S5 support to Instiki.

This commit is contained in:
Jacques Distler 2007-02-28 13:31:34 -06:00
parent b65a5b8e30
commit 8359047fd5
16 changed files with 1200 additions and 12 deletions

View file

@ -9,7 +9,7 @@ class WikiController < ApplicationController
caches_action :show, :published, :authors, :recently_revised, :list
cache_sweeper :revision_sweeper
layout 'default', :except => [:rss_feed, :rss_with_content, :rss_with_headlines, :tex, :pdf, :export_tex, :export_html]
layout 'default', :except => [:rss_feed, :rss_with_content, :rss_with_headlines, :tex, :pdf, :s5, :export_tex, :export_html]
def index
if @web_name
@ -56,9 +56,7 @@ class WikiController < ApplicationController
renderer = PageRenderer.new(page.revisions.last)
rendered_page = <<-EOL
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1 plus MathML 2.0//EN" "http://www.w3.org/Math/DTD/mathml2/xhtml-math11-f.dtd" >
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>#{page.plain_name} in #{@web.name}</title>
@ -283,8 +281,14 @@ class WikiController < ApplicationController
if @web.markup == :markdownMML
@tex_content = Maruku.new(@page.content).to_latex
else
@tex_content = RedClothForTex.new(@page.content).to_tex
@tex_content = RedClothForTex.new(@page.content).to_tex
end
end
def s5
if @web.markup == :markdownMML or @web.markup == :markdown
@s5_content = Maruku.new(@page.content).to_s5
end
end
protected
@ -342,8 +346,13 @@ class WikiController < ApplicationController
end
def export_web_to_tex(file_path)
# if @web.markup == :markdownMML
# @tex_content = Maruku.new(@page.content).to_latex
# else
# @tex_content = RedClothForTex.new(@page.content).to_tex
# end
@tex_content = table_of_contents(@web.page('HomePage').content, render_tex_web)
File.open(file_path, 'w') { |f| f.write(render_to_string(:template => 'wiki/tex_web', :layout => nil)) }
File.open(file_path, 'w') { |f| f.write(render_to_string(:template => 'wiki/tex_web', :layout => tex)) }
end
def get_page_and_revision
@ -407,7 +416,7 @@ class WikiController < ApplicationController
if @web.markup == :markdownMML
tex_web[page.name] = Maruku.new(page.content).to_latex
else
tex_web[page.name] = RedClothForTex.new(page.content).to_tex
tex_web[page.name] = RedClothForTex.new(page.content).to_tex
end
tex_web
end

BIN
public/s5/ui/bg-shade.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 594 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 B

BIN
public/s5/ui/default/bodybg.gif Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

View file

@ -0,0 +1,22 @@
/* The following styles size, place, and layer the slide components.
Edit these if you want to change the overall slide layout.
The commented lines can be uncommented (and modified, if necessary)
to help you with the rearrangement process. */
/* target = 1024x768 */
div#header, div#footer, .slide {width: 100%; top: 0; left: 0;}
div#header {top: 0; height: 3em; z-index: 1;}
div#footer {top: auto; bottom: 0; height: 2.5em; z-index: 5;}
.slide {top: 0; width: 92%; padding: 3.5em 4% 4%; z-index: 2; list-style: none;}
div#controls {left: 50%; bottom: 0; width: 50%; z-index: 100;}
div#controls form {text-align: right; width: 100%; margin: 0;}
#currentSlide {position: absolute; width: 10%; left: 45%; bottom: 1em; z-index: 10;}
html>body #currentSlide {position: fixed;}
/*
div#header {background: #FCC;}
div#footer {background: #CCF;}
div#controls {background: #BBD;}
div#currentSlide {background: #FFC;}
*/

View file

@ -0,0 +1,42 @@
<public:component>
<public:attach event="onpropertychange" onevent="doFix()" />
<script>
// IE5.5+ PNG Alpha Fix v1.0 by Angus Turnbull http://www.twinhelix.com
// Free usage permitted as long as this notice remains intact.
// This must be a path to a blank image. That's all the configuration you need here.
var blankImg = 'ui/default/blank.gif';
var f = 'DXImageTransform.Microsoft.AlphaImageLoader';
function filt(s, m) {
if (filters[f]) {
filters[f].enabled = s ? true : false;
if (s) with (filters[f]) { src = s; sizingMethod = m }
} else if (s) style.filter = 'progid:'+f+'(src="'+s+'",sizingMethod="'+m+'")';
}
function doFix() {
if ((parseFloat(navigator.userAgent.match(/MSIE (\S+)/)[1]) < 5.5) ||
(event && !/(background|src)/.test(event.propertyName))) return;
if (tagName == 'IMG') {
if ((/\.png$/i).test(src)) {
filt(src, 'image'); // was 'scale'
src = blankImg;
} else if (src.indexOf(blankImg) < 0) filt();
} else if (style.backgroundImage) {
if (style.backgroundImage.match(/^url[("']+(.*\.png)[)"']+$/i)) {
var s = RegExp.$1;
style.backgroundImage = '';
filt(s, 'crop');
} else filt();
}
}
doFix();
</script>
</public:component>

View file

@ -0,0 +1,122 @@
/* Following are the note styles -- edit away! */
body {
margin: 0;
padding: 1.0em;
background: #333;
color: #FFF;
font: 2em/1.4em 'Lucida Grande', Verdana, sans-serif;
}
div.timers {
background: #FFF;
color: #333;
border: 0.08em solid #222;
border-top-width: 1px;
border-left-width: 1px;
float: left;
padding: 0.2em;
margin: 0 0 0.5em;
position: relative;
}
div.timers h1 {
text-align: left;
font-size: 0.6em;
line-height: 1.4em;
background-color: #FF9;
padding: 0 0.75em;
margin: 0.25em 0 0;
border: 1px solid #EE8;
}
div.timers div.controls {
position: absolute;
right: 0.25em;
top: 0.1em;
line-height: 1em;
}
div.timers h1 a {
text-decoration: none;
color: #000;
}
div.timers div.controls a {
font-size: 0.5em;
padding: 0;
color: #330;
}
div.timers a.control {
position: absolute;
text-decoration: none;
padding: 0 0.25em;
color: #AAA;
outline: 0;
}
#minus {
left: 0.25em;
}
#plus {
right: 0.25em;
}
.overtime {
background: yellow;
color: red;
border: 3px solid;
padding: 0.1em 0.25em;
font-weight: bold;
}
div.timers h2 {
font-size: 0.6em;
line-height: 1.0em;
font-weight: normal;
margin: 0 0 -0.25em;
padding-top: 0.5em;
color: #666;
}
div.timers p {margin: 0; padding: 0 0.5em;}
div.timers form {margin: 0;}
div.timers span.clock {
font-family: monospace;
}
div.timers ul {margin: 0; padding: 0; list-style: none;}
div.timers li {float: left; width: 5em; margin: 0; padding: 0 0.5em;
text-align: center;}
div#elapsed {width: 12.1em;}
div#remaining {clear: left; width: 12.1em;}
div#remaining p {text-align: center;}
#slide,
#next,
#notes,
#nextnotes {
font-size: 0.75em;
line-height: 1.4em;
clear: left;
/* max-width: 30.0em; */
text-shadow: 0.1em 0.1em 0.1em #111;
}
#next {margin-top: 2.5em;}
#next, #nextnotes {
color: #999;
font-size: 0.66em;
}
em.disclaimer {
color: #666;
}
div.collapsed h1 {display: block; font-size: 0.33em;}
div.collapsed h1 a {display: inline;}
div.collapsed * {display: none;}

View file

@ -0,0 +1,7 @@
/* DO NOT CHANGE THESE unless you really want to break Opera Show */
.slide {
visibility: visible !important;
position: static !important;
page-break-before: always;
}
#slide0 {page-break-before: avoid;}

View file

@ -0,0 +1,15 @@
/* don't change this unless you want the layout stuff to show up in the outline view! */
.layout div, #footer *, #controlForm * {display: none;}
#footer, #controls, #controlForm, #navLinks, #toggle {
display: block; visibility: visible; margin: 0; padding: 0;}
#toggle {float: right; padding: 0.5em;}
html>body #toggle {position: fixed; top: 0; right: 0;}
/* making the outline look pretty-ish */
#slide0 h1, #slide0 h2, #slide0 h3, #slide0 h4 {border: none; margin: 0;}
#slide0 h1 {padding-top: 1.5em;}
.slide h1 {margin: 1.5em 0 0; padding-top: 0.25em;
border-top: 1px solid #888; border-bottom: 1px solid #AAA;}
#toggle {border: 1px solid; border-width: 0 0 1px 1px; background: #FFF;}

View file

@ -0,0 +1,82 @@
/* Following are the presentation styles -- edit away! */
body {background: #FFF url(bodybg.gif) -16px 0 no-repeat; color: #000; font-size: 2.25em;}
:link, :visited {text-decoration: none; color: #00C;}
#controls :active {color: #88A !important;}
#controls :focus {outline: 1px dotted #227;}
h1, h2, h3, h4 {font-size: 100%; margin: 0; padding: 0; font-weight: inherit;}
ul, pre {margin: 0; line-height: 1em;}
html, body {margin: 0; padding: 0;}
blockquote, q {font-style: italic;}
blockquote {padding: 0 2em 0.5em; margin: 0 1.5em 0.5em; text-align: center; font-size: 1em;}
blockquote p {margin: 0;}
blockquote i {font-style: normal;}
blockquote b {display: block; margin-top: 0.5em; font-weight: normal; font-size: smaller; font-style: normal;}
blockquote b i {font-style: italic;}
kbd {font-weight: bold; font-size: 1em;}
sup {font-size: smaller; line-height: 1px;}
.slide code {padding: 2px 0.25em; font-weight: bold; color: #533;}
.slide code.bad, code del {color: red;}
.slide code.old {color: silver;}
.slide pre {padding: 0; margin: 0.25em 0 0.5em 0.5em; color: #533; font-size: 90%;}
.slide pre code {display: block;}
.slide ul {margin-left: 5%; margin-right: 7%; list-style: disc;}
.slide li {margin-top: 0.75em; margin-right: 0;}
.slide ul ul {line-height: 1;}
.slide ul ul li {margin: .2em; font-size: 85%; list-style: square;}
.slide img.leader {display: block; margin: 0 auto;}
div#header, div#footer {background: #005; color: #AAB;
font-family: Verdana, Helvetica, sans-serif;}
div#header {background: #005 url(bodybg.gif) -16px 0 no-repeat;
line-height: 1px;}
div#footer {font-size: 0.5em; font-weight: bold; padding: 1em 0;}
#footer h1, #footer h2 {display: block; padding: 0 1em;}
#footer h2 {font-style: italic;}
div.long {font-size: 0.75em;}
.slide h1 {position: absolute; top: 0.7em; left: 87px; z-index: 1;
margin: 0; padding: 0.3em 0 0 50px; white-space: nowrap;
font: bold 150%/1em Helvetica, sans-serif; text-transform: capitalize;
color: #DDE; background: #005;}
.slide h3 {font-size: 130%;}
h1 abbr {font-variant: small-caps;}
div#controls {position: absolute; left: 60%; bottom: 0;
width: 40%;
text-align: right; font: bold 0.9em Verdana, Helvetica, sans-serif;}
html>body div#controls {position: fixed; padding: 0; top: auto;}
#controls #navLinks a {padding: 0; margin: 0 0.5em;
background: #005; border: none; color: #779;
cursor: pointer;}
#controls #navList #jumplist {background: #DDD; color: #227;}
#currentSlide {text-align: center; font-size: 0.5em; color: #449;}
#slide0 {padding-top: 3.5em; font-size: 90%;}
#slide0 h1 {position: static; margin: 1em 0 0; padding: 0;
font: bold 2em Helvetica, sans-serif; white-space: normal;
color: #000; background: transparent;}
#slide0 h2 {font: bold italic 1em Helvetica, sans-serif; margin: 0.25em;}
#slide0 h3 {margin-top: 1.5em; font-size: 1.5em;}
#slide0 h4 {margin-top: 0; font-size: 1em;}
ul.urls {list-style: none; display: inline; margin: 0;}
.urls li {display: inline; margin: 0;}
.note {display: none;}
.external {border-bottom: 1px dotted gray;}
html>body .external {border-bottom: none;}
.external:after {content: " \274F"; font-size: smaller; color: #77B;}
.incremental, .incremental *, .incremental *:after {color: #DDE; visibility: visible;}
img.incremental {visibility: hidden;}
.slide .current {color: #B02;}
/* diagnostics
li:after {content: " [" attr(class) "]"; color: #F88;}
*/

View file

@ -0,0 +1 @@
/* The following rule is necessary to have all slides appear in print! DO NOT REMOVE IT! */ .slide, ul {page-break-inside: avoid; visibility: visible !important;} h1 {page-break-after: avoid;} body {font-size: 12pt; background: white;} * {color: black;} #slide0 h1 {font-size: 200%; border: none; margin: 0.5em 0 0.25em;} #slide0 h3 {margin: 0; padding: 0;} #slide0 h4 {margin: 0 0 0.5em; padding: 0;} #slide0 {margin-bottom: 3em;} h1 {border-top: 2pt solid gray; border-bottom: 1px dotted silver;} .extra {background: transparent !important;} div.extra, pre.extra, .example {font-size: 10pt; color: #333;} ul.extra a {font-weight: bold;} p.example {display: none;} #header {display: none;} #footer h1 {margin: 0; border-bottom: 1px solid; color: gray; font-style: italic;} #footer h2, #controls {display: none;} /* The following rule keeps the layout stuff out of print. Remove at your own risk! */ .layout, .layout * {display: none !important;}

View file

@ -0,0 +1,9 @@
/* Do not edit or override these styles! The system will likely break if you do. */
div#header, div#footer, div#controls, .slide {position: absolute;}
html>body div#header, html>body div#footer,
html>body div#controls, html>body .slide {position: fixed;}
.handout, .notes {display: none;}
.layout {display: block;}
.slide, .hideme, .incremental {visibility: hidden;}
#slide0 {visibility: visible;}

View file

@ -0,0 +1,3 @@
@import url(s5-core.css); /* required to make the slide show run at all */
@import url(framing.css); /* sets basic placement and size of slide components */
@import url(pretty.css); /* stuff that makes the slides look better than blah */

View file

@ -0,0 +1,812 @@
// S5 v1.2a1 slides.js -- released into the Public Domain
//
// Please see http://www.meyerweb.com/eric/tools/s5/credits.html for information
// about all the wonderful and talented contributors to this code!
var undef;
var slideCSS = '';
var snum = 0;
var smax = 1;
var incpos = 0;
var number = undef;
var s5mode = true;
var defaultView = 'slideshow';
var controlVis = 'visible';
var s5NotesWindow;
var s5NotesWindowLoaded = false;
var previousSlide = 0;
var presentationStart = new Date();
var slideStart = new Date();
var countdown = {
timer: 0,
state: 'pause',
start: new Date(),
end: 0,
remaining: 0
};
var isIE = navigator.appName == 'Microsoft Internet Explorer' && navigator.userAgent.indexOf('Opera') < 1 ? 1 : 0;
var isOp = navigator.userAgent.indexOf('Opera') > -1 ? 1 : 0;
var isGe = navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('Safari') < 1 ? 1 : 0;
function hasClass(object, className) {
if (!object.className) return false;
return (object.className.search('(^|\\s)' + className + '(\\s|$)') != -1);
}
function hasValue(object, value) {
if (!object) return false;
return (object.search('(^|\\s)' + value + '(\\s|$)') != -1);
}
function removeClass(object,className) {
if (!object || !hasClass(object,className)) return;
object.className = object.className.replace(new RegExp('(^|\\s)'+className+'(\\s|$)'), RegExp.$1+RegExp.$2);
}
function addClass(object,className) {
if (!object || hasClass(object, className)) return;
if (object.className) {
object.className += ' '+className;
} else {
object.className = className;
}
}
function GetElementsWithClassName(elementName,className) {
var allElements = document.getElementsByTagName(elementName);
var elemColl = new Array();
for (var i = 0; i< allElements.length; i++) {
if (hasClass(allElements[i], className)) {
elemColl[elemColl.length] = allElements[i];
}
}
return elemColl;
}
function isParentOrSelf(element, id) {
if (element == null || element.nodeName=='body') return false;
else if (element.id == id) return true;
else return isParentOrSelf(element.parentNode, id);
}
function nodeValue(node) {
var result = "";
if (node.nodeType == 1) {
var children = node.childNodes;
for (var i = 0; i < children.length; ++i) {
result += nodeValue(children[i]);
}
}
else if (node.nodeType == 3) {
result = node.nodeValue;
}
return(result);
}
function slideLabel() {
var slideColl = GetElementsWithClassName('*','slide');
var list = document.getElementById('jumplist');
smax = slideColl.length;
for (var n = 0; n < smax; n++) {
var obj = slideColl[n];
var did = 'slide' + n.toString();
obj.setAttribute('id',did);
// if (isOp) continue; // Opera fix (hallvord)
var otext = '';
var menu = obj.firstChild;
if (!menu) continue; // to cope with empty slides
while (menu && menu.nodeType == 3) {
menu = menu.nextSibling;
}
if (!menu) continue; // to cope with slides with only text nodes
var menunodes = menu.childNodes;
for (var o = 0; o < menunodes.length; o++) {
otext += nodeValue(menunodes[o]);
}
list.options[list.length] = new Option(n + ' : ' + otext, n);
}
}
function currentSlide() {
var cs;
if (document.getElementById) {
cs = document.getElementById('currentSlide');
} else {
cs = document.currentSlide;
}
var plink = document.createElement('a');
plink.id = 'plink';
plink.setAttribute('href', '');
var csHere = document.createElement('span');
var csSep = document.createElement('span');
var csTotal = document.createElement('span');
csHere.id = 'csHere';
csSep.id = 'csSep';
csTotal.id = 'csTotal';
csHere.appendChild(document.createTextNode(this.snum));
csSep.appendChild(document.createTextNode('/'));
csTotal.appendChild(document.createTextNode(this.smax-1));
plink.appendChild(csHere);
plink.appendChild(csSep);
plink.appendChild(csTotal);
cs.removeChild(cs.firstChild);
cs.appendChild(plink);
if (snum == 0) {
cs.style.visibility = 'hidden';
} else {
cs.style.visibility = 'visible';
}
}
function go(step) {
if (document.getElementById('slideProj').disabled || step == 0) return;
var jl = document.getElementById('jumplist');
var cid = 'slide' + snum;
var ce = document.getElementById(cid);
if (incrementals[snum].length > 0) {
for (var i = 0; i < incrementals[snum].length; i++) {
removeClass(incrementals[snum][i], 'current');
removeClass(incrementals[snum][i], 'incremental');
}
}
if (step != 'j') {
snum += step;
lmax = smax - 1;
if (snum > lmax) snum = lmax;
if (snum < 0) snum = 0;
} else
snum = parseInt(jl.value);
var nid = 'slide' + snum;
var ne = document.getElementById(nid);
if (!ne) {
ne = document.getElementById('slide0');
snum = 0;
}
if (step < 0) {incpos = incrementals[snum].length} else {incpos = 0;}
if (incrementals[snum].length > 0 && incpos == 0) {
for (var i = 0; i < incrementals[snum].length; i++) {
if (hasClass(incrementals[snum][i], 'current'))
incpos = i + 1;
else
addClass(incrementals[snum][i], 'incremental');
}
}
if (incrementals[snum].length > 0 && incpos > 0)
addClass(incrementals[snum][incpos - 1], 'current');
if (isOp) { //hallvord
location.hash = nid;
} else {
ce.style.visibility = 'hidden';
ne.style.visibility = 'visible';
} // /hallvord
jl.selectedIndex = snum;
currentSlide();
loadNote();
permaLink();
number = undef;
}
function goTo(target) {
if (target >= smax || target == snum) return;
go(target - snum);
}
function subgo(step) {
if (step > 0) {
removeClass(incrementals[snum][incpos - 1],'current');
removeClass(incrementals[snum][incpos], 'incremental');
addClass(incrementals[snum][incpos],'current');
incpos++;
} else {
incpos--;
removeClass(incrementals[snum][incpos],'current');
addClass(incrementals[snum][incpos], 'incremental');
addClass(incrementals[snum][incpos - 1],'current');
}
loadNote();
}
function toggle() {
var slideColl = GetElementsWithClassName('*','slide');
var slides = document.getElementById('slideProj');
var outline = document.getElementById('outlineStyle');
if (!slides.disabled) {
slides.disabled = true;
outline.disabled = false;
s5mode = false;
fontSize('1em');
for (var n = 0; n < smax; n++) {
var slide = slideColl[n];
slide.style.visibility = 'visible';
}
} else {
slides.disabled = false;
outline.disabled = true;
s5mode = true;
fontScale();
for (var n = 0; n < smax; n++) {
var slide = slideColl[n];
slide.style.visibility = 'hidden';
}
slideColl[snum].style.visibility = 'visible';
}
}
function showHide(action) {
var obj = GetElementsWithClassName('*','hideme')[0];
switch (action) {
case 's': obj.style.visibility = 'visible'; break;
case 'h': obj.style.visibility = 'hidden'; break;
case 'k':
if (obj.style.visibility != 'visible') {
obj.style.visibility = 'visible';
} else {
obj.style.visibility = 'hidden';
}
break;
}
}
// 'keys' code adapted from MozPoint (http://mozpoint.mozdev.org/)
function keys(key) {
if (!key) {
key = event;
key.which = key.keyCode;
}
if (key.which == 84) {
toggle();
return;
}
if (s5mode) {
switch (key.which) {
case 10: // return
case 13: // enter
if (window.event && isParentOrSelf(window.event.srcElement, 'controls')) return;
if (key.target && isParentOrSelf(key.target, 'controls')) return;
if(number != undef) {
goTo(number);
break;
}
case 32: // spacebar
case 34: // page down
case 39: // rightkey
case 40: // downkey
if(number != undef) {
go(number);
} else if (!incrementals[snum] || incpos >= incrementals[snum].length) {
go(1);
} else {
subgo(1);
}
break;
case 33: // page up
case 37: // leftkey
case 38: // upkey
if(number != undef) {
go(-1 * number);
} else if (!incrementals[snum] || incpos <= 0) {
go(-1);
} else {
subgo(-1);
}
break;
case 36: // home
goTo(0);
break;
case 35: // end
goTo(smax-1);
break;
case 67: // c
showHide('k');
break;
case 78: // n
createNotesWindow();
break;
}
if (key.which < 48 || key.which > 57) {
number = undef;
} else {
if (window.event && isParentOrSelf(window.event.srcElement, 'controls')) return;
if (key.target && isParentOrSelf(key.target, 'controls')) return;
number = (((number != undef) ? number : 0) * 10) + (key.which - 48);
}
}
return false;
}
function clicker(e) {
number = undef;
var target;
if (window.event) {
target = window.event.srcElement;
e = window.event;
} else target = e.target;
if (target.href != null || hasValue(target.rel, 'external') || isParentOrSelf(target, 'controls') || isParentOrSelf(target,'embed') || isParentOrSelf(target,'object')) return true;
if (!e.which || e.which == 1) {
if (!incrementals[snum] || incpos >= incrementals[snum].length) {
go(1);
} else {
subgo(1);
}
}
}
function findSlide(hash) {
var target = null;
var slides = GetElementsWithClassName('*','slide');
for (var i = 0; i < slides.length; i++) {
var targetSlide = slides[i];
if ( (targetSlide.name && targetSlide.name == hash)
|| (targetSlide.id && targetSlide.id == hash) ) {
target = targetSlide;
break;
}
}
while(target != null && target.nodeName != 'body') {
if (hasClass(target, 'slide')) {
return parseInt(target.id.slice(5));
}
target = target.parentNode;
}
return null;
}
function slideJump() {
if (window.location.hash == null) return;
var sregex = /^#slide(\d+)$/;
var matches = sregex.exec(window.location.hash);
var dest = null;
if (matches != null) {
dest = parseInt(matches[1]);
} else {
dest = findSlide(window.location.hash.slice(1));
}
if (dest != null)
go(dest - snum);
}
function fixLinks() {
var thisUri = window.location.href;
thisUri = thisUri.slice(0, thisUri.length - window.location.hash.length);
var aelements = document.getElementsByTagName('A');
for (var i = 0; i < aelements.length; i++) {
var a = aelements[i].href;
var slideID = a.match('\#slide[0-9]{1,2}');
if ((slideID) && (slideID[0].slice(0,1) == '#')) {
var dest = findSlide(slideID[0].slice(1));
if (dest != null) {
if (aelements[i].addEventListener) {
aelements[i].addEventListener("click", new Function("e",
"if (document.getElementById('slideProj').disabled) return;" +
"go("+dest+" - snum); " +
"if (e.preventDefault) e.preventDefault();"), true);
} else if (aelements[i].attachEvent) {
aelements[i].attachEvent("onclick", new Function("",
"if (document.getElementById('slideProj').disabled) return;" +
"go("+dest+" - snum); " +
"event.returnValue = false;"));
}
}
}
}
}
function externalLinks() {
if (!document.getElementsByTagName) return;
var anchors = document.getElementsByTagName('a');
for (var i=0; i<anchors.length; i++) {
var anchor = anchors[i];
if (anchor.getAttribute('href') && hasValue(anchor.rel, 'external')) {
anchor.target = '_blank';
addClass(anchor,'external');
}
}
}
function permaLink() {
document.getElementById('plink').href = window.location.pathname + '#slide' + snum;
}
function createControls() {
var controlsDiv = document.getElementById("controls");
if (!controlsDiv) return;
var controlForm = document.createElement('form');
controlForm.id = 'controlForm';
controlForm.setAttribute('action', '#');
if (controlVis == 'hidden') {
controlForm.setAttribute('onmouseover', 'showHide(\'s\');');
controlForm.setAttribute('onmouseout', 'showHide(\'h\');');
}
var navLinks = document.createElement('div');
navLinks.id = 'navLinks';
var showNotes = document.createElement('a');
showNotes.id = 'show-notes';
showNotes.setAttribute('accesskey', 'n');
showNotes.setAttribute('href', 'javascript:createNotesWindow();');
showNotes.setAttribute('title', 'Show Notes');
showNotes.appendChild(document.createTextNode('\u2261'));
var toggle = document.createElement('a');
toggle.id = 'toggle';
toggle.setAttribute('accesskey', 't');
toggle.setAttribute('href', 'javascript:toggle();');
toggle.appendChild(document.createTextNode('\u00D8'));
var prev = document.createElement('a');
prev.id = 'prev';
prev.setAttribute('accesskey', 'z');
prev.setAttribute('href', 'javascript:go(-1);');
prev.appendChild(document.createTextNode('\u00AB'));
var next = document.createElement('a');
next.id = 'next';
next.setAttribute('accesskey', 'x');
next.setAttribute('href', 'javascript:go(1);');
next.appendChild(document.createTextNode('\u00BB'));
var navList = document.createElement('div');
navList.id = 'navList';
if (controlVis != 'hidden') {
navList.setAttribute('onmouseover', 'showHide(\'s\');');
navList.setAttribute('onmouseout', 'showHide(\'h\');');
}
var jumplist = document.createElement('select');
jumplist.id = 'jumplist';
jumplist.setAttribute('onchange', 'go(\'j\');');
navList.appendChild(jumplist);
navLinks.appendChild(showNotes);
navLinks.appendChild(toggle);
navLinks.appendChild(prev);
navLinks.appendChild(next);
navLinks.appendChild(navList);
controlForm.appendChild(navLinks);
controlsDiv.appendChild(controlForm);
if (controlVis == 'hidden') {
var hidden = document.getElementById('navLinks');
} else {
var hidden = document.getElementById('jumplist');
}
addClass(hidden,'hideme');
}
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
if (!s5mode) return false;
var vScale = 48; // both yield 16 (the usual browser default) at 1024x768
var hScale = 64; // perhaps should auto-calculate based on theme's declared value?
if (window.innerHeight) {
var vSize = window.innerHeight;
var hSize = window.innerWidth;
} else if (document.documentElement.clientHeight) {
var vSize = document.documentElement.clientHeight;
var hSize = document.documentElement.clientWidth;
} else if (document.body.clientHeight) {
var vSize = document.body.clientHeight;
var hSize = document.body.clientWidth;
} else {
var vSize = 700; // assuming 1024x768, minus chrome and such
var hSize = 1024; // these do not account for kiosk mode or Opera Show
}
var newSize = Math.min(Math.round(vSize/vScale),Math.round(hSize/hScale));
fontSize(newSize + 'px');
if (isGe) { // hack to counter incremental reflow bugs
var obj = document.getElementsByTagName('body')[0];
obj.style.display = 'none';
obj.style.display = 'block';
}
}
function fontSize(value) {
if (!(s5ss = document.getElementById('s5ss'))) {
if (!document.createStyleSheet) {
document.getElementsByTagName('head')[0].appendChild(s5ss = document.createElement('style'));
s5ss.setAttribute('media','screen, projection');
s5ss.setAttribute('id','s5ss');
} else {
document.createStyleSheet();
document.s5ss = document.styleSheets[document.styleSheets.length - 1];
}
}
if (!(document.s5ss && document.s5ss.addRule)) {
while (s5ss.lastChild) s5ss.removeChild(s5ss.lastChild);
s5ss.appendChild(document.createTextNode('html {font-size: ' + value + ' !important;}'));
} else {
document.s5ss.addRule('html','font-size: ' + value + ' !important;');
}
}
function notOperaFix() {
slideCSS = document.getElementById('slideProj').href;
var slides = document.getElementById('slideProj');
var outline = document.getElementById('outlineStyle');
slides.setAttribute('media','screen');
outline.disabled = true;
if (isGe) {
slides.setAttribute('href','null'); // Gecko fix
slides.setAttribute('href',slideCSS); // Gecko fix
}
if (isIE && document.styleSheets && document.styleSheets[0]) {
document.styleSheets[0].addRule('img', 'behavior: url(ui/default/iepngfix.htc)');
document.styleSheets[0].addRule('div', 'behavior: url(ui/default/iepngfix.htc)');
document.styleSheets[0].addRule('.slide', 'behavior: url(ui/default/iepngfix.htc)');
}
}
function getIncrementals(obj) {
var incrementals = new Array();
if (!obj)
return incrementals;
var children = obj.childNodes;
for (var i = 0; i < children.length; i++) {
var child = children[i];
if (hasClass(child, 'incremental')) {
if (child.nodeName == 'ol' || child.nodeName == 'ul') {
removeClass(child, 'incremental');
for (var j = 0; j < child.childNodes.length; j++) {
if (child.childNodes[j].nodeType == 1) {
addClass(child.childNodes[j], 'incremental');
}
}
} else {
incrementals[incrementals.length] = child;
removeClass(child,'incremental');
}
}
if (hasClass(child, 'show-first')) {
if (child.nodeName == 'ol' || child.nodeName == 'ul') {
removeClass(child, 'show-first');
if (child.childNodes[isGe].nodeType == 1) {
removeClass(child.childNodes[isGe], 'incremental');
}
} else {
incrementals[incrementals.length] = child;
}
}
incrementals = incrementals.concat(getIncrementals(child));
}
return incrementals;
}
function createIncrementals() {
var incrementals = new Array();
for (var i = 0; i < smax; i++) {
incrementals[i] = getIncrementals(document.getElementById('slide'+i));
}
return incrementals;
}
function defaultCheck() {
var allMetas = document.getElementsByTagName('meta');
for (var i = 0; i< allMetas.length; i++) {
if (allMetas[i].name == 'defaultView') {
defaultView = allMetas[i].content;
}
if (allMetas[i].name == 'controlVis') {
controlVis = allMetas[i].content;
}
}
}
// Key trap fix, new function body for trap()
function trap(e) {
if (!e) {
e = event;
e.which = e.keyCode;
}
try {
modifierKey = e.ctrlKey || e.altKey || e.metaKey;
}
catch(e) {
modifierKey = false;
}
return modifierKey || e.which == 0;
}
function noteLabel() { // Gives notes id's to match parent slides
var notes = GetElementsWithClassName('div','notes');
for (var i = 0; i < notes.length; i++) {
var note = notes[i];
var id = 'note' + note.parentNode.id.substring(5);
note.setAttribute('id',id);
}
resetElapsedSlide();
resetRemainingTime();
window.setInterval('updateElaspedTime()', 1000);
}
function createNotesWindow() { // creates a window for our notes
if (!s5NotesWindow || s5NotesWindow.closed) { // Create the window if it doesn't exist
s5NotesWindowLoaded = false;
// Note: Safari has a tendency to ignore window options preferring to default to the settings of the parent window, grr.
s5NotesWindow = window.open('ui/s5-notes.html', 's5NotesWindow', 'top=0,left=0');
}
if (s5NotesWindowLoaded) { // Load the current note if the Note HTML has loaded
loadNote();
} else { // Keep trying...
window.setTimeout('createNotesWindow()', 50);
}
}
function loadNote() {
// Loads a note into the note window
var notes = nextNotes = '<em class="disclaimer">There are no notes for this slide.</em>';
if (document.getElementById('note' + snum)) {
notes = document.getElementById('note' + snum).innerHTML;
}
if (document.getElementById('note' + (snum + 1))) {
nextNotes = document.getElementById('note' + (snum + 1)).innerHTML;
}
var jl = document.getElementById('jumplist');
var slideTitle = jl.options[jl.selectedIndex].text.replace(/^\d+\s+:\s+/, '') + ((jl.selectedIndex) ? ' (' + jl.selectedIndex + '/' + (smax - 1) + ')' : '');
if (incrementals[snum].length > 0) {
// alert('howdy');
slideTitle += ' <small>[' + incpos + '/' + incrementals[snum].length + ']</small>';
}
if (jl.selectedIndex < smax - 1) {
var nextTitle = jl.options[jl.selectedIndex + 1].text.replace(/^\d+\s+:\s+/, '') + ((jl.selectedIndex + 1) ? ' (' + (jl.selectedIndex + 1) + '/' + (smax - 1) + ')' : '');
} else {
var nextTitle = '[end of slide show]';
}
if (s5NotesWindow && !s5NotesWindow.closed && s5NotesWindow.document) {
s5NotesWindow.document.getElementById('slide').innerHTML = slideTitle;
s5NotesWindow.document.getElementById('notes').innerHTML = notes;
s5NotesWindow.document.getElementById('next').innerHTML = nextTitle;
s5NotesWindow.document.getElementById('nextnotes').innerHTML = nextNotes;
}
resetElapsedSlide();
}
function minimizeTimer(id) {
var obj = s5NotesWindow.document.getElementById(id);
if (hasClass(obj,'collapsed')) {
removeClass(obj,'collapsed');
} else {
addClass(obj,'collapsed');
}
}
function resetElapsedTime() {
presentationStart = new Date();
slideStart = new Date();
updateElaspedTime();
}
function resetElapsedSlide() {
if (snum != previousSlide) {
slideStart = new Date();
previousSlide = snum;
updateElaspedTime();
}
}
function updateElaspedTime() {
if (!s5NotesWindowLoaded || !s5NotesWindow || s5NotesWindow.closed) return;
var now = new Date();
var ep = s5NotesWindow.document.getElementById('elapsed-presentation');
var es = s5NotesWindow.document.getElementById('elapsed-slide');
ep.removeChild(ep.firstChild);
ep.appendChild(document.createTextNode(formatTime(now.valueOf() - presentationStart.valueOf())));
es.removeChild(es.firstChild);
es.appendChild(document.createTextNode(formatTime(now.valueOf() - slideStart.valueOf())));
}
function resetRemainingTime() {
if (!s5NotesWindowLoaded || !s5NotesWindow || s5NotesWindow.closed) return;
var startField = s5NotesWindow.document.getElementById('startFrom');
startFrom = readTime(startField.value);
countdown.remaining = startFrom * 60000; // convert to msecs
countdown.start = new Date().valueOf();
countdown.end = countdown.start + countdown.remaining;
var tl = s5NotesWindow.document.getElementById('timeLeft');
var timeLeft = formatTime(countdown.remaining);
tl.removeChild(tl.firstChild);
tl.appendChild(document.createTextNode(timeLeft));
}
function updateRemainingTime() {
if (!s5NotesWindowLoaded || !s5NotesWindow || s5NotesWindow.closed) return;
var tl = s5NotesWindow.document.getElementById('timeLeft');
var now = new Date();
if (countdown.state == 'run') {
countdown.remaining = countdown.end - now;
}
tl.style.color = '';
tl.style.backgroundColor = '';
if (countdown.remaining >= 0) {
var timeLeft = formatTime(countdown.remaining);
removeClass(tl,'overtime');
if (countdown.remaining < 300000) {
tl.style.color = 'rgb(' + (255-Math.round(countdown.remaining/2000)) + ',0,0)';
tl.style.backgroundColor = 'rgb(255,255,' + (Math.round(countdown.remaining/2000)) + ')';
}
} else {
var timeLeft = '-' + formatTime(-countdown.remaining);
addClass(tl,'overtime');
}
tl.removeChild(tl.firstChild);
tl.appendChild(document.createTextNode(timeLeft));
}
function toggleRemainingTime() {
if (countdown.state == 'pause') countdown.state = 'run'; else countdown.state = 'pause';
if (countdown.state == 'pause') {
window.clearInterval(countdown.timer);
}
if (countdown.state == 'run') {
countdown.start = new Date().valueOf();
countdown.end = countdown.start + countdown.remaining;
countdown.timer = window.setInterval('updateRemainingTime()', 1000);
}
}
function alterRemainingTime(amt) {
var change = amt * 60000; // convert to msecs
countdown.end += change;
countdown.remaining += change;
updateRemainingTime();
}
function formatTime(msecs) {
var time = new Date(msecs);
var hrs = time.getUTCHours() + ((time.getUTCDate() -1) * 24); // I doubt anyone will spend more than 24 hours on a presentation or single slide but just in case...
hrs = (hrs < 10) ? '0'+hrs : hrs;
if (hrs == 'NaN' || isNaN(hrs)) hrs = '--';
var min = time.getUTCMinutes();
min = (min < 10) ? '0'+min : min;
if (min == 'NaN' || isNaN(min)) min = '--';
var sec = time.getUTCSeconds();
sec = (sec < 10) ? '0'+sec : sec;
if (sec == 'NaN' || isNaN(sec)) sec = '--';
return hrs + ':' + min + ':' + sec;
}
function readTime(val) {
var sregex = /:/;
var matches = sregex.exec(val);
if (matches == null) {
return val;
} else {
var times = val.split(':');
var hours = parseInt(times[0]);
var mins = parseInt(times[1]);
var total = (hours * 60) + mins;
return total;
}
}
function windowChange() {
fontScale();
}
function startup() {
defaultCheck();
createControls(); // hallvord
slideLabel();
incrementals = createIncrementals();
noteLabel(); // [SI:060104] must follow slideLabel()
loadNote();
fixLinks();
externalLinks();
fontScale();
if (!isOp) notOperaFix();
slideJump();
if (defaultView == 'outline') {
toggle();
}
document.onkeyup = keys;
document.onkeypress = trap;
document.onclick = clicker;
}
window.onload = startup;
window.onresize = function(){setTimeout('windowChange()',5);}

View file

@ -0,0 +1,64 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!-- Do not edit this document! The system will likely break if you do. -->
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Notes</title>
<link rel="stylesheet" href="default/notes.css" type="text/css" />
<script type="text/javascript">
// <![CDATA[
document.onkeyup = opener.keys;
document.onkeypress = opener.trap;
document.onclick = opener.clicker;
// ]]>
</script>
</head>
<body onload="opener.s5NotesWindowLoaded=true;" onunload="opener.s5NotesWindowLoaded=false;">
<div class="timers" id="elapsed">
<h1>
<a href="#" onclick="opener.minimizeTimer('elapsed'); return false;">Elapsed Time</a>
</h1>
<ul>
<li>
<h2>Presentation</h2>
<span class="clock" id="elapsed-presentation">00:00:00</span>
</li>
<li>
<h2>Current Slide</h2>
<span class="clock" id="elapsed-slide">00:00:00</span>
</li>
</ul>
<div class="controls">
<a href="#reset-elapsed" onclick="opener.resetElapsedTime(); return false;" title="Reset Elapsed Time">|&larr;</a>
</div>
</div>
<div class="timers" id="remaining">
<h1>
<a href="#" onclick="opener.minimizeTimer('remaining'); return false;">Remaining Time</a>
</h1>
<p>
<a href="#subtract-remaining" class="control" id="minus" onclick="opener.alterRemainingTime('-5'); return false;" title="Subtract 5 Minutes">-</a>
<span class="clock" id="timeLeft">00:00:00</span>
<a href="#add-remaining" class="control" id="plus" onclick="opener.alterRemainingTime('5'); return false;" title="Add 5 Minutes">+</a>
</p>
<div class="controls">
<form action="#" onsubmit="opener.resetRemainingTime(); return false;">
<input type="text" class="text" id="startFrom" value="0" size="4" maxlength="4" />
<a href="#toggle-remaining" onclick="opener.toggleRemainingTime(); return false;" title="Pause/Run Remaining Time">||</a>
<a href="#reset-remaining" onclick="opener.resetRemainingTime(); return false;" title="Reset Remaining Time">|&larr;</a>
</form>
</div>
</div>
<h2 id="slide">...</h2>
<div id="notes"></div>
<h2 id="next">...</h2>
<div id="nextnotes"></div>
</body>
</html>

View file

@ -3,11 +3,11 @@ module MaRuKu
<meta name="defaultView" content="slideshow" />
<meta name="controlVis" content="hidden" />
<link rel="stylesheet" href="ui/default/slides.css" type="text/css" media="projection" id="slideProj" />
<link rel="stylesheet" href="ui/default/outline.css" type="text/css" media="screen" id="outlineStyle" />
<link rel="stylesheet" href="ui/default/print.css" type="text/css" media="print" id="slidePrint" />
<link rel="stylesheet" href="ui/default/opera.css" type="text/css" media="projection" id="operaFix" />
<script src="ui/default/slides.js" type="text/javascript"> </script>
<link rel="stylesheet" href="s5/ui/default/slides.css" type="text/css" media="projection" id="slideProj" />
<link rel="stylesheet" href="s5/ui/default/outline.css" type="text/css" media="screen" id="outlineStyle" />
<link rel="stylesheet" href="s5/ui/default/print.css" type="text/css" media="print" id="slidePrint" />
<link rel="stylesheet" href="s5/ui/default/opera.css" type="text/css" media="projection" id="operaFix" />
<script src="s5/ui/default/slides.js" type="text/javascript"> </script>
EOF