From 6c2e0fe1f9e3bf0e164a23162bb5bdf2dd28600e Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Wed, 13 Jan 2010 16:26:22 -0800 Subject: [PATCH] create doc/talks/. move talk-20091030 down. add talk given at Stanford 2010/01/12. add doc/go-logo-white.png. R=r CC=golang-dev https://golang.org/cl/186132 --- doc/go-logo-white.png | Bin 0 -> 25371 bytes doc/{ => talks}/go_talk-20091030.pdf | Bin doc/talks/go_talk-20100112.html | 411 ++++ doc/talks/slidy.css | 277 +++ doc/talks/slidy.js | 2772 ++++++++++++++++++++++++++ lib/godoc/godoc.html | 2 +- 6 files changed, 3461 insertions(+), 1 deletion(-) create mode 100644 doc/go-logo-white.png rename doc/{ => talks}/go_talk-20091030.pdf (100%) create mode 100644 doc/talks/go_talk-20100112.html create mode 100644 doc/talks/slidy.css create mode 100644 doc/talks/slidy.js diff --git a/doc/go-logo-white.png b/doc/go-logo-white.png new file mode 100644 index 0000000000000000000000000000000000000000..4011069eb7d40a9eb81009dca7b9523417764f4d GIT binary patch literal 25371 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 jd(}Pr-$&=MS5lI%^C$5e%}j)$7yl{BsmYehm + + +Go (January 12, 2010) + + + + + + + + +
+ +
+ +
+ + +
+ +
+
+ +
+ +
+ +
+
+

The Go Programming Language

+
+

Russ Cox

+ +
+

Stanford University

January 12, 2010

+
+
+ +
+

Go

+ +

New

+

Experimental

+

Concurrent

+

Garbage-collected

+

Systems

+

Language

+
+ +
+

Hello, world

+
+package main
+
+import "fmt"
+
+func main() {
+	fmt.Printf("Hello, 世界\n")
+}
+
+
+ +
+

History

+ +

Design started in late 2007.

+

Implementation starting to work mid-2008.

+

Released as an open source project in November 2009.

+

Work continues.

+

Robert Griesemer, Ken Thompson, Rob Pike, Ian Lance Taylor, Russ Cox, many others

+
+ +
+

Why?

+ +

Go fast!

+

Make programming fun again.

+
+ +
+

Why isn't programming fun?

+ +
+

Compiled, statically-typed languages (C, C++, Java) require too much typing and too much typing:

+ +
    +
  • verbose, lots of repetition
  • +
  • too much focus on type hierarchy
  • +
  • types get in the way as much as they help
  • +
  • compiles take far too long
  • +
+
+ +
+

Dynamic languages (Python, JavaScript) fix these problems (no more types, no more compiler) but introduce others:

+ +
    +
  • errors at run time that should be caught statically
  • +
  • no compilation means slow code
  • +
+
+ +

Can we combine the best of both?

+
+ +
+

Go

+ +

Make the language fast.

+

Make the tools fast.

+
+ +
+

Go Approach: Static Types

+ +

Static types, but declarations can infer type from expression:

+ +
+var one, hi = 1, "hello"
+
+var double = func(x int) int { return x*2 }
+
+ +

Not full Hindley-Milner type inference.

+
+ + +
+

Go Approach: Methods

+ +

Methods can be defined on any type.

+ +
+type Point struct {
+	X, Y float64
+}
+
+func (p Point) Abs() float64 {
+	return math.Sqrt(p.X*p.X + p.Y*p.Y)
+}
+
+
+ +
+

Go Approach: Methods

+ +

Methods can be defined on any type.

+ +
+type MyFloat float64
+
+func (f MyFloat) Abs() float64 {
+	v := float64(f)
+	if v < 0 {
+		v = -v
+	}
+	return v
+}
+
+
+ +
+

Go Approach: Abstract Types

+ +

An interface type lists a set of methods. Any value with those methods satisfies the interface.

+ +
+type Abser interface {
+	Abs() float64
+}
+
+func AbsPrinter(a Abser)
+
+ +

Can use Point or MyFloat (or ...):

+ +
+p := Point{3, 4}
+AbsPrinter(p)
+
+f := MyFloat(-10)
+AbsPrinter(f)
+
+ +

Notice that Point never declared that it implements Abser. It just does. Same with MyFloat.

+
+ +
+

Go Approach: Packages

+ +

A Go program comprises one or more packages.

+

Each package is one or more source files compiled and imported as a unit.

+
+package draw
+
+type Point struct {
+	X, Y int
+}
+
+ +
+package main
+
+import "draw"
+
+var p draw.Point
+
+
+ +
+

Go Approach: Visibility

+ +

Inside a package, all locally defined names are visible in all source files.

+ +

When imported, only the upper case names are visible.

+ +
+package draw
+
+type Point struct {
+	X, Y int
+	dist float64
+}
+
+type cache map[Point] float64
+
+ +

Clients that import "draw" can use the black names only.

+ +

“Shift is the new public.”

+
+ +
+

Go Approach: Concurrency

+ +

Cheap to create a new flow of control (goroutine):

+ +
+func main() {
+	go expensiveComputation(x, y, z)
+	anotherExpensiveComputation(a, b, c)
+}
+
+ +

Two expensive computations in parallel.

+
+ +
+

Go Approach: Synchronization

+ +

Use explicit messages to communicate and synchronize.

+ +
+func computeAndSend(c chan int, x, y, z int) {
+	c <- expensiveComputation(x, y, z)
+}
+
+func main() {
+	c := make(chan int)
+	go computeAndSend(c, x, y, z)
+	v2 := anotherExpensiveComputation(a, b, c)
+	v1 := <-c
+	fmt.Println(v1, v2)
+}
+
+

Notice communication of result in addition to synchronization.

+
+ +
+

Go Fast: Language

+ +

Static types: enough to compile well, but inferred much of the time.

+ +

Methods: on any type, orthogonal to type system.

+ +

Abstract types: interface values, relations inferred statically.

+ +

Visibility: inferred from case of name.

+ +

Concurrency: lightweight way to start new thread of control.

+ +

Synchronization: explicit, easy message passing.

+ +
+ +

Lightweight feel of a scripting language but compiled.

+
+ +
+

Compile fast

+ +
+

Observation: much of the compile time for a source file is spent processing + other, often unrelated files.

+ +

In C: a.c includes b.h, which includes c.h, which includes d.h. +

+ +

Except that it's more often a tree instead of a chain.

+ +

On my Mac (OS X 10.5.8, gcc 4.0.1):

+
    +
  • C: #include <stdio.h> reads 360 lines from 9 files. +
  • C++: #include <iostream> reads 25,326 lines from 131 files. +
  • Objective C: #include <Carbon/Carbon.h> reads 124,730 lines from 689 files. +
+ +

And we haven't done any real work yet!

+ +

Same story in Java, Python, but reading binaries instead of source files.

+
+
+ +
+

Implementation: Summarize Dependencies

+ +
+package gui
+
+import "draw"
+
+type Mouse struct {
+	Loc draw.Point
+	Buttons uint
+}
+
+

Compiled form of gui summarizes the necessary part of draw (just Point).

+ +
+ +
+

Implementation: Summarize Dependencies

+ +

Compiled form of gui summarizes the necessary part of draw (just Point). Pseudo-object:

+ +
+package gui
+type draw.Point struct {
+	X, Y int
+}
+type gui.Mouse struct {
+	Loc draw.Point
+	Buttons uint
+}
+
+ +

A file that imports gui compiles without consulting draw or its dependencies.

+ +

In Go: import "fmt" reads one file: 184 lines summarizing types from 7 packages.

+ +

Tiny effect in this program but can be exponential in large programs.

+
+ +
+

Compilation Demo

+ +

Build all standard Go packages: ~120,000 lines of code.

+
+ +
+

Go Status

+ +
+
+

Open source:

+
    +
  • released on November 10, 2009 +
  • regular releases (~ weekly) +
  • all development done in public Mercurial repository +
  • outside contributions welcome +
+
+ +
+

Portable:

+
    +
  • FreeBSD, Linux, OS X (x86, x86-64) +
  • (in progress) Linux arm, Native Client x86, Windows x86. +
+
+ +
+

Still in progress, experimental. Yet to come:

+
    +
  • mature garbage collector +
  • generics? +
  • exceptions? +
  • unions or sum types? +
+
+
+ +
+ +
+

Questions?

+

+
+ +
+

