/* slidy.js Copyright (c) 2005-2010 W3C (MIT, ERCIM, Keio), All Rights Reserved. W3C liability, trademark, document use and software licensing rules apply, see: http://www.w3.org/Consortium/Legal/copyright-documents http://www.w3.org/Consortium/Legal/copyright-software */ // the slidy object implementation var w3c_slidy = { // classify which kind of browser we're running under ns_pos: (typeof window.pageYOffset!='undefined'), khtml: ((navigator.userAgent).indexOf("KHTML") >= 0 ? true : false), opera: ((navigator.userAgent).indexOf("Opera") >= 0 ? true : false), ipad: ((navigator.userAgent).indexOf("iPad") >= 0 ? true : false), iphone: ((navigator.userAgent).indexOf("iPhone") >= 0 ? true : false), ie: (typeof document.all != "undefined" && !this.opera), ie6: (!this.ns_pos && navigator.userAgent.indexOf("MSIE 6") != -1), ie7: (!this.ns_pos && navigator.userAgent.indexOf("MSIE 7") != -1), ie8: (!this.ns_pos && navigator.userAgent.indexOf("MSIE 8") != -1), ie9: (!this.ns_pos && navigator.userAgent.indexOf("MSIE 9") != -1), keyboardless: (this.ipad || this.iphone), // are we running as XHTML? (doesn't work on Opera) is_xhtml: /xml/.test(document.contentType), slide_number: 0, // integer slide count: 0, 1, 2, ... slide_number_element: null, // element containing slide number slides: [], // set to array of slide div's notes: [], // set to array of handout div's backgrounds: [], // set to array of background div's toolbar: null, // element containing toolbar title: null, // document title last_shown: null, // last incrementally shown item eos: null, // span element for end of slide indicator toc: null, // table of contents outline: null, // outline element with the focus selected_text_len: 0, // length of drag selection on document view_all: 0, // 1 to view all slides + handouts want_toolbar: true, // user preference to show/hide toolbar mouse_click_enabled: true, // enables left click for next slide scroll_hack: 0, // IE work around for position: fixed disable_slide_click: false, // used by clicked anchors lang: "en", // updated to language specified by html file help_anchor: null, // used for keyboard focus hack in showToolbar() help_page: "http://www.w3.org/Talks/Tools/Slidy2/help/help.html", help_text: "Navigate with mouse click, space bar, Cursor Left/Right, " + "or Pg Up and Pg Dn. Use S and B to change font size.", size_index: 0, size_adjustment: 0, sizes: new Array("10pt", "12pt", "14pt", "16pt", "18pt", "20pt", "22pt", "24pt", "26pt", "28pt", "30pt", "32pt"), // needed for efficient resizing last_width: 0, last_height: 0, // Needed for cross browser support for relative width/height on // object elements. The work around is to save width/height attributes // and then to recompute absolute width/height dimensions on resizing objects: [], // attach initialiation event handlers set_up: function () { var init = function() { w3c_slidy.init(); }; if (typeof window.addEventListener != "undefined") window.addEventListener("load", init, false); else window.attachEvent("onload", init); }, hide_slides: function () { if (document.body && !w3c_slidy.initialized) document.body.style.visibility = "hidden"; else setTimeout(w3c_slidy.hide_slides, 50); }, // hack to persuade IE to compute correct document height // as needed for simulating fixed positioning of toolbar ie_hack: function () { window.resizeBy(0,-1); window.resizeBy(0, 1); }, init: function () { //alert("slidy starting test 10"); document.body.style.visibility = "visible"; w3c_slidy_i18n.init(); this.add_toolbar(); this.wrap_implicit_slides(); this.collect_slides(); this.collect_notes(); this.collect_backgrounds(); this.objects = document.body.getElementsByTagName("object"); this.patch_anchors(); this.slide_number = this.find_slide_number(location.href); window.offscreenbuffering = true; this.size_adjustment = this.find_size_adjust(); this.time_left = this.find_duration(); this.hide_image_toolbar(); // suppress IE image toolbar popup this.init_outliner(); // activate fold/unfold support this.title = document.title; // work around for opera bug this.is_xhtml = (document.body.tagName == "BODY" ? false : true); if (this.slides.length > 0) { var slide = this.slides[this.slide_number]; if (this.slide_number > 0) { this.set_visibility_all_incremental("visible"); this.last_shown = this.previous_incremental_item(null); this.set_eos_status(true); } else { this.last_shown = null; this.set_visibility_all_incremental("hidden"); this.set_eos_status(!this.next_incremental_item(this.last_shown)); } this.set_location(); this.add_class(this.slides[0], "first-slide"); w3c_slidy.show_slide(slide); } this.toc = this.table_of_contents(); this.add_initial_prompt(); // bind event handlers without interfering with custom page scripts // Tap events behave too weirdly to support clicks reliably on // iPhone and iPad, so exclude these from click handler if (!this.keyboardless) this.add_listener(document.body, "click", this.mouse_button_click); this.add_listener(document, "keydown", this.key_down); this.add_listener(document, "keypress", this.key_press); this.add_listener(window, "resize", this.resized); this.add_listener(window, "scroll", this.scrolled); this.add_listener(window, "unload", this.unloaded); if (!document.body.onclick) document.body.onclick = function () { }; this.single_slide_view(); //this.set_location(); this.resized(); if (this.ie7) setTimeout(w3c_slidy.ie_hack, 100); this.show_toolbar(); // for back button detection setInterval(function () { w3c_slidy.check_location(); }, 200); w3c_slidy.initialized = true; }, // create div element with links to each slide table_of_contents: function () { var toc = this.create_element("div"); this.add_class(toc, "slidy_toc hidden"); //toc.setAttribute("tabindex", "0"); var heading = this.create_element("div"); this.add_class(heading, "toc-heading"); heading.innerHTML = "Table of Contents".localize(); toc.appendChild(heading); var previous = null; for (var i = 0; i < this.slides.length; ++i) { var title = this.has_class(this.slides[i], "title"); var num = document.createTextNode((i + 1) + ". "); toc.appendChild(num); var a = this.create_element("a"); a.setAttribute("href", "#(" + (i+1) + ")"); if (title) this.add_class(a, "titleslide"); var name = document.createTextNode(this.slide_name(i)); a.appendChild(name); a.onclick = w3c_slidy.toc_click; a.onkeydown = w3c_slidy.toc_keydown; a.previous = previous; if (previous) previous.next = a; toc.appendChild(a); if (i == 0) toc.first = a; if (i < this.slides.length - 1) { var br = this.create_element("br"); toc.appendChild(br); } previous = a; } toc.focus = function () { if (this.first) this.first.focus(); } toc.onmouseup = w3c_slidy.mouse_button_up; toc.onclick = function (e) { e||(e=window.event); if (w3c_slidy.selected_text_len <= 0) w3c_slidy.hide_table_of_contents(); w3c_slidy.stop_propagation(e); if (e.cancel != undefined) e.cancel = true; if (e.returnValue != undefined) e.returnValue = false; return false; }; document.body.insertBefore(toc, document.body.firstChild); return toc; }, is_shown_toc: function () { return !w3c_slidy.has_class(w3c_slidy.toc, "hidden"); }, show_table_of_contents: function () { w3c_slidy.remove_class(w3c_slidy.toc, "hidden"); var toc = w3c_slidy.toc; toc.focus(); if (w3c_slidy.ie7 && w3c_slidy.slide_number == 0) setTimeout(w3c_slidy.ie_hack, 100); }, hide_table_of_contents: function () { w3c_slidy.add_class(w3c_slidy.toc, "hidden"); if (!w3c_slidy.opera) w3c_slidy.help_anchor.focus(); }, toggle_table_of_contents: function () { if (w3c_slidy.is_shown_toc()) w3c_slidy.hide_table_of_contents(); else w3c_slidy.show_table_of_contents(); }, // called on clicking toc entry toc_click: function (e) { if (!e) e = window.event; var target = w3c_slidy.get_target(e); if (target && target.nodeType == 1) { var uri = target.getAttribute("href"); if (uri) { //alert("going to " + uri); var slide = w3c_slidy.slides[w3c_slidy.slide_number]; w3c_slidy.hide_slide(slide); w3c_slidy.slide_number = w3c_slidy.find_slide_number(uri); slide = w3c_slidy.slides[w3c_slidy.slide_number]; w3c_slidy.last_shown = null; w3c_slidy.set_location(); w3c_slidy.set_visibility_all_incremental("hidden"); w3c_slidy.set_eos_status(!w3c_slidy.next_incremental_item(w3c_slidy.last_shown)); w3c_slidy.show_slide(slide); //target.focus(); try { if (!w3c_slidy.opera) w3c_slidy.help_anchor.focus(); } catch (e) { } } } w3c_slidy.hide_table_of_contents(e); if (w3c_slidy.ie7) w3c_slidy.ie_hack(); w3c_slidy.stop_propagation(e); return w3c_slidy.cancel(e); }, // called onkeydown for toc entry toc_keydown: function (event) { var key; if (!event) var event = window.event; // kludge around NS/IE differences if (window.event) key = window.event.keyCode; else if (event.which) key = event.which; else return true; // Yikes! unknown browser // ignore event if key value is zero // as for alt on Opera and Konqueror if (!key) return true; // check for concurrent control/command/alt key // but are these only present on mouse events? if (event.ctrlKey || event.altKey) return true; if (key == 13) { var uri = this.getAttribute("href"); if (uri) { //alert("going to " + uri); var slide = w3c_slidy.slides[w3c_slidy.slide_number]; w3c_slidy.hide_slide(slide); w3c_slidy.slide_number = w3c_slidy.find_slide_number(uri); slide = w3c_slidy.slides[w3c_slidy.slide_number]; w3c_slidy.last_shown = null; w3c_slidy.set_location(); w3c_slidy.set_visibility_all_incremental("hidden"); w3c_slidy.set_eos_status(!w3c_slidy.next_incremental_item(w3c_slidy.last_shown)); w3c_slidy.show_slide(slide); //target.focus(); try { if (!w3c_slidy.opera) w3c_slidy.help_anchor.focus(); } catch (e) { } } w3c_slidy.hide_table_of_contents(); if (self.ie7) w3c_slidy.ie_hack(); return w3c_slidy.cancel(event); } if (key == 40 && this.next) { this.next.focus(); return w3c_slidy.cancel(event); } if (key == 38 && this.previous) { this.previous.focus(); return w3c_slidy.cancel(event); } return true; }, // ### OBSOLETE ### before_print: function () { this.show_all_slides(); this.hide_toolbar(); alert("before print"); }, // ### OBSOLETE ### after_print: function () { if (!this.view_all) { this.single_slide_view(); this.show_toolbar(); } alert("after print"); }, // ### OBSOLETE ### print_slides: function () { this.before_print(); window.print(); this.after_print(); }, // ### OBSOLETE ?? ### toggle_view: function () { if (this.view_all) { this.single_slide_view(); this.show_toolbar(); this.view_all = 0; } else { this.show_all_slides(); this.hide_toolbar(); this.view_all = 1; } }, // prepare for printing ### OBSOLETE ### show_all_slides: function () { this.remove_class(document.body, "single_slide"); this.set_visibility_all_incremental("visible"); }, // restore after printing ### OBSOLETE ### single_slide_view: function () { this.add_class(document.body, "single_slide"); this.set_visibility_all_incremental("visible"); this.last_shown = this.previous_incremental_item(null); }, // suppress IE's image toolbar pop up hide_image_toolbar: function () { if (!this.ns_pos) { var images = document.getElementsByTagName("IMG"); for (var i = 0; i < images.length; ++i) images[i].setAttribute("galleryimg", "no"); } }, unloaded: function (e) { //alert("unloaded"); }, // Safari and Konqueror don't yet support getComputedStyle() // and they always reload page when location.href is updated is_KHTML: function () { var agent = navigator.userAgent; return (agent.indexOf("KHTML") >= 0 ? true : false); }, // find slide name from first h1 element // default to document title + slide number slide_name: function (index) { var name = null; var slide = this.slides[index]; var heading = this.find_heading(slide); if (heading) name = this.extract_text(heading); if (!name) name = this.title + "(" + (index + 1) + ")"; name.replace(/\&/g, "&"); name.replace(/\/g, ">"); return name; }, // find first h1 element in DOM tree find_heading: function (node) { if (!node || node.nodeType != 1) return null; if (node.nodeName == "H1" || node.nodeName == "h1") return node; var child = node.firstChild; while (child) { node = this.find_heading(child); if (node) return node; child = child.nextSibling; } return null; }, // recursively extract text from DOM tree extract_text: function (node) { if (!node) return ""; // text nodes if (node.nodeType == 3) return node.nodeValue; // elements if (node.nodeType == 1) { node = node.firstChild; var text = ""; while (node) { text = text + this.extract_text(node); node = node.nextSibling; } return text; } return ""; }, // find copyright text from meta element find_copyright: function () { var name, content; var meta = document.getElementsByTagName("meta"); for (var i = 0; i < meta.length; ++i) { name = meta[i].getAttribute("name"); content = meta[i].getAttribute("content"); if (name == "copyright") return content; } return null; }, find_size_adjust: function () { var name, content, offset; var meta = document.getElementsByTagName("meta"); for (var i = 0; i < meta.length; ++i) { name = meta[i].getAttribute("name"); content = meta[i].getAttribute("content"); if (name == "font-size-adjustment") return 1 * content; } return 1; }, // for 20 minutes find_duration: function () { var name, content, offset; var meta = document.getElementsByTagName("meta"); for (var i = 0; i < meta.length; ++i) { name = meta[i].getAttribute("name"); content = meta[i].getAttribute("content"); if (name == "duration") return 60000 * content; } return null; }, replace_by_non_breaking_space: function (str) { for (var i = 0; i < str.length; ++i) str[i] = 160; }, // ### CHECK ME ### is use of "li" okay for text/html? // for XHTML do we also need to specify namespace? init_outliner: function () { var items = document.getElementsByTagName("li"); for (var i = 0; i < items.length; ++i) { var target = items[i]; if (!this.has_class(target.parentNode, "outline")) continue; target.onclick = this.outline_click; /* ### more work needed for IE6 if (!this.ns_pos) { target.onmouseover = this.hover_outline; target.onmouseout = this.unhover_outline; } */ if (this.foldable(target)) { target.foldable = true; target.onfocus = function () {w3c_slidy.outline = this;}; target.onblur = function () {w3c_slidy.outline = null;}; if (!target.getAttribute("tabindex")) target.setAttribute("tabindex", "0"); if (this.has_class(target, "expand")) this.unfold(target); else this.fold(target); } else { this.add_class(target, "nofold"); target.visible = true; target.foldable = false; } } }, foldable: function (item) { if (!item || item.nodeType != 1) return false; var node = item.firstChild; while (node) { if (node.nodeType == 1 && this.is_block(node)) return true; node = node.nextSibling; } return false; }, // ### CHECK ME ### switch to add/remove "hidden" class fold: function (item) { if (item) { this.remove_class(item, "unfolded"); this.add_class(item, "folded"); } var node = item ? item.firstChild : null; while (node) { if (node.nodeType == 1 && this.is_block(node)) // element { w3c_slidy.add_class(node, "hidden"); } node = node.nextSibling; } item.visible = false; }, // ### CHECK ME ### switch to add/remove "hidden" class unfold: function (item) { if (item) { this.add_class(item, "unfolded"); this.remove_class(item, "folded"); } var node = item ? item.firstChild : null; while (node) { if (node.nodeType == 1 && this.is_block(node)) // element { w3c_slidy.remove_class(node, "hidden"); } node = node.nextSibling; } item.visible = true; }, outline_click: function (e) { if (!e) e = window.event; var rightclick = false; var target = w3c_slidy.get_target(e); while (target && target.visible == undefined) target = target.parentNode; if (!target) return true; if (e.which) rightclick = (e.which == 3); else if (e.button) rightclick = (e.button == 2); if (!rightclick && target.visible != undefined) { if (target.foldable) { if (target.visible) w3c_slidy.fold(target); else w3c_slidy.unfold(target); } w3c_slidy.stop_propagation(e); e.cancel = true; e.returnValue = false; } return false; }, add_initial_prompt: function () { var prompt = this.create_element("div"); prompt.setAttribute("class", "initial_prompt"); var p1 = this.create_element("p"); prompt.appendChild(p1); p1.setAttribute("class", "help"); if (this.keyboardless) p1.innerHTML = "Tap footer to move to next slide"; else p1.innerHTML = "Space or Right Arrow to move to next " + "slide, click help below for more details"; this.add_listener(prompt, "click", function (e) { document.body.removeChild(prompt); w3c_slidy.stop_propagation(e); if (e.cancel != undefined) e.cancel = true; if (e.returnValue != undefined) e.returnValue = false; return false; }); document.body.appendChild(prompt); this.initial_prompt = prompt; setTimeout(function() {document.body.removeChild(prompt);}, 5000); }, add_toolbar: function () { var counter, page; this.toolbar = this.create_element("div"); this.toolbar.setAttribute("class", "toolbar"); // a reasonably behaved browser if (this.ns_pos || !this.ie6) { var right = this.create_element("div"); right.setAttribute("style", "float: right; text-align: right"); counter = this.create_element("span") counter.innerHTML = "slide".localize() + " n/m"; right.appendChild(counter); this.toolbar.appendChild(right); var left = this.create_element("div"); left.setAttribute("style", "text-align: left"); // global end of slide indicator this.eos = this.create_element("span"); this.eos.innerHTML = "* "; left.appendChild(this.eos); var help = this.create_element("a"); help.setAttribute("href", this.help_page); help.setAttribute("title", this.help_text.localize()); help.innerHTML = "help?".localize(); left.appendChild(help); this.help_anchor = help; // save for focus hack var gap1 = document.createTextNode(" "); left.appendChild(gap1); var contents = this.create_element("a"); contents.setAttribute("href", "javascript:w3c_slidy.toggle_table_of_contents()"); contents.setAttribute("title", "table of contents".localize()); contents.innerHTML = "contents?".localize(); left.appendChild(contents); var gap2 = document.createTextNode(" "); left.appendChild(gap2); var copyright = this.find_copyright(); if (copyright) { var span = this.create_element("span"); span.className = "copyright"; span.innerHTML = copyright; left.appendChild(span); } this.toolbar.setAttribute("tabindex", "0"); this.toolbar.appendChild(left); } else // IE6 so need to work around its poor CSS support { this.toolbar.style.position = (this.ie7 ? "fixed" : "absolute"); this.toolbar.style.zIndex = "200"; this.toolbar.style.width = "99.9%"; this.toolbar.style.height = "1.2em"; this.toolbar.style.top = "auto"; this.toolbar.style.bottom = "0"; this.toolbar.style.left = "0"; this.toolbar.style.right = "0"; this.toolbar.style.textAlign = "left"; this.toolbar.style.fontSize = "60%"; this.toolbar.style.color = "red"; this.toolbar.borderWidth = 0; this.toolbar.className = "toolbar"; this.toolbar.style.background = "rgb(240,240,240)"; // would like to have help text left aligned // and page counter right aligned, floating // div's don't work, so instead use nested // absolutely positioned div's. var sp = this.create_element("span"); sp.innerHTML = "  * "; this.toolbar.appendChild(sp); this.eos = sp; // end of slide indicator var help = this.create_element("a"); help.setAttribute("href", this.help_page); help.setAttribute("title", this.help_text.localize()); help.innerHTML = "help?".localize(); this.toolbar.appendChild(help); this.help_anchor = help; // save for focus hack var gap1 = document.createTextNode(" "); this.toolbar.appendChild(gap1); var contents = this.create_element("a"); contents.setAttribute("href", "javascript:toggleTableOfContents()"); contents.setAttribute("title", "table of contents".localize()); contents.innerHTML = "contents?".localize(); this.toolbar.appendChild(contents); var gap2 = document.createTextNode(" "); this.toolbar.appendChild(gap2); var copyright = this.find_copyright(); if (copyright) { var span = this.create_element("span"); span.innerHTML = copyright; span.style.color = "black"; span.style.marginLeft = "0.5em"; this.toolbar.appendChild(span); } counter = this.create_element("div") counter.style.position = "absolute"; counter.style.width = "auto"; //"20%"; counter.style.height = "1.2em"; counter.style.top = "auto"; counter.style.bottom = 0; counter.style.right = "0"; counter.style.textAlign = "right"; counter.style.color = "red"; counter.style.background = "rgb(240,240,240)"; counter.innerHTML = "slide".localize() + " n/m"; this.toolbar.appendChild(counter); } // ensure that click isn't passed through to the page this.toolbar.onclick = function (e) { if (!e) e = window.event; var target = e.target; if (!target && e.srcElement) target = e.srcElement; // work around Safari bug if (target && target.nodeType == 3) target = target.parentNode; w3c_slidy.stop_propagation(e); if (target && target.nodeName.toLowerCase() != "a") w3c_slidy.mouse_button_click(e); }; this.slide_number_element = counter; this.set_eos_status(false); document.body.appendChild(this.toolbar); }, // wysiwyg editors make it hard to use div elements // e.g. amaya loses the div when you copy and paste // this function wraps div elements around implicit // slides which start with an h1 element and continue // up to the next heading or div element wrap_implicit_slides: function () { var i, heading, node, next, div; var headings = document.getElementsByTagName("h1"); if (!headings) return; for (i = 0; i < headings.length; ++i) { heading = headings[i]; if (heading.parentNode != document.body) continue; node = heading.nextSibling; div = document.createElement("div"); this.add_class(div, "slide"); document.body.replaceChild(div, heading); div.appendChild(heading); while (node) { if (node.nodeType == 1 && // an element (node.nodeName == "H1" || node.nodeName == "h1" || node.nodeName == "DIV" || node.nodeName == "div")) break; next = node.nextSibling; node = document.body.removeChild(node); div.appendChild(node); node = next; } } }, // return new array of all slides collect_slides: function () { var slides = new Array(); var divs = document.body.getElementsByTagName("div"); for (var i = 0; i < divs.length; ++i) { div = divs.item(i); if (this.has_class(div, "slide")) { // add slide to collection slides[slides.length] = div; // hide each slide as it is found this.add_class(div, "hidden"); // add dummy
at end for scrolling hack var node1 = document.createElement("br"); div.appendChild(node1); var node2 = document.createElement("br"); div.appendChild(node2); } else if (this.has_class(div, "background")) { // work around for Firefox SVG reload bug // which otherwise replaces 1st SVG graphic with 2nd div.style.display = "block"; } } this.slides = slides; }, // return new array of all
collect_notes: function () { var notes = new Array(); var divs = document.body.getElementsByTagName("div"); for (var i = 0; i < divs.length; ++i) { div = divs.item(i); if (this.has_class(div, "handout")) { // add note to collection notes[notes.length] = div; // and hide it this.add_class(div, "hidden"); } } this.notes = notes; }, // return new array of all
// including named backgrounds e.g. class="background titlepage" collect_backgrounds: function () { var backgrounds = new Array(); var divs = document.body.getElementsByTagName("div"); for (var i = 0; i < divs.length; ++i) { div = divs.item(i); if (this.has_class(div, "background")) { // add background to collection backgrounds[backgrounds.length] = div; // and hide it this.add_class(div, "hidden"); } } this.backgrounds = backgrounds; }, // set click handlers on all anchors patch_anchors: function () { var self = w3c_slidy; var handler = function (event) { // compare this.href with location.href // for link to another slide in this doc if (self.page_address(this.href) == self.page_address(location.href)) { // yes, so find new slide number var newslidenum = self.find_slide_number(this.href); if (newslidenum != self.slide_number) { var slide = self.slides[self.slide_number]; self.hide_slide(slide); self.slide_number = newslidenum; slide = self.slides[self.slide_number]; self.show_slide(slide); self.set_location(); } } else if (this.target == null) location.href = this.href; this.blur(); self.disable_slide_click = true; }; var anchors = document.body.getElementsByTagName("a"); for (var i = 0; i < anchors.length; ++i) { if (window.addEventListener) anchors[i].addEventListener("click", handler, false); else anchors[i].attachEvent("onclick", handler); } }, // ### CHECK ME ### see which functions are invoked via setTimeout // either directly or indirectly for use of w3c_slidy vs this show_slide_number: function () { var timer = w3c_slidy.get_timer(); w3c_slidy.slide_number_element.innerHTML = timer + "slide".localize() + " " + (w3c_slidy.slide_number + 1) + "/" + w3c_slidy.slides.length; }, // every 200mS check if the location has been changed as a // result of the user activating the Back button/menu item // doesn't work for Opera < 9.5 check_location: function () { var hash = location.hash; if (w3c_slidy.slide_number > 0 && (hash == "" || hash == "#")) w3c_slidy.goto_slide(0); else if (hash.length > 2 && hash != "#("+(w3c_slidy.slide_number+1)+")") { var num = parseInt(location.hash.substr(2)); if (!isNaN(num)) w3c_slidy.goto_slide(num-1); } if (w3c_slidy.time_left && w3c_slidy.slide_number > 0) { w3c_slidy.show_slide_number(); if (w3c_slidy.time_left > 0) w3c_slidy.time_left -= 200; } }, get_timer: function () { var timer = ""; if (w3c_slidy.time_left) { var mins, secs; secs = Math.floor(w3c_slidy.time_left/1000); mins = Math.floor(secs / 60); secs = secs % 60; timer = (mins ? mins+"m" : "") + secs + "s "; } return timer; }, // this doesn't push location onto history stack for IE // for which a hidden iframe hack is needed: load page into // the iframe with script that set's parent's location.hash // but that won't work for standalone use unless we can // create the page dynamically via a javascript: URL set_location: function () { var uri = w3c_slidy.page_address(location.href); var hash = "#(" + (w3c_slidy.slide_number+1) + ")"; if (w3c_slidy.slide_number >= 0) uri = uri + hash; if (w3c_slidy.ie && !w3c_slidy.ie8) w3c_slidy.push_hash(hash); if (uri != location.href) // && !khtml location.href = uri; if (this.khtml) hash = "(" + (w3c_slidy.slide_number+1) + ")"; if (!this.ie && location.hash != hash && location.hash != "") location.hash = hash; document.title = w3c_slidy.title + " (" + (w3c_slidy.slide_number+1) + ")"; w3c_slidy.show_slide_number(); }, page_address: function (uri) { var i = uri.indexOf("#"); if (i < 0) i = uri.indexOf("%23"); // check if anchor is entire page if (i < 0) return uri; // yes return uri.substr(0, i); }, // only used for IE6 and IE7 on_frame_loaded: function (hash) { location.hash = hash; var uri = w3c_slidy.page_address(location.href); location.href = uri + hash; }, // history hack with thanks to Bertrand Le Roy push_hash: function (hash) { if (hash == "") hash = "#(1)"; window.location.hash = hash; var doc = document.getElementById("historyFrame").contentWindow.document; doc.open("javascript:''"); // PWL modified this string literal to break the close script tag // which otherwise gets parsed when incorporated doc.write("