Skip to content

Commit

Permalink
Updated to latest Slate version.
Browse files Browse the repository at this point in the history
  • Loading branch information
enzoferey committed Nov 21, 2018
1 parent e01d577 commit 25503ac
Show file tree
Hide file tree
Showing 10 changed files with 602 additions and 582 deletions.
12 changes: 12 additions & 0 deletions lib/commands.js
@@ -0,0 +1,12 @@
import { Inline } from "slate";

import { getPreviousNode, isFirstCharOfNode } from "./queries";

export const focusPreviousNode = editor => {
if (isFirstCharOfNode(editor)) {
const previousNode = getPreviousNode(editor);
if (previousNode && Inline.isInline(previousNode)) {
editor.moveToEndOfNode(previousNode).normalize(document);
}
}
};
92 changes: 31 additions & 61 deletions lib/index.js
@@ -1,74 +1,44 @@
import { Inline } from "slate";

export const isPrintableChar = event => event.key.length === 1;

export const isCtrlOrCmd = event => event.ctrlKey || event.metaKey;

const isSpace = event => event.key === " ";

const getSelection = change => change.value.fragment.text;

const getLastWordRec = (change, maxIndex, counter = 0) => {
// If first char of the input is found just select everything (single word)
if (counter === maxIndex) {
const selectedWord = getSelection(change);
change.extend(counter);
return selectedWord;
}

// Move selection
const selectedWord = getSelection(change.extend(-1));

// Exit condition
if (selectedWord[0] === " ") {
change.extend(counter + 1); // one more needed because space
return selectedWord.substring(1);
}

return getLastWordRec(change, maxIndex, counter + 1);
};

export const getLastWord = change => {
const offsetCurrentWord = change.value.focusOffset;
return getLastWordRec(change, offsetCurrentWord);
};

const getPreviousNode = change => {
const block = change.value.focusBlock;
const activeKey = change.value.selection.focusKey;
return block.getPreviousSibling(activeKey);
};

export const focusPreviousNode = change => {
const offsetCurrentWord = change.value.focusOffset;
// check if we just started a the node
if (offsetCurrentWord === 0) {
const previousNode = getPreviousNode(change);
if (previousNode && Inline.isInline(previousNode)) {
change.moveToRangeOf(previousNode);
change.collapseToEnd();
}
}
};
import {
getSelection,
getCurrentWordOffset,
getLastWord,
getPreviousNode,
isFirstCharOfNode,
} from "./queries";
import { focusPreviousNode } from "./commands";
import { isPrintableChar, isCtrlOrCmd, isSpace } from "./keyHelpers";

const InstantReplace = transforms => ({
onKeyDown(event, change) {
if (!isPrintableChar(event)) return;
queries: {
getSelection,
getCurrentWordOffset,
getLastWord,
getPreviousNode,
isFirstCharOfNode,
},
commands: {
focusPreviousNode,
},
onKeyDown(event, editor, next) {
if (!isPrintableChar(event)) return next();

// needed to handle space & control + key actions by default
// Needed to handle space & control + key actions by default
if (!isCtrlOrCmd(event)) {
if (!isSpace(event)) focusPreviousNode(change);
change.insertText(event.key);
// Focus previous node to make sure to write inside the previous Inline
if (!isSpace(event)) focusPreviousNode(editor);

// Insert the text manually
editor.insertText(event.key);

// Apply transforms
if (Array.isArray(transforms)) {
transforms.forEach(transform => {
const lastWord = getLastWord(change);
transform(change, lastWord);
const lastWord = getLastWord(editor);
transform(editor, lastWord);
});
} else if (transforms) {
const lastWord = getLastWord(change);
transforms(change, lastWord);
const lastWord = getLastWord(editor);
transforms(editor, lastWord);
}

// Prevent insertion of the char
Expand Down
5 changes: 5 additions & 0 deletions lib/keyHelpers.js
@@ -0,0 +1,5 @@
export const isPrintableChar = event => event.key.length === 1;

export const isCtrlOrCmd = event => event.ctrlKey || event.metaKey;

export const isSpace = event => event.key === " ";
37 changes: 37 additions & 0 deletions lib/queries.js
@@ -0,0 +1,37 @@
export const getSelection = editor => editor.value.fragment.text;

export const getCurrentWordOffset = editor =>
editor.value.selection.focus.offset;

export const isFirstCharOfNode = editor => getCurrentWordOffset(editor) === 0;

export const getPreviousNode = editor => {
const block = editor.value.focusBlock;
const focusKey = editor.value.selection.focus.key;
return block.getPreviousSibling(focusKey);
};

export const getLastWord = editor => {
const currentWordOffset = getCurrentWordOffset(editor);
return getLastWordRec(editor, currentWordOffset);
};

const getLastWordRec = (editor, maxIndex, counter = 0) => {
// If first char of the input is found just select everything (single word)
if (counter === maxIndex) {
const selectedWord = getSelection(editor);
editor.moveFocusForward(counter);
return selectedWord;
}

// Move selection
const selectedWord = getSelection(editor.moveFocusBackward(1));

// If we find a space it means previous chars are the last word !
if (selectedWord[0] === " ") {
editor.moveFocusForward(counter + 1); // one more needed because space
return selectedWord.substring(1);
}

return getLastWordRec(editor, maxIndex, counter + 1);
};

0 comments on commit 25503ac

Please sign in to comment.