// Copyright 2016 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // Store child window object which will display slides with notes var notesWindow = null; var isParentWindow = window.parent == window; // When parent window closes, clear storage and close child window if (isParentWindow) { window.onbeforeunload = function() { localStorage.clear(); if (notesWindow) notesWindow.close(); }; } function toggleNotesWindow() { if (!isParentWindow) return; if (notesWindow) { notesWindow.close(); notesWindow = null; return; } initNotes(); } // Create a unique key for the local storage so we don't mix the // destSlide of different presentations. For golang.org/issue/24688. function destSlideKey() { var key = ''; if (notesWindow) { var slides = notesWindow.document.getElementById('presenter-slides'); key = slides.src.split('#')[0]; } else { key = window.location.href.split('#')[0]; } return 'destSlide:' + key; } function initNotes() { notesWindow = window.open('', '', 'width=1000,height=700'); var w = notesWindow; var slidesUrl = window.location.href; // Hack to apply css. Requires existing html on notesWindow. w.document.write("
"); w.document.title = window.document.title; var slides = w.document.createElement('iframe'); slides.id = 'presenter-slides'; slides.src = slidesUrl; w.document.body.appendChild(slides); var curSlide = parseInt(localStorage.getItem(destSlideKey()), 10); var formattedNotes = ''; var section = sections[curSlide - 1]; // curSlide is 0 when initialized from the first page of slides. // Check if section is valid before retrieving Notes. if (section) { formattedNotes = formatNotes(section.Notes); } else if (curSlide == 0) { formattedNotes = formatNotes(titleNotes); } // setTimeout needed for Firefox setTimeout(function() { slides.focus(); }, 100); var notes = w.document.createElement('div'); notes.id = 'presenter-notes'; notes.innerHTML = formattedNotes; w.document.body.appendChild(notes); w.document.close(); function addPresenterNotesStyle() { var el = w.document.createElement('link'); el.rel = 'stylesheet'; el.type = 'text/css'; el.href = PERMANENT_URL_PREFIX + 'notes.css'; w.document.body.appendChild(el); w.document.querySelector('head').appendChild(el); } addPresenterNotesStyle(); // Add listener on notesWindow to update notes when triggered from // parent window w.addEventListener('storage', updateNotes, false); } function formatNotes(notes) { var formattedNotes = ''; if (notes) { for (var i = 0; i < notes.length; i++) { formattedNotes = formattedNotes + '

' + notes[i] + '

'; } } return formattedNotes; } function updateNotes() { // When triggered from parent window, notesWindow is null // The storage event listener on notesWindow will update notes if (!notesWindow) return; var destSlide = parseInt(localStorage.getItem(destSlideKey()), 10); var section = sections[destSlide - 1]; var el = notesWindow.document.getElementById('presenter-notes'); if (!el) return; if (section && section.Notes) { el.innerHTML = formatNotes(section.Notes); } else if (destSlide == 0) { el.innerHTML = formatNotes(titleNotes); } else { el.innerHTML = ''; } } /* Playground syncing */ // When presenter notes are enabled, playground click handlers are // stored here to sync click events on the correct playground var playgroundHandlers = { onRun: [], onKill: [], onClose: [] }; // Reset 'run', 'kill', 'close' storage items when synced // so that successive actions can be synced correctly function updatePlayStorage(action, index, e) { localStorage.setItem('play-index', index); if (localStorage.getItem('play-action') === action) { // We're the receiving window, and the message has been received localStorage.removeItem('play-action'); } else { // We're the triggering window, send the message localStorage.setItem('play-action', action); } if (action === 'onRun') { if (localStorage.getItem('play-shiftKey') === 'true') { localStorage.removeItem('play-shiftKey'); } else if (e.shiftKey) { localStorage.setItem('play-shiftKey', e.shiftKey); } } }