mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-09-01 03:11:44 +02:00
change from ordered map to list for nodes
This commit is contained in:
@@ -4,7 +4,7 @@ import Inline from './inline'
|
||||
import Node from './node'
|
||||
import Text from './text'
|
||||
import uid from 'uid'
|
||||
import Immutable, { Map, OrderedMap, Record } from 'immutable'
|
||||
import Immutable, { Map, List, Record } from 'immutable'
|
||||
|
||||
/**
|
||||
* Default properties.
|
||||
@@ -13,7 +13,7 @@ import Immutable, { Map, OrderedMap, Record } from 'immutable'
|
||||
const DEFAULTS = {
|
||||
data: new Map(),
|
||||
key: null,
|
||||
nodes: new OrderedMap(),
|
||||
nodes: new List(),
|
||||
type: null
|
||||
}
|
||||
|
||||
@@ -38,26 +38,21 @@ class Block extends Record(DEFAULTS) {
|
||||
|
||||
properties.key = uid(4)
|
||||
properties.data = Data.create(properties.data)
|
||||
properties.nodes = Block.createMap(properties.nodes)
|
||||
properties.nodes = Block.createList(properties.nodes)
|
||||
|
||||
let block = new Block(properties)
|
||||
return block.normalize()
|
||||
return new Block(properties).normalize()
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an ordered map of `Blocks` from an array of `Blocks`.
|
||||
* Create a list of `Blocks` from an array.
|
||||
*
|
||||
* @param {Array} elements
|
||||
* @return {OrderedMap} map
|
||||
* @return {List} list
|
||||
*/
|
||||
|
||||
static createMap(elements = []) {
|
||||
if (OrderedMap.isOrderedMap(elements)) return elements
|
||||
return elements
|
||||
.map(Block.create)
|
||||
.reduce((map, element) => {
|
||||
return map.set(element.key, element)
|
||||
}, new OrderedMap())
|
||||
static createList(elements = []) {
|
||||
if (List.isList(elements)) return elements
|
||||
return new List(elements.map(Block.create))
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -26,11 +26,8 @@ class Document extends Record(DEFAULTS) {
|
||||
|
||||
static create(properties = {}) {
|
||||
if (properties instanceof Document) return properties
|
||||
|
||||
properties.nodes = Block.createMap(properties.nodes)
|
||||
|
||||
let document = new Document(properties)
|
||||
return document.normalize()
|
||||
properties.nodes = Block.createList(properties.nodes)
|
||||
return new Document(properties).normalize()
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -4,7 +4,7 @@ import Data from './data'
|
||||
import Node from './node'
|
||||
import Text from './text'
|
||||
import uid from 'uid'
|
||||
import Immutable, { Map, OrderedMap, Record } from 'immutable'
|
||||
import { List, Map, Record } from 'immutable'
|
||||
|
||||
/**
|
||||
* Record.
|
||||
@@ -13,7 +13,7 @@ import Immutable, { Map, OrderedMap, Record } from 'immutable'
|
||||
const DEFAULTS = {
|
||||
data: new Map(),
|
||||
key: null,
|
||||
nodes: new OrderedMap(),
|
||||
nodes: new List(),
|
||||
type: null
|
||||
}
|
||||
|
||||
@@ -38,26 +38,22 @@ class Inline extends Record(DEFAULTS) {
|
||||
|
||||
properties.key = uid(4)
|
||||
properties.data = Data.create(properties.data)
|
||||
properties.nodes = Inline.createMap(properties.nodes)
|
||||
properties.nodes = Inline.createList(properties.nodes)
|
||||
|
||||
let inline = new Inline(properties)
|
||||
return inline.normalize()
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an ordered map of `Inlines` from an array of `Inlines`.
|
||||
* Create a list of `Inlines` from an array.
|
||||
*
|
||||
* @param {Array} elements
|
||||
* @return {OrderedMap} map
|
||||
* @return {List} map
|
||||
*/
|
||||
|
||||
static createMap(elements = []) {
|
||||
if (OrderedMap.isOrderedMap(elements)) return elements
|
||||
return elements
|
||||
.map(Inline.create)
|
||||
.reduce((map, element) => {
|
||||
return map.set(element.key, element)
|
||||
}, new OrderedMap())
|
||||
static createList(elements = []) {
|
||||
if (List.isList(elements)) return elements
|
||||
return new List(elements.map(Inline.create))
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -27,9 +27,7 @@ class Mark extends Record(DEFAULTS) {
|
||||
static create(properties = {}) {
|
||||
if (properties instanceof Mark) return properties
|
||||
if (!properties.type) throw new Error('You must provide a `type` for the mark.')
|
||||
|
||||
properties.data = Data.create(properties.data)
|
||||
|
||||
return new Mark(properties)
|
||||
}
|
||||
|
||||
|
@@ -5,7 +5,7 @@ import Data from './data'
|
||||
import Mark from './mark'
|
||||
import Selection from './selection'
|
||||
import Text from './text'
|
||||
import { List, Map, OrderedMap, OrderedSet, Set } from 'immutable'
|
||||
import { List, Map, Set } from 'immutable'
|
||||
|
||||
/**
|
||||
* Node.
|
||||
@@ -49,9 +49,7 @@ const Node = {
|
||||
|
||||
// If the start and end nodes are the same, remove the matching characters.
|
||||
if (startKey == endKey) {
|
||||
let { characters } = startNode
|
||||
|
||||
characters = characters.filterNot((char, i) => {
|
||||
const characters = startNode.characters.filterNot((char, i) => {
|
||||
return startOffset <= i && i < endOffset
|
||||
})
|
||||
|
||||
@@ -92,7 +90,7 @@ const Node = {
|
||||
|
||||
const nodes = node.nodes
|
||||
.takeUntil(child => child == startGrandestParent)
|
||||
.set(startGrandestParent.key, startGrandestParent)
|
||||
.push(startGrandestParent)
|
||||
.concat(node.nodes.skipUntil(child => child == endGrandestParent))
|
||||
|
||||
node = node.merge({ nodes })
|
||||
@@ -214,17 +212,11 @@ const Node = {
|
||||
*/
|
||||
|
||||
filterDeep(iterator) {
|
||||
return this.nodes.reduce((matches, child) => {
|
||||
if (iterator(child, child.key, this.nodes)) {
|
||||
matches = matches.set(child.key, child)
|
||||
}
|
||||
|
||||
if (child.kind != 'text') {
|
||||
matches = matches.concat(child.filterDeep(iterator))
|
||||
}
|
||||
|
||||
return this.nodes.reduce((matches, child, i, nodes) => {
|
||||
if (iterator(child, i, nodes)) matches = matches.push(child)
|
||||
if (child.kind != 'text') matches = matches.concat(child.filterDeep(iterator))
|
||||
return matches
|
||||
}, new OrderedMap())
|
||||
}, Block.createList())
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -362,7 +354,8 @@ const Node = {
|
||||
key = normalizeKey(key)
|
||||
this.assertHasDeep(key)
|
||||
|
||||
if (this.nodes.has(key)) return startAt
|
||||
const shallow = this.nodes.find(node => node.key == key)
|
||||
if (shallow) return startAt
|
||||
|
||||
const child = this.nodes.find(node => {
|
||||
return node.kind == 'text'
|
||||
@@ -465,7 +458,8 @@ const Node = {
|
||||
key = normalizeKey(key)
|
||||
this.assertHasDeep(key)
|
||||
|
||||
if (this.nodes.has(key)) {
|
||||
const shallow = this.nodes.find(node => node.key == key)
|
||||
if (shallow) {
|
||||
return this.nodes
|
||||
.skipUntil(node => node.key == key)
|
||||
.rest()
|
||||
@@ -526,7 +520,7 @@ const Node = {
|
||||
|
||||
// If the child's parent is this node, return the offset of all of the nodes
|
||||
// before it, otherwise recurse.
|
||||
return this.nodes.has(match.key)
|
||||
return this.nodes.find(node => node.key == match.key)
|
||||
? offset
|
||||
: offset + child.getOffset(key)
|
||||
},
|
||||
@@ -542,7 +536,8 @@ const Node = {
|
||||
key = normalizeKey(key)
|
||||
// this.assertHasDeep(key)
|
||||
|
||||
if (this.nodes.has(key)) return this
|
||||
const shallow = this.nodes.find(node => node.key == key)
|
||||
if (shallow) return this
|
||||
|
||||
let node = null
|
||||
this.nodes.forEach((child) => {
|
||||
@@ -565,7 +560,8 @@ const Node = {
|
||||
key = normalizeKey(key)
|
||||
this.assertHasDeep(key)
|
||||
|
||||
if (this.nodes.has(key)) {
|
||||
const shallow = this.nodes.find(node => node.key == key)
|
||||
if (shallow) {
|
||||
return this.nodes
|
||||
.takeUntil(node => node.key == key)
|
||||
.last()
|
||||
@@ -620,9 +616,9 @@ const Node = {
|
||||
getTextNodes() {
|
||||
return this.nodes.reduce((texts, node) => {
|
||||
return node.kind == 'text'
|
||||
? texts.set(node.key, node)
|
||||
? texts.push(node)
|
||||
: texts.concat(node.getTextNodes())
|
||||
}, new OrderedMap())
|
||||
}, Block.createList())
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -648,7 +644,7 @@ const Node = {
|
||||
const endNode = this.getDeep(endKey)
|
||||
const afterStart = texts.skipUntil(node => node.key == startKey)
|
||||
const upToEnd = afterStart.takeUntil(node => node.key == endKey)
|
||||
const matches = upToEnd.set(endNode.key, endNode)
|
||||
const matches = upToEnd.push(endNode)
|
||||
return matches
|
||||
},
|
||||
|
||||
@@ -802,18 +798,12 @@ const Node = {
|
||||
/**
|
||||
* Push a new `node` onto the map of nodes.
|
||||
*
|
||||
* @param {String or Node} key
|
||||
* @param {Node} node (optional)
|
||||
* @param {Node} node
|
||||
* @return {Node} node
|
||||
*/
|
||||
|
||||
pushNode(key, node) {
|
||||
if (arguments.length == 1) {
|
||||
node = key
|
||||
key = normalizeKey(key)
|
||||
}
|
||||
|
||||
let nodes = this.nodes.set(key, node)
|
||||
pushNode(node) {
|
||||
const nodes = this.nodes.push(node)
|
||||
return this.merge({ nodes })
|
||||
},
|
||||
|
||||
@@ -827,8 +817,7 @@ const Node = {
|
||||
removeDeep(key) {
|
||||
key = normalizeKey(key)
|
||||
this.assertHasDeep(key)
|
||||
|
||||
let nodes = this.nodes.remove(key)
|
||||
const nodes = this.nodes.filterNot(node => node.key == key)
|
||||
return this.merge({ nodes })
|
||||
},
|
||||
|
||||
@@ -943,8 +932,8 @@ const Node = {
|
||||
// Replace the block in the parent with the two new blocks.
|
||||
let parent = node.getParent(firstBlock)
|
||||
const nodes = parent.nodes.takeUntil(n => n.key == firstBlock.key)
|
||||
.set(firstBlock.key, firstBlock)
|
||||
.set(secondBlock.key, secondBlock)
|
||||
.push(firstBlock)
|
||||
.push(secondBlock)
|
||||
.concat(parent.nodes.skipUntil(n => n.key == firstBlock.key).rest())
|
||||
|
||||
// If the node is the parent, just merge, otherwise deep merge.
|
||||
@@ -960,7 +949,6 @@ const Node = {
|
||||
},
|
||||
|
||||
splitInlineAtRange(range) {
|
||||
debugger
|
||||
range = range.normalize(this)
|
||||
const Inline = require('./inline').default
|
||||
let node = this
|
||||
@@ -979,7 +967,7 @@ const Node = {
|
||||
|
||||
// While the parent is an inline parent, split the inline nodes.
|
||||
while (parent = node.getClosestInline(firstChild)) {
|
||||
firstChild = parent.merge({ nodes: Inline.createMap([firstChild]) })
|
||||
firstChild = parent.merge({ nodes: Inline.createList([firstChild]) })
|
||||
secondChild = Inline.create({
|
||||
nodes: [secondChild],
|
||||
type: parent.type,
|
||||
@@ -987,16 +975,15 @@ const Node = {
|
||||
})
|
||||
|
||||
// Split the children.
|
||||
const isGrandparent = node.nodes.has(parent.key)
|
||||
const grandparent = isGrandparent ? node : node.getParent(parent)
|
||||
const grandparent = node.getParent(parent)
|
||||
const nodes = grandparent.nodes
|
||||
.takeUntil(c => c.key == firstChild.key)
|
||||
.set(firstChild.key, firstChild)
|
||||
.set(secondChild.key, secondChild)
|
||||
.push(firstChild)
|
||||
.push(secondChild)
|
||||
.concat(grandparent.nodes.skipUntil(n => n.key == firstChild.key).rest())
|
||||
|
||||
// Update the grandparent.
|
||||
node = isGrandparent
|
||||
node = grandparent == node
|
||||
? node.merge({ nodes })
|
||||
: node.updateDeep(grandparent.merge({ nodes }))
|
||||
}
|
||||
@@ -1034,8 +1021,8 @@ const Node = {
|
||||
let parent = node.getParent(text)
|
||||
const nodes = parent.nodes
|
||||
.takeUntil(c => c.key == firstChild.key)
|
||||
.set(firstChild.key, firstChild)
|
||||
.set(secondChild.key, secondChild)
|
||||
.push(firstChild)
|
||||
.push(secondChild)
|
||||
.concat(parent.nodes.skipUntil(n => n.key == firstChild.key).rest())
|
||||
|
||||
// Update the nodes.
|
||||
@@ -1090,26 +1077,21 @@ const Node = {
|
||||
/**
|
||||
* Set a new value for a child node by `key`.
|
||||
*
|
||||
* @param {String or Node} key
|
||||
* @param {Node} node (optional)
|
||||
* @param {Node} node
|
||||
* @return {Node} node
|
||||
*/
|
||||
|
||||
updateDeep(key, node) {
|
||||
if (arguments.length == 1) {
|
||||
node = key
|
||||
key = normalizeKey(key)
|
||||
}
|
||||
|
||||
updateDeep(node) {
|
||||
// this.assertHasDeep(key)
|
||||
|
||||
if (this.nodes.get(key)) {
|
||||
const nodes = this.nodes.set(key, node)
|
||||
return this.set('nodes', nodes)
|
||||
const shallow = this.nodes.find(child => child.key == node.key)
|
||||
if (shallow) {
|
||||
const nodes = this.nodes.map(child => child.key == node.key ? node : child)
|
||||
return this.merge({ nodes })
|
||||
}
|
||||
|
||||
const nodes = this.nodes.map((child) => {
|
||||
return child.kind == 'text' ? child : child.updateDeep(key, node)
|
||||
return child.kind == 'text' ? child : child.updateDeep(node)
|
||||
})
|
||||
|
||||
return this.merge({ nodes })
|
||||
@@ -1146,9 +1128,9 @@ const Node = {
|
||||
const sibling = node.getDepth(block) == depth
|
||||
? block
|
||||
: node.getClosest(block, (p) => node.getDepth(p) == depth)
|
||||
siblings = siblings.set(sibling.key, sibling)
|
||||
siblings = siblings.push(sibling)
|
||||
return siblings
|
||||
}, new OrderedMap())
|
||||
}, Block.createList())
|
||||
|
||||
// Wrap the siblings in a new block.
|
||||
const wrapper = Block.create({
|
||||
@@ -1158,20 +1140,16 @@ const Node = {
|
||||
})
|
||||
|
||||
// Replace the siblings with the wrapper.
|
||||
const isDirectChild = node.nodes.has(highest.key)
|
||||
let parent = isDirectChild ? node : node.getParent(highest)
|
||||
const parent = node.getParent(highest)
|
||||
const nodes = parent.nodes
|
||||
.takeUntil(node => node == highest)
|
||||
.set(wrapper.key, wrapper)
|
||||
.push(wrapper)
|
||||
.concat(parent.nodes.skipUntil(node => node == highest).rest())
|
||||
|
||||
// Update the parent.
|
||||
if (isDirectChild) {
|
||||
node = node.merge({ nodes })
|
||||
} else {
|
||||
parent = parent.merge({ nodes })
|
||||
node = node.updateDeep(parent)
|
||||
}
|
||||
node = parent == node
|
||||
? node.merge({ nodes })
|
||||
: node.updateDeep(parent.merge({ nodes }))
|
||||
|
||||
return node
|
||||
},
|
||||
@@ -1208,14 +1186,13 @@ const Node = {
|
||||
return true
|
||||
})
|
||||
|
||||
if (match) wrappers = wrappers.set(match.key, match)
|
||||
if (match) wrappers = wrappers.add(match)
|
||||
return wrappers
|
||||
}, new OrderedMap())
|
||||
}, new Set())
|
||||
|
||||
// Replace each of the wrappers with their child nodes.
|
||||
wrappers.forEach((wrapper) => {
|
||||
const isDirectChild = node.nodes.has(wrapper.key)
|
||||
let parent = isDirectChild ? node : node.getParent(wrapper)
|
||||
const parent = node.getParent(wrapper)
|
||||
|
||||
// Replace the wrapper in the parent's nodes with the block.
|
||||
const nodes = parent.nodes.takeUntil(n => n == wrapper)
|
||||
@@ -1223,12 +1200,9 @@ const Node = {
|
||||
.concat(parent.nodes.skipUntil(n => n == wrapper).rest())
|
||||
|
||||
// Update the parent.
|
||||
if (isDirectChild) {
|
||||
node = node.merge({ nodes })
|
||||
} else {
|
||||
parent = parent.merge({ nodes })
|
||||
node = node.updateDeep(parent)
|
||||
}
|
||||
node = parent == node
|
||||
? node.merge({ nodes })
|
||||
: node.updateDeep(parent.merge({ nodes }))
|
||||
})
|
||||
|
||||
return node.normalize()
|
||||
@@ -1298,7 +1272,7 @@ const Node = {
|
||||
// Replace the child in it's parent with the wrapper.
|
||||
const parent = node.getParent(child)
|
||||
const nodes = parent.nodes.takeUntil(n => n == child)
|
||||
.set(wrapper.key, wrapper)
|
||||
.push(wrapper)
|
||||
.concat(parent.nodes.skipUntil(n => n == child).rest())
|
||||
|
||||
// Update the parent.
|
||||
@@ -1343,14 +1317,13 @@ const Node = {
|
||||
return true
|
||||
})
|
||||
|
||||
if (match) wrappers = wrappers.set(match.key, match)
|
||||
if (match) wrappers = wrappers.add(match)
|
||||
return wrappers
|
||||
}, new OrderedMap())
|
||||
}, new Set())
|
||||
|
||||
// Replace each of the wrappers with their child nodes.
|
||||
wrappers.forEach((wrapper) => {
|
||||
const parent = node.getParent(wrapper)
|
||||
const isDirectChild = parent == node
|
||||
|
||||
// Replace the wrapper in the parent's nodes with the block.
|
||||
const nodes = parent.nodes.takeUntil(n => n == wrapper)
|
||||
@@ -1358,7 +1331,7 @@ const Node = {
|
||||
.concat(parent.nodes.skipUntil(n => n == wrapper).rest())
|
||||
|
||||
// Update the parent.
|
||||
node = isDirectChild
|
||||
node = parent == node
|
||||
? node.merge({ nodes })
|
||||
: node.updateDeep(parent.merge({ nodes }))
|
||||
})
|
||||
|
@@ -60,10 +60,8 @@ class State extends Record(DEFAULTS) {
|
||||
|
||||
static create(properties = {}) {
|
||||
if (properties instanceof State) return properties
|
||||
|
||||
properties.document = Document.create(properties.document)
|
||||
properties.selection = Selection.create(properties.selection)
|
||||
|
||||
return new State(properties)
|
||||
}
|
||||
|
||||
|
@@ -27,10 +27,8 @@ class Text extends Record(DEFAULTS) {
|
||||
|
||||
static create(properties = {}) {
|
||||
if (properties instanceof Text) return properties
|
||||
|
||||
properties.key = uid(4)
|
||||
properties.characters = Character.createList(properties.characters)
|
||||
|
||||
return new Text(properties)
|
||||
}
|
||||
|
||||
|
@@ -94,7 +94,7 @@ function serializeMark(mark) {
|
||||
function deserialize(object) {
|
||||
return State.create({
|
||||
document: Document.create({
|
||||
nodes: Block.createMap(object.nodes.map(deserializeNode))
|
||||
nodes: Block.createList(object.nodes.map(deserializeNode))
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -111,15 +111,15 @@ function deserializeNode(object) {
|
||||
case 'block': {
|
||||
return Block.create({
|
||||
type: object.type,
|
||||
data: new Map(object.data),
|
||||
nodes: Block.createMap(object.nodes.map(deserializeNode))
|
||||
data: object.data,
|
||||
nodes: Block.createList(object.nodes.map(deserializeNode))
|
||||
})
|
||||
}
|
||||
case 'inline': {
|
||||
return Inline.create({
|
||||
type: object.type,
|
||||
data: new Map(object.data),
|
||||
nodes: Inline.createMap(object.nodes.map(deserializeNode))
|
||||
data: object.data,
|
||||
nodes: Inline.createList(object.nodes.map(deserializeNode))
|
||||
})
|
||||
}
|
||||
case 'text': {
|
||||
@@ -161,10 +161,7 @@ function deserializeRanges(array) {
|
||||
*/
|
||||
|
||||
function deserializeMark(object) {
|
||||
return Mark.create({
|
||||
type: object.type,
|
||||
data: new Map(object.data)
|
||||
})
|
||||
return Mark.create(object)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -25,6 +25,7 @@
|
||||
"mocha-phantomjs": "^4.0.2",
|
||||
"react-dom": "^15.1.0",
|
||||
"read-metadata": "^1.0.0",
|
||||
"source-map-support": "^0.4.0",
|
||||
"standard": "^7.1.2",
|
||||
"to-camel-case": "^1.0.0",
|
||||
"watchify": "^3.7.0"
|
||||
|
@@ -1,2 +1,3 @@
|
||||
|
||||
import 'source-map-support/register'
|
||||
import './transforms'
|
||||
|
Reference in New Issue
Block a user