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

Fix various editor bugs and upgrade latest Slate packages #1189

Merged
merged 7 commits into from
Jan 31, 2019
51 changes: 25 additions & 26 deletions packages/@sanity/form-builder/src/inputs/BlockEditor/SyncWrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -416,32 +416,31 @@ export default withPatchSubscriber(
const isDeprecated = deprecatedSchema || deprecatedBlockValue
return (
<div className={styles.root}>
{!isDeprecated &&
!invalidBlockValue && (
<Input
blockContentFeatures={this._blockContentFeatures}
controller={this._controller}
editorValue={editorValue}
focusPath={focusPath}
isLoading={isLoading}
level={level}
markers={markers}
onBlur={onBlur}
onChange={this.handleEditorChange}
onFocus={onFocus}
onLoading={this.handleOnLoading}
onPaste={onPaste}
onPatch={this.handleFormBuilderPatch}
readOnly={readOnly}
ref={this.refInput}
renderBlockActions={renderBlockActions}
renderCustomMarkers={renderCustomMarkers}
type={type}
undoRedoStack={this._undoRedoStack}
userIsWritingText={userIsWritingText}
value={value}
/>
)}
{!isDeprecated && !invalidBlockValue && (
<Input
blockContentFeatures={this._blockContentFeatures}
controller={this._controller}
editorValue={editorValue}
focusPath={focusPath}
isLoading={isLoading}
level={level}
markers={markers}
onBlur={onBlur}
onChange={this.handleEditorChange}
onFocus={onFocus}
onLoading={this.handleOnLoading}
onPaste={onPaste}
onPatch={this.handleFormBuilderPatch}
readOnly={readOnly}
ref={this.refInput}
renderBlockActions={renderBlockActions}
renderCustomMarkers={renderCustomMarkers}
type={type}
undoRedoStack={this._undoRedoStack}
userIsWritingText={userIsWritingText}
value={value}
/>
)}
{invalidBlockValue && (
<InvalidValueInput
validTypes={type.of ? type.of.map(mType => mType.name) : []}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,26 @@ type Props = {
export default class Markers extends React.Component<Props & SlateComponentProps> {
_clickCounter = 0
_clickTimeout = null
_clickMouseXY = {x: null, y: null}

handleMouseDown = () => {
// Prevent triple clicks for tangling with the block below
// This is a bug in Slate (Jan. 2019), and should be fixed there!
handleMouseDown = (event: SyntheticMouseEvent<>) => {
const mouseXWithinRange =
this._clickMouseXY.x && Math.abs(event.clientX - this._clickMouseXY.x) < 20
const mouseYWithinRange =
this._clickMouseXY.y && Math.abs(event.clientY - this._clickMouseXY.y) < 20
if (this._clickTimeout) {
clearTimeout(this._clickTimeout)
}
this._clickTimeout = setTimeout(() => {
if (this._clickCounter > 2) {
if (this._clickCounter > 2 && mouseXWithinRange && mouseYWithinRange) {
this.props.editor.moveToRangeOfNode(this.props.editor.value.anchorBlock)
}
this._clickCounter = 0
}, 500)
this._clickCounter++
this._clickMouseXY = {x: event.clientX, y: event.clientY}
}

render() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,20 +82,16 @@ export default function createOperationToPatches(
afterValue: SlateValue,
formBuilderValue: ?(FormBuilderValue[])
) {
const patches = []
// Make sure we have a document / start block first
if (!formBuilderValue || formBuilderValue.length === 0) {
const blocks = editorValueToBlocks(afterValue.toJSON(VALUE_TO_JSON_OPTS), blockContentType)
// Value is undefined
if (!formBuilderValue) {
patches.push(
setIfMissing(editorValueToBlocks(afterValue.toJSON(VALUE_TO_JSON_OPTS), blockContentType))
)
return [setIfMissing(blocks), set(blocks, [])]
}
// Value is empty
if (formBuilderValue && formBuilderValue.length === 0) {
patches.push(
set(editorValueToBlocks(afterValue.toJSON(VALUE_TO_JSON_OPTS), blockContentType), [])
)
return [set(blocks, [])]
}
}
const blockBefore = toBlock(beforeValue, operation.path.get(0))
Expand Down Expand Up @@ -131,7 +127,7 @@ export default function createOperationToPatches(
const targetInsertPath = targetPath
.slice(0, -2)
.concat({_key: blockAfter.children[spanIndex - 1]._key})
return patches.concat(insert([span], 'after', targetInsertPath))
return [insert([span], 'after', targetInsertPath)]
}
// Check if marks have changed and set the whole span with new marks if so
const point = {path: operation.path, offset: operation.offset + 1}
Expand All @@ -145,10 +141,10 @@ export default function createOperationToPatches(
.map(m => m.type)
.toArray()
if (!isEqual(textMarks, span.marks)) {
return patches.concat(set(span, targetPath.slice(0, -1)))
return [set(span, targetPath.slice(0, -1))]
}
// Marks not changed, just set the text
return patches.concat(set(span.text, targetPath))
return [set(span.text, targetPath)]
}

function setNodePatch(
Expand All @@ -157,25 +153,17 @@ export default function createOperationToPatches(
afterValue: SlateValue,
formBuilderValue: ?(FormBuilderValue[])
) {
const patches = []
const block = toBlock(afterValue, operation.path.get(0))
// Value is undefined
if (!formBuilderValue) {
patches.push(
setIfMissing(editorValueToBlocks(afterValue.toJSON(VALUE_TO_JSON_OPTS), blockContentType))
)
const blocks = editorValueToBlocks(afterValue.toJSON(VALUE_TO_JSON_OPTS), blockContentType)
return [setIfMissing(blocks), set(blocks)]
}
// Value is empty
if (formBuilderValue && formBuilderValue.length === 0) {
patches.push(
set(editorValueToBlocks(afterValue.toJSON(VALUE_TO_JSON_OPTS), blockContentType), [])
)
}
if (formBuilderValue && formBuilderValue.length > 0) {
patches.push(set(block, [{_key: block._key}]))
return [set(editorValueToBlocks(afterValue.toJSON(VALUE_TO_JSON_OPTS), blockContentType), [])]
}
// console.log(JSON.stringify(patches, null, 2))
return patches
const block = toBlock(afterValue, operation.path.get(0))
return [set(block, [{_key: block._key}])]
}

function insertNodePatch(
Expand All @@ -186,9 +174,8 @@ export default function createOperationToPatches(
) {
// Value is undefined
if (!formBuilderValue) {
return [
setIfMissing(editorValueToBlocks(afterValue.toJSON(VALUE_TO_JSON_OPTS), blockContentType))
]
const blocks = editorValueToBlocks(afterValue.toJSON(VALUE_TO_JSON_OPTS), blockContentType)
return [setIfMissing(blocks), set(blocks, [])]
}
// Value is empty
if (formBuilderValue && formBuilderValue.length === 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import {blocksToEditorValue} from '@sanity/block-tools'
import {Selection, Text, Mark} from 'slate'
import {isEqual, isString} from 'lodash'
import {List} from 'immutable'

import type {
BlockContentFeatures,
Expand Down Expand Up @@ -197,9 +196,11 @@ export default function createPatchesToChange(
delete data.annotations[annotationKey]
// If no more annotations, unwrap the inline
if (Object.keys(data.annotations).length === 0) {
return editor.unwrapInlineByKey(node.key)
editor.unwrapInlineByKey(node.key)
return editor.operations
}
return editor.setNodeByKey(node.key, {data})
editor.setNodeByKey(node.key, {data})
return editor.operations
}
const _patch = {...patch}
_patch.path = patch.path.slice(2)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[{
"_type": "block",
"_key": "13a7c69b9aa4",
"style": "normal",
"markDefs": [],
"children": [
{
"_type": "span",
"_key": "13a7c69b9aa40",
"text": "",
"marks": []
}
]
}]
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
[
{
"object": "operation",
"type": "insert_node",
"path": [
1
],
"node": {
"object": "block",
"type": "contentBlock",
"data": {
"_type": "block",
"_key": "a678262701f7",
"style": "normal"
},
"nodes": [
{
"object": "text",
"leaves": [
{
"object": "leaf",
"text": "B",
"marks": []
}
]
}
]
},
"data": {}
},
{
"object": "operation",
"type": "move_node",
"path": [
0,
0
],
"newPath": [
1,
1
],
"data": {}
},
{
"object": "operation",
"type": "remove_node",
"path": [
0
],
"data": {}
},
{
"object": "operation",
"type": "insert_node",
"path": [
0
],
"node": {
"object": "block",
"type": "contentBlock",
"data": {
"_type": "block",
"_key": "32758f62d727",
"style": "normal"
},
"nodes": [
{
"object": "text",
"leaves": [
{
"object": "leaf",
"text": "A",
"marks": []
}
]
}
]
},
"data": {}
},
{
"object": "operation",
"type": "merge_node",
"path": [
1,
1
],
"position": 1,
"properties": {
"data": {}
},
"target": null,
"data": {}
},
{
"object": "operation",
"type": "set_selection",
"properties": {
"anchor": {
"object": "point",
"offset": 0,
"path": [
1,
0
]
},
"focus": {
"object": "point",
"offset": 0,
"path": [
1,
0
]
}
},
"data": {}
},
{
"object": "operation",
"type": "set_selection",
"properties": {
"anchor": {
"object": "point",
"offset": 1,
"path": [
1,
0
]
}
},
"data": {}
},
{
"object": "operation",
"type": "set_selection",
"properties": {
"focus": {
"object": "point",
"offset": 1,
"path": [
1,
0
]
}
},
"data": {}
}
]