the postMessage API now works for getter methods

This commit is contained in:
Hakim El Hattab 2019-04-23 10:52:45 +02:00
parent 32197bd77d
commit a16b71a981
2 changed files with 45 additions and 4 deletions

View File

@ -1065,18 +1065,38 @@ The framework has a built-in postMessage API that can be used when communicating
<window>.postMessage( JSON.stringify({ method: 'slide', args: [ 2 ] }), '*' ); <window>.postMessage( JSON.stringify({ method: 'slide', args: [ 2 ] }), '*' );
``` ```
#### postMessage Events
When reveal.js runs inside of an iframe it can optionally bubble all of its events to the parent. Bubbled events are stringified JSON with three fields: namespace, eventName and state. Here's how you subscribe to them from the parent window: When reveal.js runs inside of an iframe it can optionally bubble all of its events to the parent. Bubbled events are stringified JSON with three fields: namespace, eventName and state. Here's how you subscribe to them from the parent window:
```javascript ```javascript
window.addEventListener( 'message', function( event ) { window.addEventListener( 'message', function( event ) {
var data = JSON.parse( event.data ); var data = JSON.parse( event.data );
if( data.namespace === 'reveal' && data.eventName ==='slidechanged' ) { if( data.namespace === 'reveal' && data.eventName === 'slidechanged' ) {
// Slide changed, see data.state for slide number // Slide changed, see data.state for slide number
} }
} ); } );
``` ```
This cross-window messaging can be toggled on or off using configuration flags. #### postMessage Callbacks
When you call any method via the postMessage API, reveal.js will dispatch a message with the return value. This is done so that you can call a getter method and see what the result is. Check out this example:
```javascript
<revealWindow>.postMessage( JSON.stringify({ method: 'getTotalSlides' }), '*' );
window.addEventListener( 'message', function( event ) {
var data = JSON.parse( event.data );
// `data.method`` is the method that we invoked
if( data.namespace === 'reveal' && data.eventName === 'callback' && data.method === 'getTotalSlides' ) {
data.result // = the total number of slides
}
} );
```
#### Turning postMessage on/off
This cross-window messaging can be toggled on or off using configuration flags. These are the default values.
```javascript ```javascript
Reveal.initialize({ Reveal.initialize({

View File

@ -1276,7 +1276,11 @@
// Check if the requested method can be found // Check if the requested method can be found
if( data.method && typeof Reveal[data.method] === 'function' ) { if( data.method && typeof Reveal[data.method] === 'function' ) {
Reveal[data.method].apply( Reveal, data.args ); var result = Reveal[data.method].apply( Reveal, data.args );
// Dispatch a postMessage event with the returned value from
// our method invocation for getter functions
dispatchPostMessage( 'callback', { method: data.method, result: result } );
} }
} }
}, false ); }, false );
@ -1981,8 +1985,25 @@
// If we're in an iframe, post each reveal.js event to the // If we're in an iframe, post each reveal.js event to the
// parent window. Used by the notes plugin // parent window. Used by the notes plugin
dispatchPostMessage( type );
}
/**
* Dispatched a postMessage of the given type from our window.
*/
function dispatchPostMessage( type, data ) {
if( config.postMessageEvents && window.parent !== window.self ) { if( config.postMessageEvents && window.parent !== window.self ) {
window.parent.postMessage( JSON.stringify({ namespace: 'reveal', eventName: type, state: getState() }), '*' ); var message = {
namespace: 'reveal',
eventName: type,
state: getState()
};
extend( message, data );
window.parent.postMessage( JSON.stringify( message ), '*' );
} }
} }