Skip to content

Commit

Permalink
MetaBoxes: compare meta boxes HTML while leaving the editor to warn a…
Browse files Browse the repository at this point in the history
…bout unsaved changes
  • Loading branch information
youknowriad committed Jan 10, 2018
1 parent 9eff87c commit 35276f0
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 3 deletions.
2 changes: 1 addition & 1 deletion editor/components/meta-boxes/meta-boxes-area/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ class MetaBoxesArea extends Component {
return (
<div className={ classes }>
{ loading && <Spinner /> }
<div ref={ this.bindNode } />
<div className="editor-meta-boxes-area__container" ref={ this.bindNode } />
<div className="editor-meta-boxes-area__clear" />
</div>
);
Expand Down
10 changes: 8 additions & 2 deletions editor/components/unsaved-changes-warning/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* External dependencies
*/
import { connect } from 'react-redux';
import { some } from 'lodash';

/**
* WordPress dependencies
Expand All @@ -12,7 +13,8 @@ import { Component } from '@wordpress/element';
/**
* Internal dependencies
*/
import { isEditedPostDirty } from '../../store/selectors';
import { isEditedPostDirty, getMetaBoxes } from '../../store/selectors';
import { getLocationHtml } from '../../edit-post/meta-boxes';

class UnsavedChangesWarning extends Component {
constructor() {
Expand All @@ -29,7 +31,10 @@ class UnsavedChangesWarning extends Component {
}

warnIfUnsavedChanges( event ) {
if ( this.props.isDirty ) {
const areMetaBoxesDirty = some( this.props.metaBoxes, ( metaBoxe, location ) => {
return metaBoxe.isActive && getLocationHtml( location ) !== metaBoxe.html;
} );
if ( this.props.isDirty || areMetaBoxesDirty ) {
event.returnValue = __( 'You have unsaved changes. If you proceed, they will be lost.' );
return event.returnValue;
}
Expand All @@ -43,5 +48,6 @@ class UnsavedChangesWarning extends Component {
export default connect(
( state ) => ( {
isDirty: isEditedPostDirty( state ),
metaBoxes: getMetaBoxes( state ),
} )
)( UnsavedChangesWarning );
16 changes: 16 additions & 0 deletions editor/edit-post/meta-boxes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
* Function returning the current Meta Boxes HTML in the editor
* whether the meta box area is opened or not.
* This is not so clear, but I believe it's the only way to have this data synchronously
*
* @param {String} location Meta Box location
* @returns {String} HTML content
*/
export const getLocationHtml = ( location ) => {
const area = document.querySelector( `.editor-meta-boxes-area.is-${ location } .editor-meta-boxes-area__container` );
if ( area ) {
return area.innerHTML;
}

return document.querySelector( '.metabox-location-' + location ).innerHTML;
};
3 changes: 3 additions & 0 deletions editor/store/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import { getBlockTypes, getBlockType } from '@wordpress/blocks';
import withHistory from '../utils/with-history';
import withChangeDetection from '../utils/with-change-detection';
import { PREFERENCES_DEFAULTS } from './defaults';
import { getLocationHtml } from '../edit-post/meta-boxes';

/***
* Module constants
Expand Down Expand Up @@ -667,6 +668,7 @@ export function metaBoxes( state = defaultMetaBoxState, action ) {
...state[ location ],
isLoaded: false,
isActive: action.metaBoxes[ location ],
html: getLocationHtml( location ),
};
return newState;
}, { ...state } );
Expand All @@ -685,6 +687,7 @@ export function metaBoxes( state = defaultMetaBoxState, action ) {
[ action.location ]: {
...state[ action.location ],
isUpdating: false,
html: getLocationHtml( action.location ),
},
};
case 'REQUEST_META_BOX_UPDATES':
Expand Down
10 changes: 10 additions & 0 deletions editor/store/test/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ import {
reusableBlocks,
} from '../reducer';

jest.mock( '../../edit-post/meta-boxes', () => {
return {
getLocationHtml: () => 'meta boxes content',
};
} );

describe( 'state', () => {
describe( 'getPostRawValue', () => {
it( 'returns original value for non-rendered content', () => {
Expand Down Expand Up @@ -1284,16 +1290,19 @@ describe( 'state', () => {
isActive: false,
isUpdating: false,
isLoaded: false,
html: 'meta boxes content',
},
side: {
isActive: true,
isUpdating: false,
isLoaded: false,
html: 'meta boxes content',
},
advanced: {
isActive: false,
isUpdating: false,
isLoaded: false,
html: 'meta boxes content',
},
};

Expand All @@ -1311,6 +1320,7 @@ describe( 'state', () => {
const expected = {
isActive: false,
isUpdating: false,
html: 'meta boxes content',
};

expect( actual ).toEqual( expected );
Expand Down

0 comments on commit 35276f0

Please sign in to comment.