migrate from transform API to change API
This commit is contained in:
parent
8c04b4f1d5
commit
af2eb78e2b
@ -18,16 +18,16 @@ export default class RawEditor extends React.Component {
|
||||
return !this.state.editorState.equals(nextState.editorState);
|
||||
}
|
||||
|
||||
handleChange = editorState => {
|
||||
this.setState({ editorState });
|
||||
}
|
||||
handleChange = change => {
|
||||
this.setState({ editorState: change.state });
|
||||
};
|
||||
|
||||
/**
|
||||
* When the document value changes, serialize from Slate's AST back to plain
|
||||
* text (which is Markdown) and pass that up as the new value.
|
||||
*/
|
||||
handleDocumentChange = debounce((doc, editorState) => {
|
||||
const value = Plain.serialize(editorState);
|
||||
handleDocumentChange = debounce((doc, change) => {
|
||||
const value = Plain.serialize(change.state);
|
||||
this.props.onChange(value);
|
||||
}, 150);
|
||||
|
||||
@ -36,10 +36,10 @@ export default class RawEditor extends React.Component {
|
||||
* to the document. Selection logic (where to insert, whether to replace) is
|
||||
* handled by Slate.
|
||||
*/
|
||||
handlePaste = (e, data, state) => {
|
||||
handlePaste = (e, data, change) => {
|
||||
if (data.text) {
|
||||
const fragment = Plain.deserialize(data.text).document;
|
||||
return state.transform().insertFragment(fragment).apply();
|
||||
return change.insertFragment(fragment);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -35,17 +35,17 @@ export default class Editor extends Component {
|
||||
return !this.state.editorState.equals(nextState.editorState);
|
||||
}
|
||||
|
||||
handlePaste = (e, data, state) => {
|
||||
handlePaste = (e, data, change) => {
|
||||
if (data.type !== 'html' || data.isShift) {
|
||||
return;
|
||||
}
|
||||
const ast = htmlToSlate(data.html);
|
||||
const { document: doc } = Raw.deserialize(ast, { terse: true });
|
||||
return state.transform().insertFragment(doc).apply();
|
||||
return change.insertFragment(doc);
|
||||
}
|
||||
|
||||
handleDocumentChange = debounce((doc, editorState) => {
|
||||
const raw = Raw.serialize(editorState, { terse: true });
|
||||
handleDocumentChange = debounce((doc, change) => {
|
||||
const raw = Raw.serialize(change.state, { terse: true });
|
||||
const plugins = this.state.shortcodePlugins;
|
||||
const markdown = slateToMarkdown(raw, plugins);
|
||||
this.props.onChange(markdown);
|
||||
@ -56,21 +56,22 @@ export default class Editor extends Component {
|
||||
|
||||
handleMarkClick = (event, type) => {
|
||||
event.preventDefault();
|
||||
const resolvedState = this.state.editorState.transform().focus().toggleMark(type).apply();
|
||||
this.ref.onChange(resolvedState);
|
||||
this.setState({ editorState: resolvedState });
|
||||
const resolvedChange = this.state.editorState.change().focus().toggleMark(type);
|
||||
this.ref.onChange(resolvedChange);
|
||||
this.setState({ editorState: resolvedChange.state });
|
||||
};
|
||||
|
||||
handleBlockClick = (event, type) => {
|
||||
event.preventDefault();
|
||||
let { editorState } = this.state;
|
||||
const { document: doc, selection } = editorState;
|
||||
const transform = editorState.transform();
|
||||
const { unwrapList, wrapInList } = EditListConfigured.changes;
|
||||
let change = editorState.change();
|
||||
|
||||
// Handle everything except list buttons.
|
||||
if (!['bulleted-list', 'numbered-list'].includes(type)) {
|
||||
const isActive = this.hasBlock(type);
|
||||
const transformed = transform.setBlock(isActive ? 'paragraph' : type);
|
||||
change = change.setBlock(isActive ? 'paragraph' : type);
|
||||
}
|
||||
|
||||
// Handle the extra wrapping required for list buttons.
|
||||
@ -81,19 +82,18 @@ export default class Editor extends Component {
|
||||
const isInList = EditListConfigured.utils.isSelectionInList(editorState);
|
||||
|
||||
if (isInList && isSameListType) {
|
||||
EditListConfigured.transforms.unwrapList(transform, type);
|
||||
change = change.call(unwrapList, type);
|
||||
} else if (isInList) {
|
||||
const currentListType = type === 'bulleted-list' ? 'numbered-list' : 'bulleted-list';
|
||||
EditListConfigured.transforms.unwrapList(transform, currentListType);
|
||||
EditListConfigured.transforms.wrapInList(transform, type);
|
||||
change = change.call(unwrapList, currentListType).call(wrapInList, type);
|
||||
} else {
|
||||
EditListConfigured.transforms.wrapInList(transform, type);
|
||||
change = change.call(wrapInList, type);
|
||||
}
|
||||
}
|
||||
|
||||
const resolvedState = transform.focus().apply();
|
||||
this.ref.onChange(resolvedState);
|
||||
this.setState({ editorState: resolvedState });
|
||||
const resolvedChange = change.focus();
|
||||
this.ref.onChange(resolvedChange);
|
||||
this.setState({ editorState: resolvedChange.state });
|
||||
};
|
||||
|
||||
hasLinks = () => {
|
||||
@ -101,12 +101,12 @@ export default class Editor extends Component {
|
||||
};
|
||||
|
||||
handleLink = () => {
|
||||
let { editorState } = this.state;
|
||||
let change = this.state.editorState.change();
|
||||
|
||||
// If the current selection contains links, clicking the "link" button
|
||||
// should simply unlink them.
|
||||
if (this.hasLinks()) {
|
||||
editorState = editorState.transform().unwrapInline('link').apply();
|
||||
change = change.unwrapInline('link');
|
||||
}
|
||||
|
||||
else {
|
||||
@ -115,23 +115,20 @@ export default class Editor extends Component {
|
||||
// If nothing is entered in the URL prompt, do nothing.
|
||||
if (!url) return;
|
||||
|
||||
let transform = editorState.transform();
|
||||
|
||||
// If no text is selected, use the entered URL as text.
|
||||
if (editorState.isCollapsed) {
|
||||
transform = transform
|
||||
if (change.state.isCollapsed) {
|
||||
change = change
|
||||
.insertText(url)
|
||||
.extend(0 - url.length);
|
||||
}
|
||||
|
||||
editorState = transform
|
||||
change = change
|
||||
.wrapInline({ type: 'link', data: { url } })
|
||||
.collapseToEnd()
|
||||
.apply();
|
||||
.collapseToEnd();
|
||||
}
|
||||
|
||||
this.ref.onChange(editorState);
|
||||
this.setState({ editorState });
|
||||
this.ref.onChange(change);
|
||||
this.setState({ editorState: change.state });
|
||||
};
|
||||
|
||||
handlePluginSubmit = (plugin, shortcodeData) => {
|
||||
@ -142,9 +139,9 @@ export default class Editor extends Component {
|
||||
};
|
||||
const nodes = [Text.createFromString('')];
|
||||
const block = { kind: 'block', type: 'shortcode', data, isVoid: true, nodes };
|
||||
const resolvedState = editorState.transform().insertBlock(block).focus().apply();
|
||||
this.ref.onChange(resolvedState);
|
||||
this.setState({ editorState: resolvedState });
|
||||
const resolvedChange = editorState.change().insertBlock(block).focus();
|
||||
this.ref.onChange(resolvedChange);
|
||||
this.setState({ editorState: resolvedChange.state });
|
||||
};
|
||||
|
||||
handleToggle = () => {
|
||||
@ -158,6 +155,10 @@ export default class Editor extends Component {
|
||||
return { onAction: e => handler(e, type), active: isActive(type) };
|
||||
};
|
||||
|
||||
handleChange = change => {
|
||||
this.setState({ editorState: change.state });
|
||||
};
|
||||
|
||||
render() {
|
||||
const { onAddAsset, onRemoveAsset, getAsset } = this.props;
|
||||
|
||||
@ -194,7 +195,7 @@ export default class Editor extends Component {
|
||||
state={this.state.editorState}
|
||||
schema={this.state.schema}
|
||||
plugins={plugins}
|
||||
onChange={editorState => this.setState({ editorState })}
|
||||
onChange={this.handleChange}
|
||||
onDocumentChange={this.handleDocumentChange}
|
||||
onKeyDown={onKeyDown}
|
||||
onPaste={this.handlePaste}
|
||||
|
@ -2,7 +2,7 @@ import { Block, Text } from 'slate';
|
||||
|
||||
export default onKeyDown;
|
||||
|
||||
function onKeyDown(e, data, state) {
|
||||
function onKeyDown(e, data, change) {
|
||||
const createDefaultBlock = () => {
|
||||
return Block.create({
|
||||
type: 'paragraph',
|
||||
@ -18,7 +18,7 @@ function onKeyDown(e, data, state) {
|
||||
* If the selected block is the first block in the document, create the
|
||||
* new block above it. If not, create the new block below it.
|
||||
*/
|
||||
const { document: doc, selection, anchorBlock, focusBlock } = state;
|
||||
const { document: doc, selection, anchorBlock, focusBlock } = change.state;
|
||||
const singleBlockSelected = anchorBlock === focusBlock;
|
||||
if (!singleBlockSelected || !focusBlock.isVoid) return;
|
||||
|
||||
@ -31,10 +31,9 @@ function onKeyDown(e, data, state) {
|
||||
const newBlock = createDefaultBlock();
|
||||
const newBlockIndex = focusBlockIsFirstChild ? 0 : focusBlockIndex + 1;
|
||||
|
||||
return state.transform()
|
||||
return change
|
||||
.insertNodeByKey(focusBlockParent.key, newBlockIndex, newBlock)
|
||||
.collapseToStartOf(newBlock)
|
||||
.apply();
|
||||
.collapseToStartOf(newBlock);
|
||||
}
|
||||
|
||||
if (data.isMod) {
|
||||
@ -61,7 +60,7 @@ function onKeyDown(e, data, state) {
|
||||
|
||||
if (mark) {
|
||||
e.preventDefault();
|
||||
return state.transform().toggleMark(mark).apply();
|
||||
return change.toggleMark(mark);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -4,31 +4,30 @@ import EditList from 'slate-edit-list';
|
||||
import EditTable from 'slate-edit-table';
|
||||
|
||||
const SoftBreak = (options = {}) => ({
|
||||
onKeyDown(e, data, state) {
|
||||
onKeyDown(e, data, change) {
|
||||
if (data.key != 'enter') return;
|
||||
if (options.shift && e.shiftKey == false) return;
|
||||
|
||||
const { onlyIn, ignoreIn, closeAfter, unwrapBlocks, defaultBlock = 'paragraph' } = options;
|
||||
const { type, nodes } = state.startBlock;
|
||||
const { type, nodes } = change.state.startBlock;
|
||||
if (onlyIn && !onlyIn.includes(type)) return;
|
||||
if (ignoreIn && ignoreIn.includes(type)) return;
|
||||
|
||||
const shouldClose = nodes.last().characters.takeLast(closeAfter).every(c => c.text === '\n');
|
||||
if (closeAfter && shouldClose) {
|
||||
const trimmed = state.transform().deleteBackward(closeAfter);
|
||||
const trimmed = change.deleteBackward(closeAfter);
|
||||
const unwrapped = unwrapBlocks
|
||||
? unwrapBlocks.reduce((acc, blockType) => acc.unwrapBlock(blockType), trimmed)
|
||||
: trimmed;
|
||||
return unwrapped.insertBlock(defaultBlock).apply();
|
||||
return unwrapped.insertBlock(defaultBlock);
|
||||
}
|
||||
|
||||
const textNode = Text.createFromString('\n');
|
||||
const breakNode = Inline.create({ type: 'break', nodes: [ textNode ] });
|
||||
return state.transform()
|
||||
return change
|
||||
.insertInline(breakNode)
|
||||
.insertText('')
|
||||
.collapseToStartOfNextText()
|
||||
.apply();
|
||||
.collapseToStartOfNextText();
|
||||
}
|
||||
});
|
||||
|
||||
@ -42,10 +41,11 @@ export const SoftBreakConfigured = SoftBreak(SoftBreakOpts);
|
||||
export const ParagraphSoftBreakConfigured = SoftBreak({ onlyIn: ['paragraph'], shift: true });
|
||||
|
||||
const BreakToDefaultBlock = ({ onlyIn = [], defaultBlock = 'paragraph' }) => ({
|
||||
onKeyDown(e, data, state) {
|
||||
onKeyDown(e, data, change) {
|
||||
const { state } = change;
|
||||
if (data.key != 'enter' || e.shiftKey == true || state.isExpanded) return;
|
||||
if (onlyIn.includes(state.startBlock.type)) {
|
||||
return state.transform().insertBlock(defaultBlock).apply();
|
||||
return change.insertBlock(defaultBlock);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -57,11 +57,11 @@ const BreakToDefaultBlockOpts = {
|
||||
export const BreakToDefaultBlockConfigured = BreakToDefaultBlock(BreakToDefaultBlockOpts);
|
||||
|
||||
const BackspaceCloseBlock = (options = {}) => ({
|
||||
onKeyDown(e, data, state) {
|
||||
onKeyDown(e, data, change) {
|
||||
if (data.key != 'backspace') return;
|
||||
|
||||
const { defaultBlock = 'paragraph', ignoreIn, onlyIn } = options;
|
||||
const { startBlock } = state;
|
||||
const { startBlock } = change.state;
|
||||
const { type } = startBlock;
|
||||
|
||||
if (onlyIn && !onlyIn.includes(type)) return;
|
||||
@ -71,7 +71,7 @@ const BackspaceCloseBlock = (options = {}) => ({
|
||||
const isEmpty = !characters || characters.isEmpty();
|
||||
|
||||
if (isEmpty) {
|
||||
return state.transform().insertBlock(defaultBlock).focus().apply();
|
||||
return change.insertBlock(defaultBlock).focus();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -15,13 +15,13 @@ const enforceNeverEmpty = {
|
||||
const hasBlocks = !doc.getBlocks().isEmpty();
|
||||
return hasBlocks ? null : {};
|
||||
},
|
||||
normalize: transform => {
|
||||
normalize: change => {
|
||||
const block = Block.create({
|
||||
type: 'paragraph',
|
||||
nodes: [Text.createFromString('')],
|
||||
});
|
||||
const { key } = transform.state.document;
|
||||
return transform.insertNodeByKey(key, 0, block).focus();
|
||||
const { key } = change.state.document;
|
||||
return change.insertNodeByKey(key, 0, block).focus();
|
||||
},
|
||||
};
|
||||
|
||||
@ -35,8 +35,8 @@ const shortcodesAtRoot = {
|
||||
return node.type === 'shortcode' && doc.getParent(node.key).key !== doc.key;
|
||||
});
|
||||
},
|
||||
normalize: (transform, doc, node) => {
|
||||
return transform.unwrapNodeByKey(node.key);
|
||||
normalize: (change, doc, node) => {
|
||||
return change.unwrapNodeByKey(node.key);
|
||||
},
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user