1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-08-30 10:29:48 +02:00

fix selection setting for history

This commit is contained in:
Ian Storm Taylor
2016-09-10 17:12:45 -07:00
parent 52c6bb9596
commit 521f0d9f1d
8 changed files with 90 additions and 26 deletions

View File

@@ -99,6 +99,16 @@ class Selection extends new Record(DEFAULTS) {
return this.isBackward == null ? null : !this.isBackward
}
/**
* Check whether the selection's keys are not set.
*
* @return {Boolean}
*/
get isUnset() {
return this.anchorKey == null || this.focusKey == null
}
/**
* Get the start key.
*
@@ -281,19 +291,18 @@ class Selection extends new Record(DEFAULTS) {
const { isCollapsed } = selection
let { anchorKey, anchorOffset, focusKey, focusOffset, isBackward } = selection
// If the selection isn't formed yet or is malformed, set it to the
// beginning of the node.
// If the selection isn't formed yet or is malformed, ensure that it is
// properly zeroed out.
if (
anchorKey == null ||
focusKey == null ||
!node.hasDescendant(anchorKey) ||
!node.hasDescendant(focusKey)
) {
const first = node.getTexts().first()
return selection.merge({
anchorKey: first.key,
anchorKey: null,
anchorOffset: 0,
focusKey: first.key,
focusKey: null,
focusOffset: 0,
isBackward: false
})

View File

@@ -42,9 +42,16 @@ class State extends new Record(DEFAULTS) {
static create(properties = {}) {
if (properties instanceof State) return properties
properties.document = Document.create(properties.document)
properties.selection = Selection.create(properties.selection).normalize(properties.document)
return new State(properties)
let document = Document.create(properties.document)
let selection = Selection.create(properties.selection)
if (selection.isUnset) {
const text = document.getTexts().first()
selection = selection.collapseToStartOf(text)
}
return new State({ document, selection })
}
/**

View File

@@ -281,15 +281,17 @@ function setSelection(state, operation) {
let properties = { ...operation.properties }
let { document, selection } = state
if (properties.anchorPath) {
const anchorNode = document.assertPath(properties.anchorPath)
properties.anchorKey = anchorNode.key
if (properties.anchorPath !== undefined) {
properties.anchorKey = properties.anchorPath === null
? null
: document.assertPath(properties.anchorPath).key
delete properties.anchorPath
}
if (properties.focusPath) {
const focusNode = document.assertPath(properties.focusPath)
properties.focusKey = focusNode.key
if (properties.focusPath !== undefined) {
properties.focusKey = properties.focusPath === null
? null
: document.assertPath(properties.focusPath).key
delete properties.focusPath
}

View File

@@ -80,6 +80,7 @@ export function _delete(transform) {
}
return transform
.unsetSelection()
.deleteAtRange(selection)
.moveTo(after)
}
@@ -154,6 +155,7 @@ export function deleteBackward(transform, n = 1) {
}
return transform
.unsetSelection()
.deleteBackwardAtRange(selection, n)
.moveTo(after)
}
@@ -213,6 +215,7 @@ export function deleteForward(transform, n = 1) {
}
return transform
.unsetSelection()
.deleteForwardAtRange(selection, n)
.moveTo(after)
}
@@ -230,6 +233,7 @@ export function insertBlock(transform, block) {
let { document, selection } = state
const keys = document.getTexts().map(text => text.key)
transform.unsetSelection()
transform.insertBlockAtRange(selection, block)
state = transform.state
document = state.document
@@ -258,6 +262,7 @@ export function insertFragment(transform, fragment) {
const lastInline = fragment.getClosestInline(lastText)
const beforeTexts = document.getTexts()
transform.unsetSelection()
transform.insertFragmentAtRange(selection, fragment)
state = transform.state
document = state.document
@@ -306,6 +311,7 @@ export function insertInline(transform, inline) {
const hasVoid = document.hasVoidParent(startText)
const keys = document.getTexts().map(text => text.key)
transform.unsetSelection()
transform.insertInlineAtRange(selection, inline)
state = transform.state
document = state.document
@@ -353,6 +359,7 @@ export function insertText(transform, text, marks) {
marks = marks || selection.marks
return transform
.unsetSelection()
.insertTextAtRange(selection, text, marks)
.moveTo(after)
}
@@ -397,6 +404,7 @@ export function splitBlock(transform, depth = 1) {
let { state } = transform
let { document, selection } = state
transform.unsetSelection()
transform.splitBlockAtRange(selection, depth)
state = transform.state
@@ -423,6 +431,7 @@ export function splitInline(transform, depth = Infinity) {
let { document, selection } = state
let after = selection
transform.unsetSelection()
transform.splitInlineAtRange(selection, depth)
state = transform.state
document = state.document
@@ -551,6 +560,7 @@ export function wrapInline(transform, properties) {
const { startKey } = selection
const previous = document.getPreviousText(startKey)
transform.unsetSelection()
transform.wrapInlineAtRange(selection, properties)
state = transform.state
document = state.document
@@ -612,6 +622,7 @@ export function wrapText(transform, prefix, suffix = prefix) {
}
return transform
.unsetSelection()
.wrapTextAtRange(selection, prefix, suffix)
.moveTo(after)
}

View File

@@ -124,6 +124,7 @@ import {
moveTo,
moveToOffsets,
moveToRangeOf,
unsetSelection,
} from './on-selection'
/**
@@ -267,6 +268,7 @@ export default {
moveTo,
moveToOffsets,
moveToRangeOf,
unsetSelection,
/**
* History.

View File

@@ -364,6 +364,7 @@ export function moveForward(transform, n) {
*/
export function moveTo(transform, properties) {
debugger
return transform.setSelectionOperation(properties)
}
@@ -398,3 +399,21 @@ export function moveToRangeOf(transform, start, end) {
const sel = selection.moveToRangeOf(start, end).normalize(document)
return transform.setSelectionOperation(sel)
}
/**
* Unset the selection, removing an association to a node.
*
* @param {Transform} transform
* @return {Transform}
*/
export function unsetSelection(transform) {
return transform.setSelectionOperation({
anchorKey: null,
anchorOffset: 0,
focusKey: null,
focusOffset: 0,
isFocused: false,
isBackward: false
})
}

