github.com/sentienttechnologies/studio-go-runner@v0.0.0-20201118202441-6d21f2ced8ee/docs/slides/plugin/notes/notes.js (about) 1 /** 2 * Handles opening of and synchronization with the reveal.js 3 * notes window. 4 * 5 * Handshake process: 6 * 1. This window posts 'connect' to notes window 7 * - Includes URL of presentation to show 8 * 2. Notes window responds with 'connected' when it is available 9 * 3. This window proceeds to send the current presentation state 10 * to the notes window 11 */ 12 var RevealNotes = (function() { 13 14 function openNotes( notesFilePath ) { 15 16 if( !notesFilePath ) { 17 var jsFileLocation = document.querySelector('script[src$="notes.js"]').src; // this js file path 18 jsFileLocation = jsFileLocation.replace(/notes\.js(\?.*)?$/, ''); // the js folder path 19 notesFilePath = jsFileLocation + 'notes.html'; 20 } 21 22 var notesPopup = window.open( notesFilePath, 'reveal.js - Notes', 'width=1100,height=700' ); 23 24 // Allow popup window access to Reveal API 25 notesPopup.Reveal = this.Reveal; 26 27 /** 28 * Connect to the notes window through a postmessage handshake. 29 * Using postmessage enables us to work in situations where the 30 * origins differ, such as a presentation being opened from the 31 * file system. 32 */ 33 function connect() { 34 // Keep trying to connect until we get a 'connected' message back 35 var connectInterval = setInterval( function() { 36 notesPopup.postMessage( JSON.stringify( { 37 namespace: 'reveal-notes', 38 type: 'connect', 39 url: window.location.protocol + '//' + window.location.host + window.location.pathname + window.location.search, 40 state: Reveal.getState() 41 } ), '*' ); 42 }, 500 ); 43 44 window.addEventListener( 'message', function( event ) { 45 var data = JSON.parse( event.data ); 46 if( data && data.namespace === 'reveal-notes' && data.type === 'connected' ) { 47 clearInterval( connectInterval ); 48 onConnected(); 49 } 50 } ); 51 } 52 53 /** 54 * Posts the current slide data to the notes window 55 */ 56 function post( event ) { 57 58 var slideElement = Reveal.getCurrentSlide(), 59 notesElement = slideElement.querySelector( 'aside.notes' ), 60 fragmentElement = slideElement.querySelector( '.current-fragment' ); 61 62 var messageData = { 63 namespace: 'reveal-notes', 64 type: 'state', 65 notes: '', 66 markdown: false, 67 whitespace: 'normal', 68 state: Reveal.getState() 69 }; 70 71 // Look for notes defined in a slide attribute 72 if( slideElement.hasAttribute( 'data-notes' ) ) { 73 messageData.notes = slideElement.getAttribute( 'data-notes' ); 74 messageData.whitespace = 'pre-wrap'; 75 } 76 77 // Look for notes defined in a fragment 78 if( fragmentElement ) { 79 var fragmentNotes = fragmentElement.querySelector( 'aside.notes' ); 80 if( fragmentNotes ) { 81 notesElement = fragmentNotes; 82 } 83 else if( fragmentElement.hasAttribute( 'data-notes' ) ) { 84 messageData.notes = fragmentElement.getAttribute( 'data-notes' ); 85 messageData.whitespace = 'pre-wrap'; 86 87 // In case there are slide notes 88 notesElement = null; 89 } 90 } 91 92 // Look for notes defined in an aside element 93 if( notesElement ) { 94 messageData.notes = notesElement.innerHTML; 95 messageData.markdown = typeof notesElement.getAttribute( 'data-markdown' ) === 'string'; 96 } 97 98 notesPopup.postMessage( JSON.stringify( messageData ), '*' ); 99 100 } 101 102 /** 103 * Called once we have established a connection to the notes 104 * window. 105 */ 106 function onConnected() { 107 108 // Monitor events that trigger a change in state 109 Reveal.addEventListener( 'slidechanged', post ); 110 Reveal.addEventListener( 'fragmentshown', post ); 111 Reveal.addEventListener( 'fragmenthidden', post ); 112 Reveal.addEventListener( 'overviewhidden', post ); 113 Reveal.addEventListener( 'overviewshown', post ); 114 Reveal.addEventListener( 'paused', post ); 115 Reveal.addEventListener( 'resumed', post ); 116 117 // Post the initial state 118 post(); 119 120 } 121 122 connect(); 123 124 } 125 126 if( !/receiver/i.test( window.location.search ) ) { 127 128 // If the there's a 'notes' query set, open directly 129 if( window.location.search.match( /(\?|\&)notes/gi ) !== null ) { 130 openNotes(); 131 } 132 133 // Open the notes when the 's' key is hit 134 document.addEventListener( 'keydown', function( event ) { 135 // Disregard the event if the target is editable or a 136 // modifier is present 137 if ( document.querySelector( ':focus' ) !== null || event.shiftKey || event.altKey || event.ctrlKey || event.metaKey ) return; 138 139 // Disregard the event if keyboard is disabled 140 if ( Reveal.getConfig().keyboard === false ) return; 141 142 if( event.keyCode === 83 ) { 143 event.preventDefault(); 144 openNotes(); 145 } 146 }, false ); 147 148 // Show our keyboard shortcut in the reveal.js help overlay 149 if( window.Reveal ) Reveal.registerKeyboardShortcut( 'S', 'Speaker notes view' ); 150 151 } 152 153 return { open: openNotes }; 154 155 })();