Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Record selection changes in history (undo) #16428

Closed
wants to merge 11 commits into from
Original file line number Diff line number Diff line change
Expand Up @@ -691,7 +691,7 @@ _Returns_
Returns true if the block corresponding to the specified client ID is
currently selected but isn't the last of the selected blocks. Here "last"
refers to the block sequence in the document, _not_ the sequence of
multi-selection, which is why `state.blockSelection.end` isn't used.
multi-selection, which is why `state.selectionEnd` isn't used.

_Parameters_

Expand Down Expand Up @@ -1033,6 +1033,20 @@ _Returns_

- `Object`: Action object.

<a name="resetSelection" href="#resetSelection">#</a> **resetSelection**

Returns an action object used in signalling that selection state should be
reset to the specified selection.

_Parameters_

- _selectionStart_ `WPBlockSelection`: The selection start.
- _selectionEnd_ `WPBlockSelection`: The selection end.

_Returns_

- `Object`: Action object.

<a name="selectBlock" href="#selectBlock">#</a> **selectBlock**

Returns an action object used in signalling that the block with the
Expand Down
37 changes: 37 additions & 0 deletions docs/designers-developers/developers/data/data-core-editor.md
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,30 @@ _Returns_

- `Array`: Block list.

<a name="getEditorSelectionEnd" href="#getEditorSelectionEnd">#</a> **getEditorSelectionEnd**

Return the current selection end.

_Parameters_

- _state_ `Object`:

_Returns_

- `WPBlockSelection`: The selection end.

<a name="getEditorSelectionStart" href="#getEditorSelectionStart">#</a> **getEditorSelectionStart**

Return the current selection start.

_Parameters_

- _state_ `Object`:

_Returns_

- `WPBlockSelection`: The selection start.

<a name="getEditorSettings" href="#getEditorSettings">#</a> **getEditorSettings**

Returns the post editor settings.
Expand Down Expand Up @@ -1209,6 +1233,19 @@ _Returns_

- `Object`: Action object

<a name="resetEditorSelection" href="#resetEditorSelection">#</a> **resetEditorSelection**

Returns an action object used to signal that the selection has been updated.

_Parameters_

- _selectionStart_ `WPBlockSelection`: The selection start.
- _selectionEnd_ `WPBlockSelection`: The selection end.

_Returns_

- `Object`: Action object

<a name="resetPost" href="#resetPost">#</a> **resetPost**

Returns an action object used in signalling that the latest version of the
Expand Down
21 changes: 21 additions & 0 deletions packages/block-editor/src/components/provider/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,20 @@ BlockEditorProvider is a component which establishes a new block editing context

The current array of blocks.

### `selectionStart`

* **Type:** `WPBlockSelection`
* **Required** `no`

The current selection start.

### `selectionEnd`

* **Type:** `WPBlockSelection`
* **Required** `no`

The current selection end.

### `onChange`

* **Type:** `Function`
Expand All @@ -32,6 +46,13 @@ In the context of an editor, an example usage of this distinction is for managin

A callback invoked when the blocks have been modified in a non-persistent manner. Contrasted with `onChange`, a "non-persistent" change is one which is part of a composed input. Any sequence of updates to the same block attribute are treated as non-persistent, except for the first.

### `onChangeSelection`

* **Type:** `Function`
* **Required** `no`

A callback invoked when the block selection has been modified.

### `children`

* **Type:** `WPElement`
Expand Down
20 changes: 20 additions & 0 deletions packages/block-editor/src/components/provider/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ class BlockEditorProvider extends Component {
updateSettings,
value,
resetBlocks,
selectionStart,
selectionEnd,
resetSelection,
registry,
} = this.props;

Expand Down Expand Up @@ -50,6 +53,10 @@ class BlockEditorProvider extends Component {
this.isSyncingOutcomingValue = null;
this.isSyncingIncomingValue = value;
resetBlocks( value );

if ( selectionStart && selectionEnd ) {
resetSelection( selectionStart, selectionEnd );
}
}
}

Expand Down Expand Up @@ -78,6 +85,8 @@ class BlockEditorProvider extends Component {

const {
getBlocks,
getSelectionStart,
getSelectionEnd,
isLastBlockChangePersistent,
__unstableIsLastBlockChangeIgnored,
} = registry.select( 'core/block-editor' );
Expand All @@ -89,6 +98,7 @@ class BlockEditorProvider extends Component {
const {
onChange,
onInput,
onChangeSelection,
} = this.props;

const newBlocks = getBlocks();
Expand Down Expand Up @@ -120,6 +130,14 @@ class BlockEditorProvider extends Component {
blocks = newBlocks;
isPersistent = newIsPersistent;

// Selection must be updated first, so it is recorded in history when the content change happens.
if ( onChangeSelection ) {
onChangeSelection(
getSelectionStart(),
getSelectionEnd()
);
}

if ( isPersistent ) {
onChange( blocks );
} else {
Expand All @@ -142,11 +160,13 @@ export default compose( [
const {
updateSettings,
resetBlocks,
resetSelection,
} = dispatch( 'core/block-editor' );

return {
updateSettings,
resetBlocks,
resetSelection,
};
} ),
] )( BlockEditorProvider );
25 changes: 25 additions & 0 deletions packages/block-editor/src/store/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,31 @@ export function resetBlocks( blocks ) {
};
}

/**
* @typedef {WPBlockSelection} A block selection object.
*
* @property {string} clientId A block client ID.
* @property {string} attributeKey A block attribute key.
* @property {number} offset A block attribute offset.
*/

/**
* Returns an action object used in signalling that selection state should be
* reset to the specified selection.
*
* @param {WPBlockSelection} selectionStart The selection start.
* @param {WPBlockSelection} selectionEnd The selection end.
*
* @return {Object} Action object.
*/
export function resetSelection( selectionStart, selectionEnd ) {
return {
type: 'RESET_SELECTION',
selectionStart,
selectionEnd,
};
}

/**
* Returns an action object used in signalling that blocks have been received.
* Unlike resetBlocks, these should be appended to the existing known set, not
Expand Down
Loading