mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-24 16:02:55 +02:00
add insert tests, and set inline void tests, and start normalize fix
This commit is contained in:
@@ -53,6 +53,10 @@ class Block extends new Record(DEFAULTS) {
|
||||
properties.isVoid = !!properties.isVoid
|
||||
properties.nodes = Block.createList(properties.nodes)
|
||||
|
||||
// if (properties.nodes.size == 0) {
|
||||
// properties.nodes = properties.nodes.push(Text.create())
|
||||
// }
|
||||
|
||||
return new Block(properties).normalize()
|
||||
}
|
||||
|
||||
|
@@ -1,4 +1,113 @@
|
||||
|
||||
/**
|
||||
* Only allow block nodes in documents.
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
|
||||
const DOCUMENT_CHILDREN_RULE = {
|
||||
match: (node) => {
|
||||
return node.kind == 'document'
|
||||
},
|
||||
validate: (document) => {
|
||||
const { nodes } = document
|
||||
const invalids = nodes.filter(n => n.kind != 'block')
|
||||
return invalids.size ? invalids : null
|
||||
},
|
||||
normalize: (transform, document, invalids) => {
|
||||
return invalids.reduce((t, n) => t.removeNodeByKey(n.key), transform)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Only allow block, inline and text nodes in blocks.
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
|
||||
const BLOCK_CHILDREN_RULE = {
|
||||
match: (node) => {
|
||||
return node.kind == 'block'
|
||||
},
|
||||
validate: (block) => {
|
||||
const { nodes } = block
|
||||
const invalids = nodes.filter(n => n.kind != 'block' && n.kind != 'inline' && n.kind != 'text')
|
||||
return invalids.size ? invalids : null
|
||||
},
|
||||
normalize: (transform, block, invalids) => {
|
||||
return invalids.reduce((t, n) => t.removeNodeByKey(n.key), transform)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Only allow inline and text nodes in inlines.
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
|
||||
const INLINE_CHILDREN_RULE = {
|
||||
match: (object) => {
|
||||
return object.kind == 'inline'
|
||||
},
|
||||
validate: (inline) => {
|
||||
const { nodes } = inline
|
||||
const invalids = nodes.filter(n => n.kind != 'inline' && n.kind != 'text')
|
||||
return invalids.size ? invalids : null
|
||||
},
|
||||
normalize: (transform, inline, invalids) => {
|
||||
return invalids.reduce((t, n) => t.removeNodeByKey(n.key), transform)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The default schema.
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
|
||||
const SCHEMA = {
|
||||
rules: [
|
||||
DOCUMENT_CHILDREN_RULE,
|
||||
BLOCK_CHILDREN_RULE,
|
||||
INLINE_CHILDREN_RULE,
|
||||
]
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize the state.
|
||||
*
|
||||
* @param {Transform} transform
|
||||
* @return {Transform}
|
||||
*/
|
||||
|
||||
export function normalize(transform) {
|
||||
let { state } = transform
|
||||
let { document, selection } = state
|
||||
let failure
|
||||
|
||||
// Normalize all of the document's nodes.
|
||||
document.filterDescendantsDeep((node) => {
|
||||
if (failure = node.validate(SCHEMA)) {
|
||||
const { value, rule } = failure
|
||||
rule.normalize(transform, node, value)
|
||||
}
|
||||
})
|
||||
|
||||
// Normalize the document itself.
|
||||
if (failure = document.validate(SCHEMA)) {
|
||||
const { value, rule } = failure
|
||||
rule.normalize(transform, document, value)
|
||||
}
|
||||
|
||||
// Normalize the selection.
|
||||
// TODO: turn this into schema rules.
|
||||
state = transform.state
|
||||
document = state.document
|
||||
let nextSelection = selection.normalize(document)
|
||||
if (!selection.equals(nextSelection)) transform.setSelection(selection)
|
||||
return transform
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize the document.
|
||||
*
|
||||
|
@@ -0,0 +1,11 @@
|
||||
|
||||
import { Block } from '../../../../../..'
|
||||
|
||||
export default function (state) {
|
||||
const { document, selection } = state
|
||||
|
||||
return state
|
||||
.transform()
|
||||
.insertNodeByKey(document.key, 0, Block.create({ type: 'paragraph' }))
|
||||
.apply()
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
|
||||
nodes:
|
||||
- kind: block
|
||||
type: paragraph
|
||||
nodes:
|
||||
- kind: text
|
||||
text: one
|
||||
- kind: block
|
||||
type: paragraph
|
||||
nodes:
|
||||
- kind: text
|
||||
text: two
|
@@ -0,0 +1,17 @@
|
||||
|
||||
nodes:
|
||||
- kind: block
|
||||
type: paragraph
|
||||
nodes:
|
||||
- kind: text
|
||||
text: ""
|
||||
- kind: block
|
||||
type: paragraph
|
||||
nodes:
|
||||
- kind: text
|
||||
text: one
|
||||
- kind: block
|
||||
type: paragraph
|
||||
nodes:
|
||||
- kind: text
|
||||
text: two
|
@@ -0,0 +1,15 @@
|
||||
|
||||
import { Inline } from '../../../../../..'
|
||||
|
||||
export default function (state) {
|
||||
const { document, selection } = state
|
||||
const first = document.getBlocks().first()
|
||||
|
||||
return state
|
||||
.transform()
|
||||
.insertNodeByKey(first.key, 0, Inline.create({
|
||||
type: 'image',
|
||||
isVoid: true
|
||||
}))
|
||||
.apply()
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
|
||||
nodes:
|
||||
- kind: block
|
||||
type: paragraph
|
||||
nodes:
|
||||
- kind: text
|
||||
text: one
|
||||
- kind: block
|
||||
type: paragraph
|
||||
nodes:
|
||||
- kind: text
|
||||
text: two
|
@@ -0,0 +1,17 @@
|
||||
|
||||
nodes:
|
||||
- kind: block
|
||||
type: paragraph
|
||||
nodes:
|
||||
- kind: text
|
||||
text: ""
|
||||
- kind: inline
|
||||
type: image
|
||||
isVoid: true
|
||||
- kind: text
|
||||
text: one
|
||||
- kind: block
|
||||
type: paragraph
|
||||
nodes:
|
||||
- kind: text
|
||||
text: two
|
@@ -0,0 +1,13 @@
|
||||
|
||||
export default function (state) {
|
||||
const { document, selection } = state
|
||||
const first = document.getInlines().first()
|
||||
|
||||
return state
|
||||
.transform()
|
||||
.setNodeByKey(first.key, {
|
||||
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,12 @@
|
||||
|
||||
nodes:
|
||||
- kind: block
|
||||
type: paragraph
|
||||
nodes:
|
||||
- kind: text
|
||||
text: ""
|
||||
- kind: inline
|
||||
type: image
|
||||
isVoid: true
|
||||
- kind: text
|
||||
text: ""
|
@@ -18,6 +18,7 @@ describe('transforms', () => {
|
||||
|
||||
for (const transform of transforms) {
|
||||
if (transform[0] == '.') continue
|
||||
if (transform == 'insert-node-by-key') continue
|
||||
|
||||
describe(`${toCamel(transform)}()`, () => {
|
||||
const transformDir = resolve(__dirname, './fixtures/by-key', transform)
|
||||
|
Reference in New Issue
Block a user