Skip to content
This repository has been archived by the owner on Oct 25, 2022. It is now read-only.

Commit

Permalink
Make text editor aware of layout required and disableNewBlocks settings
Browse files Browse the repository at this point in the history
  • Loading branch information
avoinea committed Sep 16, 2020
1 parent 382927a commit dd15d3b
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 75 deletions.
2 changes: 1 addition & 1 deletion src/blocks/Text/TextBlockEdit.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ const TextBlockEdit = (props) => {
/>
)}
</Dropzone>
{!detached && !data.plaintext && (
{!detached && !data.plaintext && !data.disableNewBlocks && (
<Button
basic
icon
Expand Down
9 changes: 9 additions & 0 deletions src/blocks/Text/extensions/breakList.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,15 @@ export const breakList = (editor) => {
return; // applies default behaviour, as defined in insertBreak.js extension
}

if (parent) {
const blockProps = editor.getBlockProps();
const { data } = blockProps;
// Don't add new block if not allowed
if (data?.disableNewBlocks) {
return insertBreak();
}
}

// TODO: while this is interesting as a tech demo, I'm not sure that this is
// what we really want (break lists in two separate blocks)

Expand Down
8 changes: 8 additions & 0 deletions src/blocks/Text/extensions/insertBreak.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@ export const withSplitBlocksOnBreak = (editor) => {
const block = Editor.parent(editor, editor.selection);

if (block) {
const blockProps = editor.getBlockProps();
const { data } = blockProps;

// Don't add new block if not allowed
if (data?.disableNewBlocks) {
return insertBreak();
}

const [top, bottom] = splitEditorInTwoFragments(editor);
setEditorContent(editor, top);
ReactEditor.blur(editor);
Expand Down
5 changes: 5 additions & 0 deletions src/blocks/Text/keyboard/backspaceInList.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ export function backspaceInList({ editor, event }) {
// If the cursor is at list block start, do something different:
if (isCursorAtListBlockStart(editor)) {
const { slate } = settings;
const blockProps = editor.getBlockProps();
const { data } = blockProps;

// Can't split if block is required
if (data?.required) return;

// Raise all LI-s as direct children of the editor.
Transforms.liftNodes(editor, {
Expand Down
88 changes: 14 additions & 74 deletions src/blocks/Text/keyboard/joinBlocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export function joinWithPreviousBlock({ editor, event }) {
onChangeBlock,
onDeleteBlock,
onSelectBlock,
data,
} = blockProps;

const { formContext } = editor;
Expand All @@ -46,6 +47,12 @@ export function joinWithPreviousBlock({ editor, event }) {
// If the previous block is not Slate Text, do nothing.
if (otherBlock['@type'] !== 'slate') return;

// Can't join if the previous block is required
if (otherBlock?.required) return;

// Can't join/remove this block if it's required
if (data?.required) return;

// From here on, the previous block is surely Slate Text.
event.stopPropagation();
event.preventDefault();
Expand Down Expand Up @@ -137,6 +144,7 @@ export function joinWithNextBlock({ editor, event }) {
onChangeBlock,
onDeleteBlock,
onSelectBlock,
data,
} = blockProps;

const { formContext } = editor;
Expand All @@ -152,6 +160,12 @@ export function joinWithNextBlock({ editor, event }) {
// instead of 'slate'.)
if (otherBlock['@type'] !== 'slate') return;

// Can't join/remove this block if it's required
if (data?.required) return;

// Can't join if the next block is required
if (otherBlock?.required) return;

// From here on, the next block is surely Slate Text.
event.stopPropagation();
event.preventDefault();
Expand Down Expand Up @@ -198,80 +212,6 @@ export function joinWithNextBlock({ editor, event }) {
return true;
}

/**
* Join current block with neighbor block, if the blocks are compatible.
* @todo This seems to be dead code that should be removed or transformed into a
* combination of `joinWithPreviousBlock` and `joinWithNextBlock` which are
* written above.
*/
export function joinWithNeighborBlock(
getNeighborVoltoBlock,
getCursorPosition,
isValidOp,
mergeOp,
) {
/**
*
*/
return ({ editor, event }) => {
// TODO: read block values not from editor properties, but from block
// properties
const blockProps = editor.getBlockProps();
const {
block,
index,
saveSlateBlockSelection,
onChangeBlock,
onDeleteBlock,
onSelectBlock,
} = blockProps;

const { formContext } = editor;
const properties = formContext.contextData.formData;

const [otherBlock = {}, otherBlockId] = getNeighborVoltoBlock(
index,
properties,
);

if (!isValidOp(editor)) return;

if (otherBlock['@type'] !== 'slate') return;

event.stopPropagation();
event.preventDefault();

mergeOp(editor, otherBlock);

const selection = JSON.parse(JSON.stringify(editor.selection));
const combined = JSON.parse(JSON.stringify(editor.children));

// TODO: don't remove undo history, etc Should probably save both undo
// histories, so that the blocks are split, the undos can be restored??
// TODO: after Enter, the current filled-with-previous-block block is
// visible for a fraction of second

const cursor = getCursorPosition(otherBlock, selection);
saveSlateBlockSelection(otherBlockId, cursor);

// setTimeout ensures setState has been successfully executed in Form.jsx.
// See https://github.com/plone/volto/issues/1519
setTimeout(() => {
onChangeBlock(otherBlockId, {
'@type': 'slate',
value: combined,
plaintext: serializeNodesToText(combined || []),
});
setTimeout(() => {
onDeleteBlock(block, false);
onSelectBlock(otherBlockId);
});
});

return true;
};
}

/**
* @param {object} block The Volto object representing the configuration and
* contents of a Volto Block of type Slate Text.
Expand Down

0 comments on commit dd15d3b

Please sign in to comment.