summary refs log tree commit diff stats
path: root/geschichte/plugin/notes/plugin.js
diff options
context:
space:
mode:
Diffstat (limited to 'geschichte/plugin/notes/plugin.js')
-rw-r--r--geschichte/plugin/notes/plugin.js261
1 files changed, 0 insertions, 261 deletions
diff --git a/geschichte/plugin/notes/plugin.js b/geschichte/plugin/notes/plugin.js
deleted file mode 100644
index ecbf4ad..0000000
--- a/geschichte/plugin/notes/plugin.js
+++ /dev/null
@@ -1,261 +0,0 @@
-import speakerViewHTML from './speaker-view.html'
-
-import { marked } from 'marked';
-
-/**
- * Handles opening of and synchronization with the reveal.js
- * notes window.
- *
- * Handshake process:
- * 1. This window posts 'connect' to notes window
- *    - Includes URL of presentation to show
- * 2. Notes window responds with 'connected' when it is available
- * 3. This window proceeds to send the current presentation state
- *    to the notes window
- */
-const Plugin = () => {
-
-	let connectInterval;
-	let speakerWindow = null;
-	let deck;
-
-	/**
-	 * Opens a new speaker view window.
-	 */
-	function openSpeakerWindow() {
-
-		// If a window is already open, focus it
-		if( speakerWindow && !speakerWindow.closed ) {
-			speakerWindow.focus();
-		}
-		else {
-			speakerWindow = window.open( 'about:blank', 'reveal.js - Notes', 'width=1100,height=700' );
-			speakerWindow.marked = marked;
-			speakerWindow.document.write( speakerViewHTML );
-
-			if( !speakerWindow ) {
-				alert( 'Speaker view popup failed to open. Please make sure popups are allowed and reopen the speaker view.' );
-				return;
-			}
-
-			connect();
-		}
-
-	}
-
-	/**
-	 * Reconnect with an existing speaker view window.
-	 */
-	function reconnectSpeakerWindow( reconnectWindow ) {
-
-		if( speakerWindow && !speakerWindow.closed ) {
-			speakerWindow.focus();
-		}
-		else {
-			speakerWindow = reconnectWindow;
-			window.addEventListener( 'message', onPostMessage );
-			onConnected();
-		}
-
-	}
-
-	/**
-		* Connect to the notes window through a postmessage handshake.
-		* Using postmessage enables us to work in situations where the
-		* origins differ, such as a presentation being opened from the
-		* file system.
-		*/
-	function connect() {
-
-		const presentationURL = deck.getConfig().url;
-
-		const url = typeof presentationURL === 'string' ? presentationURL :
-								window.location.protocol + '//' + window.location.host + window.location.pathname + window.location.search;
-
-		// Keep trying to connect until we get a 'connected' message back
-		connectInterval = setInterval( function() {
-			speakerWindow.postMessage( JSON.stringify( {
-				namespace: 'reveal-notes',
-				type: 'connect',
-				state: deck.getState(),
-				url
-			} ), '*' );
-		}, 500 );
-
-		window.addEventListener( 'message', onPostMessage );
-
-	}
-
-	/**
-	 * Calls the specified Reveal.js method with the provided argument
-	 * and then pushes the result to the notes frame.
-	 */
-	function callRevealApi( methodName, methodArguments, callId ) {
-
-		let result = deck[methodName].apply( deck, methodArguments );
-		speakerWindow.postMessage( JSON.stringify( {
-			namespace: 'reveal-notes',
-			type: 'return',
-			result,
-			callId
-		} ), '*' );
-
-	}
-
-	/**
-	 * Posts the current slide data to the notes window.
-	 */
-	function post( event ) {
-
-		let slideElement = deck.getCurrentSlide(),
-			notesElements = slideElement.querySelectorAll( 'aside.notes' ),
-			fragmentElement = slideElement.querySelector( '.current-fragment' );
-
-		let messageData = {
-			namespace: 'reveal-notes',
-			type: 'state',
-			notes: '',
-			markdown: false,
-			whitespace: 'normal',
-			state: deck.getState()
-		};
-
-		// Look for notes defined in a slide attribute
-		if( slideElement.hasAttribute( 'data-notes' ) ) {
-			messageData.notes = slideElement.getAttribute( 'data-notes' );
-			messageData.whitespace = 'pre-wrap';
-		}
-
-		// Look for notes defined in a fragment
-		if( fragmentElement ) {
-			let fragmentNotes = fragmentElement.querySelector( 'aside.notes' );
-			if( fragmentNotes ) {
-				messageData.notes = fragmentNotes.innerHTML;
-				messageData.markdown = typeof fragmentNotes.getAttribute( 'data-markdown' ) === 'string';
-
-				// Ignore other slide notes
-				notesElements = null;
-			}
-			else if( fragmentElement.hasAttribute( 'data-notes' ) ) {
-				messageData.notes = fragmentElement.getAttribute( 'data-notes' );
-				messageData.whitespace = 'pre-wrap';
-
-				// In case there are slide notes
-				notesElements = null;
-			}
-		}
-
-		// Look for notes defined in an aside element
-		if( notesElements ) {
-			messageData.notes = Array.from(notesElements).map( notesElement => notesElement.innerHTML ).join( '\n' );
-			messageData.markdown = notesElements[0] && typeof notesElements[0].getAttribute( 'data-markdown' ) === 'string';
-		}
-
-		speakerWindow.postMessage( JSON.stringify( messageData ), '*' );
-
-	}
-
-	/**
-	 * Check if the given event is from the same origin as the
-	 * current window.
-	 */
-	function isSameOriginEvent( event ) {
-
-		try {
-			return window.location.origin === event.source.location.origin;
-		}
-		catch ( error ) {
-			return false;
-		}
-
-	}
-
-	function onPostMessage( event ) {
-
-		// Only allow same-origin messages
-		// (added 12/5/22 as a XSS safeguard)
-		if( isSameOriginEvent( event ) ) {
-
-			let data = JSON.parse( event.data );
-			if( data && data.namespace === 'reveal-notes' && data.type === 'connected' ) {
-				clearInterval( connectInterval );
-				onConnected();
-			}
-			else if( data && data.namespace === 'reveal-notes' && data.type === 'call' ) {
-				callRevealApi( data.methodName, data.arguments, data.callId );
-			}
-
-		}
-
-	}
-
-	/**
-	 * Called once we have established a connection to the notes
-	 * window.
-	 */
-	function onConnected() {
-
-		// Monitor events that trigger a change in state
-		deck.on( 'slidechanged', post );
-		deck.on( 'fragmentshown', post );
-		deck.on( 'fragmenthidden', post );
-		deck.on( 'overviewhidden', post );
-		deck.on( 'overviewshown', post );
-		deck.on( 'paused', post );
-		deck.on( 'resumed', post );
-
-		// Post the initial state
-		post();
-
-	}
-
-	return {
-		id: 'notes',
-
-		init: function( reveal ) {
-
-			deck = reveal;
-
-			if( !/receiver/i.test( window.location.search ) ) {
-
-				// If the there's a 'notes' query set, open directly
-				if( window.location.search.match( /(\?|\&)notes/gi ) !== null ) {
-					openSpeakerWindow();
-				}
-				else {
-					// Keep listening for speaker view hearbeats. If we receive a
-					// heartbeat from an orphaned window, reconnect it. This ensures
-					// that we remain connected to the notes even if the presentation
-					// is reloaded.
-					window.addEventListener( 'message', event => {
-
-						if( !speakerWindow && typeof event.data === 'string' ) {
-							let data;
-
-							try {
-								data = JSON.parse( event.data );
-							}
-							catch( error ) {}
-
-							if( data && data.namespace === 'reveal-notes' && data.type === 'heartbeat' ) {
-								reconnectSpeakerWindow( event.source );
-							}
-						}
-					});
-				}
-
-				// Open the notes when the 's' key is hit
-				deck.addKeyBinding({keyCode: 83, key: 'S', description: 'Speaker notes view'}, function() {
-					openSpeakerWindow();
-				} );
-
-			}
-
-		},
-
-		open: openSpeakerWindow
-	};
-
-};
-
-export default Plugin;