!! visibleBlocksByCategory[ category.slug ] && (
.editor-inserter__block {
+ opacity: 0;
+ transition: opacity 150ms;
+ margin: 0 10px;
+ width: auto;
+ font-family: $default-font;
+ font-size: $default-font-size;
+ box-shadow: none;
+
+ &:active {
+ background: none;
+ }
+ }
+
+ &:hover > .editor-inserter__block,
+ &.is-showing-controls > .editor-inserter__block {
+ opacity: 1;
+ }
+}
diff --git a/editor/layout/index.js b/editor/layout/index.js
deleted file mode 100644
index 9055f185875d09..00000000000000
--- a/editor/layout/index.js
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * External dependencies
- */
-import { connect } from 'react-redux';
-import classnames from 'classnames';
-
-/**
- * WordPress dependencies
- */
-import { NoticeList } from 'components';
-
-/**
- * Internal dependencies
- */
-import './style.scss';
-import Header from '../header';
-import Sidebar from '../sidebar';
-import TextEditor from '../modes/text-editor';
-import VisualEditor from '../modes/visual-editor';
-import UnsavedChangesWarning from '../unsaved-changes-warning';
-import DocumentTitle from '../document-title';
-import { removeNotice } from '../actions';
-import {
- getEditorMode,
- isEditorSidebarOpened,
- getNotices,
-} from '../selectors';
-
-function Layout( { mode, isSidebarOpened, notices, ...props } ) {
- const className = classnames( 'editor-layout', {
- 'is-sidebar-opened': isSidebarOpened,
- } );
-
- return (
-
-
-
-
-
-
- { mode === 'text' && }
- { mode === 'visual' && }
-
- { isSidebarOpened &&
}
-
- );
-}
-
-export default connect(
- ( state ) => ( {
- mode: getEditorMode( state ),
- isSidebarOpened: isEditorSidebarOpened( state ),
- notices: getNotices( state ),
- } ),
- { removeNotice }
-)( Layout );
diff --git a/editor/modes/visual-editor/block-list.js b/editor/modes/visual/block-list.js
similarity index 82%
rename from editor/modes/visual-editor/block-list.js
rename to editor/modes/visual/block-list.js
index 28576de7b33eab..ec31a503138797 100644
--- a/editor/modes/visual-editor/block-list.js
+++ b/editor/modes/visual/block-list.js
@@ -2,7 +2,6 @@
* External dependencies
*/
import { connect } from 'react-redux';
-import classnames from 'classnames';
import { throttle, reduce, noop } from 'lodash';
/**
@@ -10,15 +9,13 @@ import { throttle, reduce, noop } from 'lodash';
*/
import { __ } from 'i18n';
import { Component } from 'element';
-import { serialize, getDefaultBlock, createBlock } from 'blocks';
-import { IconButton } from 'components';
+import { serialize, createBlock } from 'blocks';
import { ENTER } from 'utils/keycodes';
/**
* Internal dependencies
*/
import VisualEditorBlock from './block';
-import Inserter from '../../inserter';
import {
getBlockUids,
getBlockInsertionPoint,
@@ -27,6 +24,9 @@ import {
getMultiSelectedBlocksEndUid,
getMultiSelectedBlocks,
getMultiSelectedBlockUids,
+ getDefaultBlockType,
+ getBlockType,
+ getBlockTypes,
} from '../../selectors';
import { insertBlock, multiSelect } from '../../actions';
@@ -35,9 +35,6 @@ const INSERTION_POINT_PLACEHOLDER = '[[insertion-point]]';
class VisualEditorBlockList extends Component {
constructor( props ) {
super( props );
- this.state = {
- showContinueWritingControls: false,
- };
this.onSelectionStart = this.onSelectionStart.bind( this );
this.onSelectionChange = this.onSelectionChange.bind( this );
this.onSelectionEnd = this.onSelectionEnd.bind( this );
@@ -48,7 +45,6 @@ class VisualEditorBlockList extends Component {
this.setLastClientY = this.setLastClientY.bind( this );
this.onPointerMove = throttle( this.onPointerMove.bind( this ), 250 );
this.onPlaceholderKeyDown = this.onPlaceholderKeyDown.bind( this );
- this.toggleContinueWritingControls = this.toggleContinueWritingControls.bind( this );
// Browser does not fire `*move` event when the pointer position changes
// relative to the document, so fire it with the last known position.
this.onScroll = () => this.onPointerMove( { clientY: this.lastClientY } );
@@ -107,10 +103,10 @@ class VisualEditorBlockList extends Component {
}
onCopy( event ) {
- const { multiSelectedBlocks } = this.props;
+ const { multiSelectedBlocks, blockTypes } = this.props;
if ( multiSelectedBlocks.length ) {
- const serialized = serialize( multiSelectedBlocks );
+ const serialized = serialize( multiSelectedBlocks, blockTypes );
event.clipboardData.setData( 'text/plain', serialized );
event.clipboardData.setData( 'text/html', serialized );
@@ -193,19 +189,10 @@ class VisualEditorBlockList extends Component {
}
appendDefaultBlock() {
- const newBlock = createBlock( getDefaultBlock() );
- this.props.onInsertBlock( newBlock );
- }
-
- insertBlock( name ) {
- const newBlock = createBlock( name );
+ const newBlock = createBlock( this.props.defaultBlockType );
this.props.onInsertBlock( newBlock );
}
- toggleContinueWritingControls( showContinueWritingControls ) {
- return () => this.setState( { showContinueWritingControls } );
- }
-
render() {
const {
blocks,
@@ -222,9 +209,6 @@ class VisualEditorBlockList extends Component {
...blocks.slice( insertionPointIndex + 1 ),
]
: blocks;
- const continueWritingClassname = classnames( 'editor-visual-editor__continue-writing', {
- 'is-showing-controls': this.state.showContinueWritingControls,
- } );
return (
@@ -260,29 +244,6 @@ class VisualEditorBlockList extends Component {
/>
}
-
-
- this.insertBlock( 'core/text' ) }
- label={ __( 'Insert text block' ) }
- >
- { __( 'Text' ) }
-
- this.insertBlock( 'core/image' ) }
- label={ __( 'Insert image block' ) }
- >
- { __( 'Image' ) }
-
-
);
}
@@ -297,6 +258,8 @@ export default connect(
selectionEnd: getMultiSelectedBlocksEndUid( state ),
multiSelectedBlocks: getMultiSelectedBlocks( state ),
multiSelectedBlockUids: getMultiSelectedBlockUids( state ),
+ defaultBlockType: getBlockType( state, getDefaultBlockType( state ) ),
+ blockTypes: getBlockTypes( state ),
} ),
( dispatch ) => ( {
onInsertBlock( block ) {
@@ -308,5 +271,9 @@ export default connect(
onRemove( uids ) {
dispatch( { type: 'REMOVE_BLOCKS', uids } );
},
- } )
+ } ),
+ undefined,
+ {
+ storeKey: 'editor',
+ }
)( VisualEditorBlockList );
diff --git a/editor/block-mover/index.js b/editor/modes/visual/block-mover/index.js
similarity index 88%
rename from editor/block-mover/index.js
rename to editor/modes/visual/block-mover/index.js
index fd57c070c1ac2c..9e2beb9a6422b7 100644
--- a/editor/block-mover/index.js
+++ b/editor/modes/visual/block-mover/index.js
@@ -8,13 +8,18 @@ import { first, last } from 'lodash';
* WordPress dependencies
*/
import { IconButton } from 'components';
-import { getBlockType } from 'blocks';
/**
* Internal dependencies
*/
import './style.scss';
-import { isFirstBlock, isLastBlock, getBlockIndex, getBlock } from '../selectors';
+import {
+ isFirstBlock,
+ isLastBlock,
+ getBlockIndex,
+ getBlock,
+ getBlockType,
+} from '../../../selectors';
import { getBlockMoverLabel } from './mover-label';
function BlockMover( { onMoveUp, onMoveDown, isFirst, isLast, uids, blockType, firstIndex } ) {
@@ -61,7 +66,7 @@ export default connect(
isFirst: isFirstBlock( state, first( ownProps.uids ) ),
isLast: isLastBlock( state, last( ownProps.uids ) ),
firstIndex: getBlockIndex( state, first( ownProps.uids ) ),
- blockType: getBlockType( getBlock( state, first( ownProps.uids ) ).name ),
+ blockType: getBlockType( state, getBlock( state, first( ownProps.uids ) ).name ),
} ),
( dispatch, ownProps ) => ( {
onMoveDown() {
@@ -76,5 +81,9 @@ export default connect(
uids: ownProps.uids,
} );
},
- } )
+ } ),
+ undefined,
+ {
+ storeKey: 'editor',
+ }
)( BlockMover );
diff --git a/editor/block-mover/mover-label.js b/editor/modes/visual/block-mover/mover-label.js
similarity index 100%
rename from editor/block-mover/mover-label.js
rename to editor/modes/visual/block-mover/mover-label.js
diff --git a/editor/block-mover/style.scss b/editor/modes/visual/block-mover/style.scss
similarity index 100%
rename from editor/block-mover/style.scss
rename to editor/modes/visual/block-mover/style.scss
diff --git a/editor/block-mover/test/mover-label.js b/editor/modes/visual/block-mover/test/mover-label.js
similarity index 100%
rename from editor/block-mover/test/mover-label.js
rename to editor/modes/visual/block-mover/test/mover-label.js
diff --git a/editor/block-settings-menu/index.js b/editor/modes/visual/block-settings-menu/index.js
similarity index 67%
rename from editor/block-settings-menu/index.js
rename to editor/modes/visual/block-settings-menu/index.js
index 5ca862946be9e8..e16157e5de8701 100644
--- a/editor/block-settings-menu/index.js
+++ b/editor/modes/visual/block-settings-menu/index.js
@@ -13,15 +13,11 @@ import { IconButton } from 'components';
* Internal dependencies
*/
import './style.scss';
-import { isEditorSidebarOpened } from 'editor/selectors';
-function BlockSettingsMenu( { onDelete, selectBlock, isSidebarOpened, toggleSidebar, setActivePanel } ) {
+function BlockSettingsMenu( { onDelete, selectBlock } ) {
const toggleInspector = () => {
selectBlock();
- setActivePanel();
- if ( ! isSidebarOpened ) {
- toggleSidebar();
- }
+ // TODO: onToggleBlockInspector
};
return (
@@ -43,9 +39,7 @@ function BlockSettingsMenu( { onDelete, selectBlock, isSidebarOpened, toggleSide
}
export default connect(
- ( state ) => ( {
- isSidebarOpened: isEditorSidebarOpened( state ),
- } ),
+ undefined,
( dispatch, ownProps ) => ( {
onDelete() {
dispatch( {
@@ -60,14 +54,9 @@ export default connect(
uid: ownProps.uid,
} );
},
- setActivePanel() {
- dispatch( {
- type: 'SET_ACTIVE_PANEL',
- panel: 'block',
- } );
- },
- toggleSidebar() {
- dispatch( { type: 'TOGGLE_SIDEBAR' } );
- },
- } )
+ } ),
+ undefined,
+ {
+ storeKey: 'editor',
+ }
)( BlockSettingsMenu );
diff --git a/editor/block-settings-menu/style.scss b/editor/modes/visual/block-settings-menu/style.scss
similarity index 90%
rename from editor/block-settings-menu/style.scss
rename to editor/modes/visual/block-settings-menu/style.scss
index 39176b763deceb..e9e00ee6913937 100644
--- a/editor/block-settings-menu/style.scss
+++ b/editor/modes/visual/block-settings-menu/style.scss
@@ -13,7 +13,7 @@
}
}
-.editor-block-settings-menu__control {
+.components-icon-button.editor-block-settings-menu__control {
display: block;
padding: 0;
border: none;
diff --git a/editor/block-switcher/index.js b/editor/modes/visual/block-switcher/index.js
similarity index 78%
rename from editor/block-switcher/index.js
rename to editor/modes/visual/block-switcher/index.js
index a0dd66b4cadc6a..6cf3c7edac7c0c 100644
--- a/editor/block-switcher/index.js
+++ b/editor/modes/visual/block-switcher/index.js
@@ -11,14 +11,14 @@ import clickOutside from 'react-click-outside';
import { __ } from 'i18n';
import { Component } from 'element';
import { Dashicon, IconButton } from 'components';
-import { getBlockType, getBlockTypes, switchToBlockType } from 'blocks';
+import { switchToBlockType } from 'blocks';
/**
* Internal dependencies
*/
import './style.scss';
-import { replaceBlocks } from '../actions';
-import { getBlock } from '../selectors';
+import { replaceBlocks } from '../../../actions';
+import { getBlock, getBlockTypes } from '../../../selectors';
class BlockSwitcher extends Component {
constructor() {
@@ -43,18 +43,22 @@ class BlockSwitcher extends Component {
} ) );
}
+ getBlockType( name ) {
+ return find( this.props.blockTypes, ( bt ) => bt.name === name );
+ }
+
switchBlockType( name ) {
return () => {
this.setState( {
open: false,
} );
- this.props.onTransform( this.props.block, name );
+ this.props.onTransform( this.props.block, this.getBlockType( this.props.block.name ), this.getBlockType( name ) );
};
}
render() {
- const blockType = getBlockType( this.props.block.name );
- const blocksToBeTransformedFrom = reduce( getBlockTypes(), ( memo, block ) => {
+ const blockType = this.getBlockType( this.props.block.name );
+ const blocksToBeTransformedFrom = reduce( this.props.blockTypes, ( memo, block ) => {
const transformFrom = get( block, 'transforms.from', [] );
const transformation = find( transformFrom, t => t.type === 'block' && t.blocks.indexOf( this.props.block.name ) !== -1 );
return transformation ? memo.concat( [ block.name ] ) : memo;
@@ -63,7 +67,7 @@ class BlockSwitcher extends Component {
.reduce( ( memo, transformation ) => memo.concat( transformation.blocks ), [] );
const allowedBlocks = uniq( blocksToBeTransformedFrom.concat( blocksToBeTransformedTo ) )
.reduce( ( memo, name ) => {
- const block = getBlockType( name );
+ const block = this.getBlockType( name );
return !! block ? memo.concat( block ) : memo;
}, [] );
@@ -111,13 +115,18 @@ class BlockSwitcher extends Component {
export default connect(
( state, ownProps ) => ( {
block: getBlock( state, ownProps.uid ),
+ blockTypes: getBlockTypes( state ),
} ),
( dispatch, ownProps ) => ( {
- onTransform( block, name ) {
+ onTransform( block, blockType ) {
dispatch( replaceBlocks(
[ ownProps.uid ],
- switchToBlockType( block, name )
+ switchToBlockType( block, blockType )
) );
},
- } )
+ } ),
+ undefined,
+ {
+ storeKey: 'editor',
+ }
)( clickOutside( BlockSwitcher ) );
diff --git a/editor/block-switcher/style.scss b/editor/modes/visual/block-switcher/style.scss
similarity index 100%
rename from editor/block-switcher/style.scss
rename to editor/modes/visual/block-switcher/style.scss
diff --git a/editor/modes/visual-editor/block.js b/editor/modes/visual/block.js
similarity index 93%
rename from editor/modes/visual-editor/block.js
rename to editor/modes/visual/block.js
index 144f33c9746f96..1eb810c50ad5d6 100644
--- a/editor/modes/visual-editor/block.js
+++ b/editor/modes/visual/block.js
@@ -13,16 +13,16 @@ import CSSTransitionGroup from 'react-transition-group/CSSTransitionGroup';
import { Children, Component } from 'element';
import { IconButton, Toolbar } from 'components';
import { BACKSPACE, ESCAPE, DELETE, UP, DOWN, LEFT, RIGHT } from 'utils/keycodes';
-import { getBlockType, getBlockDefaultClassname } from 'blocks';
+import { getBlockDefaultClassname } from 'blocks';
import { __, sprintf } from 'i18n';
/**
* Internal dependencies
*/
import InvalidBlockWarning from './invalid-block-warning';
-import BlockMover from '../../block-mover';
-import BlockRightMenu from '../../block-settings-menu';
-import BlockSwitcher from '../../block-switcher';
+import BlockMover from './block-mover';
+import BlockRightMenu from './block-settings-menu';
+import BlockSwitcher from './block-switcher';
import {
updateBlockAttributes,
focusBlock,
@@ -45,6 +45,9 @@ import {
isBlockMultiSelected,
isFirstMultiSelectedBlock,
isTyping,
+ getBlockType,
+ getBlockTypes,
+ getEditorConfig,
} from '../../selectors';
function FirstChild( { children } ) {
@@ -206,7 +209,7 @@ class VisualEditorBlock extends Component {
}
mergeBlocks( forward = false ) {
- const { block, previousBlock, nextBlock, onMerge } = this.props;
+ const { block, previousBlock, nextBlock, onMerge, blockTypes } = this.props;
// Do nothing when it's the first block.
if (
@@ -217,9 +220,9 @@ class VisualEditorBlock extends Component {
}
if ( forward ) {
- onMerge( block, nextBlock );
+ onMerge( [ block, nextBlock ], blockTypes );
} else {
- onMerge( previousBlock, block );
+ onMerge( [ previousBlock, block ], blockTypes );
}
}
@@ -304,9 +307,8 @@ class VisualEditorBlock extends Component {
}
render() {
- const { block, multiSelectedBlockUids } = this.props;
- const { name: blockName, isValid } = block;
- const blockType = getBlockType( blockName );
+ const { block, multiSelectedBlockUids, blockType, editorConfig } = this.props;
+ const { isValid } = block;
// translators: %s: Type of block (i.e. Text, Image etc)
const blockLabel = sprintf( __( 'Block: %s' ), blockType.title );
// The block as rendered in the editor is composed of general block UI
@@ -346,7 +348,7 @@ class VisualEditorBlock extends Component {
}
// Generate a class name for the block's editable form
- let { className = getBlockDefaultClassname( block.name ) } = blockType;
+ let { className = getBlockDefaultClassname( blockType.name ) } = blockType;
className = classnames( className, block.attributes.className );
// Disable reason: Each block can be selected by clicking on it
@@ -415,6 +417,7 @@ class VisualEditorBlock extends Component {
mergeBlocks={ this.mergeBlocks }
className={ className }
id={ block.uid }
+ editorConfig={ editorConfig }
/>
) }
{ ! isValid && (
@@ -433,10 +436,11 @@ class VisualEditorBlock extends Component {
export default connect(
( state, ownProps ) => {
+ const block = getBlock( state, ownProps.uid );
+
return {
previousBlock: getPreviousBlock( state, ownProps.uid ),
nextBlock: getNextBlock( state, ownProps.uid ),
- block: getBlock( state, ownProps.uid ),
isSelected: isBlockSelected( state, ownProps.uid ),
isMultiSelected: isBlockMultiSelected( state, ownProps.uid ),
isFirstMultiSelected: isFirstMultiSelectedBlock( state, ownProps.uid ),
@@ -444,6 +448,10 @@ export default connect(
focus: getBlockFocus( state, ownProps.uid ),
isTyping: isTyping( state ),
order: getBlockIndex( state, ownProps.uid ),
+ blockType: getBlockType( state, block.name ),
+ blockTypes: getBlockTypes( state ),
+ editorConfig: getEditorConfig( state ),
+ block,
};
},
( dispatch, ownProps ) => ( {
@@ -497,12 +505,16 @@ export default connect(
dispatch( removeBlocks( uids ) );
},
- onMerge( ...args ) {
- dispatch( mergeBlocks( ...args ) );
+ onMerge( blocks, blockTypes ) {
+ mergeBlocks( dispatch, blocks, blockTypes );
},
onReplace( blocks ) {
dispatch( replaceBlocks( [ ownProps.uid ], blocks ) );
},
- } )
+ } ),
+ undefined,
+ {
+ storeKey: 'editor',
+ }
)( VisualEditorBlock );
diff --git a/editor/modes/visual-editor/index.js b/editor/modes/visual/index.js
similarity index 93%
rename from editor/modes/visual-editor/index.js
rename to editor/modes/visual/index.js
index 8feb5ddf30d6b0..572f03d86e1ea4 100644
--- a/editor/modes/visual-editor/index.js
+++ b/editor/modes/visual/index.js
@@ -7,7 +7,6 @@ import { first, last } from 'lodash';
/**
* WordPress dependencies
*/
-import { __ } from 'i18n';
import { Component, findDOMNode } from 'element';
import { KeyboardShortcuts } from 'components';
@@ -16,7 +15,6 @@ import { KeyboardShortcuts } from 'components';
*/
import './style.scss';
import VisualEditorBlockList from './block-list';
-import PostTitle from '../../post-title';
import { getBlockUids } from '../../selectors';
import { clearSelectedBlock, multiSelect } from '../../actions';
@@ -62,8 +60,6 @@ class VisualEditor extends Component {
/* eslint-disable jsx-a11y/no-static-element-interactions, jsx-a11y/onclick-has-role, jsx-a11y/click-events-have-key-events */
return (
-
);
@@ -90,5 +85,9 @@ export default connect(
{
clearSelectedBlock,
multiSelect,
+ },
+ undefined,
+ {
+ storeKey: 'editor',
}
)( VisualEditor );
diff --git a/editor/modes/visual-editor/invalid-block-warning.js b/editor/modes/visual/invalid-block-warning.js
similarity index 100%
rename from editor/modes/visual-editor/invalid-block-warning.js
rename to editor/modes/visual/invalid-block-warning.js
diff --git a/editor/modes/visual-editor/style.scss b/editor/modes/visual/style.scss
similarity index 87%
rename from editor/modes/visual-editor/style.scss
rename to editor/modes/visual/style.scss
index 4db64a4f8ada00..49fb63f15d1880 100644
--- a/editor/modes/visual-editor/style.scss
+++ b/editor/modes/visual/style.scss
@@ -1,27 +1,11 @@
.editor-visual-editor {
position: relative;
- margin: 0 auto;
- padding: 50px 0; // Floating up/down arrows invisible
-
&,
& p {
font-family: $editor-font;
font-size: $editor-font-size;
line-height: $editor-line-height;
}
-
- @include break-small() {
- padding: 50px 0;
- }
-
- @include break-large() {
- padding: 60px 0;
- }
-}
-
-.editor-visual-editor {
- margin-left: auto;
- margin-right: auto;
}
.editor-visual-editor__block {
@@ -339,19 +323,6 @@ $sticky-bottom-offset: 20px;
display: inline-flex;
}
-.editor-visual-editor .editor-inserter {
- margin: $item-spacing;
-
- .editor-inserter__toggle {
- color: $dark-gray-300;
- margin: 4px 0 0 -4px; // align better with text blocks
- }
-
- .editor-inserter__toggle.components-icon-button:not(:disabled):hover {
- color: $blue-medium-500;
- }
-}
-
.editor-visual-editor .editor-visual-editor__insertion-point {
position: relative;
width: $visual-editor-max-width - $block-padding - $block-padding;
@@ -377,7 +348,7 @@ $sticky-bottom-offset: 20px;
position: relative;
@include break-small() {
- padding: 0 ( $block-padding + $block-mover-padding-visible );
+ padding: 0 $block-mover-padding-visible;
}
input[type=text] {
@@ -403,43 +374,6 @@ $sticky-bottom-offset: 20px;
}
padding: ( $block-padding - 2px ) $block-padding;
-
- @include break-small() {
- margin-left: -$block-padding;
- margin-right: -$block-padding;
- }
- }
-}
-
-.editor-visual-editor__continue-writing {
- display: flex;
- align-items: baseline;
- max-width: $visual-editor-max-width + ( 2 * $block-mover-padding-visible );
- margin: 0 auto;
- clear: both;
-
- padding: 0;
- @include break-small() {
- padding: 0 ( $block-mover-padding-visible );
- }
-
- > .editor-inserter__block {
- opacity: 0;
- transition: opacity 150ms;
- margin: 0 10px;
- width: auto;
- font-family: $default-font;
- font-size: $default-font-size;
- box-shadow: none;
-
- &:active {
- background: none;
- }
- }
-
- &:hover > .editor-inserter__block,
- &.is-showing-controls > .editor-inserter__block {
- opacity: 1;
}
}
diff --git a/editor/multi-selection-header/index.js b/editor/multi-selection-header/index.js
new file mode 100644
index 00000000000000..356fad0beb7656
--- /dev/null
+++ b/editor/multi-selection-header/index.js
@@ -0,0 +1,67 @@
+/**
+ * External dependencies
+ */
+import { connect } from 'react-redux';
+
+/**
+ * WordPress dependencies
+ */
+import { sprintf, _n, __ } from 'i18n';
+import { IconButton } from 'components';
+
+/**
+ * Internal dependencies
+ */
+import './style.scss';
+import { getMultiSelectedBlockUids } from '../selectors';
+import { clearSelectedBlock } from '../actions';
+
+function MultiSelectionHeader( { multiSelectedBlockUids, onRemove, onDeselect } ) {
+ const count = multiSelectedBlockUids.length;
+
+ if ( ! count ) {
+ return null;
+ }
+
+ return (
+
+
+ { sprintf( _n( '%d block selected', '%d blocks selected', count ), count ) }
+
+
+ onRemove( multiSelectedBlockUids ) }
+ focus={ true }
+ >
+ { __( 'Delete' ) }
+
+
+
+ onDeselect() }
+ />
+
+
+ );
+}
+
+export default connect(
+ ( state ) => ( {
+ multiSelectedBlockUids: getMultiSelectedBlockUids( state ),
+ } ),
+ ( dispatch ) => ( {
+ onDeselect: () => dispatch( clearSelectedBlock() ),
+ onRemove: ( uids ) => dispatch( {
+ type: 'REMOVE_BLOCKS',
+ uids,
+ } ),
+ } ),
+ undefined,
+ {
+ storeKey: 'editor',
+ }
+)( MultiSelectionHeader );
diff --git a/editor/multi-selection-header/style.scss b/editor/multi-selection-header/style.scss
new file mode 100644
index 00000000000000..7f5fa662813f71
--- /dev/null
+++ b/editor/multi-selection-header/style.scss
@@ -0,0 +1,14 @@
+.editor-multi-selection-header {
+ background: $blue-medium-100;
+ border-bottom: 1px solid $blue-medium-200;
+}
+
+.editor-multi-selection-header__count {
+ padding-right: $item-spacing;
+ color: $dark-gray-500;
+ border-right: 1px solid $light-gray-500;
+}
+
+.editor-multi-selection-header__clear {
+ margin: 0 0 0 auto;
+}
diff --git a/editor/provider/index.js b/editor/provider/index.js
new file mode 100644
index 00000000000000..8038fd3b138b8b
--- /dev/null
+++ b/editor/provider/index.js
@@ -0,0 +1,56 @@
+/**
+ * External dependencies
+ */
+import { createProvider } from 'react-redux';
+
+/**
+ * WordPress dependencies
+ */
+import { Component } from 'element';
+
+/**
+ * Internal dependencies
+ */
+import createReduxStore from '../state';
+import { getBlocks } from '../selectors';
+
+class Provider extends Component {
+ constructor() {
+ super( ...arguments );
+ // Trigger onChange if blocks change
+ this.provider = createProvider( 'editor' );
+ this.store = createReduxStore();
+ this.store.dispatch( {
+ type: 'INIT_EDITOR',
+ config: this.props.config,
+ } );
+ this.blocks = getBlocks( this.store.getState() );
+ this.store.subscribe( () => {
+ const newBlocks = getBlocks( this.store.getState() );
+ if ( this.blocks !== newBlocks ) {
+ this.props.onChange( newBlocks );
+ this.blocks = newBlocks;
+ }
+ } );
+ }
+
+ componentDidUpdate() {
+ if ( this.props.value !== this.blocks ) {
+ this.store.dispatch( {
+ type: 'RESET_BLOCKS',
+ blocks: this.props.value,
+ } );
+ }
+ }
+
+ render() {
+ const ReduxProvider = this.provider;
+ return (
+
+ { this.props.children }
+
+ );
+ }
+}
+
+export default Provider;
diff --git a/editor/selectors.js b/editor/selectors.js
index 84cb2124bb7bb4..1ecf91c3164ef4 100644
--- a/editor/selectors.js
+++ b/editor/selectors.js
@@ -1,299 +1,58 @@
/**
* External dependencies
*/
-import moment from 'moment';
-import { first, last, get, values } from 'lodash';
+import { first, last, find } from 'lodash';
import createSelector from 'rememo';
/**
- * WordPress dependencies
- */
-import { getBlockType } from 'blocks';
-
-/**
- * Internal dependencies
- */
-import { addQueryArgs } from './utils/url';
-
-/**
- * WordPress dependencies
- */
-import { __ } from 'i18n';
-
-/**
- * Returns the current editing mode.
+ * Returns all editor config object
*
* @param {Object} state Global application state
- * @return {String} Editing mode
- */
-export function getEditorMode( state ) {
- return state.mode;
-}
-
-/**
- * Returns the current active panel for the sidebar.
- *
- * @param {Object} state Global application state
- * @return {String} Active sidebar panel
- */
-export function getActivePanel( state ) {
- return state.panel;
-}
-
-/**
- * Returns true if the editor sidebar panel is open, or false otherwise.
- *
- * @param {Object} state Global application state
- * @return {Boolean} Whether sidebar is open
- */
-export function isEditorSidebarOpened( state ) {
- return state.isSidebarOpened;
-}
-
-/**
- * Returns true if any past editor history snapshots exist, or false otherwise.
- *
- * @param {Object} state Global application state
- * @return {Boolean} Whether undo history exists
- */
-export function hasEditorUndo( state ) {
- return state.editor.history.past.length > 0;
-}
-
-/**
- * Returns true if any future editor history snapshots exist, or false
- * otherwise.
- *
- * @param {Object} state Global application state
- * @return {Boolean} Whether redo history exists
- */
-export function hasEditorRedo( state ) {
- return state.editor.history.future.length > 0;
-}
-
-/**
- * Returns true if the currently edited post is yet to be saved, or false if
- * the post has been saved.
- *
- * @param {Object} state Global application state
- * @return {Boolean} Whether the post is new
- */
-export function isEditedPostNew( state ) {
- return getEditedPostAttribute( state, 'status' ) === 'auto-draft';
-}
-
-/**
- * Returns true if there are unsaved values for the current edit session, or
- * false if the editing state matches the saved or new post.
- *
- * @param {Object} state Global application state
- * @return {Boolean} Whether unsaved values exist
- */
-export function isEditedPostDirty( state ) {
- return state.editor.dirty;
-}
-
-/**
- * Returns true if there are no unsaved values for the current edit session and if
- * the currently edited post is new (and has never been saved before).
- *
- * @param {Object} state Global application state
- * @return {Boolean} Whether new post and unsaved values exist
- */
-export function isCleanNewPost( state ) {
- return ! isEditedPostDirty( state ) && isEditedPostNew( state );
-}
-
-/**
- * Returns the post currently being edited in its last known saved state, not
- * including unsaved edits. Returns an object containing relevant default post
- * values if the post has not yet been saved.
- *
- * @param {Object} state Global application state
- * @return {Object} Post object
- */
-export function getCurrentPost( state ) {
- return state.currentPost;
-}
-
-/**
- * Returns the post type of the post currently being edited
- *
- * @param {Object} state Global application state
- * @return {String} Post type
- */
-export function getCurrentPostType( state ) {
- return state.currentPost.type;
-}
-
-/**
- * Returns the ID of the post currently being edited, or null if the post has
- * not yet been saved.
- *
- * @param {Object} state Global application state
- * @return {?Number} ID of current post
- */
-export function getCurrentPostId( state ) {
- return getCurrentPost( state ).id || null;
-}
-
-/**
- * Returns any post values which have been changed in the editor but not yet
- * been saved.
- *
- * @param {Object} state Global application state
- * @return {Object} Object of key value pairs comprising unsaved edits
- */
-export function getPostEdits( state ) {
- return state.editor.edits;
-}
-
-/**
- * Returns a single attribute of the post being edited, preferring the unsaved
- * edit if one exists, but falling back to the attribute for the last known
- * saved state of the post.
- *
- * @param {Object} state Global application state
- * @param {String} attributeName Post attribute name
- * @return {*} Post attribute value
+ * @return {Object} Editor Config
*/
-export function getEditedPostAttribute( state, attributeName ) {
- return state.editor.edits[ attributeName ] === undefined
- ? state.currentPost[ attributeName ]
- : state.editor.edits[ attributeName ];
+export function getEditorConfig( state ) {
+ return state.editorConfig;
}
/**
- * Returns the current visibility of the post being edited, preferring the
- * unsaved value if different than the saved post. The return value is one of
- * "private", "password", or "public".
+ * Returns a block type its name.
*
* @param {Object} state Global application state
- * @return {String} Post visibility
- */
-export function getEditedPostVisibility( state ) {
- const status = getEditedPostAttribute( state, 'status' );
- const password = getEditedPostAttribute( state, 'password' );
-
- if ( status === 'private' ) {
- return 'private';
- } else if ( password ) {
- return 'password';
- }
- return 'public';
-}
-
-/**
- * Return true if the current post has already been published.
- *
- * @param {Object} state Global application state
- * @return {Boolean} Whether the post has been published
- */
-export function isCurrentPostPublished( state ) {
- const post = getCurrentPost( state );
-
- return [ 'publish', 'private' ].indexOf( post.status ) !== -1 ||
- ( post.status === 'future' && moment( post.date ).isBefore( moment() ) );
-}
-
-/**
- * Return true if the post being edited can be published
- *
- * @param {Object} state Global application state
- * @return {Boolean} Whether the post can been published
- */
-export function isEditedPostPublishable( state ) {
- const post = getCurrentPost( state );
- return isEditedPostDirty( state ) || [ 'publish', 'private', 'future' ].indexOf( post.status ) === -1;
-}
-
-/**
- * Returns true if the post can be saved, or false otherwise. A post must
- * contain a title, an excerpt, or non-empty content to be valid for save.
- *
- * @param {Object} state Global application state
- * @return {Boolean} Whether the post can be saved
- */
-export function isEditedPostSaveable( state ) {
- return (
- getBlockCount( state ) > 0 ||
- !! getEditedPostTitle( state ) ||
- !! getEditedPostExcerpt( state )
- );
-}
-
-/**
- * Return true if the post being edited is being scheduled. Preferring the
- * unsaved status values.
- *
- * @param {Object} state Global application state
- * @return {Boolean} Whether the post has been published
+ * @param {String} name Block name
+ * @return {Object} BlockType
*/
-export function isEditedPostBeingScheduled( state ) {
- const date = getEditedPostAttribute( state, 'date' );
- return moment( date ).isAfter( moment() );
+export function getBlockType( state, name ) {
+ return find( state.editorConfig.blockTypes, ( blockType ) => blockType.name === name );
}
/**
- * Returns the raw title of the post being edited, preferring the unsaved value
- * if different than the saved post.
+ * Returns all the available block types
*
* @param {Object} state Global application state
- * @return {String} Raw post title
- */
-export function getEditedPostTitle( state ) {
- const editedTitle = getPostEdits( state ).title;
- if ( editedTitle !== undefined ) {
- return editedTitle;
- }
- const currentPost = getCurrentPost( state );
- if ( currentPost.title && currentPost.title.raw ) {
- return currentPost.title.raw;
- }
- return '';
-}
-
-/**
- * Gets the document title to be used.
- *
- * @param {Object} state Global application state
- * @return {string} Document title
+ * @return {Array} BlockTypes
*/
-export function getDocumentTitle( state ) {
- let title = getEditedPostTitle( state );
-
- if ( ! title.trim() ) {
- title = isCleanNewPost( state ) ? __( 'New post' ) : __( '(Untitled)' );
- }
- return title;
+export function getBlockTypes( state ) {
+ return state.editorConfig.blockTypes;
}
/**
- * Returns the raw excerpt of the post being edited, preferring the unsaved
- * value if different than the saved post.
+ * Returns all the available block categories
*
* @param {Object} state Global application state
- * @return {String} Raw post excerpt
+ * @return {Array} categories
*/
-export function getEditedPostExcerpt( state ) {
- return state.editor.edits.excerpt === undefined
- ? get( state.currentPost, 'excerpt.raw' )
- : state.editor.edits.excerpt;
+export function getCategories( state ) {
+ return state.editorConfig.categories;
}
/**
- * Returns a URL to preview the post being edited.
+ * Returns the default block type name.
*
* @param {Object} state Global application state
- * @return {String} Preview URL
+ * @return {String} Block name
*/
-export function getEditedPostPreviewLink( state ) {
- const link = state.currentPost.link;
- if ( ! link ) {
- return null;
- }
-
- return addQueryArgs( link, { preview: 'true' } );
+export function getDefaultBlockType( state ) {
+ return state.editorConfig.defaultBlockType;
}
/**
@@ -607,10 +366,6 @@ export function isTyping( state ) {
* @return {?String} Unique ID after which insertion will occur
*/
export function getBlockInsertionPoint( state ) {
- if ( getEditorMode( state ) !== 'visual' ) {
- return last( state.editor.blockOrder );
- }
-
const lastMultiSelectedBlock = getLastMultiSelectedBlockUid( state );
if ( lastMultiSelectedBlock ) {
return lastMultiSelectedBlock;
@@ -634,77 +389,6 @@ export function isBlockInsertionPointVisible( state ) {
return state.showInsertionPoint;
}
-/**
- * Returns true if the post is currently being saved, or false otherwise.
- *
- * @param {Object} state Global application state
- * @return {Boolean} Whether post is being saved
- */
-export function isSavingPost( state ) {
- return state.saving.requesting;
-}
-
-/**
- * Returns true if a previous post save was attempted successfully, or false
- * otherwise.
- *
- * @param {Object} state Global application state
- * @return {Boolean} Whether the post was saved successfully
- */
-export function didPostSaveRequestSucceed( state ) {
- return state.saving.successful;
-}
-
-/**
- * Returns true if a previous post save was attempted but failed, or false
- * otherwise.
- *
- * @param {Object} state Global application state
- * @return {Boolean} Whether the post save failed
- */
-export function didPostSaveRequestFail( state ) {
- return !! state.saving.error;
-}
-
-/**
- * Returns a suggested post format for the current post, inferred only if there
- * is a single block within the post and it is of a type known to match a
- * default post format. Returns null if the format cannot be determined.
- *
- * @param {Object} state Global application state
- * @return {?String} Suggested post format
- */
-export function getSuggestedPostFormat( state ) {
- const blocks = state.editor.blockOrder;
-
- let name;
- // If there is only one block in the content of the post grab its name so
- // so we can derive a suitable post format from it.
- if ( blocks.length === 1 ) {
- name = state.editor.blocksByUid[ blocks[ 0 ] ].name;
- }
-
- // We only convert to default post formats in core.
- switch ( name ) {
- case 'core/image':
- return 'Image';
- case 'core/quote':
- return 'Quote';
- }
-
- return null;
-}
-
-/**
- * Returns the user notices array
- *
- * @param {Object} state Global application state
- * @return {Array} List of notices
- */
-export function getNotices( state ) {
- return values( state.notices );
-}
-
/**
* Resolves the list of recently used block names into a list of block type settings.
*
@@ -713,5 +397,5 @@ export function getNotices( state ) {
*/
export function getRecentlyUsedBlocks( state ) {
// resolves the block names in the state to the block type settings
- return state.userData.recentlyUsedBlocks.map( blockType => getBlockType( blockType ) );
+ return state.userData.recentlyUsedBlocks.map( ( blockName ) => getBlockType( state, blockName ) );
}
diff --git a/editor/state.js b/editor/state.js
index a714a621631e39..17c13ab26ef6f3 100644
--- a/editor/state.js
+++ b/editor/state.js
@@ -2,23 +2,8 @@
* External dependencies
*/
import optimist from 'redux-optimist';
-import { combineReducers, applyMiddleware, createStore } from 'redux';
-import refx from 'refx';
-import { reduce, keyBy, first, last, omit, without, flowRight, forOwn } from 'lodash';
-
-/**
- * WordPress dependencies
- */
-import { getBlockTypes } from 'blocks';
-
-/**
- * Internal dependencies
- */
-import { combineUndoableReducers } from './utils/undoable-reducer';
-import effects from './effects';
-
-const isMobile = window.innerWidth < 782;
-const renderedPostProps = new Set( [ 'guid', 'title', 'excerpt', 'content' ] );
+import { combineReducers, createStore } from 'redux';
+import { reduce, keyBy, first, last, omit, without } from 'lodash';
/**
* Undoable reducer returning the editor post state, including blocks parsed
@@ -34,59 +19,7 @@ const renderedPostProps = new Set( [ 'guid', 'title', 'excerpt', 'content' ] );
* @param {Object} action Dispatched action
* @return {Object} Updated state
*/
-export const editor = combineUndoableReducers( {
- edits( state = {}, action ) {
- switch ( action.type ) {
- case 'EDIT_POST':
- case 'SETUP_NEW_POST':
- return reduce( action.edits, ( result, value, key ) => {
- // Only assign into result if not already same value
- if ( value !== state[ key ] ) {
- // Avoid mutating original state by creating shallow
- // clone. Should only occur once per reduce.
- if ( result === state ) {
- result = { ...state };
- }
-
- result[ key ] = value;
- }
-
- return result;
- }, state );
-
- case 'CLEAR_POST_EDITS':
- // Don't return a new object if there's not any edits
- if ( ! Object.keys( state ).length ) {
- return state;
- }
-
- return {};
- }
-
- return state;
- },
-
- dirty( state = false, action ) {
- switch ( action.type ) {
- case 'RESET_BLOCKS':
- case 'REQUEST_POST_UPDATE_SUCCESS':
- case 'TRASH_POST_SUCCESS':
- return false;
-
- case 'UPDATE_BLOCK_ATTRIBUTES':
- case 'INSERT_BLOCKS':
- case 'MOVE_BLOCKS_DOWN':
- case 'MOVE_BLOCKS_UP':
- case 'REPLACE_BLOCKS':
- case 'REMOVE_BLOCKS':
- case 'EDIT_POST':
- case 'MARK_DIRTY':
- return true;
- }
-
- return state;
- },
-
+export const editor = combineReducers( {
blocksByUid( state = {}, action ) {
switch ( action.type ) {
case 'RESET_BLOCKS':
@@ -240,11 +173,11 @@ export const userData = combineReducers( {
recentlyUsedBlocks( state = [], action ) {
const maxRecent = 8;
switch ( action.type ) {
- case 'LOAD_USER_DATA':
+ case 'INIT_EDITOR':
// This is where we initially populate the recently used blocks,
// for now this inserts blocks from the common category, but will
// load this from an API in the future.
- return getBlockTypes()
+ return action.config.blockTypes
.filter( ( blockType ) => 'common' === blockType.category )
.slice( 0, maxRecent )
.map( ( blockType ) => blockType.name );
@@ -261,34 +194,6 @@ export const userData = combineReducers( {
},
} );
-/**
- * Reducer returning the last-known state of the current post, in the format
- * returned by the WP REST API.
- *
- * @param {Object} state Current state
- * @param {Object} action Dispatched action
- * @return {Object} Updated state
- */
-export function currentPost( state = {}, action ) {
- switch ( action.type ) {
- case 'RESET_POST':
- return action.post;
-
- case 'UPDATE_POST':
- const post = { ...state };
- forOwn( action.edits, ( value, key ) => {
- if ( renderedPostProps.has( key ) ) {
- post[ key ] = { raw: value };
- } else {
- post[ key ] = value;
- }
- } );
- return post;
- }
-
- return state;
-}
-
/**
* Reducer returning selected block state.
*
@@ -442,88 +347,10 @@ export function showInsertionPoint( state = false, action ) {
return state;
}
-/**
- * Reducer returning current editor mode, either "visual" or "text".
- *
- * @param {string} state Current state
- * @param {Object} action Dispatched action
- * @return {string} Updated state
- */
-export function mode( state = 'visual', action ) {
- switch ( action.type ) {
- case 'SWITCH_MODE':
- return action.mode;
- }
-
- return state;
-}
-
-export function isSidebarOpened( state = ! isMobile, action ) {
- switch ( action.type ) {
- case 'TOGGLE_SIDEBAR':
- return ! state;
- }
-
- return state;
-}
-
-export function panel( state = 'document', action ) {
- switch ( action.type ) {
- case 'SET_ACTIVE_PANEL':
- return action.panel;
- }
-
- return state;
-}
-
-/**
- * Reducer returning current network request state (whether a request to the WP
- * REST API is in progress, successful, or failed).
- *
- * @param {Object} state Current state
- * @param {Object} action Dispatched action
- * @return {Object} Updated state
- */
-export function saving( state = {}, action ) {
- switch ( action.type ) {
- case 'REQUEST_POST_UPDATE':
- return {
- requesting: true,
- successful: false,
- error: null,
- };
-
- case 'REQUEST_POST_UPDATE_SUCCESS':
- return {
- requesting: false,
- successful: true,
- error: null,
- };
-
- case 'REQUEST_POST_UPDATE_FAILURE':
- return {
- requesting: false,
- successful: false,
- error: action.error,
- };
- }
-
- return state;
-}
-
-export function notices( state = {}, action ) {
+export function editorConfig( state = { blockTypes: [], categories: [], defaultBlockType: null, fallbackBlockType: null }, action ) {
switch ( action.type ) {
- case 'CREATE_NOTICE':
- return {
- ...state,
- [ action.notice.id ]: action.notice,
- };
- case 'REMOVE_NOTICE':
- if ( ! state.hasOwnProperty( action.noticeId ) ) {
- return state;
- }
-
- return omit( state, action.noticeId );
+ case 'INIT_EDITOR':
+ return action.config;
}
return state;
@@ -537,26 +364,16 @@ export function notices( state = {}, action ) {
export function createReduxStore() {
const reducer = optimist( combineReducers( {
editor,
- currentPost,
selectedBlock,
isTyping,
multiSelectedBlocks,
hoveredBlock,
showInsertionPoint,
- mode,
- isSidebarOpened,
- panel,
- saving,
- notices,
userData,
+ editorConfig,
} ) );
- const enhancers = [ applyMiddleware( refx( effects ) ) ];
- if ( window.__REDUX_DEVTOOLS_EXTENSION__ ) {
- enhancers.push( window.__REDUX_DEVTOOLS_EXTENSION__() );
- }
-
- return createStore( reducer, flowRight( enhancers ) );
+ return createStore( reducer );
}
export default createReduxStore;
diff --git a/editor/sidebar/table-of-contents/index.js b/editor/table-of-contents/index.js
similarity index 93%
rename from editor/sidebar/table-of-contents/index.js
rename to editor/table-of-contents/index.js
index c56bff3fc30f80..736d6a57959ecd 100644
--- a/editor/sidebar/table-of-contents/index.js
+++ b/editor/table-of-contents/index.js
@@ -15,7 +15,7 @@ import { PanelBody } from 'components';
* Internal Dependencies
*/
import './style.scss';
-import { getBlocks } from '../../selectors';
+import { getBlocks } from '../selectors';
const TableOfContents = ( { blocks } ) => {
const headings = filter( blocks, ( block ) => block.name === 'core/heading' );
@@ -48,5 +48,10 @@ export default connect(
return {
blocks: getBlocks( state ),
};
+ },
+ undefined,
+ undefined,
+ {
+ storeKey: 'editor',
}
)( TableOfContents );
diff --git a/editor/sidebar/table-of-contents/style.scss b/editor/table-of-contents/style.scss
similarity index 100%
rename from editor/sidebar/table-of-contents/style.scss
rename to editor/table-of-contents/style.scss
diff --git a/lib/client-assets.php b/lib/client-assets.php
index 5b17117a41ff2a..5cdfa1c25bf28f 100644
--- a/lib/client-assets.php
+++ b/lib/client-assets.php
@@ -103,9 +103,15 @@ function gutenberg_register_scripts_and_styles() {
wp_register_script(
'wp-blocks',
gutenberg_url( 'blocks/build/index.js' ),
- array( 'wp-element', 'wp-components', 'wp-utils', 'tinymce-nightly', 'tinymce-nightly-lists', 'tinymce-nightly-paste', 'tinymce-nightly-table', 'media-views', 'media-models' ),
+ array( 'wp-i18n', 'wp-element', 'wp-components', 'wp-utils', 'tinymce-nightly', 'tinymce-nightly-lists', 'tinymce-nightly-paste', 'tinymce-nightly-table', 'media-views', 'media-models' ),
filemtime( gutenberg_dir_path() . 'blocks/build/index.js' )
);
+ wp_register_script(
+ 'wp-editor',
+ gutenberg_url( 'editor/build/index.js' ),
+ array( 'wp-i18n', 'wp-element', 'wp-components', 'wp-blocks' ),
+ filemtime( gutenberg_dir_path() . 'editor/build/index.js' )
+ );
// Editor Styles.
wp_register_style(
@@ -126,6 +132,12 @@ function gutenberg_register_scripts_and_styles() {
array(),
filemtime( gutenberg_dir_path() . 'blocks/build/edit-blocks.css' )
);
+ wp_register_style(
+ 'wp-editor',
+ gutenberg_url( 'editor/build/style.css' ),
+ array(),
+ filemtime( gutenberg_dir_path() . 'editor/build/style.css' )
+ );
}
add_action( 'init', 'gutenberg_register_scripts_and_styles' );
@@ -426,10 +438,10 @@ function gutenberg_editor_scripts_and_styles( $hook ) {
// The editor code itself.
wp_enqueue_script(
- 'wp-editor',
- gutenberg_url( 'editor/build/index.js' ),
- array( 'wp-api', 'wp-date', 'wp-i18n', 'wp-blocks', 'wp-element', 'wp-components', 'wp-utils', 'editor' ),
- filemtime( gutenberg_dir_path() . 'editor/build/index.js' ),
+ 'wp-editor-chrome',
+ gutenberg_url( 'editor-chrome/build/index.js' ),
+ array( 'wp-api', 'wp-date', 'wp-i18n', 'wp-editor', 'wp-blocks', 'wp-element', 'wp-components', 'wp-utils', 'editor' ),
+ filemtime( gutenberg_dir_path() . 'editor-chrome/build/index.js' ),
true // enqueue in the footer.
);
@@ -545,14 +557,14 @@ function gutenberg_editor_scripts_and_styles( $hook ) {
// Initialize the post data.
wp_add_inline_script(
- 'wp-editor',
+ 'wp-editor-chrome',
'window._wpGutenbergPost = ' . wp_json_encode( $post_to_edit ) . ';'
);
// Prepopulate with some test content in demo.
if ( $is_demo ) {
wp_add_inline_script(
- 'wp-editor',
+ 'wp-editor-chrome',
file_get_contents( gutenberg_dir_path() . 'post-content.js' )
);
}
@@ -560,13 +572,13 @@ function gutenberg_editor_scripts_and_styles( $hook ) {
// Prepare Jed locale data.
$locale_data = gutenberg_get_jed_locale_data( 'gutenberg' );
wp_add_inline_script(
- 'wp-editor',
+ 'wp-editor-chrome',
'wp.i18n.setLocaleData( ' . json_encode( $locale_data ) . ' );',
'before'
);
// Initialize the editor.
- wp_add_inline_script( 'wp-editor', 'wp.api.init().done( function() { wp.editor.createEditorInstance( \'editor\', window._wpGutenbergPost ); } );' );
+ wp_add_inline_script( 'wp-editor-chrome', 'wp.api.init().done( function() { wp[ \'editor-chrome\' ].createEditorInstance( \'editor\', window._wpGutenbergPost ); } );' );
/**
* Scripts
@@ -585,10 +597,10 @@ function gutenberg_editor_scripts_and_styles( $hook ) {
'https://fonts.googleapis.com/css?family=Noto+Serif:400,400i,700,700i'
);
wp_enqueue_style(
- 'wp-editor',
- gutenberg_url( 'editor/build/style.css' ),
- array( 'wp-components', 'wp-blocks', 'wp-edit-blocks' ),
- filemtime( gutenberg_dir_path() . 'editor/build/style.css' )
+ 'wp-editor-chrome',
+ gutenberg_url( 'editor-chrome/build/style.css' ),
+ array( 'wp-components', 'wp-blocks', 'wp-edit-blocks', 'wp-editor' ),
+ filemtime( gutenberg_dir_path() . 'editor-chrome/build/style.css' )
);
/**
diff --git a/webpack.config.js b/webpack.config.js
index c1940ee209dab5..cd0d7578f6703d 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -27,7 +27,7 @@ const extractConfig = {
{
loader: 'sass-loader',
query: {
- includePaths: [ 'editor/assets/stylesheets' ],
+ includePaths: [ 'editor-chrome/assets/stylesheets' ],
data: '@import "variables"; @import "mixins"; @import "animations";@import "z-index";',
outputStyle: 'production' === process.env.NODE_ENV ?
'compressed' : 'nested',
@@ -44,6 +44,7 @@ const entryPointNames = [
'blocks',
'date',
'editor',
+ 'editor-chrome',
];
const externals = {