/templates/slidy.js
JavaScript | 2879 lines | 2103 code | 535 blank | 241 comment | 634 complexity | 4f52094bf0c0d11351fd166107618e47 MD5 | raw file
Large files files are truncated, but you can click here to view the full file
1/* slidy.js 2 3 Copyright (c) 2005-2010 W3C (MIT, ERCIM, Keio), All Rights Reserved. 4 W3C liability, trademark, document use and software licensing 5 rules apply, see: 6 7 http://www.w3.org/Consortium/Legal/copyright-documents 8 http://www.w3.org/Consortium/Legal/copyright-software 9 10 Defines single name "w3c_slidy" in global namespace 11 Adds event handlers without trampling on any others 12*/ 13 14// the slidy object implementation 15var w3c_slidy = { 16 // classify which kind of browser we're running under 17 ns_pos: (typeof window.pageYOffset!='undefined'), 18 khtml: ((navigator.userAgent).indexOf("KHTML") >= 0 ? true : false), 19 opera: ((navigator.userAgent).indexOf("Opera") >= 0 ? true : false), 20 ipad: ((navigator.userAgent).indexOf("iPad") >= 0 ? true : false), 21 iphone: ((navigator.userAgent).indexOf("iPhone") >= 0 ? true : false), 22 ie: (typeof document.all != "undefined" && !this.opera), 23 ie6: (!this.ns_pos && navigator.userAgent.indexOf("MSIE 6") != -1), 24 ie7: (!this.ns_pos && navigator.userAgent.indexOf("MSIE 7") != -1), 25 ie8: (!this.ns_pos && navigator.userAgent.indexOf("MSIE 8") != -1), 26 ie9: (!this.ns_pos && navigator.userAgent.indexOf("MSIE 9") != -1), 27 keyboardless: (this.ipad || this.iphone), 28 29 // are we running as XHTML? (doesn't work on Opera) 30 is_xhtml: /xml/.test(document.contentType), 31 32 slide_number: 0, // integer slide count: 0, 1, 2, ... 33 slide_number_element: null, // element containing slide number 34 slides: [], // set to array of slide div's 35 notes: [], // set to array of handout div's 36 backgrounds: [], // set to array of background div's 37 toolbar: null, // element containing toolbar 38 title: null, // document title 39 last_shown: null, // last incrementally shown item 40 eos: null, // span element for end of slide indicator 41 toc: null, // table of contents 42 outline: null, // outline element with the focus 43 selected_text_len: 0, // length of drag selection on document 44 view_all: 0, // 1 to view all slides + handouts 45 want_toolbar: true, // user preference to show/hide toolbar 46 mouse_click_enabled: true, // enables left click for next slide 47 scroll_hack: 0, // IE work around for position: fixed 48 disable_slide_click: false, // used by clicked anchors 49 50 lang: "en", // updated to language specified by html file 51 52 help_anchor: null, // used for keyboard focus hack in showToolbar() 53 help_page: "http://www.w3.org/Talks/Tools/Slidy2/help/help.html", 54 help_text: "Navigate with mouse click, space bar, Cursor Left/Right, " + 55 "or Pg Up and Pg Dn. Use S and B to change font size.", 56 57 size_index: 0, 58 size_adjustment: 0, 59 sizes: new Array("10pt", "12pt", "14pt", "16pt", "18pt", "20pt", 60 "22pt", "24pt", "26pt", "28pt", "30pt", "32pt"), 61 62 // needed for efficient resizing 63 last_width: 0, 64 last_height: 0, 65 66 67 // Needed for cross browser support for relative width/height on 68 // object elements. The work around is to save width/height attributes 69 // and then to recompute absolute width/height dimensions on resizing 70 objects: [], 71 72 // attach initialiation event handlers 73 set_up: function () { 74 var init = function() { w3c_slidy.init(); }; 75 if (typeof window.addEventListener != "undefined") 76 window.addEventListener("load", init, false); 77 else 78 window.attachEvent("onload", init); 79 }, 80 81 hide_slides: function () { 82 if (document.body && !w3c_slidy.initialized) 83 document.body.style.visibility = "hidden"; 84 else 85 setTimeout(w3c_slidy.hide_slides, 50); 86 }, 87 88 // hack to persuade IE to compute correct document height 89 // as needed for simulating fixed positioning of toolbar 90 ie_hack: function () { 91 window.resizeBy(0,-1); 92 window.resizeBy(0, 1); 93 }, 94 95 init: function () { 96 //alert("slidy starting test 10"); 97 document.body.style.visibility = "visible"; 98 this.init_localization(); 99 this.add_toolbar(); 100 this.wrap_implicit_slides(); 101 this.collect_slides(); 102 this.collect_notes(); 103 this.collect_backgrounds(); 104 this.objects = document.body.getElementsByTagName("object"); 105 this.patch_anchors(); 106 this.slide_number = this.find_slide_number(location.href); 107 window.offscreenbuffering = true; 108 this.size_adjustment = this.find_size_adjust(); 109 this.time_left = this.find_duration(); 110 this.hide_image_toolbar(); // suppress IE image toolbar popup 111 this.init_outliner(); // activate fold/unfold support 112 this.title = document.title; 113 114 // work around for opera bug 115 this.is_xhtml = (document.body.tagName == "BODY" ? false : true); 116 117 if (this.slides.length > 0) 118 { 119 var slide = this.slides[this.slide_number]; 120 121 if (this.slide_number > 0) 122 { 123 this.set_visibility_all_incremental("visible"); 124 this.last_shown = this.previous_incremental_item(null); 125 this.set_eos_status(true); 126 } 127 else 128 { 129 this.last_shown = null; 130 this.set_visibility_all_incremental("hidden"); 131 this.set_eos_status(!this.next_incremental_item(this.last_shown)); 132 } 133 134 this.set_location(); 135 this.add_class(this.slides[0], "first-slide"); 136 w3c_slidy.show_slide(slide); 137 } 138 139 this.toc = this.table_of_contents(); 140 141 this.add_initial_prompt(); 142 143 // bind event handlers without interfering with custom page scripts 144 // Tap events behave too weirdly to support clicks reliably on 145 // iPhone and iPad, so exclude these from click handler 146 147 if (!this.keyboardless) 148 this.add_listener(document.body, "click", this.mouse_button_click); 149 150 this.add_listener(document, "keydown", this.key_down); 151 this.add_listener(document, "keypress", this.key_press); 152 this.add_listener(window, "resize", this.resized); 153 this.add_listener(window, "scroll", this.scrolled); 154 this.add_listener(window, "unload", this.unloaded); 155 156 // this seems to be a debugging hack 157 //if (!document.body.onclick) 158 // document.body.onclick = function () { }; 159 160 this.single_slide_view(); 161 162 //this.set_location(); 163 164 this.resized(); 165 166 if (this.ie7) 167 setTimeout(w3c_slidy.ie_hack, 100); 168 169 this.show_toolbar(); 170 171 // for back button detection 172 setInterval(function () { w3c_slidy.check_location(); }, 200); 173 w3c_slidy.initialized = true; 174 }, 175 176 // create div element with links to each slide 177 table_of_contents: function () { 178 var toc = this.create_element("div"); 179 this.add_class(toc, "slidy_toc hidden"); 180 //toc.setAttribute("tabindex", "0"); 181 182 var heading = this.create_element("div"); 183 this.add_class(heading, "toc-heading"); 184 heading.innerHTML = this.localize("Table of Contents"); 185 186 toc.appendChild(heading); 187 var previous = null; 188 189 for (var i = 0; i < this.slides.length; ++i) 190 { 191 var title = this.has_class(this.slides[i], "title"); 192 var num = document.createTextNode((i + 1) + ". "); 193 194 toc.appendChild(num); 195 196 var a = this.create_element("a"); 197 a.setAttribute("href", "#(" + (i+1) + ")"); 198 199 if (title) 200 this.add_class(a, "titleslide"); 201 202 var name = document.createTextNode(this.slide_name(i)); 203 a.appendChild(name); 204 a.onclick = w3c_slidy.toc_click; 205 a.onkeydown = w3c_slidy.toc_key_down; 206 a.previous = previous; 207 208 if (previous) 209 previous.next = a; 210 211 toc.appendChild(a); 212 213 if (i == 0) 214 toc.first = a; 215 216 if (i < this.slides.length - 1) 217 { 218 var br = this.create_element("br"); 219 toc.appendChild(br); 220 } 221 222 previous = a; 223 } 224 225 toc.focus = function () { 226 if (this.first) 227 this.first.focus(); 228 } 229 230 toc.onmouseup = w3c_slidy.mouse_button_up; 231 232 toc.onclick = function (e) { 233 e||(e=window.event); 234 235 if (w3c_slidy.selected_text_len <= 0) 236 w3c_slidy.hide_table_of_contents(true); 237 238 w3c_slidy.stop_propagation(e); 239 240 if (e.cancel != undefined) 241 e.cancel = true; 242 243 if (e.returnValue != undefined) 244 e.returnValue = false; 245 246 return false; 247 }; 248 249 document.body.insertBefore(toc, document.body.firstChild); 250 return toc; 251 }, 252 253 is_shown_toc: function () { 254 return !w3c_slidy.has_class(w3c_slidy.toc, "hidden"); 255 }, 256 257 show_table_of_contents: function () { 258 w3c_slidy.remove_class(w3c_slidy.toc, "hidden"); 259 var toc = w3c_slidy.toc; 260 toc.focus(); 261 262 if (w3c_slidy.ie7 && w3c_slidy.slide_number == 0) 263 setTimeout(w3c_slidy.ie_hack, 100); 264 }, 265 266 hide_table_of_contents: function (focus) { 267 w3c_slidy.add_class(w3c_slidy.toc, "hidden"); 268 269 if (focus && !w3c_slidy.opera) 270 w3c_slidy.help_anchor.focus(); 271 }, 272 273 toggle_table_of_contents: function () { 274 if (w3c_slidy.is_shown_toc()) 275 w3c_slidy.hide_table_of_contents(true); 276 else 277 w3c_slidy.show_table_of_contents(); 278 }, 279 280 // called on clicking toc entry 281 toc_click: function (e) { 282 if (!e) 283 e = window.event; 284 285 var target = w3c_slidy.get_target(e); 286 287 if (target && target.nodeType == 1) 288 { 289 var uri = target.getAttribute("href"); 290 291 if (uri) 292 { 293 //alert("going to " + uri); 294 var slide = w3c_slidy.slides[w3c_slidy.slide_number]; 295 w3c_slidy.hide_slide(slide); 296 w3c_slidy.slide_number = w3c_slidy.find_slide_number(uri); 297 slide = w3c_slidy.slides[w3c_slidy.slide_number]; 298 w3c_slidy.last_shown = null; 299 w3c_slidy.set_location(); 300 w3c_slidy.set_visibility_all_incremental("hidden"); 301 w3c_slidy.set_eos_status(!w3c_slidy.next_incremental_item(w3c_slidy.last_shown)); 302 w3c_slidy.show_slide(slide); 303 //target.focus(); 304 305 try 306 { 307 if (!w3c_slidy.opera) 308 w3c_slidy.help_anchor.focus(); 309 } 310 catch (e) 311 { 312 } 313 } 314 } 315 316 w3c_slidy.hide_table_of_contents(true); 317 if (w3c_slidy.ie7) w3c_slidy.ie_hack(); 318 w3c_slidy.stop_propagation(e); 319 return w3c_slidy.cancel(e); 320 }, 321 322 // called onkeydown for toc entry 323 toc_key_down: function (event) { 324 var key; 325 326 if (!event) 327 var event = window.event; 328 329 // kludge around NS/IE differences 330 if (window.event) 331 key = window.event.keyCode; 332 else if (event.which) 333 key = event.which; 334 else 335 return true; // Yikes! unknown browser 336 337 // ignore event if key value is zero 338 // as for alt on Opera and Konqueror 339 if (!key) 340 return true; 341 342 // check for concurrent control/command/alt key 343 // but are these only present on mouse events? 344 345 if (event.ctrlKey || event.altKey) 346 return true; 347 348 if (key == 13) 349 { 350 var uri = this.getAttribute("href"); 351 352 if (uri) 353 { 354 //alert("going to " + uri); 355 var slide = w3c_slidy.slides[w3c_slidy.slide_number]; 356 w3c_slidy.hide_slide(slide); 357 w3c_slidy.slide_number = w3c_slidy.find_slide_number(uri); 358 slide = w3c_slidy.slides[w3c_slidy.slide_number]; 359 w3c_slidy.last_shown = null; 360 w3c_slidy.set_location(); 361 w3c_slidy.set_visibility_all_incremental("hidden"); 362 w3c_slidy.set_eos_status(!w3c_slidy.next_incremental_item(w3c_slidy.last_shown)); 363 w3c_slidy.show_slide(slide); 364 //target.focus(); 365 366 try 367 { 368 if (!w3c_slidy.opera) 369 w3c_slidy.help_anchor.focus(); 370 } 371 catch (e) 372 { 373 } 374 } 375 376 w3c_slidy.hide_table_of_contents(true); 377 378 if (self.ie7) 379 w3c_slidy.ie_hack(); 380 381 return w3c_slidy.cancel(event); 382 } 383 384 if (key == 40 && this.next) 385 { 386 this.next.focus(); 387 return w3c_slidy.cancel(event); 388 } 389 390 if (key == 38 && this.previous) 391 { 392 this.previous.focus(); 393 return w3c_slidy.cancel(event); 394 } 395 396 return true; 397 }, 398 399 400 // ### OBSOLETE ### 401 before_print: function () { 402 this.show_all_slides(); 403 this.hide_toolbar(); 404 alert("before print"); 405 }, 406 407 // ### OBSOLETE ### 408 after_print: function () { 409 if (!this.view_all) 410 { 411 this.single_slide_view(); 412 this.show_toolbar(); 413 } 414 alert("after print"); 415 }, 416 417 // ### OBSOLETE ### 418 print_slides: function () { 419 this.before_print(); 420 window.print(); 421 this.after_print(); 422 }, 423 424 // ### OBSOLETE ?? ### 425 toggle_view: function () { 426 if (this.view_all) 427 { 428 this.single_slide_view(); 429 this.show_toolbar(); 430 this.view_all = 0; 431 } 432 else 433 { 434 this.show_all_slides(); 435 this.hide_toolbar(); 436 this.view_all = 1; 437 } 438 }, 439 440 // prepare for printing ### OBSOLETE ### 441 show_all_slides: function () { 442 this.remove_class(document.body, "single_slide"); 443 this.set_visibility_all_incremental("visible"); 444 }, 445 446 // restore after printing ### OBSOLETE ### 447 single_slide_view: function () { 448 this.add_class(document.body, "single_slide"); 449 this.set_visibility_all_incremental("visible"); 450 this.last_shown = this.previous_incremental_item(null); 451 }, 452 453 // suppress IE's image toolbar pop up 454 hide_image_toolbar: function () { 455 if (!this.ns_pos) 456 { 457 var images = document.getElementsByTagName("IMG"); 458 459 for (var i = 0; i < images.length; ++i) 460 images[i].setAttribute("galleryimg", "no"); 461 } 462 }, 463 464 unloaded: function (e) { 465 //alert("unloaded"); 466 }, 467 468 // Safari and Konqueror don't yet support getComputedStyle() 469 // and they always reload page when location.href is updated 470 is_KHTML: function () { 471 var agent = navigator.userAgent; 472 return (agent.indexOf("KHTML") >= 0 ? true : false); 473 }, 474 475 // find slide name from first h1 element 476 // default to document title + slide number 477 slide_name: function (index) { 478 var name = null; 479 var slide = this.slides[index]; 480 481 var heading = this.find_heading(slide); 482 483 if (heading) 484 name = this.extract_text(heading); 485 486 if (!name) 487 name = this.title + "(" + (index + 1) + ")"; 488 489 name.replace(/\&/g, "&"); 490 name.replace(/\</g, "<"); 491 name.replace(/\>/g, ">"); 492 493 return name; 494 }, 495 496 // find first h1 element in DOM tree 497 find_heading: function (node) { 498 if (!node || node.nodeType != 1) 499 return null; 500 501 if (node.nodeName == "H1" || node.nodeName == "h1") 502 return node; 503 504 var child = node.firstChild; 505 506 while (child) 507 { 508 node = this.find_heading(child); 509 510 if (node) 511 return node; 512 513 child = child.nextSibling; 514 } 515 516 return null; 517 }, 518 519 // recursively extract text from DOM tree 520 extract_text: function (node) { 521 if (!node) 522 return ""; 523 524 // text nodes 525 if (node.nodeType == 3) 526 return node.nodeValue; 527 528 // elements 529 if (node.nodeType == 1) 530 { 531 node = node.firstChild; 532 var text = ""; 533 534 while (node) 535 { 536 text = text + this.extract_text(node); 537 node = node.nextSibling; 538 } 539 540 return text; 541 } 542 543 return ""; 544 }, 545 546 // find copyright text from meta element 547 find_copyright: function () { 548 var name, content; 549 var meta = document.getElementsByTagName("meta"); 550 551 for (var i = 0; i < meta.length; ++i) 552 { 553 name = meta[i].getAttribute("name"); 554 content = meta[i].getAttribute("content"); 555 556 if (name == "copyright") 557 return content; 558 } 559 560 return null; 561 }, 562 563 find_size_adjust: function () { 564 var name, content, offset; 565 var meta = document.getElementsByTagName("meta"); 566 567 for (var i = 0; i < meta.length; ++i) 568 { 569 name = meta[i].getAttribute("name"); 570 content = meta[i].getAttribute("content"); 571 572 if (name == "font-size-adjustment") 573 return 1 * content; 574 } 575 576 return 1; 577 }, 578 579 // <meta name="duration" content="20" /> for 20 minutes 580 find_duration: function () { 581 var name, content, offset; 582 var meta = document.getElementsByTagName("meta"); 583 584 for (var i = 0; i < meta.length; ++i) 585 { 586 name = meta[i].getAttribute("name"); 587 content = meta[i].getAttribute("content"); 588 589 if (name == "duration") 590 return 60000 * content; 591 } 592 593 return null; 594 }, 595 596 replace_by_non_breaking_space: function (str) { 597 for (var i = 0; i < str.length; ++i) 598 str[i] = 160; 599 }, 600 601 // ### CHECK ME ### is use of "li" okay for text/html? 602 // for XHTML do we also need to specify namespace? 603 init_outliner: function () { 604 var items = document.getElementsByTagName("li"); 605 606 for (var i = 0; i < items.length; ++i) 607 { 608 var target = items[i]; 609 610 if (!this.has_class(target.parentNode, "outline")) 611 continue; 612 613 target.onclick = this.outline_click; 614/* ### more work needed for IE6 615 if (!this.ns_pos) 616 { 617 target.onmouseover = this.hover_outline; 618 target.onmouseout = this.unhover_outline; 619 } 620*/ 621 if (this.foldable(target)) 622 { 623 target.foldable = true; 624 target.onfocus = function () {w3c_slidy.outline = this;}; 625 target.onblur = function () {w3c_slidy.outline = null;}; 626 627 if (!target.getAttribute("tabindex")) 628 target.setAttribute("tabindex", "0"); 629 630 if (this.has_class(target, "expand")) 631 this.unfold(target); 632 else 633 this.fold(target); 634 } 635 else 636 { 637 this.add_class(target, "nofold"); 638 target.visible = true; 639 target.foldable = false; 640 } 641 } 642 }, 643 644 foldable: function (item) { 645 if (!item || item.nodeType != 1) 646 return false; 647 648 var node = item.firstChild; 649 650 while (node) 651 { 652 if (node.nodeType == 1 && this.is_block(node)) 653 return true; 654 655 node = node.nextSibling; 656 } 657 658 return false; 659 }, 660 661 // ### CHECK ME ### switch to add/remove "hidden" class 662 fold: function (item) { 663 if (item) 664 { 665 this.remove_class(item, "unfolded"); 666 this.add_class(item, "folded"); 667 } 668 669 var node = item ? item.firstChild : null; 670 671 while (node) 672 { 673 if (node.nodeType == 1 && this.is_block(node)) // element 674 { 675 w3c_slidy.add_class(node, "hidden"); 676 } 677 678 node = node.nextSibling; 679 } 680 681 item.visible = false; 682 }, 683 684 // ### CHECK ME ### switch to add/remove "hidden" class 685 unfold: function (item) { 686 if (item) 687 { 688 this.add_class(item, "unfolded"); 689 this.remove_class(item, "folded"); 690 } 691 692 var node = item ? item.firstChild : null; 693 694 while (node) 695 { 696 if (node.nodeType == 1 && this.is_block(node)) // element 697 { 698 w3c_slidy.remove_class(node, "hidden"); 699 } 700 701 node = node.nextSibling; 702 } 703 704 item.visible = true; 705 }, 706 707 outline_click: function (e) { 708 if (!e) 709 e = window.event; 710 711 var rightclick = false; 712 var target = w3c_slidy.get_target(e); 713 714 while (target && target.visible == undefined) 715 target = target.parentNode; 716 717 if (!target) 718 return true; 719 720 if (e.which) 721 rightclick = (e.which == 3); 722 else if (e.button) 723 rightclick = (e.button == 2); 724 725 if (!rightclick && target.visible != undefined) 726 { 727 if (target.foldable) 728 { 729 if (target.visible) 730 w3c_slidy.fold(target); 731 else 732 w3c_slidy.unfold(target); 733 } 734 735 w3c_slidy.stop_propagation(e); 736 e.cancel = true; 737 e.returnValue = false; 738 } 739 740 return false; 741 }, 742 743 add_initial_prompt: function () { 744 var prompt = this.create_element("div"); 745 prompt.setAttribute("class", "initial_prompt"); 746 747 var p1 = this.create_element("p"); 748 prompt.appendChild(p1); 749 p1.setAttribute("class", "help"); 750 751 if (this.keyboardless) 752 p1.innerHTML = "Tap footer to move to next slide"; 753 else 754 p1.innerHTML = "Space or Right Arrow to move to next " + 755 "slide, click help below for more details"; 756 757 this.add_listener(prompt, "click", function (e) { 758 document.body.removeChild(prompt); 759 w3c_slidy.stop_propagation(e); 760 761 if (e.cancel != undefined) 762 e.cancel = true; 763 764 if (e.returnValue != undefined) 765 e.returnValue = false; 766 767 return false; 768 }); 769 770 document.body.appendChild(prompt); 771 this.initial_prompt = prompt; 772 setTimeout(function() {document.body.removeChild(prompt);}, 5000); 773 }, 774 775 add_toolbar: function () { 776 var counter, page; 777 778 this.toolbar = this.create_element("div"); 779 this.toolbar.setAttribute("class", "toolbar"); 780 781 // a reasonably behaved browser 782 if (this.ns_pos || !this.ie6) 783 { 784 var right = this.create_element("div"); 785 right.setAttribute("style", "float: right; text-align: right"); 786 787 counter = this.create_element("span") 788 counter.innerHTML = this.localize("slide") + " n/m"; 789 right.appendChild(counter); 790 this.toolbar.appendChild(right); 791 792 var left = this.create_element("div"); 793 left.setAttribute("style", "text-align: left"); 794 795 // global end of slide indicator 796 this.eos = this.create_element("span"); 797 this.eos.innerHTML = "* "; 798 left.appendChild(this.eos); 799 800 var help = this.create_element("a"); 801 help.setAttribute("href", this.help_page); 802 help.setAttribute("title", this.localize(this.help_text)); 803 help.innerHTML = this.localize("help?"); 804 left.appendChild(help); 805 this.help_anchor = help; // save for focus hack 806 807 var gap1 = document.createTextNode(" "); 808 left.appendChild(gap1); 809 810 var contents = this.create_element("a"); 811 contents.setAttribute("href", "javascript:w3c_slidy.toggle_table_of_contents()"); 812 contents.setAttribute("title", this.localize("table of contents")); 813 contents.innerHTML = this.localize("contents?"); 814 left.appendChild(contents); 815 816 var gap2 = document.createTextNode(" "); 817 left.appendChild(gap2); 818 819 var copyright = this.find_copyright(); 820 821 if (copyright) 822 { 823 var span = this.create_element("span"); 824 span.className = "copyright"; 825 span.innerHTML = copyright; 826 left.appendChild(span); 827 } 828 829 this.toolbar.setAttribute("tabindex", "0"); 830 this.toolbar.appendChild(left); 831 } 832 else // IE6 so need to work around its poor CSS support 833 { 834 this.toolbar.style.position = (this.ie7 ? "fixed" : "absolute"); 835 this.toolbar.style.zIndex = "200"; 836 this.toolbar.style.width = "99.9%"; 837 this.toolbar.style.height = "1.2em"; 838 this.toolbar.style.top = "auto"; 839 this.toolbar.style.bottom = "0"; 840 this.toolbar.style.left = "0"; 841 this.toolbar.style.right = "0"; 842 this.toolbar.style.textAlign = "left"; 843 this.toolbar.style.fontSize = "60%"; 844 this.toolbar.style.color = "red"; 845 this.toolbar.borderWidth = 0; 846 this.toolbar.className = "toolbar"; 847 this.toolbar.style.background = "rgb(240,240,240)"; 848 849 // would like to have help text left aligned 850 // and page counter right aligned, floating 851 // div's don't work, so instead use nested 852 // absolutely positioned div's. 853 854 var sp = this.create_element("span"); 855 sp.innerHTML = " * "; 856 this.toolbar.appendChild(sp); 857 this.eos = sp; // end of slide indicator 858 859 var help = this.create_element("a"); 860 help.setAttribute("href", this.help_page); 861 help.setAttribute("title", this.localize(this.help_text)); 862 help.innerHTML = this.localize("help?"); 863 this.toolbar.appendChild(help); 864 this.help_anchor = help; // save for focus hack 865 866 var gap1 = document.createTextNode(" "); 867 this.toolbar.appendChild(gap1); 868 869 var contents = this.create_element("a"); 870 contents.setAttribute("href", "javascript:toggleTableOfContents()"); 871 contents.setAttribute("title", this.localize("table of contents".localize)); 872 contents.innerHTML = this.localize("contents?"); 873 this.toolbar.appendChild(contents); 874 875 var gap2 = document.createTextNode(" "); 876 this.toolbar.appendChild(gap2); 877 878 var copyright = this.find_copyright(); 879 880 if (copyright) 881 { 882 var span = this.create_element("span"); 883 span.innerHTML = copyright; 884 span.style.color = "black"; 885 span.style.marginLeft = "0.5em"; 886 this.toolbar.appendChild(span); 887 } 888 889 counter = this.create_element("div") 890 counter.style.position = "absolute"; 891 counter.style.width = "auto"; //"20%"; 892 counter.style.height = "1.2em"; 893 counter.style.top = "auto"; 894 counter.style.bottom = 0; 895 counter.style.right = "0"; 896 counter.style.textAlign = "right"; 897 counter.style.color = "red"; 898 counter.style.background = "rgb(240,240,240)"; 899 900 counter.innerHTML = this.localize("slide") + " n/m"; 901 this.toolbar.appendChild(counter); 902 } 903 904 // ensure that click isn't passed through to the page 905 this.toolbar.onclick = 906 function (e) { 907 if (!e) 908 e = window.event; 909 910 var target = e.target; 911 912 if (!target && e.srcElement) 913 target = e.srcElement; 914 915 // work around Safari bug 916 if (target && target.nodeType == 3) 917 target = target.parentNode; 918 919 w3c_slidy.stop_propagation(e); 920 921 if (target && target.nodeName.toLowerCase() != "a") 922 w3c_slidy.mouse_button_click(e); 923 }; 924 925 this.slide_number_element = counter; 926 this.set_eos_status(false); 927 document.body.appendChild(this.toolbar); 928 }, 929 930 // wysiwyg editors make it hard to use div elements 931 // e.g. amaya loses the div when you copy and paste 932 // this function wraps div elements around implicit 933 // slides which start with an h1 element and continue 934 // up to the next heading or div element 935 wrap_implicit_slides: function () { 936 var i, heading, node, next, div; 937 var headings = document.getElementsByTagName("h1"); 938 939 if (!headings) 940 return; 941 942 for (i = 0; i < headings.length; ++i) 943 { 944 heading = headings[i]; 945 946 if (heading.parentNode != document.body) 947 continue; 948 949 node = heading.nextSibling; 950 951 div = document.createElement("div"); 952 this.add_class(div, "slide"); 953 document.body.replaceChild(div, heading); 954 div.appendChild(heading); 955 956 while (node) 957 { 958 if (node.nodeType == 1 && // an element 959 (node.nodeName == "H1" || 960 node.nodeName == "h1" || 961 node.nodeName == "DIV" || 962 node.nodeName == "div")) 963 break; 964 965 next = node.nextSibling; 966 node = document.body.removeChild(node); 967 div.appendChild(node); 968 node = next; 969 } 970 } 971 }, 972 973// return new array of all slides 974 collect_slides: function () { 975 var slides = new Array(); 976 var divs = document.body.getElementsByTagName("div"); 977 978 for (var i = 0; i < divs.length; ++i) 979 { 980 div = divs.item(i); 981 982 if (this.has_class(div, "slide")) 983 { 984 // add slide to collection 985 slides[slides.length] = div; 986 987 // hide each slide as it is found 988 this.add_class(div, "hidden"); 989 990 // add dummy <br/> at end for scrolling hack 991 var node1 = document.createElement("br"); 992 div.appendChild(node1); 993 var node2 = document.createElement("br"); 994 div.appendChild(node2); 995 } 996 else if (this.has_class(div, "background")) 997 { // work around for Firefox SVG reload bug 998 // which otherwise replaces 1st SVG graphic with 2nd 999 div.style.display = "block"; 1000 } 1001 } 1002 1003 this.slides = slides; 1004 }, 1005 1006 // return new array of all <div class="handout"> 1007 collect_notes: function () { 1008 var notes = new Array(); 1009 var divs = document.body.getElementsByTagName("div"); 1010 1011 for (var i = 0; i < divs.length; ++i) 1012 { 1013 div = divs.item(i); 1014 1015 if (this.has_class(div, "handout")) 1016 { 1017 // add note to collection 1018 notes[notes.length] = div; 1019 1020 // and hide it 1021 this.add_class(div, "hidden"); 1022 } 1023 } 1024 1025 this.notes = notes; 1026 }, 1027 1028 // return new array of all <div class="background"> 1029 // including named backgrounds e.g. class="background titlepage" 1030 collect_backgrounds: function () { 1031 var backgrounds = new Array(); 1032 var divs = document.body.getElementsByTagName("div"); 1033 1034 for (var i = 0; i < divs.length; ++i) 1035 { 1036 div = divs.item(i); 1037 1038 if (this.has_class(div, "background")) 1039 { 1040 // add background to collection 1041 backgrounds[backgrounds.length] = div; 1042 1043 // and hide it 1044 this.add_class(div, "hidden"); 1045 } 1046 } 1047 1048 this.backgrounds = backgrounds; 1049 }, 1050 1051 // set click handlers on all anchors 1052 patch_anchors: function () { 1053 var self = w3c_slidy; 1054 var handler = function (event) { 1055 // compare this.href with location.href 1056 // for link to another slide in this doc 1057 1058 if (self.page_address(this.href) == self.page_address(location.href)) 1059 { 1060 // yes, so find new slide number 1061 var newslidenum = self.find_slide_number(this.href); 1062 1063 if (newslidenum != self.slide_number) 1064 { 1065 var slide = self.slides[self.slide_number]; 1066 self.hide_slide(slide); 1067 self.slide_number = newslidenum; 1068 slide = self.slides[self.slide_number]; 1069 self.show_slide(slide); 1070 self.set_location(); 1071 } 1072 } 1073 else 1074 w3c_slidy.stop_propagation(event); 1075 1076// else if (this.target == null) 1077// location.href = this.href; 1078 1079 this.blur(); 1080 self.disable_slide_click = true; 1081 }; 1082 1083 var anchors = document.body.getElementsByTagName("a"); 1084 1085 for (var i = 0; i < anchors.length; ++i) 1086 { 1087 if (window.addEventListener) 1088 anchors[i].addEventListener("click", handler, false); 1089 else 1090 anchors[i].attachEvent("onclick", handler); 1091 } 1092 }, 1093 1094 // ### CHECK ME ### see which functions are invoked via setTimeout 1095 // either directly or indirectly for use of w3c_slidy vs this 1096 show_slide_number: function () { 1097 var timer = w3c_slidy.get_timer(); 1098 w3c_slidy.slide_number_element.innerHTML = timer + w3c_slidy.localize("slide") + " " + 1099 (w3c_slidy.slide_number + 1) + "/" + w3c_slidy.slides.length; 1100 }, 1101 1102 // every 200mS check if the location has been changed as a 1103 // result of the user activating the Back button/menu item 1104 // doesn't work for Opera < 9.5 1105 check_location: function () { 1106 var hash = location.hash; 1107 1108 if (w3c_slidy.slide_number > 0 && (hash == "" || hash == "#")) 1109 w3c_slidy.goto_slide(0); 1110 else if (hash.length > 2 && hash != "#("+(w3c_slidy.slide_number+1)+")") 1111 { 1112 var num = parseInt(location.hash.substr(2)); 1113 1114 if (!isNaN(num)) 1115 w3c_slidy.goto_slide(num-1); 1116 } 1117 1118 if (w3c_slidy.time_left && w3c_slidy.slide_number > 0) 1119 { 1120 w3c_slidy.show_slide_number(); 1121 1122 if (w3c_slidy.time_left > 0) 1123 w3c_slidy.time_left -= 200; 1124 } 1125 }, 1126 1127 get_timer: function () { 1128 var timer = ""; 1129 if (w3c_slidy.time_left) 1130 { 1131 var mins, secs; 1132 secs = Math.floor(w3c_slidy.time_left/1000); 1133 mins = Math.floor(secs / 60); 1134 secs = secs % 60; 1135 timer = (mins ? mins+"m" : "") + secs + "s "; 1136 } 1137 1138 return timer; 1139 }, 1140 1141 // this doesn't push location onto history stack for IE 1142 // for which a hidden iframe hack is needed: load page into 1143 // the iframe with script that set's parent's location.hash 1144 // but that won't work for standalone use unless we can 1145 // create the page dynamically via a javascript: URL 1146 set_location: function () { 1147 var uri = w3c_slidy.page_address(location.href); 1148 var hash = "#(" + (w3c_slidy.slide_number+1) + ")"; 1149 1150 if (w3c_slidy.slide_number >= 0) 1151 uri = uri + hash; 1152 1153 if (w3c_slidy.ie && !w3c_slidy.ie8) 1154 w3c_slidy.push_hash(hash); 1155 1156 if (uri != location.href) // && !khtml 1157 location.href = uri; 1158 1159 if (this.khtml) 1160 hash = "(" + (w3c_slidy.slide_number+1) + ")"; 1161 1162 if (!this.ie && location.hash != hash && location.hash != "") 1163 location.hash = hash; 1164 1165 document.title = w3c_slidy.title + " (" + (w3c_slidy.slide_number+1) + ")"; 1166 w3c_slidy.show_slide_number(); 1167 }, 1168 1169 page_address: function (uri) { 1170 var i = uri.indexOf("#"); 1171 1172 if (i < 0) 1173 i = uri.indexOf("%23"); 1174 1175 // check if anchor is entire page 1176 1177 if (i < 0) 1178 return uri; // yes 1179 1180 return uri.substr(0, i); 1181 }, 1182 1183 // only used for IE6 and IE7 1184 on_frame_loaded: function (hash) { 1185 location.hash = hash; 1186 var uri = w3c_slidy.page_address(location.href); 1187 location.href = uri + hash; 1188 }, 1189 1190 // history hack with thanks to Bertrand Le Roy 1191 push_hash: function (hash) { 1192 if (hash == "") hash = "#(1)"; 1193 window.location.hash = hash; 1194 1195 var doc = document.getElementById("historyFrame").contentWindow.document; 1196 doc.open("javascript:'<html></html>'"); 1197 doc.write("<html><head><script type=\"text/javascript\">window.parent.w3c_slidy.on_frame_loaded('"+ 1198 (hash) + "');</script></head><body>hello mum</body></html>"); 1199 doc.close(); 1200 }, 1201 1202 // find current slide based upon location 1203 // first find target anchor and then look 1204 // for associated div element enclosing it 1205 // finally map that to slide number 1206 find_slide_number: function (uri) { 1207 // first get anchor from page location 1208 1209 var i = uri.indexOf("#"); 1210 1211 // check if anchor is entire page 1212 if (i < 0) 1213 return 0; // yes 1214 1215 var anchor = unescape(uri.substr(i+1)); 1216 1217 // now use anchor as XML ID to find target 1218 var target = document.getElementById(anchor); 1219 1220 if (!target) 1221 { 1222 // does anchor look like "(2)" for slide 2 ?? 1223 // where first slide is (1) 1224 var re = /\((\d)+\)/; 1225 1226 if (anchor.match(re)) 1227 { 1228 var num = parseInt(anchor.substring(1, anchor.length-1)); 1229 1230 if (num > this.slides.length) 1231 num = 1; 1232 1233 if (--num < 0) 1234 num = 0; 1235 1236 return num; 1237 } 1238 1239 // accept [2] for backwards compatibility 1240 re = /\[(\d)+\]/; 1241 1242 if (anchor.match(re)) 1243 { 1244 var num = parseInt(anchor.substring(1, anchor.length-1)); 1245 1246 if (num > this.slides.length) 1247 num = 1; 1248 1249 if (--num < 0) 1250 num = 0; 1251 1252 return num; 1253 } 1254 1255 // oh dear unknown anchor 1256 return 0; 1257 } 1258 1259 // search for enclosing slide 1260 1261 while (true) 1262 { 1263 // browser coerces html elements to uppercase! 1264 if (target.nodeName.toLowerCase() == "div" && 1265 this.has_class(target, "slide")) 1266 { 1267 // found the slide element 1268 break; 1269 } 1270 1271 // otherwise try parent element if any 1272 1273 target = target.parentNode; 1274 1275 if (!target) 1276 { 1277 return 0; // no luck! 1278 } 1279 }; 1280 1281 for (i = 0; i < slides.length; ++i) 1282 { 1283 if (slides[i] == target) 1284 return i; // success 1285 } 1286 1287 // oh dear still no luck 1288 return 0; 1289 }, 1290 1291 previous_slide: function (incremental) { 1292 if (!w3c_slidy.view_all) 1293 { 1294 var slide; 1295 1296 if ((incremental || w3c_slidy.slide_number == 0) && w3c_slidy.last_shown != null) 1297 { 1298 w3c_slidy.last_shown = w3c_slidy.hide_previous_item(w3c_slidy.last_shown); 1299 w3c_slidy.set_eos_status(false); 1300 } 1301 else if (w3c_slidy.slide_number > 0) 1302 { 1303 slide = w3c_slidy.slides[w3c_slidy.slide_number]; 1304 w3c_slidy.hide_slide(slide); 1305 1306 w3c_slidy.slide_number = w3c_slidy.slide_number - 1; 1307 slide = w3c_slidy.slides[w3c_slidy.slide_number]; 1308 w3c_slidy.set_visibility_all_incremental("visible"); 1309 w3c_slidy.last_shown = w3c_slidy.previous_incremental_item(null); 1310 w3c_slidy.set_eos_status(true); 1311 w3c_slidy.show_slide(slide); 1312 } 1313 1314 w3c_slidy.set_location(); 1315 1316 if (!w3c_slidy.ns_pos) 1317 w3c_slidy.refresh_toolbar(200); 1318 } 1319 }, 1320 1321 next_slide: function (incremental) { 1322 if (!w3c_slidy.view_all) 1323 { 1324 var slide, last = w3c_slidy.last_shown; 1325 1326 if (incremental || w3c_slidy.slide_number == w3c_slidy.slides.length - 1) 1327 w3c_slidy.last_shown = w3c_slidy.reveal_next_item(w3c_slidy.last_shown); 1328 1329 if ((!incremental || w3c_slidy.last_shown == null) && 1330 w3c_slidy.slide_number < w3c_slidy.slides.length - 1) 1331 { 1332 slide = w3c_slidy.slides[w3c_slidy.slide_number]; 1333 w3c_slidy.hide_slide(slide); 1334 1335 w3c_slidy.slide_number = w3c_slidy.slide_number + 1; 1336 slide = w3c_slidy.slides[w3c_slidy.slide_number]; 1337 w3c_slidy.last_shown = null; 1338 w3c_slidy.set_visibility_all_incremental("hidden"); 1339 w3c_slidy.show_slide(slide); 1340 } 1341 else if (!w3c_slidy.last_shown) 1342 { 1343 if (last && incremental) 1344 w3c_slidy.last_shown = last; 1345 } 1346 1347 w3c_slidy.set_location(); 1348 1349 w3c_slidy.set_eos_status(!w3c_slidy.next_incremental_item(w3c_slidy.last_shown)); 1350 1351 if (!w3c_slidy.ns_pos) 1352 w3c_slidy.refresh_toolbar(200); 1353 } 1354 }, 1355 1356 // to first slide with nothing revealed 1357 // i.e. state at start of presentation 1358 first_slide: function () { 1359 if (!w3c_slidy.view_all) 1360 { 1361 var slide; 1362 1363 if (w3c_slidy.slide_number != 0) 1364 { 1365 slide = w3c_slidy.slides[w3c_slidy.slide_number]; 1366 w3c_slidy.hide_slide(slide); 1367 1368 w3c_slidy.slide_number = 0; 1369 slide = w3c_slidy.slides[w3c_slidy.slide_number]; 1370 w3c_slidy.last_shown = null; 1371 w3c_slidy.set_visibility_all_incremental("hidden"); 1372 w3c_slidy.show_slide(slide); 1373 } 1374 1375 w3c_slidy.set_eos_status( 1376 !w3c_slidy.next_incremental_item(w3c_slidy.last_shown)); 1377 w3c_slidy.set_location(); 1378 } 1379 }, 1380 1381 // goto last slide with everything revealed 1382 // i.e. state at end of presentation 1383 last_slide: function () { 1384 if (!w3c_slidy.view_all) 1385 { 1386 var slide; 1387 1388 w3c_slidy.last_shown = null; //revealNextItem(lastShown); 1389 1390 if (w3c_slidy.last_shown == null && 1391 w3c_slidy.slide_number < w3c_slidy.slides.length - 1) 1392 { 1393 slide = w3c_slidy.slides[w3c_slidy.slide_number]; 1394 w3c_slidy.hide_slide(slide); 1395 w3c_slidy.slide_number = w3c_slidy.slides.length - 1; 1396 slide = w3c_slidy.slides[w3c_slidy.slide_number]; 1397 w3c_slidy.set_visibility_all_incremental("visible"); 1398 w3c_slidy.last_shown = w3c_slidy.previous_incremental_item(null); 1399 1400 w3c_slidy.show_slide(slide); 1401 } 1402 else 1403 { 1404 w3c_slidy.set_visibility_all_incremental("visible"); 1405 w3c_slidy.last_shown = w3c_slidy.previous_incremental_item(null); 1406 } 1407 1408 w3c_slidy.set_eos_status(true); 1409 w3c_slidy.set_location(); 1410 } 1411 }, 1412 1413 1414 // ### check this and consider add/remove class 1415 set_eos_status: function (state) { 1416 if (this.eos) 1417 this.eos.style.color = (state ? "rgb(240,240,240)" : "red"); 1418 }, 1419 1420 // first slide is 0 1421 goto_slide: function (num) { 1422 //alert("going to slide " + (num+1)); 1423 var slide = w3c_slidy.slides[w3c_slidy.slide_number]; 1424 w3c_slidy.hide_slide(slide); 1425 w3c_slidy.slide_number = num; 1426 slide = w3c_slidy.slides[w3c_slidy.slide_number]; 1427 w3c_slidy.last_shown = null; 1428 w3c_slidy.set_visibility_all_incremental("hidden"); 1429 w3c_slidy.set_eos_status(!w3c_slidy.next_incremental_item(w3c_slidy.last_shown)); 1430 document.title = w3c_slidy.title + " (" + (w3c_slidy.slide_number+1) + ")"; 1431 w3c_slidy.show_slide(slide); 1432 w3c_slidy.show_slide_number(); 1433 }, 1434 1435 1436 show_slide: function (slide) { 1437 this.sync_background(slide); 1438 window.scrollTo(0,0); 1439 this.remove_class(slide, "hidden"); 1440 }, 1441 1442 hide_slide: function (slide) { 1443 this.add_class(slide, "hidden"); 1444 }, 1445 1446 // show just the backgrounds pertinent to this slide 1447 // when slide background-color is transparent 1448 // this should now work with rgba color values 1449 sync_background: function (slide) { 1450 var background; 1451 var bgColor; 1452 1453 if (slide.currentStyle) 1454 bgColor = slide.currentStyle["backgroundColor"]; 1455 else if (document.defaultView) 1456 { 1457 var styles = document.defaultView.getComputedStyle(slide,null); 1458 1459 if (styles) 1460 bgColor = styles.getPropertyValue("background-color"); 1461 else // broken implementation probably due Safari or Konqueror 1462 { 1463 //alert("defective implementation of getComputedStyle()"); 1464 bgColor = "transparent"; 1465 } 1466 } 1467 else 1468 bgColor == "transparent"; 1469 1470 if (bgColor == "transparent" || 1471 bgColor.indexOf("rgba") >= 0 || 1472 bgColor.indexOf("opacity") >= 0) 1473 { 1474 var slideClass = this.get_class_list(slide); 1475 1476 for (var i = 0; i < this.backgrounds.length; i++) 1477 { 1478 background = this.backgrounds[i]; 1479 1480 var bgClass = this.get_class_list(background); 1481 1482 if (this.matching_background(slideClass, bgClass)) 1483 this.remove_class(background, "hidden"); 1484 else 1485 this.add_class(background, "hidden"); 1486 } 1487 } 1488 else // forcibly hide all backgrounds 1489 this.hide_backgrounds(); 1490 }, 1491 1492 hide_backgrounds: function () { 1493 for (var i = 0; i < this.backgrounds.length; i++) 1494 { 1495 background = this.backgrounds[i]; 1496 this.add_class(background, "hidden"); 1497 } 1498 }, 1499 1500 // compare classes for slide and background 1501 matching_background: function (slideClass, bgClass) { 1502 var i, count, pattern, result; 1503 1504 // define pattern as regular expression 1505 pattern = /\w+/g; 1506 1507 // check background class names 1508 result = bgClass.match(pattern); 1509 1510 for (i = count = 0; i < result.length; i++) 1511 { 1512 if (result[i] == "hidden") 1513 continue; 1514 1515 if (result[i] == "background") 1516 continue; 1517 1518 ++count; 1519 } 1520 1521 if (count == 0) // default match 1522 return true; 1523 1524 // check for matches and place result in array 1525 result = slideClass.match(pattern); 1526 1527 // now check if desired name is present for background 1528 for (i = count = 0; i < result.length; i++) 1529 { 1530 if (result[i] == "hidden") 1531 continue; 1532 1533 if (this.has_token(bgClass, result[i])) 1534 return true; 1535 } 1536 1537 return false; 1538 }, 1539 1540 resized: function () { 1541 var width = 0; 1542 1543 if ( typeof( window.innerWidth ) == 'number' ) 1544 width = window.innerWidth; // Non IE browser 1545 else if (document.documentElement && document.documentElement.clientWidth) 1546 width = document.documentElement.clientWidth; // IE6 1547 else if (document.body && document.body.clientWidth) 1548 width = document.body.clientWidth; // IE4 1549 1550 var height = 0; 1551 1552 if ( typeof( window.innerHeight ) == 'number' ) 1553 height = window.innerHeight; // Non IE browser 1554 else if (document.documentElement && document.documentElement.clientHeight) 1555 height = document.documentElement.clientHeight; // IE6 1556 else if (document.body && document.body.clientHeight) 1557 height = document.body.clientHeight; // IE4 1558 1559 if (height && (width/height > 1.05*1024/768)) 1560 { 1561 width = height * 1024.0/768; 1562 } 1563 1564 // IE fires onresize even when only font size is changed! 1565 // so we do a check to avoid blocking < and > actions 1566 if (width != w3c_slidy.last_width || height != w3c_slidy.last_height) 1567 { 1568 if (width >= 1100) 1569 w3c_slidy.size_index = 5; // 4 1570 else if (width >= 1000) 1571 w3c_slidy.size_index = 4; // 3 1572 else if (width >= 800) 1573 w3c_slidy.size_index = 3; // 2 1574 else if (width >= 600) 1575 w3c_slidy.size_index = 2; // 1 1576 else if (width) 1577 w3c_slidy.size_index = 0; 1578 1579 // add in font size adjustment from meta element e.g. 1580 // <meta name="font-size-adjustment" content="-2" /> 1581 // useful when slides have too much content ;-) 1582 1583 if (0 <= w3c_slidy.size_index + w3c_slidy.size_adjustment && 1584 w3c_slidy.size_index + w3c_slidy.size_adjustment < w3c_slidy.sizes.length) 1585 w3c_slidy.size_index = w3c_slidy.size_index + w3c_slidy.size_adjustment; 1586 1587 // enables cross browser use of relative width/height 1588 // on object elements for use with SVG and Flash media 1589 w3c_slidy.adjust_object_dimensions(width, height); 1590 1591 if (document.body.style.fontSize != w3c_slidy.sizes[w3c_slidy.size_index]) 1592 { 1593 document.body.style.fontSize = w3c_slidy.sizes[w3c_slidy.size_index]; 1594 } 1595 1596 w3c_slidy.last_width = width; 1597 w3c_slidy.last_height = height; 1598 1599 // force reflow to work around Mozilla bug 1600 if (w3c_slidy.ns_pos) 1601 { 1602 var slide = w3c_slidy.slides[w3c_slidy.slide_number]; 1603 w3c_slidy.hide_slide(slide); 1604 w3c_slidy.show_slide(slide); 1605 } 1606 1607 // force correct positioning of toolbar 1608 w3c_slidy.refresh_toolbar(200); 1609 } 1610 }, 1611 1612 scrolled: function () { 1613 if (w3c_slidy.toolbar && !w3c_slidy.ns_pos && !w3c_slidy.ie7) 1614 { 1615 w3c_slidy.hack_offset = w3c_slidy.scroll_x_offset(); 1616 // hide toolbar 1617 w3c_slidy.toolbar.style.display = "none"; 1618 1619 // make it reappear later 1620 if (w3c_slidy.scrollhack == 0 && !w3c_slidy.view_all) 1621 { 1622 setTimeout(function () {w3c_slidy.show_toolbar(); }, 1000); 1623 w3c_slidy.scrollhack = 1; 1624 } 1625 } 1626 }, 1627 1628 hide_toolbar: function () { 1629 w3c_slidy.add_class(w3c_slidy.toolbar, "hidden"); 1630 window.focus(); 1631 }, 1632 1633 // used to ensure IE refreshes toolbar in correct position 1634 refresh_toolbar: function (interval) { 1635 if (!w3c_slidy.ns_pos && !w3c_slidy.ie7) 1636 { 1637 w3c_slidy.hide_toolbar(); 1638 setTimeout(function () {w3c_slidy.show_toolbar(); }, interval); 1639 } 1640 }, 1641 1642 // restores toolbar after short delay 1643 show_toolbar: function () { 1644 if (w3c_slidy.want_toolbar) 1645 { 1646 w3c_slidy.toolbar.style.display = "block"; 1647 1648 if (!w3c_slidy.ns_pos) 1649 { 1650 // adjust position to allow for scrolling 1651 var xoffset = w3c_slidy.scroll_x_offset(); 1652 w3c_slidy.toolbar.style.left = xoffset; 1653 w3c_slidy.toolbar.style.right = xoffset; 1654 1655 // determine vertical scroll offset 1656 //var yoffset = scrollYOffset(); 1657 1658 // bottom is doc height - window height - scroll offset 1659 //var bottom = documentHeight() - lastHeight - yoffset 1660 1661 //if (yoffset > 0 || documentHeight() > lastHeight) 1662 // bottom += 16; // allow for height of scrollbar 1663 1664 w3c_slidy.toolbar.style.bottom = 0; //bottom; 1665 } 1666 1667 w3c_slidy.remove_class(w3c_slidy.toolbar, "hidden"); 1668 } 1669 1670 w3c_slidy.scrollhack = 0; 1671 1672 1673 // set the keyboard focus to the help link on the 1674 // toolbar to ensure that document has the focus 1675 // IE doesn't always work with window.focus() 1676 // and this hack has benefit of Enter for help 1677 1678 try 1679 { 1680 if (!w3c_slidy.opera) 1681 w3c_slidy.help_anchor.focus(); 1682 } 1683 catch (e) 1684 { 1685 } 1686 }, 1687 1688// invoked via F key 1689 toggle_toolbar: function () { 1690 if (!w3c_slidy.view_all) 1691 { 1692 if (w3c_slidy.has_class(w3c_slidy.toolbar, "hidden")) 1693 { 1694 w3c_slidy.remove_class(w3c_slidy.toolbar, "hidden") 1695 w3c_slidy.want_toolbar = 1; 1696 } 1697 else 1698 { 1699 w3c_slidy.add_class(w3c_slidy.toolbar, "hidden") 1700 w3c_slidy.want_toolbar = 0; 1701 } 1702 } 1703 }, 1704 1705 scroll_x_offset: function () { 1706 if (window.pageXOffset) 1707 return self.pageXOffset; 1708 1709 if (document.documentElement && 1710 document.documentElement.scrollLeft) 1711 return document.documentElement.scrollLeft; 1712 1713 if (document.body) 1714 return document.body.scrollLeft; 1715 1716 return 0; 1717 }, 1718 1719 scroll_y_offset: function () { 1720 if (window.pageYOffset) 1721 return self.pageYOffset; 1722 1723 if (document.documentElement && 1724 document.documentElement.scrollTop) 1725 return document.documentElement.scrollTop; 1726 1727 if (document.body) 1728 return document.body.scrollTop; 1729 1730 return 0; 1731 }, 1732 1733 // looking for a way to determine height of slide content 1734 // the slide itself is set to the height of the window 1735 optimize_font_size: function () { 1736 var slide = w3c_slidy.slides[w3c_slidy.slide_number]; 1737 1738 //var dh = documentHeight(); //getDocHeight(document); 1739 var dh = slide.scrollHeight; 1740 var wh = getWindowHeight(); 1741 var u = 100 * dh / wh; 1742 1743 alert("window utilization = " + u + "% (doc " 1744 + dh + " win " + wh + ")"); 1745 }, 1746 1747 // from document object 1748 get_doc_height: function (doc) { 1749 if (!doc) 1750 doc = document; 1751 1752 if (doc && doc.body && doc.body.offsetHeight) 1753 return doc.body.offsetHeight; // ns/gecko syntax 1754 1755 if (doc && doc.body && doc.body.scrollHeight) 1756 return doc.body.scrollHeight; 1757 1758 alert("couldn't determine document height"); 1759 }, 1760 1761 get_window_height: function () { 1762 if ( typeof( window.innerHeight ) == 'number' ) 1763 return window.innerHeight; // Non IE browser 1764 1765 if (document.documentElement && document.documentElement.clientHeight) 1766 return document.documentElement.clientHeight; // IE6 1767 1768 if (document.body && document.body.clientHeight) 1769 return document.body.clientHeight; // IE4 1770 }, 1771 1772 document_height: function () { 1773 var sh, oh; 1774 1775 sh = document.body.scrollHeight; 1776 oh = document.body.offsetHeight; 1777 1778 if (sh && oh) 1779 { 1780 return (sh > oh ? sh : oh); 1781 } 1782 1783 // no idea! 1784 return 0; 1785 }, 1786 1787 smaller: function () { 1788 if (w3c_slidy.size_index > 0) 1789 { 1790 --w3c_slidy.size_index; 1791 } 1792 1793 w3c_slidy.toolbar.style.display = "none"; 1794 document.body.style.fontSize = w3c_slidy.sizes[w3c_slidy.size_index]; 1795 var slide = w3c_slidy.slides[w3c_slidy.slide_number]; 1796 w3c_slidy.hide_slide(slide); 1797 w3c_slidy.show_slide(slide); 1798 setTimeout(function () {w3c_slidy.show_toolbar(); }, 50); 1799 }, 1800 1801 bigger: function () { 1802 if (w3c_slidy.size_index < w3c_slidy.sizes.length - 1) 1803 { 1804 ++w3c_slidy.size_index; 1805 } 1806 1807 w3c_slidy.toolbar.style.display = "none"; 1808 document.body.style.fontSize = w3c_slidy.sizes[w3c_slidy.size_index]; 1809 var slide = w3c_slidy.slides[w3c_slidy.slide_number]; 1810 w3c_slidy.hide_slide(slide); 1811 w3c_slidy.show_slide(slide); 1812 setTimeout(function () {w3c_slidy.show_toolbar(); }, 50); 1813 }, 1814 1815 // enables cross browser use of relative width/height 1816 // on object elements for use with SVG and Flash media 1817 // with thanks to Ivan Herman for the suggestion 1818 adjust_object_dimensions: function (width, height) { 1819 for( var i = 0; i < w3c_slid…
Large files files are truncated, but you can click here to view the full file