mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-30 10:29:48 +02:00
add insertInline with tests
This commit is contained in:
@@ -99,11 +99,24 @@ Delete forward `n` characters at the current cursor. If the selection is expande
|
|||||||
|
|
||||||
Delete everything in the current selection.
|
Delete everything in the current selection.
|
||||||
|
|
||||||
|
### `insertBlock`
|
||||||
|
`insertBlock(block: Block) => Transform`
|
||||||
|
`insertBlock(properties: Object) => Transform`
|
||||||
|
`insertBlock(type: String) => Transform`
|
||||||
|
|
||||||
|
Insert a new block at the same level as the current block, splitting the current block to make room if it is non-empty. If the selection is expanded, it will be deleted first.
|
||||||
|
|
||||||
### `insertFragment`
|
### `insertFragment`
|
||||||
`insertFragment(fragment: Document) => Transform`
|
`insertFragment(fragment: Document) => Transform`
|
||||||
|
|
||||||
Insert a `fragment` at the current selection. If the selection is expanded, it will be deleted first.
|
Insert a `fragment` at the current selection. If the selection is expanded, it will be deleted first.
|
||||||
|
|
||||||
|
### `insertInline`
|
||||||
|
`insertInline(inline: Inline) => Transform`
|
||||||
|
`insertInline(properties: Object) => Transform`
|
||||||
|
|
||||||
|
Insert a new inline at the current cursor position, splitting the text to make room if it is non-empty. If the selection is expanded, it will be deleted first.
|
||||||
|
|
||||||
### `insertText`
|
### `insertText`
|
||||||
`insertText(text: String) => Transform`
|
`insertText(text: String) => Transform`
|
||||||
|
|
||||||
@@ -267,11 +280,24 @@ Delete forward `n` characters at a `range`. If the `range` is expanded, this met
|
|||||||
|
|
||||||
Delete everything in a `range`.
|
Delete everything in a `range`.
|
||||||
|
|
||||||
|
### `insertBlockAtRange`
|
||||||
|
`insertBlockAtRange(range: Selection, block: Block) => Transform`
|
||||||
|
`insertBlockAtRange(range: Selection, properties: Object) => Transform`
|
||||||
|
`insertBlockAtRange(range: Selection, type: String) => Transform`
|
||||||
|
|
||||||
|
Insert a new block at the same level as the leaf block at a `range`, splitting the current block to make room if it is non-empty. If the selection is expanded, it will be deleted first.
|
||||||
|
|
||||||
### `insertFragmentAtRange`
|
### `insertFragmentAtRange`
|
||||||
`insertFragmentAtRange(range: Selection, fragment: Document) => Transform`
|
`insertFragmentAtRange(range: Selection, fragment: Document) => Transform`
|
||||||
|
|
||||||
Insert a `fragment` at a `range`. If the selection is expanded, it will be deleted first.
|
Insert a `fragment` at a `range`. If the selection is expanded, it will be deleted first.
|
||||||
|
|
||||||
|
### `insertInlineAtRange`
|
||||||
|
`insertInlineAtRange(range: Selection, inline: Inline) => Transform`
|
||||||
|
`insertInlineAtRange(range: Selection, properties: Object) => Transform`
|
||||||
|
|
||||||
|
Insert a new inline at a `range`, splitting the text to make room if it is non-empty. If the selection is expanded, it will be deleted first.
|
||||||
|
|
||||||
### `insertTextAtRange`
|
### `insertTextAtRange`
|
||||||
`insertTextAtRange(range: Selection, text: String) => Transform`
|
`insertTextAtRange(range: Selection, text: String) => Transform`
|
||||||
|
|
||||||
|
@@ -827,6 +827,38 @@ class State extends new Record(DEFAULTS) {
|
|||||||
return state
|
return state
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert a `inline` at the current selection.
|
||||||
|
*
|
||||||
|
* @param {String || Object || Block} inline
|
||||||
|
* @return {State} state
|
||||||
|
*/
|
||||||
|
|
||||||
|
insertInline(inline) {
|
||||||
|
let state = this
|
||||||
|
let { document, selection, startText } = state
|
||||||
|
let after = selection
|
||||||
|
const hasVoid = document.hasVoidParent(startText)
|
||||||
|
|
||||||
|
// Insert the inline
|
||||||
|
document = document.insertInlineAtRange(selection, inline)
|
||||||
|
|
||||||
|
// Determine what the selection should be after inserting.
|
||||||
|
if (hasVoid) {
|
||||||
|
selection = selection
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
const keys = state.document.getTexts().map(text => text.key)
|
||||||
|
const text = document.getTexts().find(n => !keys.includes(n.key))
|
||||||
|
selection = selection.collapseToEndOf(text)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the document and selection.
|
||||||
|
state = state.merge({ document, selection })
|
||||||
|
return state
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert a `text` string at the current selection.
|
* Insert a `text` string at the current selection.
|
||||||
*
|
*
|
||||||
|
@@ -0,0 +1,20 @@
|
|||||||
|
|
||||||
|
export default function (state) {
|
||||||
|
const { document, selection } = state
|
||||||
|
const texts = document.getTexts()
|
||||||
|
const first = texts.first()
|
||||||
|
const range = selection.merge({
|
||||||
|
anchorKey: first.key,
|
||||||
|
anchorOffset: 2,
|
||||||
|
focusKey: first.key,
|
||||||
|
focusOffset: 2
|
||||||
|
})
|
||||||
|
|
||||||
|
return state
|
||||||
|
.transform()
|
||||||
|
.insertInlineAtRange(range, {
|
||||||
|
type: 'image',
|
||||||
|
isVoid: true
|
||||||
|
})
|
||||||
|
.apply()
|
||||||
|
}
|
@@ -0,0 +1,10 @@
|
|||||||
|
|
||||||
|
nodes:
|
||||||
|
- kind: block
|
||||||
|
type: paragraph
|
||||||
|
nodes:
|
||||||
|
- kind: inline
|
||||||
|
type: link
|
||||||
|
nodes:
|
||||||
|
- kind: text
|
||||||
|
text: word
|
@@ -0,0 +1,15 @@
|
|||||||
|
|
||||||
|
nodes:
|
||||||
|
- kind: block
|
||||||
|
type: paragraph
|
||||||
|
nodes:
|
||||||
|
- kind: inline
|
||||||
|
type: link
|
||||||
|
nodes:
|
||||||
|
- kind: text
|
||||||
|
text: wo
|
||||||
|
- kind: inline
|
||||||
|
type: image
|
||||||
|
isVoid: true
|
||||||
|
- kind: text
|
||||||
|
text: rd
|
32
test/transforms/fixtures/insert-inline/block-end/index.js
Normal file
32
test/transforms/fixtures/insert-inline/block-end/index.js
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
|
||||||
|
import assert from 'assert'
|
||||||
|
|
||||||
|
export default function (state) {
|
||||||
|
const { document, selection } = state
|
||||||
|
const texts = document.getTexts()
|
||||||
|
const first = texts.first()
|
||||||
|
const range = selection.merge({
|
||||||
|
anchorKey: first.key,
|
||||||
|
anchorOffset: first.length,
|
||||||
|
focusKey: first.key,
|
||||||
|
focusOffset: first.length
|
||||||
|
})
|
||||||
|
|
||||||
|
const next = state
|
||||||
|
.transform()
|
||||||
|
.moveTo(range)
|
||||||
|
.insertInline({
|
||||||
|
type: 'hashtag',
|
||||||
|
isVoid: true
|
||||||
|
})
|
||||||
|
.apply()
|
||||||
|
|
||||||
|
const updated = next.document.getTexts().last()
|
||||||
|
|
||||||
|
assert.deepEqual(
|
||||||
|
next.selection.toJS(),
|
||||||
|
range.collapseToEndOf(updated).toJS()
|
||||||
|
)
|
||||||
|
|
||||||
|
return next
|
||||||
|
}
|
@@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
nodes:
|
||||||
|
- kind: block
|
||||||
|
type: paragraph
|
||||||
|
nodes:
|
||||||
|
- kind: text
|
||||||
|
text: word
|
10
test/transforms/fixtures/insert-inline/block-end/output.yaml
Normal file
10
test/transforms/fixtures/insert-inline/block-end/output.yaml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
|
||||||
|
nodes:
|
||||||
|
- kind: block
|
||||||
|
type: paragraph
|
||||||
|
nodes:
|
||||||
|
- kind: text
|
||||||
|
text: word
|
||||||
|
- kind: inline
|
||||||
|
type: hashtag
|
||||||
|
isVoid: true
|
32
test/transforms/fixtures/insert-inline/block-middle/index.js
Normal file
32
test/transforms/fixtures/insert-inline/block-middle/index.js
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
|
||||||
|
import assert from 'assert'
|
||||||
|
|
||||||
|
export default function (state) {
|
||||||
|
const { document, selection } = state
|
||||||
|
const texts = document.getTexts()
|
||||||
|
const first = texts.first()
|
||||||
|
const range = selection.merge({
|
||||||
|
anchorKey: first.key,
|
||||||
|
anchorOffset: 2,
|
||||||
|
focusKey: first.key,
|
||||||
|
focusOffset: 2
|
||||||
|
})
|
||||||
|
|
||||||
|
const next = state
|
||||||
|
.transform()
|
||||||
|
.moveTo(range)
|
||||||
|
.insertInline({
|
||||||
|
type: 'hashtag',
|
||||||
|
isVoid: true
|
||||||
|
})
|
||||||
|
.apply()
|
||||||
|
|
||||||
|
const updated = next.document.getTexts().get(1)
|
||||||
|
|
||||||
|
assert.deepEqual(
|
||||||
|
next.selection.toJS(),
|
||||||
|
range.collapseToEndOf(updated).toJS()
|
||||||
|
)
|
||||||
|
|
||||||
|
return next
|
||||||
|
}
|
@@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
nodes:
|
||||||
|
- kind: block
|
||||||
|
type: paragraph
|
||||||
|
nodes:
|
||||||
|
- kind: text
|
||||||
|
text: word
|
@@ -0,0 +1,12 @@
|
|||||||
|
|
||||||
|
nodes:
|
||||||
|
- kind: block
|
||||||
|
type: paragraph
|
||||||
|
nodes:
|
||||||
|
- kind: text
|
||||||
|
text: wo
|
||||||
|
- kind: inline
|
||||||
|
type: hashtag
|
||||||
|
isVoid: true
|
||||||
|
- kind: text
|
||||||
|
text: rd
|
32
test/transforms/fixtures/insert-inline/block-start/index.js
Normal file
32
test/transforms/fixtures/insert-inline/block-start/index.js
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
|
||||||
|
import assert from 'assert'
|
||||||
|
|
||||||
|
export default function (state) {
|
||||||
|
const { document, selection } = state
|
||||||
|
const texts = document.getTexts()
|
||||||
|
const first = texts.first()
|
||||||
|
const range = selection.merge({
|
||||||
|
anchorKey: first.key,
|
||||||
|
anchorOffset: 0,
|
||||||
|
focusKey: first.key,
|
||||||
|
focusOffset: 0
|
||||||
|
})
|
||||||
|
|
||||||
|
const next = state
|
||||||
|
.transform()
|
||||||
|
.moveTo(range)
|
||||||
|
.insertInline({
|
||||||
|
type: 'hashtag',
|
||||||
|
isVoid: true
|
||||||
|
})
|
||||||
|
.apply()
|
||||||
|
|
||||||
|
const updated = next.document.getTexts().first()
|
||||||
|
|
||||||
|
assert.deepEqual(
|
||||||
|
next.selection.toJS(),
|
||||||
|
range.collapseToEndOf(updated).toJS()
|
||||||
|
)
|
||||||
|
|
||||||
|
return next
|
||||||
|
}
|
@@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
nodes:
|
||||||
|
- kind: block
|
||||||
|
type: paragraph
|
||||||
|
nodes:
|
||||||
|
- kind: text
|
||||||
|
text: word
|
@@ -0,0 +1,10 @@
|
|||||||
|
|
||||||
|
nodes:
|
||||||
|
- kind: block
|
||||||
|
type: paragraph
|
||||||
|
nodes:
|
||||||
|
- kind: inline
|
||||||
|
type: hashtag
|
||||||
|
isVoid: true
|
||||||
|
- kind: text
|
||||||
|
text: word
|
@@ -0,0 +1,32 @@
|
|||||||
|
|
||||||
|
import assert from 'assert'
|
||||||
|
|
||||||
|
export default function (state) {
|
||||||
|
const { document, selection } = state
|
||||||
|
const texts = document.getTexts()
|
||||||
|
const first = texts.first()
|
||||||
|
const range = selection.merge({
|
||||||
|
anchorKey: first.key,
|
||||||
|
anchorOffset: 2,
|
||||||
|
focusKey: first.key,
|
||||||
|
focusOffset: 2
|
||||||
|
})
|
||||||
|
|
||||||
|
const next = state
|
||||||
|
.transform()
|
||||||
|
.moveTo(range)
|
||||||
|
.insertInline({
|
||||||
|
type: 'image',
|
||||||
|
isVoid: true
|
||||||
|
})
|
||||||
|
.apply()
|
||||||
|
|
||||||
|
const updated = next.document.getTexts().get(1)
|
||||||
|
|
||||||
|
assert.deepEqual(
|
||||||
|
next.selection.toJS(),
|
||||||
|
range.collapseToEndOf(updated).toJS()
|
||||||
|
)
|
||||||
|
|
||||||
|
return next
|
||||||
|
}
|
@@ -0,0 +1,10 @@
|
|||||||
|
|
||||||
|
nodes:
|
||||||
|
- kind: block
|
||||||
|
type: paragraph
|
||||||
|
nodes:
|
||||||
|
- kind: inline
|
||||||
|
type: link
|
||||||
|
nodes:
|
||||||
|
- kind: text
|
||||||
|
text: word
|
@@ -0,0 +1,15 @@
|
|||||||
|
|
||||||
|
nodes:
|
||||||
|
- kind: block
|
||||||
|
type: paragraph
|
||||||
|
nodes:
|
||||||
|
- kind: inline
|
||||||
|
type: link
|
||||||
|
nodes:
|
||||||
|
- kind: text
|
||||||
|
text: wo
|
||||||
|
- kind: inline
|
||||||
|
type: image
|
||||||
|
isVoid: true
|
||||||
|
- kind: text
|
||||||
|
text: rd
|
32
test/transforms/fixtures/insert-inline/is-empty/index.js
Normal file
32
test/transforms/fixtures/insert-inline/is-empty/index.js
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
|
||||||
|
import assert from 'assert'
|
||||||
|
|
||||||
|
export default function (state) {
|
||||||
|
const { document, selection } = state
|
||||||
|
const texts = document.getTexts()
|
||||||
|
const first = texts.first()
|
||||||
|
const range = selection.merge({
|
||||||
|
anchorKey: first.key,
|
||||||
|
anchorOffset: 0,
|
||||||
|
focusKey: first.key,
|
||||||
|
focusOffset: 0
|
||||||
|
})
|
||||||
|
|
||||||
|
const next = state
|
||||||
|
.transform()
|
||||||
|
.moveTo(range)
|
||||||
|
.insertInline({
|
||||||
|
type: 'hashtag',
|
||||||
|
isVoid: true
|
||||||
|
})
|
||||||
|
.apply()
|
||||||
|
|
||||||
|
const updated = next.document.getTexts().last()
|
||||||
|
|
||||||
|
assert.deepEqual(
|
||||||
|
next.selection.toJS(),
|
||||||
|
range.collapseToEndOf(updated).toJS()
|
||||||
|
)
|
||||||
|
|
||||||
|
return next
|
||||||
|
}
|
@@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
nodes:
|
||||||
|
- kind: block
|
||||||
|
type: paragraph
|
||||||
|
nodes:
|
||||||
|
- kind: text
|
||||||
|
text: ""
|
@@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
nodes:
|
||||||
|
- kind: block
|
||||||
|
type: paragraph
|
||||||
|
nodes:
|
||||||
|
- kind: inline
|
||||||
|
type: hashtag
|
||||||
|
isVoid: true
|
30
test/transforms/fixtures/insert-inline/is-void/index.js
Normal file
30
test/transforms/fixtures/insert-inline/is-void/index.js
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
|
||||||
|
import assert from 'assert'
|
||||||
|
|
||||||
|
export default function (state) {
|
||||||
|
const { document, selection } = state
|
||||||
|
const texts = document.getTexts()
|
||||||
|
const first = texts.first()
|
||||||
|
const range = selection.merge({
|
||||||
|
anchorKey: first.key,
|
||||||
|
anchorOffset: 0,
|
||||||
|
focusKey: first.key,
|
||||||
|
focusOffset: 0
|
||||||
|
})
|
||||||
|
|
||||||
|
const next = state
|
||||||
|
.transform()
|
||||||
|
.moveTo(range)
|
||||||
|
.insertInline({
|
||||||
|
type: 'hashtag',
|
||||||
|
isVoid: true
|
||||||
|
})
|
||||||
|
.apply()
|
||||||
|
|
||||||
|
assert.deepEqual(
|
||||||
|
next.selection.toJS(),
|
||||||
|
range.toJS()
|
||||||
|
)
|
||||||
|
|
||||||
|
return next
|
||||||
|
}
|
@@ -0,0 +1,5 @@
|
|||||||
|
|
||||||
|
nodes:
|
||||||
|
- kind: block
|
||||||
|
type: image
|
||||||
|
isVoid: true
|
@@ -0,0 +1,5 @@
|
|||||||
|
|
||||||
|
nodes:
|
||||||
|
- kind: block
|
||||||
|
type: image
|
||||||
|
isVoid: true
|
33
test/transforms/fixtures/insert-inline/with-inline/index.js
Normal file
33
test/transforms/fixtures/insert-inline/with-inline/index.js
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
|
||||||
|
import { Inline } from '../../../../..'
|
||||||
|
import assert from 'assert'
|
||||||
|
|
||||||
|
export default function (state) {
|
||||||
|
const { document, selection } = state
|
||||||
|
const texts = document.getTexts()
|
||||||
|
const first = texts.first()
|
||||||
|
const range = selection.merge({
|
||||||
|
anchorKey: first.key,
|
||||||
|
anchorOffset: 0,
|
||||||
|
focusKey: first.key,
|
||||||
|
focusOffset: 0
|
||||||
|
})
|
||||||
|
|
||||||
|
const next = state
|
||||||
|
.transform()
|
||||||
|
.moveTo(range)
|
||||||
|
.insertInline(Inline.create({
|
||||||
|
type: 'image',
|
||||||
|
isVoid: true
|
||||||
|
}))
|
||||||
|
.apply()
|
||||||
|
|
||||||
|
const updated = next.document.getTexts().first()
|
||||||
|
|
||||||
|
assert.deepEqual(
|
||||||
|
next.selection.toJS(),
|
||||||
|
range.collapseToEndOf(updated).toJS()
|
||||||
|
)
|
||||||
|
|
||||||
|
return next
|
||||||
|
}
|
@@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
nodes:
|
||||||
|
- kind: block
|
||||||
|
type: paragraph
|
||||||
|
nodes:
|
||||||
|
- kind: text
|
||||||
|
text: word
|
@@ -0,0 +1,10 @@
|
|||||||
|
|
||||||
|
nodes:
|
||||||
|
- kind: block
|
||||||
|
type: paragraph
|
||||||
|
nodes:
|
||||||
|
- kind: inline
|
||||||
|
type: image
|
||||||
|
isVoid: true
|
||||||
|
- kind: text
|
||||||
|
text: word
|
Reference in New Issue
Block a user