Skip to content

Commit

Permalink
Text Editor: Fix insertion point
Browse files Browse the repository at this point in the history
  • Loading branch information
youknowriad committed Jun 12, 2017
1 parent 6354eaa commit 44f6fe1
Show file tree
Hide file tree
Showing 8 changed files with 114 additions and 97 deletions.
9 changes: 4 additions & 5 deletions editor/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,15 @@ export function insertBlock( block, after ) {
};
}

export function setInsertionPoint( uid ) {
export function showInsertionPoint() {
return {
type: 'SET_INSERTION_POINT',
uid,
type: 'SHOW_INSERTION_POINT',
};
}

export function clearInsertionPoint() {
export function hideInsertionPoint() {
return {
type: 'CLEAR_INSERTION_POINT',
type: 'HIDE_INSERTION_POINT',
};
}

Expand Down
19 changes: 6 additions & 13 deletions editor/inserter/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import { IconButton } from 'components';
* Internal dependencies
*/
import InserterMenu from './menu';
import { getLastMultiSelectedBlockUid, getSelectedBlock } from '../selectors';
import { insertBlock, clearInsertionPoint } from '../actions';
import { getBlockInsertionPoint, getEditorMode } from '../selectors';
import { insertBlock, hideInsertionPoint } from '../actions';

class Inserter extends wp.element.Component {
constructor() {
Expand All @@ -41,14 +41,7 @@ class Inserter extends wp.element.Component {

insertBlock( slug ) {
if ( slug ) {
const { selectedBlock, lastMultiSelectedBlock, onInsertBlock } = this.props;
let insertionPoint = null;
if ( lastMultiSelectedBlock ) {
insertionPoint = lastMultiSelectedBlock;
} else if ( selectedBlock ) {
insertionPoint = selectedBlock.uid;
}

const { insertionPoint, onInsertBlock } = this.props;
onInsertBlock(
slug,
insertionPoint
Expand Down Expand Up @@ -96,13 +89,13 @@ class Inserter extends wp.element.Component {
export default connect(
( state ) => {
return {
selectedBlock: getSelectedBlock( state ),
lastMultiSelectedBlock: getLastMultiSelectedBlockUid( state ),
insertionPoint: getBlockInsertionPoint( state ),
mode: getEditorMode( state ),
};
},
( dispatch ) => ( {
onInsertBlock( slug, after ) {
dispatch( clearInsertionPoint() );
dispatch( hideInsertionPoint() );
dispatch( insertBlock(
wp.blocks.createBlock( slug ),
after
Expand Down
33 changes: 5 additions & 28 deletions editor/inserter/menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ import { TAB, ESCAPE, LEFT, UP, RIGHT, DOWN } from 'utils/keycodes';
* Internal dependencies
*/
import './style.scss';
import { getLastMultiSelectedBlockUid, getSelectedBlock } from '../selectors';
import { setInsertionPoint, clearInsertionPoint } from '../actions';
import { showInsertionPoint, hideInsertionPoint } from '../actions';

class InserterMenu extends wp.element.Component {
constructor() {
Expand Down Expand Up @@ -67,23 +66,6 @@ class InserterMenu extends wp.element.Component {
};
}

hoverBlock() {
const { lastMultiSelectedBlock, selectedBlock } = this.props;
let insertionPoint = null;
if ( lastMultiSelectedBlock ) {
insertionPoint = lastMultiSelectedBlock;
} else if ( selectedBlock ) {
insertionPoint = selectedBlock.uid;
}
return () => {
this.props.setInsertionPoint( insertionPoint );
};
}

unhoverBlock() {
return () => this.props.clearInsertionPoint();
}

getVisibleBlocks( blockTypes ) {
return filter( blockTypes, this.isShownBlock );
}
Expand Down Expand Up @@ -275,8 +257,8 @@ class InserterMenu extends wp.element.Component {
onClick={ this.selectBlock( slug ) }
ref={ this.bindReferenceNode( slug ) }
tabIndex="-1"
onMouseEnter={ this.hoverBlock() }
onMouseLeave={ this.unhoverBlock() }
onMouseEnter={ this.props.showInsertionPoint }
onMouseLeave={ this.props.hideInsertionPoint }
>
<Dashicon icon={ icon } />
{ title }
Expand Down Expand Up @@ -308,11 +290,6 @@ class InserterMenu extends wp.element.Component {
InserterMenu.instances = 0;

export default connect(
( state ) => {
return {
selectedBlock: getSelectedBlock( state ),
lastMultiSelectedBlock: getLastMultiSelectedBlockUid( state ),
};
},
{ setInsertionPoint, clearInsertionPoint }
undefined,
{ showInsertionPoint, hideInsertionPoint }
)( withFocusReturn( InserterMenu ) );
6 changes: 4 additions & 2 deletions editor/modes/visual-editor/block-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import VisualEditorBlock from './block';
import {
getBlockUids,
getBlockInsertionPoint,
isBlockInsertionPointVisible,
getMultiSelectedBlocksStartUid,
getMultiSelectedBlocksEndUid,
getMultiSelectedBlocks,
Expand Down Expand Up @@ -97,9 +98,9 @@ class VisualEditorBlockList extends wp.element.Component {
}

render() {
const { blocks, insertionPoint, multiSelectedBlockUids } = this.props;
const { blocks, showInsertionPoint, insertionPoint, multiSelectedBlockUids } = this.props;
const insertionPointIndex = blocks.indexOf( insertionPoint );
const blocksWithInsertionPoint = insertionPoint
const blocksWithInsertionPoint = showInsertionPoint
? [
...blocks.slice( 0, insertionPointIndex + 1 ),
INSERTION_POINT_PLACEHOLDER,
Expand Down Expand Up @@ -139,6 +140,7 @@ export default connect(
( state ) => ( {
blocks: getBlockUids( state ),
insertionPoint: getBlockInsertionPoint( state ),
showInsertionPoint: isBlockInsertionPointVisible( state ),
selectionStart: getMultiSelectedBlocksStartUid( state ),
selectionEnd: getMultiSelectedBlocksEndUid( state ),
multiSelectedBlocks: getMultiSelectedBlocks( state ),
Expand Down
31 changes: 24 additions & 7 deletions editor/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -243,9 +243,7 @@ export function getBlock( state, uid ) {
*/
export const getBlocks = createSelector(
( state ) => {
return state.editor.blockOrder.map( ( uid ) => (
state.editor.blocksByUid[ uid ]
) );
return state.editor.blockOrder.map( ( uid ) => getBlock( state, uid ) );
},
( state ) => [
state.editor.blockOrder,
Expand Down Expand Up @@ -528,12 +526,31 @@ export function isTypingInBlock( state, uid ) {
* @return {?String} Unique ID after which insertion will occur
*/
export function getBlockInsertionPoint( state ) {
if ( ! state.insertionPoint.show ) {
return null;
if ( getEditorMode( state ) !== 'visual' ) {
return last( state.editor.blockOrder );
}

const lastMultiSelectedBlock = getLastMultiSelectedBlockUid( state );
if ( lastMultiSelectedBlock ) {
return lastMultiSelectedBlock;
}
const blockToInsertAfter = state.insertionPoint.uid;

return blockToInsertAfter || last( state.editor.blockOrder );
const selectedBlock = getSelectedBlock( state );
if ( selectedBlock ) {
return selectedBlock.uid;
}

return last( state.editor.blockOrder );
}

/**
* Returns true if we should show the block insertion point
*
* @param {Object} state Global application state
* @return {?Boolean} Whether the insertion point is visible or not
*/
export function isBlockInsertionPointVisible( state ) {
return state.showInsertionPoint;
}

/**
Expand Down
17 changes: 6 additions & 11 deletions editor/state.js
Original file line number Diff line number Diff line change
Expand Up @@ -379,17 +379,12 @@ export function hoveredBlock( state = null, action ) {
* @param {Object} action Dispatched action
* @return {Object} Updated state
*/
export function insertionPoint( state = { show: false }, action ) {
export function showInsertionPoint( state = false, action ) {
switch ( action.type ) {
case 'SET_INSERTION_POINT':
return {
show: true,
uid: action.uid,
};
case 'CLEAR_INSERTION_POINT':
return {
show: false,
};
case 'SHOW_INSERTION_POINT':
return true;
case 'HIDE_INSERTION_POINT':
return false;
}

return state;
Expand Down Expand Up @@ -467,7 +462,7 @@ export function createReduxStore() {
selectedBlock,
multiSelectedBlocks,
hoveredBlock,
insertionPoint,
showInsertionPoint,
mode,
isSidebarOpened,
saving,
Expand Down
70 changes: 55 additions & 15 deletions editor/test/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import {
getBlockFocus,
isTypingInBlock,
getBlockInsertionPoint,
isBlockInsertionPointVisible,
isSavingPost,
didPostSaveRequestSucceed,
didPostSaveRequestFail,
Expand Down Expand Up @@ -905,39 +906,78 @@ describe( 'selectors', () => {
} );

describe( 'getBlockInsertionPoint', () => {
it( 'should return the uid of the insertion point', () => {
it( 'should return the uid of the selected block', () => {
const state = {
insertionPoint: {
show: true,
uid: 123,
mode: 'visual',
selectedBlock: {
uid: 2,
typing: true,
},
multiSelectedBlocks: {},
editor: {
blocksByUid: {
2: { uid: 2 },
},
blockOrder: [ 1, 2, 3 ],
},
};

expect( getBlockInsertionPoint( state ) ).to.equal( 123 );
expect( getBlockInsertionPoint( state ) ).to.equal( 2 );
} );

it( 'should return return the last block uid if the insertion point is null', () => {
it( 'should return the last multi selected uid', () => {
const state = {
insertionPoint: {
show: true,
uid: null,
mode: 'visual',
selectedBlock: {},
multiSelectedBlocks: {
start: 1,
end: 2,
},
editor: {
blockOrder: [ 1, 2, 3 ],
},
};

expect( getBlockInsertionPoint( state ) ).to.equal( 2 );
} );

it( 'should return the last block if no selection', () => {
const state = {
mode: 'visual',
selectedBlock: {},
multiSelectedBlocks: {},
editor: {
blockOrder: [ 34, 23 ],
blockOrder: [ 1, 2, 3 ],
},
};

expect( getBlockInsertionPoint( state ) ).to.equal( 23 );
expect( getBlockInsertionPoint( state ) ).to.equal( 3 );
} );

it( 'should return null if the insertion point is not shown', () => {
it( 'should return the last block for the text mode', () => {
const state = {
insertionPoint: {
show: false,
mode: 'text',
selectedBlock: {
uid: 2,
typing: true,
},
multiSelectedBlocks: {},
editor: {
blockOrder: [ 1, 2, 3 ],
},
};

expect( getBlockInsertionPoint( state ) ).to.equal( 3 );
} );
} );

describe( 'isBlockInsertionPointVisible', () => {
it( 'should return the value in state', () => {
const state = {
showInsertionPoint: true,
};

expect( getBlockInsertionPoint( state, 23 ) ).to.be.null();
expect( isBlockInsertionPointVisible( state ) ).to.be.true();
} );
} );

Expand Down
26 changes: 10 additions & 16 deletions editor/test/state.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
mode,
isSidebarOpened,
saving,
insertionPoint,
showInsertionPoint,
createReduxStore,
} from '../state';

Expand Down Expand Up @@ -652,27 +652,21 @@ describe( 'state', () => {
} );
} );

describe( 'insertionPoint', () => {
it( 'should set the insertion point', () => {
const state = insertionPoint( {}, {
type: 'SET_INSERTION_POINT',
uid: 'kumquat',
describe( 'showInsertionPoint', () => {
it( 'should show the insertion point', () => {
const state = showInsertionPoint( undefined, {
type: 'SHOW_INSERTION_POINT',
} );

expect( state ).to.eql( {
show: true,
uid: 'kumquat',
} );
expect( state ).to.be.true();
} );

it( 'should clear the insertion point', () => {
const state = insertionPoint( {}, {
type: 'CLEAR_INSERTION_POINT',
const state = showInsertionPoint( {}, {
type: 'HIDE_INSERTION_POINT',
} );

expect( state ).to.eql( {
show: false,
} );
expect( state ).to.be.false();
} );
} );

Expand Down Expand Up @@ -987,7 +981,7 @@ describe( 'state', () => {
'mode',
'isSidebarOpened',
'saving',
'insertionPoint',
'showInsertionPoint',
] );
} );
} );
Expand Down

0 comments on commit 44f6fe1

Please sign in to comment.