diff --git a/packages/block-editor/src/store/reducer.js b/packages/block-editor/src/store/reducer.js index ef2183981c707..64efca4e06e89 100644 --- a/packages/block-editor/src/store/reducer.js +++ b/packages/block-editor/src/store/reducer.js @@ -1336,14 +1336,14 @@ function selectionHelper( state = {}, action ) { if ( ! action.clientIds || ! action.clientIds.length || - action.clientIds.indexOf( state.clientId ) === -1 + ! action.clientIds.includes( state.clientId ) ) { return state; } return {}; case 'REPLACE_BLOCKS': { - if ( action.clientIds.indexOf( state.clientId ) === -1 ) { + if ( ! action.clientIds.includes( state.clientId ) ) { return state; } @@ -1366,6 +1366,20 @@ function selectionHelper( state = {}, action ) { return state; } +function selectionEqual( sel1, sel2 ) { + if ( sel1 === sel2 ) { + return true; + } + if ( ! sel1 || ! sel2 ) { + return false; + } + return ( + sel1.clientId === sel2.clientId && + sel1.attributeKey === sel2.attributeKey && + sel1.offset === sel2.offset + ); +} + /** * Reducer returning the selection state. * @@ -1375,33 +1389,30 @@ function selectionHelper( state = {}, action ) { * @return {boolean} Updated state. */ export function selection( state = {}, action ) { + let { selectionStart, selectionEnd } = state; + switch ( action.type ) { case 'SELECTION_CHANGE': if ( action.clientId ) { - return { - selectionStart: { - clientId: action.clientId, - attributeKey: action.attributeKey, - offset: action.startOffset, - }, - selectionEnd: { - clientId: action.clientId, - attributeKey: action.attributeKey, - offset: action.endOffset, - }, + selectionStart = { + clientId: action.clientId, + attributeKey: action.attributeKey, + offset: action.startOffset, + }; + selectionEnd = { + clientId: action.clientId, + attributeKey: action.attributeKey, + offset: action.endOffset, }; + } else { + selectionStart = action.start || selectionStart; + selectionEnd = action.end || selectionEnd; } - - return { - selectionStart: action.start || state.selectionStart, - selectionEnd: action.end || state.selectionEnd, - }; + break; case 'RESET_SELECTION': - const { selectionStart, selectionEnd } = action; - return { - selectionStart, - selectionEnd, - }; + selectionStart = action.selectionStart; + selectionEnd = action.selectionEnd; + break; case 'MULTI_SELECT': const { start, end } = action; @@ -1412,10 +1423,9 @@ export function selection( state = {}, action ) { return state; } - return { - selectionStart: { clientId: start }, - selectionEnd: { clientId: end }, - }; + selectionStart = { clientId: start }; + selectionEnd = { clientId: end }; + break; case 'RESET_BLOCKS': const startClientId = state?.selectionStart?.clientId; const endClientId = state?.selectionEnd?.clientId; @@ -1431,31 +1441,26 @@ export function selection( state = {}, action ) { ( block ) => block.clientId === startClientId ) ) { - return { - selectionStart: {}, - selectionEnd: {}, - }; + selectionStart = {}; + selectionEnd = {}; } - // If the end of the selection won't exist after reset, collapse selection. - if ( + else if ( ! action.blocks.some( ( block ) => block.clientId === endClientId ) ) { - return { - ...state, - selectionEnd: state.selectionStart, - }; + selectionEnd = selectionStart; } + break; + default: + selectionStart = selectionHelper( state.selectionStart, action ); + selectionEnd = selectionHelper( state.selectionEnd, action ); } - const selectionStart = selectionHelper( state.selectionStart, action ); - const selectionEnd = selectionHelper( state.selectionEnd, action ); - if ( - selectionStart === state.selectionStart && - selectionEnd === state.selectionEnd + selectionEqual( selectionStart, state.selectionStart ) && + selectionEqual( selectionEnd, state.selectionEnd ) ) { return state; }