Skip to content

Commit

Permalink
Bringing iframes into React/Redux
Browse files Browse the repository at this point in the history
Brings iframes into React, updates of the post now trigger submission of
the iframe forms. Fixed linting errors, and added tests for new JS
functionality.
  • Loading branch information
BE-Webdesign committed Sep 2, 2017
1 parent dab0948 commit 500dfea
Show file tree
Hide file tree
Showing 16 changed files with 329 additions and 47 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ build
coverage
vendor
node_modules
/assets/js
1 change: 1 addition & 0 deletions assets/css/metabox.css
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* Hides scrollbar to make iframe content seem as though it is part of the page. */
.gutenberg-metabox-html {
overflow: hidden;
width: 100%;
}

.gutenberg-metabox-html.sidebar-open {
Expand Down
31 changes: 31 additions & 0 deletions editor/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,37 @@ export function removeNotice( id ) {
};
}

// Metabox related actions.

/**
* Returns an action object used to trigger metabox updates.
*
* @return {Object} Action object
*/
export function updateMetaboxes() {
return {
type: 'UPDATE_METABOXES',
};
}

/**
* Returns an action object used to set metabox DOM references.
*
* @param {String} location The metabox location: normal, advanced, side.
* @param {DOMElement} node The reference node of the metabox.
*
* @return {Object} Action object
*/
export function setMetaboxReference( location, node ) {
return {
type: 'SET_METABOX_REFERENCE',
data: {
location,
node,
},
};
}

export const createSuccessNotice = partial( createNotice, 'success' );
export const createInfoNotice = partial( createNotice, 'info' );
export const createErrorNotice = partial( createNotice, 'error' );
Expand Down
15 changes: 15 additions & 0 deletions editor/effects.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
removeNotice,
savePost,
editPost,
updateMetaboxes,
} from './actions';
import {
getCurrentPost,
Expand All @@ -35,6 +36,7 @@ import {
isEditedPostDirty,
isEditedPostNew,
isEditedPostSaveable,
getMetaboxNodes,
} from './selectors';

const SAVE_POST_NOTICE_ID = 'SAVE_POST_NOTICE_ID';
Expand Down Expand Up @@ -113,6 +115,9 @@ export default {
) );
}

// Update metaboxes.
dispatch( updateMetaboxes() );

if ( get( window.history.state, 'id' ) !== post.id ) {
window.history.replaceState(
{ id: post.id },
Expand Down Expand Up @@ -273,4 +278,14 @@ export default {

return effects;
},
UPDATE_METABOXES( action, store ) {
const { getState } = store;
const state = getState();
const metaboxes = getMetaboxNodes( state );
Object.values( metaboxes ).forEach( ( iframe ) => {
// The standard post.php form ID post should probably be mimicked.
const form = iframe.contentWindow.document.getElementById( 'post' );
form.submit();
} );
},
};
10 changes: 6 additions & 4 deletions editor/layout/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import UnsavedChangesWarning from '../unsaved-changes-warning';
import DocumentTitle from '../document-title';
import AutosaveMonitor from '../autosave-monitor';
import { removeNotice } from '../actions';
import Metaboxes from '../metaboxes';
import {
getEditorMode,
isEditorSidebarOpened,
Expand All @@ -32,8 +33,8 @@ function Layout( { mode, isSidebarOpened, notices, ...props } ) {
'is-sidebar-opened': isSidebarOpened,
} );

return (
<div className={ className }>
return [
<div key="editor" className={ className }>
<DocumentTitle />
<NoticeList onRemove={ props.removeNotice } notices={ notices } />
<UnsavedChangesWarning />
Expand All @@ -44,8 +45,9 @@ function Layout( { mode, isSidebarOpened, notices, ...props } ) {
{ mode === 'visual' && <VisualEditor /> }
</div>
{ isSidebarOpened && <Sidebar /> }
</div>
);
</div>,
<Metaboxes key="metaboxes" location="normal" isSidebarOpened={ isSidebarOpened } />,
];
}

export default connect(
Expand Down
62 changes: 62 additions & 0 deletions editor/metaboxes/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/**
* External dependencies
*/
import classnames from 'classnames';
import { connect } from 'react-redux';
// @TODO Should this be React or WordPress elements?
import { Component } from 'react';

/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';

/**
* Internal dependencies
*/
import './style.scss';
import { setMetaboxReference } from '../actions';

class Metaboxes extends Component {
constructor() {
super();

this.state = {
cool: 'yeah',
};
}

componentDidMount() {
// Sets a React Node Reference into the store.
this.props.setReference( this.props.location, this.node );
}

render() {
const { location, isSidebarOpened, id = 'gutenberg-metabox-iframe' } = this.props;
const classes = classnames( {
'sidebar-open': isSidebarOpened,
'gutenberg-metabox-iframe': true,
} );

return (
<iframe
ref={ ( node ) => {
this.node = node;
} }
title={ __( 'Extended Settings' ) }
key="metabox"
id={ id }
className={ classes }
src={ `${ window._wpMetaboxUrl }&metabox=${ location }` } />
);
}
}

function mapDispatchToProps( dispatch ) {
return {
// Used to set the reference to the Metabox in redux, fired when the component mounts.
setReference: ( location, node ) => dispatch( setMetaboxReference( location, node ) ),
};
}

export default connect( null, mapDispatchToProps )( Metaboxes );
7 changes: 7 additions & 0 deletions editor/metaboxes/style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.gutenberg-metabox-iframe {
width: 100%;

&.sidebar-open {
padding: 0 $sidebar-width 0 0;
}
}
10 changes: 10 additions & 0 deletions editor/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,15 @@ export function notices( state = {}, action ) {
return state;
}

export function legacyMetaboxes( state = {}, action ) {
switch ( action.type ) {
case 'SET_METABOX_REFERENCE':
return { ...state, [ action.data.location ]: action.data.node };
default:
return state;
}
}

export default optimist( combineReducers( {
editor,
currentPost,
Expand All @@ -541,4 +550,5 @@ export default optimist( combineReducers( {
saving,
notices,
userData,
legacyMetaboxes,
} ) );
10 changes: 10 additions & 0 deletions editor/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -804,3 +804,13 @@ export function getRecentlyUsedBlocks( state ) {
// resolves the block names in the state to the block type settings
return state.userData.recentlyUsedBlocks.map( blockType => getBlockType( blockType ) );
}

/**
* Returns the object of nodes for metaboxes.
*
* @param {Object} state Global application state
* @return {Object} Map of location to metabox iframe.
*/
export function getMetaboxNodes( state ) {
return state.legacyMetaboxes;
}
24 changes: 24 additions & 0 deletions editor/test/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import {
replaceBlocks,
startTyping,
stopTyping,
updateMetaboxes,
setMetaboxReference,
} from '../actions';

describe( 'actions', () => {
Expand Down Expand Up @@ -52,4 +54,26 @@ describe( 'actions', () => {
} );
} );
} );

describe( 'updateMetaboxes', () => {
it( 'should return the UPDATE_METABOXES action', () => {
expect( updateMetaboxes() ).toEqual( {
type: 'UPDATE_METABOXES',
} );
} );
} );

describe( 'setMetaboxReference', () => {
it( 'should return the SET_METABOX_REFERENCE action with a location and node', () => {
const location = 'side';
const node = { i: 'is node' };
expect( setMetaboxReference( location, node ) ).toEqual( {
type: 'SET_METABOX_REFERENCE',
data: {
location,
node,
},
} );
} );
} );
} );
59 changes: 59 additions & 0 deletions editor/test/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
notices,
showInsertionPoint,
userData,
legacyMetaboxes,
} from '../reducer';