View File

@@ -361,39 +361,53 @@ export function setSelectionOperation(transform, properties) {
const { document, selection } = state
const prevProps = {}
if (properties.marks == selection.marks) {
// If the current selection has marks, and the new selection doesn't change
// them in some way, they are old and should be removed.
if (selection.marks && properties.marks == selection.marks) {
properties.marks = null
}
// Create a dictionary of the previous values for all of the properties that
// are being changed, for the inverse operation.
for (const k in properties) {
prevProps[k] = selection[k]
}
// Resolve the selection keys into paths.
if (properties.anchorKey) {
properties.anchorPath = document.getPath(properties.anchorKey)
prevProps.anchorPath = document.getPath(prevProps.anchorKey)
delete properties.anchorKey
}
if (prevProps.anchorKey) {
prevProps.anchorPath = document.getPath(prevProps.anchorKey)
delete prevProps.anchorKey
}
if (properties.focusKey) {
properties.focusPath = document.getPath(properties.focusKey)
prevProps.focusPath = document.getPath(prevProps.focusKey)
delete properties.focusKey
}
if (prevProps.focusKey) {
prevProps.focusPath = document.getPath(prevProps.focusKey)
delete prevProps.focusKey
}
// Define an inverse of the operation for undoing.
const inverse = [{
type: 'set_selection',
properties: prevProps
}]
// Define the operation.
const operation = {
type: 'set_selection',
properties,
inverse,
}
// Apply the operation.
return transform.applyOperation(operation)
}

View File

@@ -107,7 +107,7 @@ function markProperties(value = {}) {
case 'object': {
for (const k in value) {
if (k == 'data') {
if (value[k] != null) ret[k] = Data.create(value[k])
if (value[k] !== undefined) ret[k] = Data.create(value[k])
} else {
ret[k] = value[k]
}
@@ -138,10 +138,10 @@ function nodeProperties(value = {}) {
break
}
case 'object': {
if (value.isVoid != null) ret.isVoid = !!value.isVoid
if (value.isVoid !== undefined) ret.isVoid = !!value.isVoid
for (const k in value) {
if (k == 'data') {
if (value[k] != null) ret[k] = Data.create(value[k])
if (value[k] !== undefined) ret[k] = Data.create(value[k])
} else {
ret[k] = value[k]
}
@@ -188,12 +188,12 @@ function selectionProperties(value = {}) {
switch (typeOf(value)) {
case 'object': {
if (value.anchorKey != null) ret.anchorKey = value.anchorKey
if (value.anchorOffset != null) ret.anchorOffset = value.anchorOffset
if (value.focusKey != null) ret.focusKey = value.focusKey
if (value.focusOffset != null) ret.focusOffset = value.focusOffset
if (value.isBackward != null) ret.isBackward = !!value.isBackward
if (value.isFocused != null) ret.isFocused = !!value.isFocused
if (value.anchorKey !== undefined) ret.anchorKey = value.anchorKey
if (value.anchorOffset !== undefined) ret.anchorOffset = value.anchorOffset
if (value.focusKey !== undefined) ret.focusKey = value.focusKey
if (value.focusOffset !== undefined) ret.focusOffset = value.focusOffset
if (value.isBackward !== undefined) ret.isBackward = !!value.isBackward
if (value.isFocused !== undefined) ret.isFocused = !!value.isFocused
if (value.marks !== undefined) ret.marks = value.marks
break
}