From 630d474a5808cb134c900e62875dffd1b9709bb3 Mon Sep 17 00:00:00 2001 From: Tugdual de Kerviler Date: Mon, 22 Jul 2019 15:32:30 +0200 Subject: [PATCH 01/11] Move the post title selection state to the store and update PostTitle --- .../editor/src/components/post-title/index.js | 34 +++++------ .../src/components/post-title/index.native.js | 58 +++++++++++-------- packages/editor/src/store/actions.js | 14 +++++ packages/editor/src/store/reducer.js | 20 +++++++ packages/editor/src/store/selectors.js | 11 ++++ packages/editor/src/store/test/actions.js | 10 ++++ packages/editor/src/store/test/reducer.js | 27 +++++++++ packages/editor/src/store/test/selectors.js | 23 ++++++++ 8 files changed, 154 insertions(+), 43 deletions(-) diff --git a/packages/editor/src/components/post-title/index.js b/packages/editor/src/components/post-title/index.js index e992e25bae11a9..254ac10703406c 100644 --- a/packages/editor/src/components/post-title/index.js +++ b/packages/editor/src/components/post-title/index.js @@ -32,27 +32,12 @@ class PostTitle extends Component { super( ...arguments ); this.onChange = this.onChange.bind( this ); - this.onSelect = this.onSelect.bind( this ); - this.onUnselect = this.onUnselect.bind( this ); this.onKeyDown = this.onKeyDown.bind( this ); this.redirectHistory = this.redirectHistory.bind( this ); - - this.state = { - isSelected: false, - }; } handleFocusOutside() { - this.onUnselect(); - } - - onSelect() { - this.setState( { isSelected: true } ); - this.props.clearSelectedBlock(); - } - - onUnselect() { - this.setState( { isSelected: false } ); + this.props.onUnselect(); } onChange( event ) { @@ -93,11 +78,11 @@ class PostTitle extends Component { isCleanNewPost, isFocusMode, isPostTypeViewable, + isSelected, instanceId, placeholder, title, } = this.props; - const { isSelected } = this.state; // The wp-block className is important for editor styles. const className = classnames( 'wp-block editor-post-title__block', { @@ -126,9 +111,9 @@ class PostTitle extends Component { value={ title } onChange={ this.onChange } placeholder={ decodedPlaceholder || __( 'Add title' ) } - onFocus={ this.onSelect } + onFocus={ this.props.onSelect } onKeyDown={ this.onKeyDown } - onKeyPress={ this.onUnselect } + onKeyPress={ this.props.onUnselect } /* Only autofocus the title when the post is entirely empty. This should only happen for a new post, which means we @@ -149,7 +134,7 @@ class PostTitle extends Component { } const applyWithSelect = withSelect( ( select ) => { - const { getEditedPostAttribute, isCleanNewPost } = select( 'core/editor' ); + const { getEditedPostAttribute, isCleanNewPost, isPostTitleSelected } = select( 'core/editor' ); const { getSettings } = select( 'core/block-editor' ); const { getPostType } = select( 'core' ); const postType = getPostType( getEditedPostAttribute( 'type' ) ); @@ -157,6 +142,7 @@ const applyWithSelect = withSelect( ( select ) => { return { isCleanNewPost: isCleanNewPost(), + isSelected: isPostTitleSelected(), title: getEditedPostAttribute( 'title' ), isPostTypeViewable: get( postType, [ 'viewable' ], false ), placeholder: titlePlaceholder, @@ -174,6 +160,7 @@ const applyWithDispatch = withDispatch( ( dispatch ) => { editPost, undo, redo, + togglePostTitleSelection, } = dispatch( 'core/editor' ); return { @@ -186,6 +173,13 @@ const applyWithDispatch = withDispatch( ( dispatch ) => { onUndo: undo, onRedo: redo, clearSelectedBlock, + onSelect() { + togglePostTitleSelection( true ); + clearSelectedBlock(); + }, + onUnselect() { + togglePostTitleSelection( false ); + }, }; } ); diff --git a/packages/editor/src/components/post-title/index.native.js b/packages/editor/src/components/post-title/index.native.js index d91d0220753dfe..0458c09cfc25a1 100644 --- a/packages/editor/src/components/post-title/index.native.js +++ b/packages/editor/src/components/post-title/index.native.js @@ -10,7 +10,7 @@ import { isEmpty } from 'lodash'; import { Component } from '@wordpress/element'; import { RichText } from '@wordpress/rich-text'; import { decodeEntities } from '@wordpress/html-entities'; -import { withDispatch } from '@wordpress/data'; +import { withDispatch, withSelect } from '@wordpress/data'; import { withFocusOutside } from '@wordpress/components'; import { withInstanceId, compose } from '@wordpress/compose'; import { __, sprintf } from '@wordpress/i18n'; @@ -32,10 +32,6 @@ class PostTitle extends Component { this.props.onUnselect(); } - focus() { - this.props.onSelect(); - } - render() { const { placeholder, @@ -91,27 +87,43 @@ class PostTitle extends Component { } } -const applyWithDispatch = withDispatch( ( dispatch ) => { - const { - undo, - redo, - } = dispatch( 'core/editor' ); +export default compose( + withSelect( ( dispatch ) => { + const { + isPostTitleSelected, + } = dispatch( 'core/editor' ); - const { - insertDefaultBlock, - } = dispatch( 'core/block-editor' ); + return { + isSelected: isPostTitleSelected(), + }; + } ), + withDispatch( ( dispatch, ownProps ) => { + const { + undo, + redo, + togglePostTitleSelection, + } = dispatch( 'core/editor' ); - return { - onEnterPress() { - insertDefaultBlock( undefined, undefined, 0 ); - }, - onUndo: undo, - onRedo: redo, - }; -} ); + const { + insertDefaultBlock, + } = dispatch( 'core/block-editor' ); -export default compose( - applyWithDispatch, + return { + onEnterPress() { + insertDefaultBlock( undefined, undefined, 0 ); + }, + onUndo: undo, + onRedo: redo, + onSelect() { + togglePostTitleSelection( true ); + ownProps.onSelect(); + }, + onUnselect() { + togglePostTitleSelection( false ); + ownProps.onUnselect(); + }, + }; + } ), withInstanceId, withFocusOutside )( PostTitle ); diff --git a/packages/editor/src/store/actions.js b/packages/editor/src/store/actions.js index 8ea2c9a408de84..1f4c21ca9e3144 100644 --- a/packages/editor/src/store/actions.js +++ b/packages/editor/src/store/actions.js @@ -737,6 +737,20 @@ export function updatePostLock( lock ) { }; } +/** + * Returns an action object that enables or disables post title selection. + * + * @param {boolean} [isSelected=true] Whether post title is currently selected. + + * @return {Object} Action object. + */ +export function togglePostTitleSelection( isSelected = true ) { + return { + type: 'TOGGLE_POST_TITLE_SELECTION', + isSelected, + }; +} + /** * Returns an action object used to fetch a single reusable block or all * reusable blocks from the REST API into the store. diff --git a/packages/editor/src/store/reducer.js b/packages/editor/src/store/reducer.js index 6676b74dcbc395..89fdbc76d87f65 100644 --- a/packages/editor/src/store/reducer.js +++ b/packages/editor/src/store/reducer.js @@ -412,6 +412,25 @@ export function postSavingLock( state = {}, action ) { return state; } +/** + * Reducer returning the post title state. + * + * @param {PostTitleState} state Current state. + * @param {Object} action Dispatched action. + * + * @return {string?} Updated state. + */ +export const postTitle = combineReducers( { + isSelected( state = false, action ) { + switch ( action.type ) { + case 'TOGGLE_POST_TITLE_SELECTION': + return action.isSelected; + } + + return state; + }, +} ); + export const reusableBlocks = combineReducers( { data( state = {}, action ) { switch ( action.type ) { @@ -593,6 +612,7 @@ export default optimist( combineReducers( { preferences, saving, postLock, + postTitle, reusableBlocks, template, previewLink, diff --git a/packages/editor/src/store/selectors.js b/packages/editor/src/store/selectors.js index 7570e8b7848de6..9037d58503e2fd 100644 --- a/packages/editor/src/store/selectors.js +++ b/packages/editor/src/store/selectors.js @@ -1097,6 +1097,17 @@ export function getActivePostLock( state ) { return state.postLock.activePostLock; } +/** + * Returns true if post title is selected. + * + * @param {Object} state Global application state. + * + * @return {boolean} Whether current post title is selected. + */ +export function isPostTitleSelected( state ) { + return state.postTitle.isSelected; +} + /** * Returns whether or not the user has the unfiltered_html capability. * diff --git a/packages/editor/src/store/test/actions.js b/packages/editor/src/store/test/actions.js index ff10dcf0a9044b..6f87ad83559229 100644 --- a/packages/editor/src/store/test/actions.js +++ b/packages/editor/src/store/test/actions.js @@ -861,4 +861,14 @@ describe( 'Editor actions', () => { } ); } ); } ); + + describe( 'togglePostTitleSelection', () => { + it( 'should return the TOGGLE_POST_TITLE_SELECTION action', () => { + const result = actions.togglePostTitleSelection( true ); + expect( result ).toEqual( { + type: 'TOGGLE_POST_TITLE_SELECTION', + isSelected: true, + } ); + } ); + } ); } ); diff --git a/packages/editor/src/store/test/reducer.js b/packages/editor/src/store/test/reducer.js index d964c72c0f77a3..fcd61532230176 100644 --- a/packages/editor/src/store/test/reducer.js +++ b/packages/editor/src/store/test/reducer.js @@ -18,6 +18,7 @@ import { saving, reusableBlocks, postSavingLock, + postTitle, previewLink, } from '../reducer'; import { INITIAL_EDITS_DEFAULTS } from '../defaults'; @@ -847,6 +848,32 @@ describe( 'state', () => { } ); } ); + describe( 'postTitle', () => { + describe( 'isSelected()', () => { + it( 'should not be selected by default', () => { + expect( postTitle( undefined, {} ).isSelected ).toBe( false ); + } ); + + it( 'should return false if not selecting the post title', () => { + const action = { + type: 'TOGGLE_POST_TITLE_SELECTION', + isSelected: false, + }; + + expect( postTitle( { isSelected: true }, action ).isSelected ).toBe( false ); + } ); + + it( 'should return true if selecting the post title', () => { + const action = { + type: 'TOGGLE_POST_TITLE_SELECTION', + isSelected: true, + }; + + expect( postTitle( { isSelected: false }, action ).isSelected ).toBe( true ); + } ); + } ); + } ); + describe( 'previewLink', () => { it( 'returns null by default', () => { const state = previewLink( undefined, {} ); diff --git a/packages/editor/src/store/test/selectors.js b/packages/editor/src/store/test/selectors.js index f2e30f17372e10..d9af3b2e5d05a1 100644 --- a/packages/editor/src/store/test/selectors.js +++ b/packages/editor/src/store/test/selectors.js @@ -66,6 +66,7 @@ const { getPermalink, getPermalinkParts, isPostSavingLocked, + isPostTitleSelected, canUserUseUnfilteredHTML, } = selectors; @@ -1097,6 +1098,28 @@ describe( 'selectors', () => { } ); } ); + describe( 'isPostTitleSelected', () => { + it( 'should return true if the post title is selected', () => { + const state = { + postTitle: { + isSelected: true, + }, + }; + + expect( isPostTitleSelected( state ) ).toBe( true ); + } ); + + it( 'should return false if the post title is not selected', () => { + const state = { + postTitle: { + isSelected: false, + }, + }; + + expect( isPostTitleSelected( state ) ).toBe( false ); + } ); + } ); + describe( 'isEditedPostSaveable', () => { it( 'should return false if the post has no title, excerpt, content', () => { const state = { From 4c7ca6ae7e036383f37cc5fec732314226f4b60e Mon Sep 17 00:00:00 2001 From: Tugdual de Kerviler Date: Mon, 22 Jul 2019 15:48:52 +0200 Subject: [PATCH 02/11] Fix jsdoc type returned for postTitle reducer --- packages/editor/src/store/reducer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/editor/src/store/reducer.js b/packages/editor/src/store/reducer.js index 89fdbc76d87f65..1d7bcbb0870d2e 100644 --- a/packages/editor/src/store/reducer.js +++ b/packages/editor/src/store/reducer.js @@ -418,7 +418,7 @@ export function postSavingLock( state = {}, action ) { * @param {PostTitleState} state Current state. * @param {Object} action Dispatched action. * - * @return {string?} Updated state. + * @return {Object} Updated state. */ export const postTitle = combineReducers( { isSelected( state = false, action ) { From e1cc965d5c1af888c4d505008e50b3efaa01af10 Mon Sep 17 00:00:00 2001 From: Tugdual de Kerviler Date: Mon, 22 Jul 2019 16:47:39 +0200 Subject: [PATCH 03/11] Update native version of VisualEditor to use the store to know if the post title is selected --- .../components/visual-editor/index.native.js | 34 ++----------------- .../src/components/post-title/index.native.js | 6 ++-- 2 files changed, 6 insertions(+), 34 deletions(-) diff --git a/packages/edit-post/src/components/visual-editor/index.native.js b/packages/edit-post/src/components/visual-editor/index.native.js index 708b96c8289aea..46d7a8cd3cc446 100644 --- a/packages/edit-post/src/components/visual-editor/index.native.js +++ b/packages/edit-post/src/components/visual-editor/index.native.js @@ -15,33 +15,6 @@ import { ReadableContentView } from '@wordpress/components'; import styles from './style.scss'; class VisualEditor extends Component { - constructor() { - super( ...arguments ); - - this.onPostTitleSelect = this.onPostTitleSelect.bind( this ); - this.onPostTitleUnselect = this.onPostTitleUnselect.bind( this ); - - this.state = { - isPostTitleSelected: false, - }; - } - - static getDerivedStateFromProps( props ) { - if ( props.isAnyBlockSelected ) { - return { isPostTitleSelected: false }; - } - return null; - } - - onPostTitleSelect() { - this.setState( { isPostTitleSelected: true } ); - this.props.clearSelectedBlock(); - } - - onPostTitleUnselect() { - this.setState( { isPostTitleSelected: false } ); - } - renderHeader() { const { editTitle, @@ -55,9 +28,6 @@ class VisualEditor extends Component { innerRef={ setTitleRef } title={ title } onUpdate={ editTitle } - onSelect={ this.onPostTitleSelect } - onUnselect={ this.onPostTitleUnselect } - isSelected={ this.state.isPostTitleSelected } placeholder={ __( 'Add title' ) } borderStyle={ this.props.isFullyBordered ? @@ -93,7 +63,7 @@ class VisualEditor extends Component { isFullyBordered={ isFullyBordered } rootViewHeight={ rootViewHeight } safeAreaBottomInset={ safeAreaBottomInset } - isPostTitleSelected={ this.state.isPostTitleSelected } + isPostTitleSelected={ this.props.isPostTitleSelected } onBlockTypeSelected={ this.onPostTitleUnselect } /> @@ -106,6 +76,7 @@ export default compose( [ const { getEditorBlocks, getEditedPostAttribute, + isPostTitleSelected, } = select( 'core/editor' ); const { getSelectedBlockClientId } = select( 'core/block-editor' ); @@ -114,6 +85,7 @@ export default compose( [ blocks: getEditorBlocks(), title: getEditedPostAttribute( 'title' ), isAnyBlockSelected: !! getSelectedBlockClientId(), + isPostTitleSelected: isPostTitleSelected(), }; } ), withDispatch( ( dispatch ) => { diff --git a/packages/editor/src/components/post-title/index.native.js b/packages/editor/src/components/post-title/index.native.js index 0458c09cfc25a1..d05bb12954e301 100644 --- a/packages/editor/src/components/post-title/index.native.js +++ b/packages/editor/src/components/post-title/index.native.js @@ -97,7 +97,7 @@ export default compose( isSelected: isPostTitleSelected(), }; } ), - withDispatch( ( dispatch, ownProps ) => { + withDispatch( ( dispatch ) => { const { undo, redo, @@ -105,6 +105,7 @@ export default compose( } = dispatch( 'core/editor' ); const { + clearSelectedBlock, insertDefaultBlock, } = dispatch( 'core/block-editor' ); @@ -116,11 +117,10 @@ export default compose( onRedo: redo, onSelect() { togglePostTitleSelection( true ); - ownProps.onSelect(); + clearSelectedBlock(); }, onUnselect() { togglePostTitleSelection( false ); - ownProps.onUnselect(); }, }; } ), From e787c580cb382a16cba59a37a944ecc794d9f424 Mon Sep 17 00:00:00 2001 From: Tugdual de Kerviler Date: Tue, 23 Jul 2019 09:15:35 +0200 Subject: [PATCH 04/11] Update doc --- .../developers/data/data-core-editor.md | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/docs/designers-developers/developers/data/data-core-editor.md b/docs/designers-developers/developers/data/data-core-editor.md index e3456d65168dbd..5579208f2e0696 100644 --- a/docs/designers-developers/developers/data/data-core-editor.md +++ b/docs/designers-developers/developers/data/data-core-editor.md @@ -932,6 +932,18 @@ _Returns_ - `boolean`: Is locked. +# **isPostTitleSelected** + +Returns true if post title is selected. + +_Parameters_ + +- _state_ `Object`: Global application state. + +_Returns_ + +- `boolean`: Whether current post title is selected. + # **isPreviewingPost** Returns true if the post is being previewed, or false otherwise. @@ -1314,6 +1326,18 @@ _Related_ - toggleBlockMode in core/block-editor store. +# **togglePostTitleSelection** + +Returns an action object that enables or disables post title selection. + +_Parameters_ + +- _isSelected_ `[boolean]`: Whether post title is currently selected. + +_Returns_ + +- `Object`: Action object. + # **toggleSelection** _Related_ From cc713823905c53e955b5015839bed639ecc7afcc Mon Sep 17 00:00:00 2001 From: Tugdual de Kerviler Date: Tue, 23 Jul 2019 14:02:35 +0200 Subject: [PATCH 05/11] Remove unused clearSelectedBlock props in PostTitle web and bring back focus in native version --- packages/editor/src/components/post-title/index.js | 1 - packages/editor/src/components/post-title/index.native.js | 4 ++++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/editor/src/components/post-title/index.js b/packages/editor/src/components/post-title/index.js index 254ac10703406c..f9baf9be1e227a 100644 --- a/packages/editor/src/components/post-title/index.js +++ b/packages/editor/src/components/post-title/index.js @@ -172,7 +172,6 @@ const applyWithDispatch = withDispatch( ( dispatch ) => { }, onUndo: undo, onRedo: redo, - clearSelectedBlock, onSelect() { togglePostTitleSelection( true ); clearSelectedBlock(); diff --git a/packages/editor/src/components/post-title/index.native.js b/packages/editor/src/components/post-title/index.native.js index d05bb12954e301..94d3790c459db9 100644 --- a/packages/editor/src/components/post-title/index.native.js +++ b/packages/editor/src/components/post-title/index.native.js @@ -32,6 +32,10 @@ class PostTitle extends Component { this.props.onUnselect(); } + focus() { + this.props.onSelect(); + } + render() { const { placeholder, From 6b38663cbc7f694538b94bbf300c05ce1f060bb9 Mon Sep 17 00:00:00 2001 From: Tugdual de Kerviler Date: Wed, 24 Jul 2019 13:52:48 +0200 Subject: [PATCH 06/11] Fork core/editor store for native instead of modifying it --- packages/editor/src/store/actions.js | 14 ---- packages/editor/src/store/actions.native.js | 16 +++++ packages/editor/src/store/reducer.js | 20 ------ packages/editor/src/store/reducer.native.js | 64 +++++++++++++++++++ packages/editor/src/store/selectors.js | 11 ---- packages/editor/src/store/selectors.native.js | 13 ++++ 6 files changed, 93 insertions(+), 45 deletions(-) create mode 100644 packages/editor/src/store/actions.native.js create mode 100644 packages/editor/src/store/reducer.native.js create mode 100644 packages/editor/src/store/selectors.native.js diff --git a/packages/editor/src/store/actions.js b/packages/editor/src/store/actions.js index 1f4c21ca9e3144..8ea2c9a408de84 100644 --- a/packages/editor/src/store/actions.js +++ b/packages/editor/src/store/actions.js @@ -737,20 +737,6 @@ export function updatePostLock( lock ) { }; } -/** - * Returns an action object that enables or disables post title selection. - * - * @param {boolean} [isSelected=true] Whether post title is currently selected. - - * @return {Object} Action object. - */ -export function togglePostTitleSelection( isSelected = true ) { - return { - type: 'TOGGLE_POST_TITLE_SELECTION', - isSelected, - }; -} - /** * Returns an action object used to fetch a single reusable block or all * reusable blocks from the REST API into the store. diff --git a/packages/editor/src/store/actions.native.js b/packages/editor/src/store/actions.native.js new file mode 100644 index 00000000000000..3d638cbc2be2cf --- /dev/null +++ b/packages/editor/src/store/actions.native.js @@ -0,0 +1,16 @@ + +export * from './actions.js'; + +/** + * Returns an action object that enables or disables post title selection. + * + * @param {boolean} [isSelected=true] Whether post title is currently selected. + + * @return {Object} Action object. + */ +export function togglePostTitleSelection( isSelected = true ) { + return { + type: 'TOGGLE_POST_TITLE_SELECTION', + isSelected, + }; +} diff --git a/packages/editor/src/store/reducer.js b/packages/editor/src/store/reducer.js index 1d7bcbb0870d2e..6676b74dcbc395 100644 --- a/packages/editor/src/store/reducer.js +++ b/packages/editor/src/store/reducer.js @@ -412,25 +412,6 @@ export function postSavingLock( state = {}, action ) { return state; } -/** - * Reducer returning the post title state. - * - * @param {PostTitleState} state Current state. - * @param {Object} action Dispatched action. - * - * @return {Object} Updated state. - */ -export const postTitle = combineReducers( { - isSelected( state = false, action ) { - switch ( action.type ) { - case 'TOGGLE_POST_TITLE_SELECTION': - return action.isSelected; - } - - return state; - }, -} ); - export const reusableBlocks = combineReducers( { data( state = {}, action ) { switch ( action.type ) { @@ -612,7 +593,6 @@ export default optimist( combineReducers( { preferences, saving, postLock, - postTitle, reusableBlocks, template, previewLink, diff --git a/packages/editor/src/store/reducer.native.js b/packages/editor/src/store/reducer.native.js new file mode 100644 index 00000000000000..82b3689a98ead0 --- /dev/null +++ b/packages/editor/src/store/reducer.native.js @@ -0,0 +1,64 @@ +/** + * External dependencies + */ +import optimist from 'redux-optimist'; + +/** + * WordPress dependencies + */ +import { combineReducers } from '@wordpress/data'; + +/** + * Internal dependencies + */ +import { + editor, + initialEdits, + currentPost, + preferences, + saving, + postLock, + reusableBlocks, + template, + previewLink, + postSavingLock, + isReady, + editorSettings, +} from './reducer.js'; + +export * from './reducer.js'; + +/** + * Reducer returning the post title state. + * + * @param {PostTitleState} state Current state. + * @param {Object} action Dispatched action. + * + * @return {Object} Updated state. + */ +export const postTitle = combineReducers( { + isSelected( state = false, action ) { + switch ( action.type ) { + case 'TOGGLE_POST_TITLE_SELECTION': + return action.isSelected; + } + + return state; + }, +} ); + +export default optimist( combineReducers( { + editor, + initialEdits, + currentPost, + preferences, + saving, + postLock, + reusableBlocks, + template, + previewLink, + postSavingLock, + isReady, + editorSettings, + postTitle, +} ) ); diff --git a/packages/editor/src/store/selectors.js b/packages/editor/src/store/selectors.js index 9037d58503e2fd..7570e8b7848de6 100644 --- a/packages/editor/src/store/selectors.js +++ b/packages/editor/src/store/selectors.js @@ -1097,17 +1097,6 @@ export function getActivePostLock( state ) { return state.postLock.activePostLock; } -/** - * Returns true if post title is selected. - * - * @param {Object} state Global application state. - * - * @return {boolean} Whether current post title is selected. - */ -export function isPostTitleSelected( state ) { - return state.postTitle.isSelected; -} - /** * Returns whether or not the user has the unfiltered_html capability. * diff --git a/packages/editor/src/store/selectors.native.js b/packages/editor/src/store/selectors.native.js new file mode 100644 index 00000000000000..8c6ead8e97ba2f --- /dev/null +++ b/packages/editor/src/store/selectors.native.js @@ -0,0 +1,13 @@ + +export * from './selectors.js'; + +/** + * Returns true if post title is selected. + * + * @param {Object} state Global application state. + * + * @return {boolean} Whether current post title is selected. + */ +export function isPostTitleSelected( state ) { + return state.postTitle.isSelected; +} From 1e248f12e1e3712c34fc52b5b314e7618cfa1d29 Mon Sep 17 00:00:00 2001 From: Tugdual de Kerviler Date: Wed, 24 Jul 2019 14:46:44 +0200 Subject: [PATCH 07/11] Move tests to native --- packages/editor/src/store/test/actions.js | 10 ------ .../editor/src/store/test/actions.native.js | 17 ++++++++++ packages/editor/src/store/test/reducer.js | 27 --------------- .../editor/src/store/test/reducer.native.js | 34 +++++++++++++++++++ packages/editor/src/store/test/selectors.js | 23 ------------- .../editor/src/store/test/selectors.native.js | 28 +++++++++++++++ 6 files changed, 79 insertions(+), 60 deletions(-) create mode 100644 packages/editor/src/store/test/actions.native.js create mode 100644 packages/editor/src/store/test/reducer.native.js create mode 100644 packages/editor/src/store/test/selectors.native.js diff --git a/packages/editor/src/store/test/actions.js b/packages/editor/src/store/test/actions.js index 6f87ad83559229..ff10dcf0a9044b 100644 --- a/packages/editor/src/store/test/actions.js +++ b/packages/editor/src/store/test/actions.js @@ -861,14 +861,4 @@ describe( 'Editor actions', () => { } ); } ); } ); - - describe( 'togglePostTitleSelection', () => { - it( 'should return the TOGGLE_POST_TITLE_SELECTION action', () => { - const result = actions.togglePostTitleSelection( true ); - expect( result ).toEqual( { - type: 'TOGGLE_POST_TITLE_SELECTION', - isSelected: true, - } ); - } ); - } ); } ); diff --git a/packages/editor/src/store/test/actions.native.js b/packages/editor/src/store/test/actions.native.js new file mode 100644 index 00000000000000..b39086244d98de --- /dev/null +++ b/packages/editor/src/store/test/actions.native.js @@ -0,0 +1,17 @@ + +/** + * Internal dependencies + */ +import { togglePostTitleSelection } from '../actions'; + +describe( 'Editor actions', () => { + describe( 'togglePostTitleSelection', () => { + it( 'should return the TOGGLE_POST_TITLE_SELECTION action', () => { + const result = togglePostTitleSelection( true ); + expect( result ).toEqual( { + type: 'TOGGLE_POST_TITLE_SELECTION', + isSelected: true, + } ); + } ); + } ); +} ); diff --git a/packages/editor/src/store/test/reducer.js b/packages/editor/src/store/test/reducer.js index fcd61532230176..d964c72c0f77a3 100644 --- a/packages/editor/src/store/test/reducer.js +++ b/packages/editor/src/store/test/reducer.js @@ -18,7 +18,6 @@ import { saving, reusableBlocks, postSavingLock, - postTitle, previewLink, } from '../reducer'; import { INITIAL_EDITS_DEFAULTS } from '../defaults'; @@ -848,32 +847,6 @@ describe( 'state', () => { } ); } ); - describe( 'postTitle', () => { - describe( 'isSelected()', () => { - it( 'should not be selected by default', () => { - expect( postTitle( undefined, {} ).isSelected ).toBe( false ); - } ); - - it( 'should return false if not selecting the post title', () => { - const action = { - type: 'TOGGLE_POST_TITLE_SELECTION', - isSelected: false, - }; - - expect( postTitle( { isSelected: true }, action ).isSelected ).toBe( false ); - } ); - - it( 'should return true if selecting the post title', () => { - const action = { - type: 'TOGGLE_POST_TITLE_SELECTION', - isSelected: true, - }; - - expect( postTitle( { isSelected: false }, action ).isSelected ).toBe( true ); - } ); - } ); - } ); - describe( 'previewLink', () => { it( 'returns null by default', () => { const state = previewLink( undefined, {} ); diff --git a/packages/editor/src/store/test/reducer.native.js b/packages/editor/src/store/test/reducer.native.js new file mode 100644 index 00000000000000..d97ca0d9e5c9df --- /dev/null +++ b/packages/editor/src/store/test/reducer.native.js @@ -0,0 +1,34 @@ +/** + * Internal dependencies + */ +import { + postTitle, +} from '../reducer'; + +describe( 'state native', () => { + describe( 'postTitle', () => { + describe( 'isSelected()', () => { + it( 'should not be selected by default', () => { + expect( postTitle( undefined, {} ).isSelected ).toBe( false ); + } ); + + it( 'should return false if not selecting the post title', () => { + const action = { + type: 'TOGGLE_POST_TITLE_SELECTION', + isSelected: false, + }; + + expect( postTitle( { isSelected: true }, action ).isSelected ).toBe( false ); + } ); + + it( 'should return true if selecting the post title', () => { + const action = { + type: 'TOGGLE_POST_TITLE_SELECTION', + isSelected: true, + }; + + expect( postTitle( { isSelected: false }, action ).isSelected ).toBe( true ); + } ); + } ); + } ); +} ); diff --git a/packages/editor/src/store/test/selectors.js b/packages/editor/src/store/test/selectors.js index d9af3b2e5d05a1..f2e30f17372e10 100644 --- a/packages/editor/src/store/test/selectors.js +++ b/packages/editor/src/store/test/selectors.js @@ -66,7 +66,6 @@ const { getPermalink, getPermalinkParts, isPostSavingLocked, - isPostTitleSelected, canUserUseUnfilteredHTML, } = selectors; @@ -1098,28 +1097,6 @@ describe( 'selectors', () => { } ); } ); - describe( 'isPostTitleSelected', () => { - it( 'should return true if the post title is selected', () => { - const state = { - postTitle: { - isSelected: true, - }, - }; - - expect( isPostTitleSelected( state ) ).toBe( true ); - } ); - - it( 'should return false if the post title is not selected', () => { - const state = { - postTitle: { - isSelected: false, - }, - }; - - expect( isPostTitleSelected( state ) ).toBe( false ); - } ); - } ); - describe( 'isEditedPostSaveable', () => { it( 'should return false if the post has no title, excerpt, content', () => { const state = { diff --git a/packages/editor/src/store/test/selectors.native.js b/packages/editor/src/store/test/selectors.native.js new file mode 100644 index 00000000000000..958a68e651f743 --- /dev/null +++ b/packages/editor/src/store/test/selectors.native.js @@ -0,0 +1,28 @@ +/** + * Internal dependencies + */ +import { isPostTitleSelected } from '../selectors'; + +describe( 'selectors native', () => { + describe( 'isPostTitleSelected', () => { + it( 'should return true if the post title is selected', () => { + const state = { + postTitle: { + isSelected: true, + }, + }; + + expect( isPostTitleSelected( state ) ).toBe( true ); + } ); + + it( 'should return false if the post title is not selected', () => { + const state = { + postTitle: { + isSelected: false, + }, + }; + + expect( isPostTitleSelected( state ) ).toBe( false ); + } ); + } ); +} ); From 243cd5dd681c7e0243b4d7f0ec7f34b87bba4737 Mon Sep 17 00:00:00 2001 From: Tugdual de Kerviler Date: Wed, 24 Jul 2019 15:15:53 +0200 Subject: [PATCH 08/11] Update docs --- .../developers/data/data-core-editor.md | 24 ------------------- 1 file changed, 24 deletions(-) diff --git a/docs/designers-developers/developers/data/data-core-editor.md b/docs/designers-developers/developers/data/data-core-editor.md index 5579208f2e0696..e3456d65168dbd 100644 --- a/docs/designers-developers/developers/data/data-core-editor.md +++ b/docs/designers-developers/developers/data/data-core-editor.md @@ -932,18 +932,6 @@ _Returns_ - `boolean`: Is locked. -# **isPostTitleSelected** - -Returns true if post title is selected. - -_Parameters_ - -- _state_ `Object`: Global application state. - -_Returns_ - -- `boolean`: Whether current post title is selected. - # **isPreviewingPost** Returns true if the post is being previewed, or false otherwise. @@ -1326,18 +1314,6 @@ _Related_ - toggleBlockMode in core/block-editor store. -# **togglePostTitleSelection** - -Returns an action object that enables or disables post title selection. - -_Parameters_ - -- _isSelected_ `[boolean]`: Whether post title is currently selected. - -_Returns_ - -- `Object`: Action object. - # **toggleSelection** _Related_ From 54240768b9cbf956e7f0786ee1051166fa0c210e Mon Sep 17 00:00:00 2001 From: Tugdual de Kerviler Date: Wed, 24 Jul 2019 15:18:50 +0200 Subject: [PATCH 09/11] Revert changes to web PostTitle --- .../editor/src/components/post-title/index.js | 35 +++++++++++-------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/packages/editor/src/components/post-title/index.js b/packages/editor/src/components/post-title/index.js index f9baf9be1e227a..e992e25bae11a9 100644 --- a/packages/editor/src/components/post-title/index.js +++ b/packages/editor/src/components/post-title/index.js @@ -32,12 +32,27 @@ class PostTitle extends Component { super( ...arguments ); this.onChange = this.onChange.bind( this ); + this.onSelect = this.onSelect.bind( this ); + this.onUnselect = this.onUnselect.bind( this ); this.onKeyDown = this.onKeyDown.bind( this ); this.redirectHistory = this.redirectHistory.bind( this ); + + this.state = { + isSelected: false, + }; } handleFocusOutside() { - this.props.onUnselect(); + this.onUnselect(); + } + + onSelect() { + this.setState( { isSelected: true } ); + this.props.clearSelectedBlock(); + } + + onUnselect() { + this.setState( { isSelected: false } ); } onChange( event ) { @@ -78,11 +93,11 @@ class PostTitle extends Component { isCleanNewPost, isFocusMode, isPostTypeViewable, - isSelected, instanceId, placeholder, title, } = this.props; + const { isSelected } = this.state; // The wp-block className is important for editor styles. const className = classnames( 'wp-block editor-post-title__block', { @@ -111,9 +126,9 @@ class PostTitle extends Component { value={ title } onChange={ this.onChange } placeholder={ decodedPlaceholder || __( 'Add title' ) } - onFocus={ this.props.onSelect } + onFocus={ this.onSelect } onKeyDown={ this.onKeyDown } - onKeyPress={ this.props.onUnselect } + onKeyPress={ this.onUnselect } /* Only autofocus the title when the post is entirely empty. This should only happen for a new post, which means we @@ -134,7 +149,7 @@ class PostTitle extends Component { } const applyWithSelect = withSelect( ( select ) => { - const { getEditedPostAttribute, isCleanNewPost, isPostTitleSelected } = select( 'core/editor' ); + const { getEditedPostAttribute, isCleanNewPost } = select( 'core/editor' ); const { getSettings } = select( 'core/block-editor' ); const { getPostType } = select( 'core' ); const postType = getPostType( getEditedPostAttribute( 'type' ) ); @@ -142,7 +157,6 @@ const applyWithSelect = withSelect( ( select ) => { return { isCleanNewPost: isCleanNewPost(), - isSelected: isPostTitleSelected(), title: getEditedPostAttribute( 'title' ), isPostTypeViewable: get( postType, [ 'viewable' ], false ), placeholder: titlePlaceholder, @@ -160,7 +174,6 @@ const applyWithDispatch = withDispatch( ( dispatch ) => { editPost, undo, redo, - togglePostTitleSelection, } = dispatch( 'core/editor' ); return { @@ -172,13 +185,7 @@ const applyWithDispatch = withDispatch( ( dispatch ) => { }, onUndo: undo, onRedo: redo, - onSelect() { - togglePostTitleSelection( true ); - clearSelectedBlock(); - }, - onUnselect() { - togglePostTitleSelection( false ); - }, + clearSelectedBlock, }; } ); From db39db50fb747774cb95a971990ae0ce22f60531 Mon Sep 17 00:00:00 2001 From: Tugdual de Kerviler Date: Wed, 24 Jul 2019 19:37:33 +0200 Subject: [PATCH 10/11] Fix post title blur on block selection --- .../src/components/visual-editor/index.native.js | 3 --- .../editor/src/components/post-title/index.native.js | 9 ++++++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/edit-post/src/components/visual-editor/index.native.js b/packages/edit-post/src/components/visual-editor/index.native.js index 46d7a8cd3cc446..092ea638f68026 100644 --- a/packages/edit-post/src/components/visual-editor/index.native.js +++ b/packages/edit-post/src/components/visual-editor/index.native.js @@ -79,12 +79,9 @@ export default compose( [ isPostTitleSelected, } = select( 'core/editor' ); - const { getSelectedBlockClientId } = select( 'core/block-editor' ); - return { blocks: getEditorBlocks(), title: getEditedPostAttribute( 'title' ), - isAnyBlockSelected: !! getSelectedBlockClientId(), isPostTitleSelected: isPostTitleSelected(), }; } ), diff --git a/packages/editor/src/components/post-title/index.native.js b/packages/editor/src/components/post-title/index.native.js index 94d3790c459db9..4f5bf4b655d012 100644 --- a/packages/editor/src/components/post-title/index.native.js +++ b/packages/editor/src/components/post-title/index.native.js @@ -92,13 +92,16 @@ class PostTitle extends Component { } export default compose( - withSelect( ( dispatch ) => { + withSelect( ( select ) => { const { isPostTitleSelected, - } = dispatch( 'core/editor' ); + } = select( 'core/editor' ); + + const { getSelectedBlockClientId } = select( 'core/block-editor' ); + const isAnyBlockSelected = !! getSelectedBlockClientId(); return { - isSelected: isPostTitleSelected(), + isSelected: ! isAnyBlockSelected && isPostTitleSelected(), }; } ), withDispatch( ( dispatch ) => { From b58b35a2805bd0f789c7e81378e8a5c0529e91ea Mon Sep 17 00:00:00 2001 From: Tugdual de Kerviler Date: Wed, 24 Jul 2019 20:22:32 +0200 Subject: [PATCH 11/11] Update the isPostTitleSelected state if any other block is selected --- .../editor/src/components/post-title/index.native.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/editor/src/components/post-title/index.native.js b/packages/editor/src/components/post-title/index.native.js index 4f5bf4b655d012..ce845b8fb630f6 100644 --- a/packages/editor/src/components/post-title/index.native.js +++ b/packages/editor/src/components/post-title/index.native.js @@ -22,6 +22,13 @@ import { pasteHandler } from '@wordpress/blocks'; import styles from './style.scss'; class PostTitle extends Component { + componentDidUpdate( prevProps ) { + // Unselect if any other block is selected + if ( this.props.isSelected && ! prevProps.isAnyBlockSelected && this.props.isAnyBlockSelected ) { + this.props.onUnselect(); + } + } + componentDidMount() { if ( this.props.innerRef ) { this.props.innerRef( this ); @@ -98,10 +105,10 @@ export default compose( } = select( 'core/editor' ); const { getSelectedBlockClientId } = select( 'core/block-editor' ); - const isAnyBlockSelected = !! getSelectedBlockClientId(); return { - isSelected: ! isAnyBlockSelected && isPostTitleSelected(), + isAnyBlockSelected: !! getSelectedBlockClientId(), + isSelected: isPostTitleSelected(), }; } ), withDispatch( ( dispatch ) => {