describe( 'state', () => {
Expand Down Expand Up @@ -966,4 +967,62 @@ describe( 'state', () => {
expect( initial.recentlyUsedBlocks ).toHaveLength( 8 );
} );
} );

describe( 'legacyMetaboxes()', () => {
it( 'should return an empty object by default', () => {
const actual = legacyMetaboxes( undefined, {} );
const expected = {};

expect( actual ).toEqual( expected );
} );
it( 'should add in metabox references', () => {
const action = {
type: 'SET_METABOX_REFERENCE',
data: {
location: 'side',
node: 'I am node',
},
};

const actual = legacyMetaboxes( undefined, action );
const expected = {
side: 'I am node',
};

expect( actual ).toEqual( expected );
} );
it( 'should override existing metabox references', () => {
const action = {
type: 'SET_METABOX_REFERENCE',
data: {
location: 'side',
node: 'I am node',
},
};

const actual = legacyMetaboxes( { side: 'Ref' }, action );
const expected = {
side: 'I am node',
};

expect( actual ).toEqual( expected );
} );
it( 'should build on top of existing metabox references for new locations', () => {
const action = {
type: 'SET_METABOX_REFERENCE',
data: {
location: 'side',
node: 'I am node',
},
};

const actual = legacyMetaboxes( { normal: 'Ref' }, action );
const expected = {
normal: 'Ref',
side: 'I am node',
};

expect( actual ).toEqual( expected );
} );
} );
} );
17 changes: 17 additions & 0 deletions editor/test/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ import {
didPostSaveRequestFail,
getSuggestedPostFormat,
getNotices,
getMetaboxNodes,
} from '../selectors';

describe( 'selectors', () => {
Expand Down Expand Up @@ -1666,4 +1667,20 @@ describe( 'selectors', () => {
] );
} );
} );

describe( 'getMetaboxNodes', () => {
it( 'should return the notices array', () => {
const state = {
legacyMetaboxes: {
side: 'I am DOM Node',
normal: 'I am another DOM Node',
},
};

expect( getMetaboxNodes( state ) ).toEqual( {
side: 'I am DOM Node',
normal: 'I am another DOM Node',
} );
} );
} );
} );
2 changes: 1 addition & 1 deletion gutenberg.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
require_once dirname( __FILE__ ) . '/lib/init-checks.php';
if ( gutenberg_can_init() ) {
// Load API functions, register scripts and actions, etc.
require_once dirname( __FILE__ ) . '/lib/metabox-api.php';
require_once dirname( __FILE__ ) . '/lib/metabox-partial-page.php';
require_once dirname( __FILE__ ) . '/lib/class-wp-block-type.php';
require_once dirname( __FILE__ ) . '/lib/class-wp-block-type-registry.php';
require_once dirname( __FILE__ ) . '/lib/blocks.php';
Expand Down
8 changes: 8 additions & 0 deletions lib/client-assets.php
Original file line number Diff line number Diff line change
Expand Up @@ -796,6 +796,14 @@ function gutenberg_editor_scripts_and_styles( $hook ) {
}
wp_localize_script( 'wp-blocks', '_wpBlocksAttributes', $schemas );

// Get admin url for handling metaboxes.
$metabox_url = admin_url( 'post.php' );
$metabox_url = add_query_arg( array(
'post' => $post_id,
'action' => 'edit',
), $metabox_url );
wp_localize_script( 'wp-editor', '_wpMetaboxUrl', $metabox_url );

// Initialize the editor.
$gutenberg_theme_support = get_theme_support( 'gutenberg' );
$color_palette = gutenberg_color_palette();
Expand Down

0 comments on commit 500dfea

Please sign in to comment.