mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-23 15:32:59 +02:00
update normalization logic to account for new children
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
import Normalize from '../utils/normalize'
|
import Normalize from '../utils/normalize'
|
||||||
import Schema from '../models/schema'
|
import Schema from '../models/schema'
|
||||||
import warn from '../utils/warn'
|
import warn from '../utils/warn'
|
||||||
|
import { Set } from 'immutable'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Normalize the document and selection with a `schema`.
|
* Normalize the document and selection with a `schema`.
|
||||||
@@ -93,23 +94,44 @@ export function normalizeSelection(transform) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
function normalizeNodeAndChildren(transform, node, schema) {
|
function normalizeNodeAndChildren(transform, node, schema) {
|
||||||
// For performance considerations, we will check if the transform has actually
|
if (node.kind == 'text') {
|
||||||
// added operations to the queue.
|
normalizeNode(transform, node, schema)
|
||||||
const count = transform.operations.length
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Iterate over its children.
|
// We can't just loop the children and normalize them, because in the process
|
||||||
if (node.kind != 'text') {
|
// of normalizing one child, we might end up creating another. Instead, we
|
||||||
node.nodes.forEach((child) => {
|
// have to normalize one at a time, and check for new children along the way.
|
||||||
|
let stack = node.nodes.map(n => n.key).toStack()
|
||||||
|
let set = new Set()
|
||||||
|
|
||||||
|
// While there is still a child key that hasn't been normalized yet...
|
||||||
|
while (stack.size) {
|
||||||
|
const ops = transform.operations.length
|
||||||
|
let key
|
||||||
|
|
||||||
|
// Unwind the stack, normalizing every child and adding it to the set.
|
||||||
|
while (key = stack.peek()) {
|
||||||
|
const child = node.getChild(key)
|
||||||
normalizeNodeAndChildren(transform, child, schema)
|
normalizeNodeAndChildren(transform, child, schema)
|
||||||
})
|
set = set.add(key)
|
||||||
|
stack = stack.pop()
|
||||||
|
}
|
||||||
|
|
||||||
|
// PERF: Only re-find the node and re-normalize any new children if
|
||||||
|
// operations occured that might have changed it.
|
||||||
|
if (transform.operations.length != ops) {
|
||||||
|
node = refindNode(transform, node)
|
||||||
|
|
||||||
|
// Add any new children back onto the stack.
|
||||||
|
node.nodes.forEach(n => {
|
||||||
|
if (set.has(n.key)) return
|
||||||
|
stack = stack.push(n.key)
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Re-find the node reference if necessary.
|
// Normalize the node itself if it still exists.
|
||||||
if (transform.operations.length != count) {
|
|
||||||
node = refindNode(transform, node)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now normalize the node itself if it still exists.
|
|
||||||
if (node) {
|
if (node) {
|
||||||
normalizeNode(transform, node, schema)
|
normalizeNode(transform, node, schema)
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user