Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions lib/changes/dedentLines.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// @flow
import { type Change } from 'slate';
import { type Editor } from 'slate-react';

import type Options from '../options';

Expand All @@ -23,22 +23,22 @@ function firstDifferentCharacter(a: string, b: string): number {
*/
function dedentLines(
opts: Options,
change: Change,
editor: Editor,
// Indent to remove
indent: string
): Change {
const { value } = change;
): Editor {
const { value } = editor;
const { document, selection } = value;
const lines = document
.getBlocksAtRange(selection)
.getLeafBlocksAtRange(selection)
.filter(node => node.type === opts.lineType);

return lines.reduce((c, line) => {
return lines.reduce((editor, line) => {
// Remove a level of indent from the start of line
const textNode = line.nodes.first();
const lengthToRemove = firstDifferentCharacter(textNode.text, indent);
return c.removeTextByKey(textNode.key, 0, lengthToRemove);
}, change);
return editor.removeTextByKey(textNode.key, 0, lengthToRemove);
}, editor);
}

export default dedentLines;
16 changes: 8 additions & 8 deletions lib/changes/indentLines.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// @flow
import { type Change } from 'slate';
import { type Editor } from 'slate-react';

import type Options from '../options';

Expand All @@ -8,21 +8,21 @@ import type Options from '../options';
*/
function indentLines(
opts: Options,
change: Change,
editor: Editor,
// Indent to add
indent: string
): Change {
const { value } = change;
): Editor {
const { value } = editor;
const { document, selection } = value;
const lines = document
.getBlocksAtRange(selection)
.getLeafBlocksAtRange(selection)
.filter(node => node.type === opts.lineType);

return lines.reduce((c, line) => {
return lines.reduce((editor, line) => {
// Insert an indent at start of line
const text = line.nodes.first();
return c.insertTextByKey(text.key, 0, indent);
}, change);
return editor.insertTextByKey(text.key, 0, indent);
}, editor);
}

export default indentLines;
12 changes: 6 additions & 6 deletions lib/changes/toggleCodeBlock.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// @flow
import { type Change } from 'slate';
import { type Editor } from 'slate-react';

import type Options from '../options';
import { isInCodeBlock } from '../utils';
Expand All @@ -12,14 +12,14 @@ import unwrapCodeBlock from './unwrapCodeBlock';
*/
function toggleCodeBlock(
opts: Options,
change: Change,
editor: Editor,
// When toggling a code block off, type to convert to
type: string
): Change {
if (isInCodeBlock(opts, change.value)) {
return unwrapCodeBlock(opts, change, type);
): Editor {
if (isInCodeBlock(opts, editor.value)) {
return unwrapCodeBlock(opts, editor, type);
}
return wrapCodeBlock(opts, change);
return wrapCodeBlock(opts, editor);
}

export default toggleCodeBlock;
12 changes: 6 additions & 6 deletions lib/changes/unwrapCodeBlock.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// @flow
import { type Change } from 'slate';
import { type Editor } from 'slate-react';

import type Options from '../options';
import { getCurrentCode } from '../utils';
Expand All @@ -9,19 +9,19 @@ import unwrapCodeBlockByKey from './unwrapCodeBlockByKey';
/**
* Convert a code block to a normal block.
*/
function unwrapCodeBlock(opts: Options, change: Change, type: string): Change {
const { value } = change;
function unwrapCodeBlock(opts: Options, editor: Editor, type: string): Editor {
const { value } = editor;

const codeBlock = getCurrentCode(opts, value);

if (!codeBlock) {
return change;
return editor;
}

// Convert to paragraph
unwrapCodeBlockByKey(opts, change, codeBlock.key, type);
unwrapCodeBlockByKey(opts, editor, codeBlock.key, type);

return change;
return editor;
}

export default unwrapCodeBlock;
18 changes: 10 additions & 8 deletions lib/changes/unwrapCodeBlockByKey.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// @flow
import { type Change } from 'slate';
import { type Editor } from 'slate-react';

import type Options from '../options';

Expand All @@ -8,11 +8,11 @@ import type Options from '../options';
*/
function unwrapCodeBlockByKey(
opts: Options,
change: Change,
editor: Editor,
key: string,
type: string
): Change {
const { value } = change;
): Editor {
const { value } = editor;
const { document } = value;

// Get the code block
Expand All @@ -26,12 +26,14 @@ function unwrapCodeBlockByKey(

// change lines into paragraph
codeBlock.nodes.forEach(line =>
change
.setNodeByKey(line.key, { type }, { normalize: false })
.unwrapNodeByKey(line.key, { normalize: false })
editor.withoutNormalizing(() => {
editor
.setNodeByKey(line.key, { type })
.unwrapNodeByKey(line.key);
})
);

return change;
return editor;
}

export default unwrapCodeBlockByKey;
14 changes: 7 additions & 7 deletions lib/changes/wrapCodeBlock.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// @flow
import { type Change } from 'slate';
import { type Editor } from 'slate-react';

import type Options from '../options';

Expand All @@ -8,19 +8,19 @@ import wrapCodeBlockByKey from './wrapCodeBlockByKey';
/**
* Wrap current block into a code block.
*/
function wrapCodeBlock(opts: Options, change: Change): Change {
const { value } = change;
function wrapCodeBlock(opts: Options, editor: Editor): Editor {
const { value } = editor;
const { startBlock, selection } = value;

// Convert to code block
wrapCodeBlockByKey(opts, change, startBlock.key);
wrapCodeBlockByKey(opts, editor, startBlock.key);

// Move selection back in the block
change
.moveToStartOfNode(change.value.document.getDescendant(startBlock.key))
editor
.moveToStartOfNode(editor.value.document.getDescendant(startBlock.key))
.moveTo(selection.start.offset);

return change;
return editor;
}

export default wrapCodeBlock;
30 changes: 17 additions & 13 deletions lib/changes/wrapCodeBlockByKey.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// @flow
import { type Change } from 'slate';
import { type Editor } from 'slate-react';

import type Options from '../options';
import { deserializeCode } from '../utils';
Expand All @@ -9,33 +9,37 @@ import { deserializeCode } from '../utils';
*/
function wrapCodeBlockByKey(
opts: Options,
change: Change,
editor: Editor,
key: string
): Change {
const { value } = change;
): Editor {
const { value } = editor;
const { document } = value;

const startBlock = document.getDescendant(key);
const text = startBlock.text;

// Remove all child
startBlock.nodes.forEach(node => {
change.removeNodeByKey(node.key, { normalize: false });
editor.withoutNormalizing(() => {
// Remove all child
startBlock.nodes.forEach(node => {
editor.removeNodeByKey(node.key);
});
});

// Insert new text
const toInsert = deserializeCode(opts, text);
// Insert new text
const toInsert = deserializeCode(opts, text);

toInsert.nodes.forEach((node, i) => {
change.insertNodeByKey(startBlock.key, i, node, { normalize: false });
editor.withoutNormalizing(() => {
toInsert.nodes.forEach((node, i) => {
editor.insertNodeByKey(startBlock.key, i, node);
});
});

// Set node type
change.setNodeByKey(startBlock.key, {
editor.setNodeByKey(startBlock.key, {
type: opts.containerType
});

return change;
return editor;
}

export default wrapCodeBlockByKey;
52 changes: 52 additions & 0 deletions lib/handlers/onArrow.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// @flow

import { Block, Text } from 'slate'
import { type Editor } from 'slate-react'
import { isKeyHotkey } from 'is-hotkey'

import { getCurrentCode } from '../utils'
import { unwrapCodeBlock } from '../changes'
import type Options from '../options'

const isArrowDown = isKeyHotkey('arrowdown')
const isArrowUp = isKeyHotkey('arrowup')

/**
* User pressed arrow down or up in an editor and on last or first line of code
* block respectively:
* Append or prepend an exit block
*/
function onArrow(
opts: Options,
event: *,
editor: Editor,
next: *
): void | Editor {
const { value } = editor;
if (value.selection.isExpanded) {
return next();
}

const { selection, startText, document } = value;

const currentLine = value.startBlock;
const nextBlock = document.getNextBlock(currentLine.key);
const prevBlock = document.getPreviousBlock(currentLine.key);
if (isArrowUp(event) && currentLine.type === opts.lineType && !prevBlock) {
event.preventDefault();
editor.moveToStartOfDocument().splitBlock(10).setBlocks({
type: opts.exitBlockType,
text: '',
isVoid: false,
})
editor.moveToStartOfDocument();
return unwrapCodeBlock(opts, editor, opts.exitBlockType);
} else if (isArrowDown(event) && currentLine.type === opts.lineType && !nextBlock) {
event.preventDefault();
return opts.resolvedOnExit(editor);
}

return next();
}

export default onArrow;
25 changes: 14 additions & 11 deletions lib/handlers/onBackspace.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// @flow

import { type Change } from 'slate';
import { type Editor } from 'slate-react';
import endsWith from 'ends-with';

import { getCurrentIndent, getCurrentCode } from '../utils';
Expand All @@ -13,12 +13,12 @@ import type Options from '../options';
function onBackspace(
opts: Options,
event: *,
change: Change,
editor: *
): void | Change {
const { value } = change;
editor: Editor,
next: *
): void | Editor {
const { value } = editor;
if (value.selection.isExpanded) {
return undefined;
return next();
}

const { selection, startText } = value;
Expand All @@ -34,7 +34,7 @@ function onBackspace(
// Remove indent
event.preventDefault();

return change.deleteBackward(indent.length).focus();
return editor.deleteBackward(indent.length).focus();
} else if (opts.exitBlockType) {
// Otherwise check if we are in an empty code container...
const currentCode = getCurrentCode(opts, value);
Expand All @@ -48,12 +48,15 @@ function onBackspace(
if (isStartOfCode && isEmpty) {
event.preventDefault();
// Convert it to default exit type
return change
.setBlocks(opts.exitBlockType, { normalize: false })
.unwrapNodeByKey(currentLine.key);
editor.withoutNormalizing(() => {
editor
.setBlocks(opts.exitBlockType)
.unwrapNodeByKey(currentLine.key);
});
return editor
}
}
return undefined;
return next();
}

export default onBackspace;
Loading