Skip to content

Commit

Permalink
Hooks: Dispatch all heartbeat events as hooks actions (#11781)
Browse files Browse the repository at this point in the history
* Framework: Dispatch all heartbeat events as actions

* Editor: Send PostLockModal lock request via XHR

* Editor: Use hooks for PostLockedModal heartbeat handling

* Framework: Update package-lock.json per jQuery dependency drop

* Editor: Remove unsupported event object from action callback

* Editor: Assure withGlobalEvents is last to wrap component

Since it tests for static method on which to call

* Editor: Reuse hook name across disparate hooks
  • Loading branch information
aduth authored and youknowriad committed Mar 6, 2019
1 parent e88eb61 commit efbbca9
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 36 deletions.
27 changes: 24 additions & 3 deletions lib/client-assets.php
Original file line number Diff line number Diff line change
Expand Up @@ -1026,11 +1026,32 @@ function gutenberg_editor_scripts_and_styles( $hook ) {
// to disable it outright.
wp_enqueue_script( 'heartbeat' );

// Transform a "heartbeat-tick" jQuery event into "heartbeat.tick" hook action.
// This removes the need of using jQuery for listening to the event.
// Transforms heartbeat jQuery events into equivalent hook actions. This
// avoids a dependency on jQuery for listening to the event.
$heartbeat_hooks = <<<JS
( function() {
jQuery( document ).on( [
'heartbeat-send',
'heartbeat-tick',
'heartbeat-error',
'heartbeat-connection-lost',
'heartbeat-connection-restored',
'heartbeat-nonces-expired',
].join( ' ' ), function( event ) {
var actionName = event.type.replace( /-/g, '.' ),
args;
// Omit the event argument in applying arguments to the hook callback.
// The remaining arguments are passed to the hook.
args = Array.prototype.slice.call( arguments, 1 );
wp.hooks.doAction.apply( null, [ actionName ].concat( args ) );
} );
} )();
JS;
wp_add_inline_script(
'heartbeat',
'jQuery( document ).on( "heartbeat-tick", function ( event, response ) { wp.hooks.doAction( "heartbeat.tick", response ) } );',
$heartbeat_hooks,
'after'
);

Expand Down
1 change: 0 additions & 1 deletion lib/packages-dependencies.php
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,6 @@
'wp-viewport',
),
'wp-editor' => array(
'jquery',
'lodash',
'wp-a11y',
'wp-api-fetch',
Expand Down
6 changes: 0 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions packages/editor/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 9.0.7 (Unreleased)

### Internal

- Removed `jQuery` dependency

## 9.0.7 (2019-01-03)

## 9.0.6 (2018-12-18)
Expand Down
1 change: 0 additions & 1 deletion packages/editor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@
"classnames": "^2.2.5",
"dom-scroll-into-view": "^1.2.1",
"inherits": "^2.0.3",
"jquery": "^3.3.1",
"lodash": "^4.17.10",
"memize": "^1.0.5",
"react-autosize-textarea": "^3.0.2",
Expand Down
59 changes: 34 additions & 25 deletions packages/editor/src/components/post-locked-modal/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
/**
* External dependencies
*/
import jQuery from 'jquery';
import { get } from 'lodash';

/**
Expand All @@ -12,7 +11,8 @@ import { Modal, Button } from '@wordpress/components';
import { withSelect, withDispatch } from '@wordpress/data';
import { addQueryArgs } from '@wordpress/url';
import { Component } from '@wordpress/element';
import { compose, withGlobalEvents } from '@wordpress/compose';
import { addAction, removeAction } from '@wordpress/hooks';
import { compose, withGlobalEvents, withInstanceId } from '@wordpress/compose';

/**
* Internal dependencies
Expand All @@ -30,17 +30,30 @@ class PostLockedModal extends Component {
}

componentDidMount() {
const hookName = this.getHookName();

// Details on these events on the Heartbeat API docs
// https://developer.wordpress.org/plugins/javascript/heartbeat-api/
jQuery( document )
.on( 'heartbeat-send.refresh-lock', this.sendPostLock )
.on( 'heartbeat-tick.refresh-lock', this.receivePostLock );
addAction( 'heartbeat.send', hookName, this.sendPostLock );
addAction( 'heartbeat.tick', hookName, this.receivePostLock );
}

componentWillUnmount() {
jQuery( document )
.off( 'heartbeat-send.refresh-lock', this.sendPostLock )
.off( 'heartbeat-tick.refresh-lock', this.receivePostLock );
const hookName = this.getHookName();

removeAction( 'heartbeat.send', hookName );
removeAction( 'heartbeat.tick', hookName );
}

/**
* Returns a `@wordpress/hooks` hook name specific to the instance of the
* component.
*
* @return {string} Hook name prefix.
*/
getHookName() {
const { instanceId } = this.props;
return 'core/editor/post-locked-modal-' + instanceId;
}

/**
Expand All @@ -49,10 +62,9 @@ class PostLockedModal extends Component {
* When the user does not send a heartbeat in a heartbeat-tick
* the user is no longer editing and another user can start editing.
*
* @param {Object} event Event.
* @param {Object} data Data to send in the heartbeat request.
* @param {Object} data Data to send in the heartbeat request.
*/
sendPostLock( event, data ) {
sendPostLock( data ) {
const { isLocked, activePostLock, postId } = this.props;
if ( isLocked ) {
return;
Expand All @@ -67,10 +79,9 @@ class PostLockedModal extends Component {
/**
* Refresh post locks: update the lock string or show the dialog if somebody has taken over editing.
*
* @param {Object} event Event.
* @param {Object} data Data received in the heartbeat request
* @param {Object} data Data received in the heartbeat request
*/
receivePostLock( event, data ) {
receivePostLock( data ) {
if ( ! data[ 'wp-refresh-post-lock' ] ) {
return;
}
Expand Down Expand Up @@ -104,18 +115,15 @@ class PostLockedModal extends Component {
return;
}

const data = {
action: 'wp-remove-post-lock',
_wpnonce: postLockUtils.unlockNonce,
post_ID: postId,
active_post_lock: activePostLock,
};
const data = new window.FormData();
data.append( 'action', 'wp-remove-post-lock' );
data.append( '_wpnonce', postLockUtils.unlockNonce );
data.append( 'post_ID', postId );
data.append( 'active_post_lock', activePostLock );

jQuery.post( {
async: false,
url: postLockUtils.ajaxUrl,
data,
} );
const xhr = new window.XMLHttpRequest();
xhr.open( 'POST', postLockUtils.ajaxUrl, false );
xhr.send( data );
}

render() {
Expand Down Expand Up @@ -232,6 +240,7 @@ export default compose(
updatePostLock,
};
} ),
withInstanceId,
withGlobalEvents( {
beforeunload: 'releasePostLock',
} )
Expand Down

0 comments on commit efbbca9

Please sign in to comment.