+
+ +
+
+ + diff --git a/doc/talks/slidy.css b/doc/talks/slidy.css new file mode 100644 index 00000000000..e9ff53218fa --- /dev/null +++ b/doc/talks/slidy.css @@ -0,0 +1,277 @@ +/* http://www.w3.org/Talks/Tools/Slidy/slidy.css + + Copyright (c) 2005 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 +*/ +body +{ + margin: 0 0 0 0; + padding: 0 0 0 0; + width: 100%; + height: 100%; + color: black; + background-color: white; + font-family: "Lucida Sans", "Lucida Grande", Lucida, sans-serif; + font-size: 14pt; +} + +.hidden { display: none; visibility: hidden } + +div.toolbar { + position: fixed; z-index: 200; + top: auto; bottom: 0; left: 0; right: 0; + height: 1.2em; text-align: right; + padding-left: 1em; + padding-right: 1em; + font-size: 60%; + color: red; background: rgb(240,240,240); +} + +div.background { + display: none; +} + +div.handout { + margin-left: 20px; + margin-right: 20px; +} + +div.slide.titlepage { + color: white; + background: black; + text-align: center; +} + +div.slide { + z-index: 20; + margin: 0 0 0 0; + padding-top: 0; + padding-bottom: 0; + padding-left: 20px; + padding-right: 20px; + border-width: 0; + top: 0; + bottom: 0; + left: 0; + right: 0; + line-height: 120%; + background-color: transparent; +} + +/* this rule is hidden from IE 6 and below which don't support + selector */ +div.slide + div[class].slide { page-break-before: always;} + +div.slide h1 { + padding-left: 20px; + padding-right: 20px; + padding-top: 10px; + padding-bottom: 10px; + margin-top: 0; + margin-left: 0; + margin-right: 0; + margin-bottom: 0.5em; + border-bottom: 4px solid #36c; + display: block; + font-size: 160%; + line-height: 1.2em; +} + +div.slide h2 { + font-size:120%; + line-height: 1.2em; +} + +div.toc { + position: absolute; + top: auto; + bottom: 4em; + left: 4em; + right: auto; + width: 60%; + max-width: 30em; + height: 30em; + border: solid thin black; + padding: 1em; + background: rgb(240,240,240); + color: black; + z-index: 300; + overflow: auto; + display: block; + visibility: visible; +} + +div.toc-heading { + width: 100%; + border-bottom: solid 1px rgb(180,180,180); + margin-bottom: 1em; + text-align: center; +} + +pre { + font-size: 120%; + font-weight: bold; + line-height: 140%; + padding-top: 0.2em; + padding-bottom: 0.2em; + padding-left: 1em; + padding-right: 1em; +/* + border-style: solid; + border-left-width: 1em; + border-top-width: thin; + border-right-width: thin; + border-bottom-width: thin; + border-color: #95ABD0; +*/ + color: #0F398D; + background-color: #fff8f8; +} + +@media print { + div.slide { + display: block; + visibility: visible; + position: relative; + border-top-style: solid; + border-top-width: thin; + border-top-color: black; + } + div.slide pre { font-size: 60%; padding-left: 0.5em; } + div.handout { display: block; visibility: visible; } +} + +blockquote { font-style: italic } + +img { background-color: transparent } + +p.copyright { font-size: smaller } + +.center { text-align: center } +.footnote { font-size: smaller; margin-left: 2em; } + +a img { border-width: 0; border-style: none } + +a:visited { color: navy } +a:link { color: navy } +a:hover { color: red; text-decoration: underline } +a:active { color: red; text-decoration: underline } + +a {text-decoration: none} +.navbar a:link {color: white} +.navbar a:visited {color: yellow} +.navbar a:active {color: red} +.navbar a:hover {color: red} + +ul { list-style-type: square; } +ul ul { list-style-type: disc; } +ul ul ul { list-style-type: circle; } +ul ul ul ul { list-style-type: disc; } +li { margin-left: 2em; margin-top: 0.5em; } +li li { font-size: 85%; font-style: italic } +li li li { font-size: 85%; font-style: normal } + +div dt +{ + margin-left: 0; + margin-top: 1em; + margin-bottom: 0.5em; + font-weight: bold; +} +div dd +{ + margin-left: 2em; + margin-bottom: 0.5em; +} + + +p,pre,ul,ol,blockquote,h2,h3,h4,h5,h6,dl,table { + margin-left: 1em; + margin-right: 1em; +} + +p.subhead { font-weight: bold; margin-top: 2em; } + +p.smaller { font-size: smaller } + +td,th { padding: 0.2em } + +ul { + margin: 0.5em 1.5em 0.5em 1.5em; + padding: 0; +} + +ol { + margin: 0.5em 1.5em 0.5em 1.5em; + padding: 0; +} + +ul { list-style-type: square; } +ul ul { list-style-type: disc; } +ul ul ul { list-style-type: circle; } +ul ul ul ul { list-style-type: disc; } + +ul li { + list-style: square; + //margin: 0.1em 0em 0.6em 0; + padding: 0 0 0 0; + line-height: 140%; +} + +ol li { + margin: 0.1em 0em 0.6em 1.5em; + padding: 0 0 0 0px; + line-height: 140%; + list-style-type: decimal; +} + +li ul li { + font-size: 85%; + font-style: italic; + list-style-type: disc; + background: transparent; + padding: 0 0 0 0; +} +li li ul li { + font-size: 85%; + font-style: normal; + list-style-type: circle; + background: transparent; + padding: 0 0 0 0; +} +li li li ul li { + list-style-type: disc; + background: transparent; + padding: 0 0 0 0; +} + +li ol li { + list-style-type: decimal; +} + + +li li ol li { + list-style-type: decimal; +} + +/* + setting class="outline on ol or ul makes it behave as an + ouline list where blocklevel content in li elements is + hidden by default and can be expanded or collapsed with + mouse click. Set class="expand" on li to override default +*/ + +ol.outline li:hover { cursor: pointer } +ol.outline li.nofold:hover { cursor: default } + +ul.outline li:hover { cursor: pointer } +ul.outline li.nofold:hover { cursor: default } + +ol.outline { list-style:decimal; } +ol.outline ol { list-style-type:lower-alpha } + +/* for slides with class "title" in table of contents */ +a.titleslide { font-weight: bold; font-style: italic } diff --git a/doc/talks/slidy.js b/doc/talks/slidy.js new file mode 100644 index 00000000000..6a5561a6c1b --- /dev/null +++ b/doc/talks/slidy.js @@ -0,0 +1,2772 @@ +/* http://www.w3.org/Talks/Tools/Slidy/slidy.js + + Copyright (c) 2005 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 +*/ + +var ns_pos = (typeof window.pageYOffset!='undefined'); +var khtml = ((navigator.userAgent).indexOf("KHTML") >= 0 ? true : false); +var opera = ((navigator.userAgent).indexOf("Opera") >= 0 ? true : false); +var ie7 = (!ns_pos && navigator.userAgent.indexOf("MSIE 7") != -1); + +window.onload = startup; // equivalent to onload on body element + +// IE only event handlers to ensure all slides are printed +// I don't yet know how to emulate these for other browsers +window.onbeforeprint = beforePrint; +window.onafterprint = afterPrint; + +// hack to hide slides while loading +setTimeout(hideAll, 50); + +function hideAll() +{ + if (document.body) + document.body.style.visibility = "hidden"; + else + setTimeout(hideAll, 50); +} + +var slidenum = 0; // integer slide count: 0, 1, 2, ... +var slides; // set to array of slide div's +var slideNumElement; // element containing slide number +var notes; // set to array of handout div's +var backgrounds; // set to array of background div's +var toolbar; // element containing toolbar +var title; // document title +var lastShown = null; // last incrementally shown item +var eos = null; // span element for end of slide indicator +var toc = null; // table of contents +var outline = null; // outline element with the focus +var selectedTextLen; // length of drag selection on document + +var viewAll = 0; // 1 to view all slides + handouts +var wantToolbar = 1; // 0 if toolbar isn't wanted +var mouseClickEnabled = true; // enables left click for next slide +var scrollhack = 0; // IE work around for position: fixed + +var helpAnchor; // used for keyboard focus hack in showToolbar() +var helpPage = "http://www.w3.org/Talks/Tools/Slidy/help.html"; +var helpText = "Navigate with mouse click, space bar, Cursor Left/Right, " + + "or Pg Up and Pg Dn. Use S and B to change font size."; + +var sizeIndex = 0; +var sizeAdjustment = 0; +var sizes = new Array("10pt", "12pt", "14pt", "16pt", "18pt", "20pt", + "22pt", "24pt", "26pt", "28pt", "30pt", "32pt"); + +var okayForIncremental = incrementalElementList(); + +// needed for efficient resizing +var lastWidth = 0; +var lastHeight = 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 +var objects; + +// updated to language specified by html file +var lang = "en"; + +//var localize = {}; + +// for each language there is an associative array +var strings_es = { + "slide":"pág.", + "help?":"Ayuda", + "contents?":"Índice", + "table of contents":"tabla de contenidos", + "Table of Contents":"Tabla de Contenidos", + "restart presentation":"Reiniciar presentación", + "restart?":"Inicio" + }; + +strings_es[helpText] = + "Utilice el ratón, barra espaciadora, teclas Izda/Dhca, " + + "o Re pág y Av pág. Use S y B para cambiar el tamaño de fuente."; + +var strings_nl = { + "slide":"pagina", + "help?":"Help?", + "contents?":"Inhoud?", + "table of contents":"inhoudsopgave", + "Table of Contents":"Inhoudsopgave", + "restart presentation":"herstart presentatie", + "restart?":"Herstart?" + }; + +strings_nl[helpText] = + "Navigeer d.m.v. het muis, spatiebar, Links/Rechts toetsen, " + + "of PgUp en PgDn. Gebruik S en B om de karaktergrootte te veranderen."; + +var strings_de = { + "slide":"Seite", + "help?":"Hilfe", + "contents?":"Übersicht", + "table of contents":"Inhaltsverzeichnis", + "Table of Contents":"Inhaltsverzeichnis", + "restart presentation":"Präsentation neu starten", + "restart?":"Neustart" + }; + +strings_de[helpText] = + "Benutzen Sie die Maus, Leerschlag, die Cursortasten links/rechts" + + "oder Page up/Page Down zum Wechseln der Seiten und S und B für die Schriftgrösse."; + +var strings_pl = { + "slide":"slajd", + "help?":"pomoc?", + "contents?":"spis treści?", + "table of contents":"spis treści", + "Table of Contents":"Spis Treści", + "restart presentation":"Restartuj prezentację", + "restart?":"restart?" + }; + +strings_pl[helpText] = + "Zmieniaj slajdy klikając myszą, naciskając spację, strzałki lewo/prawo" + + "lub PgUp / PgDn. Użyj klawiszy S i B, aby zmienić rozmiar czczionki."; + +var strings_fr = { + "slide":"page", + "help?":"Aide", + "contents?":"Index", + "table of contents":"table des matières", + "Table of Contents":"Table des matières", + "restart presentation":"Recommencer l'exposé", + "restart?":"Début" + }; + +strings_fr[helpText] = +    "Naviguez avec la souris, la barre d'espace, les flèches" + + "gauche/droite ou les touches Pg Up, Pg Dn. Utilisez " + +    "les touches S et B pour modifier la taille de la police."; + +var strings_hu = { + "slide":"oldal", + "help?":"segítség", + "contents?":"tartalom", + "table of contents":"tartalomjegyzék", + "Table of Contents":"Tartalomjegyzék", + "restart presentation":"bemutató újraindítása", + "restart?":"újraindítás" + }; + +strings_hu[helpText] = + "Az oldalak közti lépkedéshez kattintson az egérrel, vagy használja a szóköz, a bal, vagy a jobb nyíl, " + + "illetve a Page Down, Page Up billentyűket. Az S és a B billentyűkkel változtathatja a szöveg méretét."; + +var strings_it = { + "slide":"pag.", + "help?":"Aiuto", + "contents?":"Indice", + "table of contents":"indice", + "Table of Contents":"Indice", + "restart presentation":"Ricominciare la presentazione", + "restart?":"Inizio" + }; + +strings_it[helpText] = + "Navigare con mouse, barra spazio, frecce sinistra/destra o " + + "PgUp e PgDn. Usare S e B per cambiare la dimensione dei caratteri."; + +var strings_el = { + "slide":"σελίδα", + "help?":"βοήθεια;", + "contents?":"περιεχόμενα;", + "table of contents":"πίνακας περιεχομένων", + "Table of Contents":"Πίνακας Περιεχομένων", + "restart presentation":"επανεκκίνηση παρουσίασης", + "restart?":"επανεκκίνηση;" + }; + +strings_el[helpText] = + "Πλοηγηθείτε με το κλίκ του ποντικιού, το space, τα βέλη αριστερά/δεξιά, " + + "ή Page Up και Page Down. Χρησιμοποιήστε τα πλήκτρα S και B για να αλλάξετε " + + "το μέγεθος της γραμματοσειράς."; + +var strings_ja = { + "slide":"スライド", + "help?":"ヘルプ", + "contents?":"目次", + "table of contents":"目次を表示", + "Table of Contents":"目次", + "restart presentation":"最初から再生", + "restart?":"最初から" +}; + +strings_ja[helpText] = + "マウス左クリック ・ スペース ・ 左右キー " + + "または Page Up ・ Page Downで操作, S ・ Bでフォントサイズ変更"; + + +// each such language array is declared in the localize array +// used indirectly as in help.innerHTML = "help".localize(); +var localize = { + "es":strings_es, + "nl":strings_nl, + "de":strings_de, + "pl":strings_pl, + "fr":strings_fr, + "hu":strings_hu, + "it":strings_it, + "el":strings_el, + "jp":strings_ja + }; + +/* general initialization */ +function startup() +{ + // find human language from html element + // for use in localizing strings + lang = document.body.parentNode.getAttribute("lang"); + + if (!lang) + lang = document.body.parentNode.getAttribute("xml:lang"); + + if (!lang) + lang = "en"; + + document.body.style.visibility = "visible"; + title = document.title; + toolbar = addToolbar(); + wrapImplicitSlides(); + slides = collectSlides(); + notes = collectNotes(); + objects = document.body.getElementsByTagName("object"); + backgrounds = collectBackgrounds(); + patchAnchors(); + + slidenum = findSlideNumber(location.href); + window.offscreenbuffering = true; + sizeAdjustment = findSizeAdjust(); + hideImageToolbar(); // suppress IE image toolbar popup + initOutliner(); // activate fold/unfold support + + if (slides.length > 0) + { + var slide = slides[slidenum]; + slide.style.position = "absolute"; + + if (slidenum > 0) + { + setVisibilityAllIncremental("visible"); + lastShown = previousIncrementalItem(null); + setEosStatus(true); + } + else + { + lastShown = null; + setVisibilityAllIncremental("hidden"); + setEosStatus(!nextIncrementalItem(lastShown)); + } + + setLocation(); + } + + toc = tableOfContents(); + hideTableOfContents(); + + // bind event handlers + document.onclick = mouseButtonClick; + document.onmouseup = mouseButtonUp; + document.onkeydown = keyDown; + window.onresize = resized; + window.onscroll = scrolled; + singleSlideView(); + + setLocation(); + resized(); + + if (ie7) + setTimeout("ieHack()", 100); + + showToolbar(); +} + +// add localize method to all strings for use +// as in help.innerHTML = "help".localize(); +String.prototype.localize = function() +{ + if (this == "") + return this; + + // try full language code, e.g. en-US + var s, lookup = localize[lang]; + + if (lookup) + { + s = lookup[this]; + + if (s) + return s; + } + + // try en if undefined for en-US + var lg = lang.split("-"); + + if (lg.length > 1) + { + lookup = localize[lg[0]]; + + if (lookup) + { + s = lookup[this]; + + if (s) + return s; + } + } + + // otherwise string as is + return this; +} + +// suppress IE's image toolbar pop up +function hideImageToolbar() +{ + if (!ns_pos) + { + var images = document.getElementsByTagName("IMG"); + + for (var i = 0; i < images.length; ++i) + images[i].setAttribute("galleryimg", "no"); + } +} + +// hack to persuade IE to compute correct document height +// as needed for simulating fixed positioning of toolbar +function ieHack() +{ + window.resizeBy(0,-1); + window.resizeBy(0, 1); +} + +// Firefox reload SVG bug work around +function reload(e) +{ + if (!e) + var e = window.event; + + hideBackgrounds(); + setTimeout("document.reload();", 100); + + stopPropagation(e); + e.cancel = true; + e.returnValue = false; + + return false; +} + +// Safari and Konqueror don't yet support getComputedStyle() +// and they always reload page when location.href is updated +function isKHTML() +{ + var agent = navigator.userAgent; + return (agent.indexOf("KHTML") >= 0 ? true : false); +} + +function resized() +{ + var width = 0; + + if ( typeof( window.innerWidth ) == 'number' ) + width = window.innerWidth; // Non IE browser + else if (document.documentElement && document.documentElement.clientWidth) + width = document.documentElement.clientWidth; // IE6 + else if (document.body && document.body.clientWidth) + width = document.body.clientWidth; // IE4 + + var height = 0; + + if ( typeof( window.innerHeight ) == 'number' ) + height = window.innerHeight; // Non IE browser + else if (document.documentElement && document.documentElement.clientHeight) + height = document.documentElement.clientHeight; // IE6 + else if (document.body && document.body.clientHeight) + height = document.body.clientHeight; // IE4 + + if (height && (width/height > 1.05*1024/768)) + { + width = height * 1024.0/768; + } + + // IE fires onresize even when only font size is changed! + // so we do a check to avoid blocking < and > actions + if (width != lastWidth || height != lastHeight) + { + if (width >= 1100) + sizeIndex = 5; // 4 + else if (width >= 1000) + sizeIndex = 4; // 3 + else if (width >= 800) + sizeIndex = 3; // 2 + else if (width >= 600) + sizeIndex = 2; // 1 + else if (width) + sizeIndex = 0; + + // add in font size adjustment from meta element e.g. + // + // useful when slides have too much content ;-) + + if (0 <= sizeIndex + sizeAdjustment && + sizeIndex + sizeAdjustment < sizes.length) + sizeIndex = sizeIndex + sizeAdjustment; + + // enables cross browser use of relative width/height + // on object elements for use with SVG and Flash media + adjustObjectDimensions(width, height); + + document.body.style.fontSize = sizes[sizeIndex]; + + lastWidth = width; + lastHeight = height; + + // force reflow to work around Mozilla bug + //if (ns_pos) + { + var slide = slides[slidenum]; + hideSlide(slide); + showSlide(slide); + } + + // force correct positioning of toolbar + refreshToolbar(200); + } +} + +function scrolled() +{ + if (toolbar && !ns_pos && !ie7) + { + hackoffset = scrollXOffset(); + // hide toolbar + toolbar.style.display = "none"; + + // make it reappear later + if (scrollhack == 0 && !viewAll) + { + setTimeout(showToolbar, 1000); + scrollhack = 1; + } + } +} + +// used to ensure IE refreshes toolbar in correct position +function refreshToolbar(interval) +{ + if (!ns_pos && !ie7) + { + hideToolbar(); + setTimeout(showToolbar, interval); + } +} + +// restores toolbar after short delay +function showToolbar() +{ + if (wantToolbar) + { + if (!ns_pos) + { + // adjust position to allow for scrolling + var xoffset = scrollXOffset(); + toolbar.style.left = xoffset; + toolbar.style.right = xoffset; + + // determine vertical scroll offset + //var yoffset = scrollYOffset(); + + // bottom is doc height - window height - scroll offset + //var bottom = documentHeight() - lastHeight - yoffset + + //if (yoffset > 0 || documentHeight() > lastHeight) + // bottom += 16; // allow for height of scrollbar + + toolbar.style.bottom = 0; //bottom; + } + + toolbar.style.display = "block"; + toolbar.style.visibility = "visible"; + } + + scrollhack = 0; + + + // set the keyboard focus to the help link on the + // toolbar to ensure that document has the focus + // IE doesn't always work with window.focus() + // and this hack has benefit of Enter for help + + try + { + if (!opera) + helpAnchor.focus(); + } + catch (e) + { + } +} + +function test() +{ + var s = "docH: " + documentHeight() + + " winH: " + lastHeight + + " yoffset: " + scrollYOffset() + + " toolbot: " + (documentHeight() - lastHeight - scrollYOffset()); + + //alert(s); + + var slide = slides[slidenum]; + // IE getAttribute requires "class" to be "className" + var name = ns_pos ? "class" : "className"; + var style = (slide.currentStyle ? slide.currentStyle["backgroundColor"] : + document.defaultView.getComputedStyle(slide, '').getPropertyValue("background-color")); + alert("class='" + slide.getAttribute(name) + "' backgroundColor: " + style); +} + +function hideToolbar() +{ + toolbar.style.display = "none"; + toolbar.style.visibility = "hidden"; + window.focus(); +} + +// invoked via F key +function toggleToolbar() +{ + if (!viewAll) + { + if (toolbar.style.display == "none") + { + toolbar.style.display = "block"; + toolbar.style.visibility = "visible"; + wantToolbar = 1; + } + else + { + toolbar.style.display = "none"; + toolbar.style.visibility = "hidden"; + wantToolbar = 0; + } + } +} + +function scrollXOffset() +{ + if (window.pageXOffset) + return self.pageXOffset; + + if (document.documentElement && + document.documentElement.scrollLeft) + return document.documentElement.scrollLeft; + + if (document.body) + return document.body.scrollLeft; + + return 0; +} + + +function scrollYOffset() +{ + if (window.pageYOffset) + return self.pageYOffset; + + if (document.documentElement && + document.documentElement.scrollTop) + return document.documentElement.scrollTop; + + if (document.body) + return document.body.scrollTop; + + return 0; +} + +// looking for a way to determine height of slide content +// the slide itself is set to the height of the window +function optimizeFontSize() +{ + var slide = slides[slidenum]; + + //var dh = documentHeight(); //getDocHeight(document); + var dh = slide.scrollHeight; + var wh = getWindowHeight(); + var u = 100 * dh / wh; + + alert("window utilization = " + u + "% (doc " + + dh + " win " + wh + ")"); +} + +function getDocHeight(doc) // from document object +{ + if (!doc) + doc = document; + + if (doc && doc.body && doc.body.offsetHeight) + return doc.body.offsetHeight; // ns/gecko syntax + + if (doc && doc.body && doc.body.scrollHeight) + return doc.body.scrollHeight; + + alert("couldn't determine document height"); +} + +function getWindowHeight() +{ + if ( typeof( window.innerHeight ) == 'number' ) + return window.innerHeight; // Non IE browser + + if (document.documentElement && document.documentElement.clientHeight) + return document.documentElement.clientHeight; // IE6 + + if (document.body && document.body.clientHeight) + return document.body.clientHeight; // IE4 +} + + + +function documentHeight() +{ + var sh, oh; + + sh = document.body.scrollHeight; + oh = document.body.offsetHeight; + + if (sh && oh) + { + return (sh > oh ? sh : oh); + } + + // no idea! + return 0; +} + +function smaller() +{ + if (sizeIndex > 0) + { + --sizeIndex; + } + + toolbar.style.display = "none"; + document.body.style.fontSize = sizes[sizeIndex]; + var slide = slides[slidenum]; + hideSlide(slide); + showSlide(slide); + setTimeout(showToolbar, 300); +} + +function bigger() +{ + if (sizeIndex < sizes.length - 1) + { + ++sizeIndex; + } + + toolbar.style.display = "none"; + document.body.style.fontSize = sizes[sizeIndex]; + var slide = slides[slidenum]; + hideSlide(slide); + showSlide(slide); + setTimeout(showToolbar, 300); +} + +// enables cross browser use of relative width/height +// on object elements for use with SVG and Flash media +// with thanks to Ivan Herman for the suggestion +function adjustObjectDimensions(width, height) +{ + for( var i = 0; i < objects.length; i++ ) + { + var obj = objects[i]; + var mimeType = obj.getAttribute("type"); + + if (mimeType == "image/svg+xml" || mimeType == "application/x-shockwave-flash") + { + if ( !obj.initialWidth ) + obj.initialWidth = obj.getAttribute("width"); + + if ( !obj.initialHeight ) + obj.initialHeight = obj.getAttribute("height"); + + if ( obj.initialWidth && obj.initialWidth.charAt(obj.initialWidth.length-1) == "%" ) + { + var w = parseInt(obj.initialWidth.slice(0, obj.initialWidth.length-1)); + var newW = width * (w/100.0); + obj.setAttribute("width",newW); + } + + if ( obj.initialHeight && obj.initialHeight.charAt(obj.initialHeight.length-1) == "%" ) + { + var h = parseInt(obj.initialHeight.slice(0, obj.initialHeight.length-1)); + var newH = height * (h/100.0); + obj.setAttribute("height", newH); + } + } + } +} + +function cancel(event) +{ + if (event) + { + event.cancel = true; + event.returnValue = false; + + if (event.preventDefault) + event.preventDefault(); + } + + return false; +} + +// See e.g. http://www.quirksmode.org/js/events/keys.html for keycodes +function keyDown(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 || event.metaKey) + return true; + + // dismiss table of contents if visible + if (isShownToc() && key != 9 && key != 16 && key != 38 && key != 40) + { + hideTableOfContents(); + + if (key == 27 || key == 84 || key == 67) + return cancel(event); + } + + if (key == 34) // Page Down + { + nextSlide(false); + return cancel(event); + } + else if (key == 33) // Page Up + { + previousSlide(false); + return cancel(event); + } + else if (key == 32) // space bar + { + nextSlide(true); + return cancel(event); + } + else if (key == 37 || key == 38) // Left arrow || Up arrow + { + previousSlide(!event.shiftKey); + return cancel(event); + } + else if (key == 36) // Home + { + firstSlide(); + return cancel(event); + } + else if (key == 35) // End + { + lastSlide(); + return cancel(event); + } + else if (key == 39 || key == 40) // Right arrow || Down arrow + { + nextSlide(!event.shiftKey); + return cancel(event); + } + else if (key == 13) // Enter + { + if (outline) + { + if (outline.visible) + fold(outline); + else + unfold(outline); + + return cancel(event); + } + } + else if (key == 188) // < for smaller fonts + { + smaller(); + return cancel(event); + } + else if (key == 190) // > for larger fonts + { + bigger(); + return cancel(event); + } + else if (key == 189 || key == 109) // - for smaller fonts + { + smaller(); + return cancel(event); + } + else if (key == 187 || key == 191 || key == 107) // = + for larger fonts + { + bigger(); + return cancel(event); + } + else if (key == 83) // S for smaller fonts + { + smaller(); + return cancel(event); + } + else if (key == 66) // B for larger fonts + { + bigger(); + return cancel(event); + } + else if (key == 90) // Z for last slide + { + lastSlide(); + return cancel(event); + } + else if (key == 70) // F for toggle toolbar + { + toggleToolbar(); + return cancel(event); + } + else if (key == 65) // A for toggle view single/all slides + { + toggleView(); + return cancel(event); + } + else if (key == 75) // toggle action of left click for next page + { + mouseClickEnabled = !mouseClickEnabled; + alert((mouseClickEnabled ? "enabled" : "disabled") + " mouse click advance"); + return cancel(event); + } + else if (key == 84 || key == 67) // T or C for table of contents + { + if (toc) + showTableOfContents(); + + return cancel(event); + } + else if (key == 72) // H for help + { + window.location = helpPage; + return cancel(event); + } + + //else if (key == 93) // Windows menu key + //alert("lastShown is " + lastShown); + //else alert("key code is "+ key); + + + return true; +} + +// make note of length of selected text +// as this evaluates to zero in click event +function mouseButtonUp(e) +{ + selectedTextLen = getSelectedText().length; +} + +// right mouse button click is reserved for context menus +// it is more reliable to detect rightclick than leftclick +function mouseButtonClick(e) +{ + var rightclick = false; + var leftclick = false; + var middleclick = false; + var target; + + if (!e) + var e = window.event; + + if (e.target) + target = e.target; + else if (e.srcElement) + target = e.srcElement; + + // work around Safari bug + if (target.nodeType == 3) + target = target.parentNode; + + if (e.which) // all browsers except IE + { + leftclick = (e.which == 1); + middleclick = (e.which == 2); + rightclick = (e.which == 3); + } + else if (e.button) + { + // Konqueror gives 1 for left, 4 for middle + // IE6 gives 0 for left and not 1 as I expected + + if (e.button == 4) + middleclick = true; + + // all browsers agree on 2 for right button + rightclick = (e.button == 2); + } + else leftclick = true; + + // dismiss table of contents + hideTableOfContents(); + + if (selectedTextLen > 0) + { + stopPropagation(e); + e.cancel = true; + e.returnValue = false; + return false; + } + + // check if target is something that probably want's clicks + // e.g. embed, object, input, textarea, select, option + + if (mouseClickEnabled && leftclick && + target.nodeName != "EMBED" && + target.nodeName != "OBJECT" && + target.nodeName != "INPUT" && + target.nodeName != "TEXTAREA" && + target.nodeName != "SELECT" && + target.nodeName != "OPTION") + { + nextSlide(true); + stopPropagation(e); + e.cancel = true; + e.returnValue = false; + } +} + +function previousSlide(incremental) +{ + if (!viewAll) + { + var slide; + + if ((incremental || slidenum == 0) && lastShown != null) + { + lastShown = hidePreviousItem(lastShown); + setEosStatus(false); + } + else if (slidenum > 0) + { + slide = slides[slidenum]; + hideSlide(slide); + + slidenum = slidenum - 1; + slide = slides[slidenum]; + setVisibilityAllIncremental("visible"); + lastShown = previousIncrementalItem(null); + setEosStatus(true); + showSlide(slide); + } + + setLocation(); + + if (!ns_pos) + refreshToolbar(200); + } +} + +function nextSlide(incremental) +{ + if (!viewAll) + { + var slide, last = lastShown; + + if (incremental || slidenum == slides.length - 1) + lastShown = revealNextItem(lastShown); + + if ((!incremental || lastShown == null) && slidenum < slides.length - 1) + { + slide = slides[slidenum]; + hideSlide(slide); + + slidenum = slidenum + 1; + slide = slides[slidenum]; + lastShown = null; + setVisibilityAllIncremental("hidden"); + showSlide(slide); + } + else if (!lastShown) + { + if (last && incremental) + lastShown = last; + } + + setLocation(); + + setEosStatus(!nextIncrementalItem(lastShown)); + + if (!ns_pos) + refreshToolbar(200); + } +} + +// to first slide with nothing revealed +// i.e. state at start of presentation +function firstSlide() +{ + if (!viewAll) + { + var slide; + + if (slidenum != 0) + { + slide = slides[slidenum]; + hideSlide(slide); + + slidenum = 0; + slide = slides[slidenum]; + lastShown = null; + setVisibilityAllIncremental("hidden"); + showSlide(slide); + } + + setEosStatus(!nextIncrementalItem(lastShown)); + setLocation(); + } +} + + +// to last slide with everything revealed +// i.e. state at end of presentation +function lastSlide() +{ + if (!viewAll) + { + var slide; + + lastShown = null; //revealNextItem(lastShown); + + if (lastShown == null && slidenum < slides.length - 1) + { + slide = slides[slidenum]; + hideSlide(slide); + slidenum = slides.length - 1; + slide = slides[slidenum]; + setVisibilityAllIncremental("visible"); + lastShown = previousIncrementalItem(null); + + showSlide(slide); + } + else + { + setVisibilityAllIncremental("visible"); + lastShown = previousIncrementalItem(null); + } + + setEosStatus(true); + setLocation(); + } +} + +function setEosStatus(state) +{ + if (eos) + eos.style.color = (state ? "rgb(240,240,240)" : "red"); +} + +function showSlide(slide) +{ + syncBackground(slide); + window.scrollTo(0,0); + slide.style.visibility = "visible"; + slide.style.display = "block"; +} + +function hideSlide(slide) +{ + slide.style.visibility = "hidden"; + slide.style.display = "none"; +} + +function beforePrint() +{ + showAllSlides(); + hideToolbar(); +} + +function afterPrint() +{ + if (!viewAll) + { + singleSlideView(); + showToolbar(); + } +} + +function printSlides() +{ + beforePrint(); + window.print(); + afterPrint(); +} + +function toggleView() +{ + if (viewAll) + { + singleSlideView(); + showToolbar(); + viewAll = 0; + } + else + { + showAllSlides(); + hideToolbar(); + viewAll = 1; + } +} + +// prepare for printing +function showAllSlides() +{ + var slide; + + for (var i = 0; i < slides.length; ++i) + { + slide = slides[i]; + + slide.style.position = "relative"; + slide.style.borderTopStyle = "solid"; + slide.style.borderTopWidth = "thin"; + slide.style.borderTopColor = "black"; + + try { + if (i == 0) + slide.style.pageBreakBefore = "avoid"; + else + slide.style.pageBreakBefore = "always"; + } + catch (e) + { + //do nothing + } + + setVisibilityAllIncremental("visible"); + showSlide(slide); + } + + var note; + + for (var i = 0; i < notes.length; ++i) + { + showSlide(notes[i]); + } + + // no easy way to render background under each slide + // without duplicating the background divs for each slide + // therefore hide backgrounds to avoid messing up slides + hideBackgrounds(); +} + +// restore after printing +function singleSlideView() +{ + var slide; + + for (var i = 0; i < slides.length; ++i) + { + slide = slides[i]; + + slide.style.position = "absolute"; + + if (i == slidenum) + { + slide.style.borderStyle = "none"; + showSlide(slide); + } + else + { + slide.style.borderStyle = "none"; + hideSlide(slide); + } + } + + setVisibilityAllIncremental("visible"); + lastShown = previousIncrementalItem(null); + + var note; + + for (var i = 0; i < notes.length; ++i) + { + hideSlide(notes[i]); + } +} + +// the string str is a whitespace separated list of tokens +// test if str contains a particular token, e.g. "slide" +function hasToken(str, token) +{ + if (str) + { + // define pattern as regular expression + var pattern = /\w+/g; + + // check for matches + // place result in array + var result = str.match(pattern); + + // now check if desired token is present + for (var i = 0; i < result.length; i++) + { + if (result[i] == token) + return true; + } + } + + return false; +} + +function getClassList(element) +{ + if (typeof window.pageYOffset =='undefined') + return element.getAttribute("className"); + + return element.getAttribute("class"); +} + +function hasClass(element, name) +{ + var regexp = new RegExp("(^| )" + name + "\W*"); + + if (regexp.test(getClassList(element))) + return true; + + return false; + +} + +function removeClass(element, name) +{ + // IE getAttribute requires "class" to be "className" + var clsname = ns_pos ? "class" : "className"; + var clsval = element.getAttribute(clsname); + + var regexp = new RegExp("(^| )" + name + "\W*"); + + if (clsval) + { + clsval = clsval.replace(regexp, ""); + element.setAttribute(clsname, clsval); + } +} + +function addClass(element, name) +{ + if (!hasClass(element, name)) + { + // IE getAttribute requires "class" to be "className" + var clsname = ns_pos ? "class" : "className"; + var clsval = element.getAttribute(clsname); + element.setAttribute(clsname, (clsval ? clsval + " " + name : name)); + } +} + +// 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 +function wrapImplicitSlides() +{ + 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"); + div.setAttribute((ns_pos ? "class" : "className"), "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 +function collectSlides() +{ + var slides = new Array(); + var divs = document.body.getElementsByTagName("div"); + + for (var i = 0; i < divs.length; ++i) + { + div = divs.item(i); + + if (hasClass(div, "slide")) + { + // add slide to collection + slides[slides.length] = div; + + // hide each slide as it is found + div.style.display = "none"; + div.style.visibility = "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 (hasClass(div, "background")) + { // work around for Firefox SVG reload bug + // which otherwise replaces 1st SVG graphic with 2nd + div.style.display = "block"; + } + } + + return slides; +} + +// return new array of all
+function collectNotes() +{ + var notes = new Array(); + var divs = document.body.getElementsByTagName("div"); + + for (var i = 0; i < divs.length; ++i) + { + div = divs.item(i); + + if (hasClass(div, "handout")) + { + // add slide to collection + notes[notes.length] = div; + + // hide handout notes as they are found + div.style.display = "none"; + div.style.visibility = "hidden"; + } + } + + return notes; +} + +// return new array of all
+// including named backgrounds e.g. class="background titlepage" +function collectBackgrounds() +{ + var backgrounds = new Array(); + var divs = document.body.getElementsByTagName("div"); + + for (var i = 0; i < divs.length; ++i) + { + div = divs.item(i); + + if (hasClass(div, "background")) + { + // add slide to collection + backgrounds[backgrounds.length] = div; + + // hide named backgrounds as they are found + // e.g. class="background epilog" + if (getClassList(div) != "background") + { + div.style.display = "none"; + div.style.visibility = "hidden"; + } + } + } + + return backgrounds; +} + +// show just the backgrounds pertinent to this slide +function syncBackground(slide) +{ + var background; + var bgColor; + + if (slide.currentStyle) + bgColor = slide.currentStyle["backgroundColor"]; + else if (document.defaultView) + { + var styles = document.defaultView.getComputedStyle(slide,null); + + if (styles) + bgColor = styles.getPropertyValue("background-color"); + else // broken implementation probably due Safari or Konqueror + { + //alert("defective implementation of getComputedStyle()"); + bgColor = "transparent"; + } + } + else + bgColor == "transparent"; + + if (bgColor == "transparent") + { + var slideClass = getClassList(slide); + + for (var i = 0; i < backgrounds.length; i++) + { + background = backgrounds[i]; + + var bgClass = getClassList(background); + + if (matchingBackground(slideClass, bgClass)) + { + background.style.display = "block"; + background.style.visibility = "visible"; + } + else + { + background.style.display = "none"; + background.style.visibility = "hidden"; + } + } + } + else // forcibly hide all backgrounds + hideBackgrounds(); +} + +function hideBackgrounds() +{ + for (var i = 0; i < backgrounds.length; i++) + { + background = backgrounds[i]; + background.style.display = "none"; + background.style.visibility = "hidden"; + } +} + +// compare classes for slide and background +function matchingBackground(slideClass, bgClass) +{ + if (bgClass == "background") + return true; + + // define pattern as regular expression + var pattern = /\w+/g; + + // check for matches and place result in array + var result = slideClass.match(pattern); + + // now check if desired name is present for background + for (var i = 0; i < result.length; i++) + { + if (hasToken(bgClass, result[i])) + return true; + } + + return false; +} + +// left to right traversal of root's content +function nextNode(root, node) +{ + if (node == null) + return root.firstChild; + + if (node.firstChild) + return node.firstChild; + + if (node.nextSibling) + return node.nextSibling; + + for (;;) + { + node = node.parentNode; + + if (!node || node == root) + break; + + if (node && node.nextSibling) + return node.nextSibling; + } + + return null; +} + +// right to left traversal of root's content +function previousNode(root, node) +{ + if (node == null) + { + node = root.lastChild; + + if (node) + { + while (node.lastChild) + node = node.lastChild; + } + + return node; + } + + if (node.previousSibling) + { + node = node.previousSibling; + + while (node.lastChild) + node = node.lastChild; + + return node; + } + + if (node.parentNode != root) + return node.parentNode; + + return null; +} + +// HTML elements that can be used with class="incremental" +// note that you can also put the class on containers like +// up, ol, dl, and div to make their contents appear +// incrementally. Upper case is used since this is what +// browsers report for HTML node names (text/html). +function incrementalElementList() +{ + var inclist = new Array(); + inclist["P"] = true; + inclist["PRE"] = true; + inclist["LI"] = true; + inclist["BLOCKQUOTE"] = true; + inclist["DT"] = true; + inclist["DD"] = true; + inclist["H2"] = true; + inclist["H3"] = true; + inclist["H4"] = true; + inclist["H5"] = true; + inclist["H6"] = true; + inclist["SPAN"] = true; + inclist["ADDRESS"] = true; + inclist["TABLE"] = true; + inclist["TR"] = true; + inclist["TH"] = true; + inclist["TD"] = true; + inclist["IMG"] = true; + inclist["OBJECT"] = true; + return inclist; +} + +function nextIncrementalItem(node) +{ + var slide = slides[slidenum]; + + for (;;) + { + node = nextNode(slide, node); + + if (node == null || node.parentNode == null) + break; + + if (node.nodeType == 1) // ELEMENT + { + if (node.nodeName == "BR") + continue; + + if (hasClass(node, "incremental") + && okayForIncremental[node.nodeName]) + return node; + + if (hasClass(node.parentNode, "incremental") + && !hasClass(node, "non-incremental")) + return node; + } + } + + return node; +} + +function previousIncrementalItem(node) +{ + var slide = slides[slidenum]; + + for (;;) + { + node = previousNode(slide, node); + + if (node == null || node.parentNode == null) + break; + + if (node.nodeType == 1) + { + if (node.nodeName == "BR") + continue; + + if (hasClass(node, "incremental") + && okayForIncremental[node.nodeName]) + return node; + + if (hasClass(node.parentNode, "incremental") + && !hasClass(node, "non-incremental")) + return node; + } + } + + return node; +} + +// set visibility for all elements on current slide with +// a parent element with attribute class="incremental" +function setVisibilityAllIncremental(value) +{ + var node = nextIncrementalItem(null); + + while (node) + { + node.style.visibility = value; + node = nextIncrementalItem(node); + } +} + +// reveal the next hidden item on the slide +// node is null or the node that was last revealed +function revealNextItem(node) +{ + node = nextIncrementalItem(node); + + if (node && node.nodeType == 1) // an element + node.style.visibility = "visible"; + + return node; +} + + +// exact inverse of revealNextItem(node) +function hidePreviousItem(node) +{ + if (node && node.nodeType == 1) // an element + node.style.visibility = "hidden"; + + return previousIncrementalItem(node); +} + + +/* set click handlers on all anchors */ +function patchAnchors() +{ + var anchors = document.body.getElementsByTagName("a"); + + for (var i = 0; i < anchors.length; ++i) + { + anchors[i].onclick = clickedAnchor; + } +} + +function clickedAnchor(e) +{ + if (!e) + var e = window.event; + + // compare this.href with location.href + // for link to another slide in this doc + + if (pageAddress(this.href) == pageAddress(location.href)) + { + // yes, so find new slide number + var newslidenum = findSlideNumber(this.href); + + if (newslidenum != slidenum) + { + slide = slides[slidenum]; + hideSlide(slide); + slidenum = newslidenum; + slide = slides[slidenum]; + showSlide(slide); + setLocation(); + } + } + else if (this.target == null) + location.href = this.href; + + this.blur(); + stopPropagation(e); +} + +function pageAddress(uri) +{ + var i = uri.indexOf("#"); + + // check if anchor is entire page + + if (i < 0) + return uri; // yes + + return uri.substr(0, i); +} + +function showSlideNumber() +{ + slideNumElement.innerHTML = "slide".localize() + " " + + (slidenum + 1) + "/" + slides.length; +} + +function setLocation() +{ + var uri = pageAddress(location.href); + + //if (slidenum > 0) + uri = uri + "#(" + (slidenum+1) + ")"; + + if (uri != location.href && !khtml) + location.href = uri; + + document.title = title + " (" + (slidenum+1) + ")"; + //document.title = (slidenum+1) + ") " + slideName(slidenum); + + showSlideNumber(); +} + +// find current slide based upon location +// first find target anchor and then look +// for associated div element enclosing it +// finally map that to slide number +function findSlideNumber(uri) +{ + // first get anchor from page location + + var i = uri.indexOf("#"); + + // check if anchor is entire page + + if (i < 0) + return 0; // yes + + var anchor = unescape(uri.substr(i+1)); + + // now use anchor as XML ID to find target + var target = document.getElementById(anchor); + + if (!target) + { + // does anchor look like "(2)" for slide 2 ?? + // where first slide is (1) + var re = /\((\d)+\)/; + + if (anchor.match(re)) + { + var num = parseInt(anchor.substring(1, anchor.length-1)); + + if (num > slides.length) + num = 1; + + if (--num < 0) + num = 0; + + return num; + } + + // accept [2] for backwards compatibility + re = /\[(\d)+\]/; + + if (anchor.match(re)) + { + var num = parseInt(anchor.substring(1, anchor.length-1)); + + if (num > slides.length) + num = 1; + + if (--num < 0) + num = 0; + + return num; + } + + // oh dear unknown anchor + return 0; + } + + // search for enclosing slide + + while (true) + { + // browser coerces html elements to uppercase! + if (target.nodeName.toLowerCase() == "div" && + hasClass(target, "slide")) + { + // found the slide element + break; + } + + // otherwise try parent element if any + + target = target.parentNode; + + if (!target) + { + return 0; // no luck! + } + }; + + for (i = 0; i < slides.length; ++i) + { + if (slides[i] == target) + return i; // success + } + + // oh dear still no luck + return 0; +} + +// find slide name from first h1 element +// default to document title + slide number +function slideName(index) +{ + var name = null; + var slide = slides[index]; + + var heading = findHeading(slide); + + if (heading) + name = extractText(heading); + + if (!name) + name = title + "(" + (index + 1) + ")"; + + name.replace(/\&/g, "&"); + name.replace(/\/g, ">"); + + return name; +} + +// find first h1 element in DOM tree +function findHeading(node) +{ + if (!node || node.nodeType != 1) + return null; + + if (node.nodeName == "H1" || node.nodeName == "h1") + return node; + + var child = node.firstChild; + + while (child) + { + node = findHeading(child); + + if (node) + return node; + + child = child.nextSibling; + } + + return null; +} + +// recursively extract text from DOM tree +function extractText(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 + extractText(node); + node = node.nextSibling; + } + + return text; + } + + return ""; +} + + +// find copyright text from meta element +function findCopyright() +{ + 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; +} + +function findSizeAdjust() +{ + 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 0; +} + +function addToolbar() +{ + var slideCounter, page; + + var toolbar = createElement("div"); + toolbar.setAttribute("class", "toolbar"); + + if (ns_pos) // a reasonably behaved browser + { + var right = document.createElement("div"); + right.setAttribute("style", "float: right; text-align: right"); + + slideCounter = document.createElement("div") + slideCounter.innerHTML = "slide".localize() + " n/m"; + right.appendChild(slideCounter); + toolbar.appendChild(right); + + var left = document.createElement("div"); + left.setAttribute("style", "text-align: left"); + + // global end of slide indicator + eos = document.createElement("span"); + eos.innerHTML = "* "; + left.appendChild(eos); + + var help = document.createElement("a"); + help.setAttribute("href", helpPage); + help.setAttribute("title", helpText.localize()); + help.innerHTML = "help?".localize(); + left.appendChild(help); + helpAnchor = help; // save for focus hack + + var gap1 = document.createTextNode(" "); + left.appendChild(gap1); + + var contents = document.createElement("a"); + contents.setAttribute("href", "javascript:toggleTableOfContents()"); + contents.setAttribute("title", "table of contents".localize()); + contents.innerHTML = "contents?".localize(); + left.appendChild(contents); + + var gap2 = document.createTextNode(" "); + left.appendChild(gap2); + + var i = location.href.indexOf("#"); + + // check if anchor is entire page + + if (i > 0) + page = location.href.substr(0, i); + else + page = location.href; + + var start = document.createElement("a"); + start.setAttribute("href", page); + start.setAttribute("title", "restart presentation".localize()); + start.innerHTML = "restart?".localize(); +// start.setAttribute("href", "javascript:printSlides()"); +// start.setAttribute("title", "print all slides".localize()); +// start.innerHTML = "print!".localize(); + left.appendChild(start); + + var copyright = findCopyright(); + + if (copyright) + { + var span = document.createElement("span"); + span.innerHTML = copyright; + span.style.color = "black"; + span.style.marginLeft = "4em"; + left.appendChild(span); + } + + toolbar.appendChild(left); + } + else // IE so need to work around its poor CSS support + { + toolbar.style.position = (ie7 ? "fixed" : "absolute"); + toolbar.style.zIndex = "200"; + toolbar.style.width = "99.9%"; + toolbar.style.height = "1.2em"; + toolbar.style.top = "auto"; + toolbar.style.bottom = "0"; + toolbar.style.left = "0"; + toolbar.style.right = "0"; + toolbar.style.textAlign = "left"; + toolbar.style.fontSize = "60%"; + toolbar.style.color = "red"; + toolbar.borderWidth = 0; + 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 = document.createElement("span"); + sp.innerHTML = "  * "; + toolbar.appendChild(sp); + eos = sp; // end of slide indicator + + var help = document.createElement("a"); + help.setAttribute("href", helpPage); + help.setAttribute("title", helpText.localize()); + help.innerHTML = "help?".localize(); + toolbar.appendChild(help); + helpAnchor = help; // save for focus hack + + var gap1 = document.createTextNode(" "); + toolbar.appendChild(gap1); + + var contents = document.createElement("a"); + contents.setAttribute("href", "javascript:toggleTableOfContents()"); + contents.setAttribute("title", "table of contents".localize()); + contents.innerHTML = "contents?".localize(); + toolbar.appendChild(contents); + + var gap2 = document.createTextNode(" "); + toolbar.appendChild(gap2); + + var i = location.href.indexOf("#"); + + // check if anchor is entire page + + if (i > 0) + page = location.href.substr(0, i); + else + page = location.href; + + var start = document.createElement("a"); + start.setAttribute("href", page); + start.setAttribute("title", "restart presentation".localize()); + start.innerHTML = "restart?".localize(); +// start.setAttribute("href", "javascript:printSlides()"); +// start.setAttribute("title", "print all slides".localize()); +// start.innerHTML = "print!".localize(); + toolbar.appendChild(start); + + var copyright = findCopyright(); + + if (copyright) + { + var span = document.createElement("span"); + span.innerHTML = copyright; + span.style.color = "black"; + span.style.marginLeft = "2em"; + toolbar.appendChild(span); + } + + slideCounter = document.createElement("div") + slideCounter.style.position = "absolute"; + slideCounter.style.width = "auto"; //"20%"; + slideCounter.style.height = "1.2em"; + slideCounter.style.top = "auto"; + slideCounter.style.bottom = 0; + slideCounter.style.right = "0"; + slideCounter.style.textAlign = "right"; + slideCounter.style.color = "red"; + slideCounter.style.background = "rgb(240,240,240)"; + + slideCounter.innerHTML = "slide".localize() + " n/m"; + toolbar.appendChild(slideCounter); + } + + // ensure that click isn't passed through to the page + toolbar.onclick = stopPropagation; + document.body.appendChild(toolbar); + slideNumElement = slideCounter; + setEosStatus(false); + + return toolbar; +} + +function isShownToc() +{ + if (toc && toc.style.visible == "visible") + return true; + + return false; +} + +function showTableOfContents() +{ + if (toc) + { + if (toc.style.visibility != "visible") + { + toc.style.visibility = "visible"; + toc.style.display = "block"; + toc.focus(); + + if (ie7 && slidenum == 0) + setTimeout("ieHack()", 100); + } + else + hideTableOfContents(); + } +} + +function hideTableOfContents() +{ + if (toc && toc.style.visibility != "hidden") + { + toc.style.visibility = "hidden"; + toc.style.display = "none"; + + try + { + if (!opera) + helpAnchor.focus(); + } + catch (e) + { + } + } +} + +function toggleTableOfContents() +{ + if (toc) + { + if (toc.style.visible != "visible") + showTableOfContents(); + else + hideTableOfContents(); + } +} + +// called on clicking toc entry +function gotoEntry(e) +{ + var target; + + if (!e) + var e = window.event; + + if (e.target) + target = e.target; + else if (e.srcElement) + target = e.srcElement; + + // work around Safari bug + if (target.nodeType == 3) + target = target.parentNode; + + if (target && target.nodeType == 1) + { + var uri = target.getAttribute("href"); + + if (uri) + { + //alert("going to " + uri); + var slide = slides[slidenum]; + hideSlide(slide); + slidenum = findSlideNumber(uri); + slide = slides[slidenum]; + lastShown = null; + setLocation(); + setVisibilityAllIncremental("hidden"); + setEosStatus(!nextIncrementalItem(lastShown)); + showSlide(slide); + //target.focus(); + + try + { + if (!opera) + helpAnchor.focus(); + } + catch (e) + { + } + } + } + + hideTableOfContents(e); + if (ie7) ieHack(); + stopPropagation(e); + return cancel(e); +} + +// called onkeydown for toc entry +function gotoTocEntry(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 = slides[slidenum]; + hideSlide(slide); + slidenum = findSlideNumber(uri); + slide = slides[slidenum]; + lastShown = null; + setLocation(); + setVisibilityAllIncremental("hidden"); + setEosStatus(!nextIncrementalItem(lastShown)); + showSlide(slide); + //target.focus(); + + try + { + if (!opera) + helpAnchor.focus(); + } + catch (e) + { + } + } + + hideTableOfContents(); + if (ie7) ieHack(); + return cancel(event); + } + + if (key == 40 && this.next) + { + this.next.focus(); + return cancel(event); + } + + if (key == 38 && this.previous) + { + this.previous.focus(); + return cancel(event); + } + + return true; +} + +function isTitleSlide(slide) +{ + return hasClass(slide, "title"); +} + +// create div element with links to each slide +function tableOfContents() +{ + var toc = document.createElement("div"); + addClass(toc, "toc"); + //toc.setAttribute("tabindex", "0"); + + var heading = document.createElement("div"); + addClass(heading, "toc-heading"); + heading.innerHTML = "Table of Contents".localize(); + + heading.style.textAlign = "center"; + heading.style.width = "100%"; + heading.style.margin = "0"; + heading.style.marginBottom = "1em"; + heading.style.borderBottomStyle = "solid"; + heading.style.borderBottomColor = "rgb(180,180,180)"; + heading.style.borderBottomWidth = "1px"; + + toc.appendChild(heading); + var previous = null; + + for (var i = 0; i < slides.length; ++i) + { + var title = hasClass(slides[i], "title"); + var num = document.createTextNode((i + 1) + ". "); + + toc.appendChild(num); + + var a = document.createElement("a"); + a.setAttribute("href", "#(" + (i+1) + ")"); + + if (title) + addClass(a, "titleslide"); + + var name = document.createTextNode(slideName(i)); + a.appendChild(name); + a.onclick = gotoEntry; + a.onkeydown = gotoTocEntry; + a.previous = previous; + + if (previous) + previous.next = a; + + toc.appendChild(a); + + if (i == 0) + toc.first = a; + + if (i < slides.length - 1) + { + var br = document.createElement("br"); + toc.appendChild(br); + } + + previous = a; + } + + toc.focus = function () { + if (this.first) + this.first.focus(); + } + + toc.onclick = function (e) { + e||(e=window.event); + hideTableOfContents(); + stopPropagation(e); + + if (e.cancel != undefined) + e.cancel = true; + + if (e.returnValue != undefined) + e.returnValue = false; + + return false; + }; + + toc.style.position = "absolute"; + toc.style.zIndex = "300"; + toc.style.width = "60%"; + toc.style.maxWidth = "30em"; + toc.style.height = "30em"; + toc.style.overflow = "auto"; + toc.style.top = "auto"; + toc.style.right = "auto"; + toc.style.left = "4em"; + toc.style.bottom = "4em"; + toc.style.padding = "1em"; + toc.style.background = "rgb(240,240,240)"; + toc.style.borderStyle = "solid"; + toc.style.borderWidth = "2px"; + toc.style.fontSize = "60%"; + + document.body.insertBefore(toc, document.body.firstChild); + return toc; +} + +function replaceByNonBreakingSpace(str) +{ + for (var i = 0; i < str.length; ++i) + str[i] = 160; +} + + +function initOutliner() +{ + var items = document.getElementsByTagName("LI"); + + for (var i = 0; i < items.length; ++i) + { + var target = items[i]; + + if (!hasClass(target.parentNode, "outline")) + continue; + + target.onclick = outlineClick; + + if (!ns_pos) + { + target.onmouseover = hoverOutline; + target.onmouseout = unhoverOutline; + } + + if (foldable(target)) + { + target.foldable = true; + target.onfocus = function () {outline = this;}; + target.onblur = function () {outline = null;}; + + if (!target.getAttribute("tabindex")) + target.setAttribute("tabindex", "0"); + + if (hasClass(target, "expand")) + unfold(target); + else + fold(target); + } + else + { + addClass(target, "nofold"); + target.visible = true; + target.foldable = false; + } + } +} + +function foldable(item) +{ + if (!item || item.nodeType != 1) + return false; + + var node = item.firstChild; + + while (node) + { + if (node.nodeType == 1 && isBlock(node)) + return true; + + node = node.nextSibling; + } + + return false; +} + +function fold(item) +{ + if (item) + { + removeClass(item, "unfolded"); + addClass(item, "folded"); + } + + var node = item ? item.firstChild : null; + + while (node) + { + if (node.nodeType == 1 && isBlock(node)) // element + { + // note that getElementStyle won't work for Safari 1.3 + node.display = getElementStyle(node, "display", "display"); + node.style.display = "none"; + node.style.visibility = "hidden"; + } + + node = node.nextSibling; + } + + item.visible = false; +} + +function unfold(item) +{ + if (item) + { + addClass(item, "unfolded"); + removeClass(item, "folded"); + } + + var node = item ? item.firstChild : null; + + while (node) + { + if (node.nodeType == 1 && isBlock(node)) // element + { + // with fallback for Safari, see above + node.style.display = (node.display ? node.display : "block"); + node.style.visibility = "visible"; + } + + node = node.nextSibling; + } + + item.visible = true; +} + +function outlineClick(e) +{ + var rightclick = false; + var target; + + if (!e) + var e = window.event; + + if (e.target) + target = e.target; + else if (e.srcElement) + target = e.srcElement; + + // work around Safari bug + if (target.nodeType == 3) + target = target.parentNode; + + 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) + fold(target); + else + unfold(target); + } + + stopPropagation(e); + e.cancel = true; + e.returnValue = false; + } + + return false; +} + +function hoverOutline(e) +{ + var target; + + if (!e) + var e = window.event; + + if (e.target) + target = e.target; + else if (e.srcElement) + target = e.srcElement; + + // work around Safari bug + if (target.nodeType == 3) + target = target.parentNode; + + while (target && target.visible == undefined) + target = target.parentNode; + + if (target && target.foldable) + target.style.cursor = "pointer"; + + return true; +} + +function unhoverOutline(e) +{ + var target; + + if (!e) + var e = window.event; + + if (e.target) + target = e.target; + else if (e.srcElement) + target = e.srcElement; + + // work around Safari bug + if (target.nodeType == 3) + target = target.parentNode; + + while (target && target.visible == undefined) + target = target.parentNode; + + if (target) + target.style.cursor = "default"; + + return true; +} + + +function stopPropagation(e) +{ + if (window.event) + { + window.event.cancelBubble = true; + //window.event.returnValue = false; + } + else if (e) + { + e.cancelBubble = true; + e.stopPropagation(); + //e.preventDefault(); + } +} + +/* can't rely on display since we set that to none to hide things */ +function isBlock(elem) +{ + var tag = elem.nodeName; + + return tag == "OL" || tag == "UL" || tag == "P" || + tag == "LI" || tag == "TABLE" || tag == "PRE" || + tag == "H1" || tag == "H2" || tag == "H3" || + tag == "H4" || tag == "H5" || tag == "H6" || + tag == "BLOCKQUOTE" || tag == "ADDRESS"; +} + +function getElementStyle(elem, IEStyleProp, CSSStyleProp) +{ + if (elem.currentStyle) + { + return elem.currentStyle[IEStyleProp]; + } + else if (window.getComputedStyle) + { + var compStyle = window.getComputedStyle(elem, ""); + return compStyle.getPropertyValue(CSSStyleProp); + } + return ""; +} + +// works with text/html and text/xhtml+xml with thanks to Simon Willison +function createElement(element) +{ + if (typeof document.createElementNS != 'undefined') + { + return document.createElementNS('http://www.w3.org/1999/xhtml', element); + } + + if (typeof document.createElement != 'undefined') + { + return document.createElement(element); + } + + return false; +} + +// designed to work with both text/html and text/xhtml+xml +function getElementsByTagName(name) +{ + if (typeof document.getElementsByTagNameNS != 'undefined') + { + return document.getElementsByTagNameNS('http://www.w3.org/1999/xhtml', name); + } + + if (typeof document.getElementsByTagName != 'undefined') + { + return document.getElementsByTagName(name); + } + + return null; +} + +/* +// clean alternative to innerHTML method, but on IE6 +// it doesn't work with named entities like   +// which need to be replaced by numeric entities +function insertText(element, text) +{ + try + { + element.textContent = text; // DOM3 only + } + catch (e) + { + if (element.firstChild) + { + // remove current children + while (element.firstChild) + element.removeChild(element.firstChild); + } + + element.appendChild(document.createTextNode(text)); + } +} + +// as above, but as method of all element nodes +// doesn't work in IE6 which doesn't allow you to +// add methods to the HTMLElement prototype +if (HTMLElement != undefined) +{ + HTMLElement.prototype.insertText = function(text) { + var element = this; + + try + { + element.textContent = text; // DOM3 only + } + catch (e) + { + if (element.firstChild) + { + // remove current children + while (element.firstChild) + element.removeChild(element.firstChild); + } + + element.appendChild(document.createTextNode(text)); + } + }; +} +*/ + +function getSelectedText() +{ + try + { + if (window.getSelection) + return window.getSelection().toString(); + + if (document.getSelection) + return document.getSelection().toString(); + + if (document.selection) + return document.selection.createRange().text; + } + catch (e) + { + return ""; + } + return ""; +} diff --git a/lib/godoc/godoc.html b/lib/godoc/godoc.html index 5f5cf310fd3..8939825007c 100644 --- a/lib/godoc/godoc.html +++ b/lib/godoc/godoc.html @@ -83,7 +83,7 @@
  • Effective Go
  • FAQ
  • Language Design FAQ
  • -
  • Tech talk (1 hour) (PDF)
  • +
  • Tech talk (1 hour) (PDF)
  • Language Specification
  • Memory Model
  • Go for C++ Programmers