1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-08-11 17:53:59 +02:00
This commit is contained in:
Ian Storm Taylor
2016-06-23 12:34:47 -07:00
parent 64e837230d
commit c639db25c4
5 changed files with 241 additions and 239 deletions

View File

@@ -24,28 +24,51 @@ clean:
# Build the source. # Build the source.
dist: $(shell find ./lib) dist: $(shell find ./lib)
@ $(babel) --out-dir ./dist ./lib @ $(babel) \
--out-dir \
./dist \
./lib
@ touch ./dist @ touch ./dist
# Build the auto-markdown example. # Build the auto-markdown example.
example-auto-markdown: example-auto-markdown:
@ $(browserify) --debug --transform babelify --outfile ./examples/auto-markdown/build.js ./examples/auto-markdown/index.js @ $(browserify) \
--debug \
--transform babelify \
--outfile ./examples/auto-markdown/build.js \
./examples/auto-markdown/index.js
# Build the links example. # Build the links example.
example-links: example-links:
@ $(browserify) --debug --transform babelify --outfile ./examples/links/build.js ./examples/links/index.js @ $(browserify) \
--debug \
--transform babelify \
--outfile ./examples/links/build.js \
./examples/links/index.js
# Build the plain-text example. # Build the plain-text example.
example-plain-text: example-plain-text:
@ $(browserify) --debug --transform babelify --outfile ./examples/plain-text/build.js ./examples/plain-text/index.js @ $(browserify) \
--debug \
--transform babelify \
--outfile ./examples/plain-text/build.js \
./examples/plain-text/index.js
# Build the rich-text example. # Build the rich-text example.
example-rich-text: example-rich-text:
@ $(browserify) --debug --transform babelify --outfile ./examples/rich-text/build.js ./examples/rich-text/index.js @ $(browserify) \
--debug \
--transform babelify \
--outfile ./examples/rich-text/build.js \
./examples/rich-text/index.js
# Build the table example. # Build the table example.
example-table: example-table:
@ $(browserify) --debug --transform babelify --outfile ./examples/table/build.js ./examples/table/index.js @ $(browserify) \
--debug \
--transform babelify \
--outfile ./examples/table/build.js \
./examples/table/index.js
# Install the dependencies. # Install the dependencies.
install: install:
@@ -57,14 +80,20 @@ lint:
# Build the test source. # Build the test source.
test/browser/support/build.js: $(shell find ./lib) ./test/browser.js test/browser/support/build.js: $(shell find ./lib) ./test/browser.js
@ $(browserify) --debug --transform babelify --outfile ./test/support/build.js ./test/browser.js @ $(browserify) \
--debug \
--transform babelify \
--outfile ./test/support/build.js ./test/browser.js
# Run the tests. # Run the tests.
test: test-browser test-server test: test-browser test-server
# Run the browser-side tests. # Run the browser-side tests.
test-browser: ./test/support/build.js test-browser: ./test/support/build.js
@ $(mocha-phantomjs) --reporter spec --timeout 5000 ./test/support/browser.html @ $(mocha-phantomjs) \
--reporter spec \
--timeout 5000 \
./test/support/browser.html
# Run the server-side tests. # Run the server-side tests.
test-server: test-server:

View File

@@ -83,7 +83,7 @@ class Content extends React.Component {
const { anchorNode, anchorOffset, focusNode, focusOffset } = native const { anchorNode, anchorOffset, focusNode, focusOffset } = native
const anchor = OffsetKey.findPoint(anchorNode, anchorOffset) const anchor = OffsetKey.findPoint(anchorNode, anchorOffset)
const focus = OffsetKey.findPoint(focusNode, focusOffset) const focus = OffsetKey.findPoint(focusNode, focusOffset)
const edges = document.filterDeep((node) => { const edges = document.filterDescendants((node) => {
return node.key == anchor.key || node.key == focus.key return node.key == anchor.key || node.key == focus.key
}) })

View File

@@ -22,8 +22,24 @@ const Node = {
* @param {String or Node} key * @param {String or Node} key
*/ */
assertHasDeep(key) { assertHasChild(key) {
if (!this.hasDeep(key)) throw new Error('Could not find that child node.') key = normalizeKey(key)
if (!this.hasChild(key)) {
throw new Error(`Could not find a child node with key "${key}".`)
}
},
/**
* Assert that the node has a descendant by `key`.
*
* @param {String or Node} key
*/
assertHasDescendant(key) {
key = normalizeKey(key)
if (!this.hasDescendant(key)) {
throw new Error(`Could not find a descendant node with key "${key}".`)
}
}, },
/** /**
@@ -42,10 +58,10 @@ const Node = {
// Make sure the children exist. // Make sure the children exist.
const { startKey, startOffset, endKey, endOffset } = range const { startKey, startOffset, endKey, endOffset } = range
node.assertHasDeep(startKey) node.assertHasDescendant(startKey)
node.assertHasDeep(endKey) node.assertHasDescendant(endKey)
let startNode = node.getDeep(startKey) let startNode = node.getDescendant(startKey)
// If the start and end nodes are the same, remove the matching characters. // If the start and end nodes are the same, remove the matching characters.
if (startKey == endKey) { if (startKey == endKey) {
@@ -81,11 +97,11 @@ const Node = {
let endParent = node.getParent(endKey) let endParent = node.getParent(endKey)
const startGrandestParent = node.nodes.find((child) => { const startGrandestParent = node.nodes.find((child) => {
return child == startParent || child.hasDeep(startParent) return child == startParent || child.hasDescendant(startParent)
}) })
const endGrandestParent = node.nodes.find((child) => { const endGrandestParent = node.nodes.find((child) => {
return child == endParent || child.hasDeep(endParent) return child == endParent || child.hasDescendant(endParent)
}) })
const nodes = node.nodes const nodes = node.nodes
@@ -103,9 +119,9 @@ const Node = {
// Then remove the end parent. // Then remove the end parent.
let endGrandparent = node.getParent(endParent) let endGrandparent = node.getParent(endParent)
if (endGrandparent == node) { if (endGrandparent == node) {
node = node.removeDeep(endParent) node = node.removeDescendant(endParent)
} else { } else {
endGrandparent = endGrandparent.removeDeep(endParent) endGrandparent = endGrandparent.removeDescendant(endParent)
node = node.updateDeep(endGrandparent) node = node.updateDeep(endGrandparent)
} }
@@ -133,7 +149,7 @@ const Node = {
// When at start of a text node, merge forwards into the next text node. // When at start of a text node, merge forwards into the next text node.
const { startKey } = range const { startKey } = range
const startNode = node.getDeep(startKey) const startNode = node.getDescendant(startKey)
if (range.isAtStartOf(startNode)) { if (range.isAtStartOf(startNode)) {
const previous = node.getPreviousText(startNode) const previous = node.getPreviousText(startNode)
@@ -170,7 +186,7 @@ const Node = {
// When at end of a text node, merge forwards into the next text node. // When at end of a text node, merge forwards into the next text node.
const { startKey } = range const { startKey } = range
const startNode = node.getDeep(startKey) const startNode = node.getDescendant(startKey)
if (range.isAtEndOf(startNode)) { if (range.isAtEndOf(startNode)) {
const next = node.getNextText(startNode) const next = node.getNextText(startNode)
@@ -188,33 +204,32 @@ const Node = {
}, },
/** /**
* Recursively find nodes nodes by `iterator`. * Recursively find all ancestor nodes by `iterator`.
* *
* @param {Function} iterator * @param {Function} iterator
* @return {Node} node * @return {Node} node
*/ */
findDeep(iterator) { findDescendant(iterator) {
const shallow = this.nodes.find(iterator) return (
if (shallow != null) return shallow this.nodes.find(iterator) ||
this.nodes
return this.nodes .map(node => node.kind == 'text' ? null : node.findDescendant(iterator))
.map(node => node.kind == 'text' ? null : node.findDeep(iterator)) .find(exists => exists)
.filter(node => node) )
.first()
}, },
/** /**
* Recursively filter nodes nodes with `iterator`. * Recursively filter all ancestor nodes with `iterator`.
* *
* @param {Function} iterator * @param {Function} iterator
* @return {OrderedMap} matches * @return {List} nodes
*/ */
filterDeep(iterator) { filterDescendants(iterator) {
return this.nodes.reduce((matches, child, i, nodes) => { return this.nodes.reduce((matches, child, i, nodes) => {
if (iterator(child, i, nodes)) matches = matches.push(child) if (iterator(child, i, nodes)) matches = matches.push(child)
if (child.kind != 'text') matches = matches.concat(child.filterDeep(iterator)) if (child.kind != 'text') matches = matches.concat(child.filterDescendants(iterator))
return matches return matches
}, Block.createList()) }, Block.createList())
}, },
@@ -223,14 +238,14 @@ const Node = {
* Get the closest block nodes for each text node in a `range`. * Get the closest block nodes for each text node in a `range`.
* *
* @param {Selection} range * @param {Selection} range
* @return {OrderedMap} nodes * @return {List} nodes
*/ */
getBlocksAtRange(range) { getBlocksAtRange(range) {
range = range.normalize(this) range = range.normalize(this)
const texts = this.getTextsAtRange(range) return this
const blocks = texts.map(text => this.getClosestBlock(text)) .getTextsAtRange(range)
return blocks .map(text => this.getClosestBlock(text))
}, },
/** /**
@@ -242,16 +257,12 @@ const Node = {
getCharactersAtRange(range) { getCharactersAtRange(range) {
range = range.normalize(this) range = range.normalize(this)
const texts = this.getTextsAtRange(range) return this
let list = new List() .getTextsAtRange(range)
.reduce((characters, text) => {
texts.forEach((text) => { const chars = text.characters.filter((char, i) => isInRange(i, text, range))
let { characters } = text return characters.concat(chars)
characters = characters.filter((char, i) => isInRange(i, text, range)) }, Character.createList())
list = list.concat(characters)
})
return list
}, },
/** /**
@@ -259,14 +270,11 @@ const Node = {
* *
* @param {String or Node} key * @param {String or Node} key
* @param {Function} iterator * @param {Function} iterator
* @return {Node or Null} parent * @return {Node or Null} node
*/ */
getClosest(key, iterator) { getClosest(key, iterator) {
key = normalizeKey(key) let node = this.getDescendant(key)
this.assertHasDeep(key)
let node = this.getDeep(key)
while (node = this.getParent(node)) { while (node = this.getParent(node)) {
if (node == this) return null if (node == this) return null
@@ -280,66 +288,46 @@ const Node = {
* Get the closest block parent of a `node`. * Get the closest block parent of a `node`.
* *
* @param {String or Node} key * @param {String or Node} key
* @return {Node or Null} parent * @return {Node or Null} node
*/ */
getClosestBlock(key) { getClosestBlock(key) {
key = normalizeKey(key) return this.getClosest(key, parent => parent.kind == 'block')
this.assertHasDeep(key)
const match = this.getClosest(key, parent => parent.kind == 'block')
return match
}, },
/** /**
* Get the closest inline parent of a `node`. * Get the closest inline parent of a `node`.
* *
* @param {String or Node} key * @param {String or Node} key
* @return {Node or Null} parent * @return {Node or Null} node
*/ */
getClosestInline(key) { getClosestInline(key) {
key = normalizeKey(key) return this.getClosest(key, parent => parent.kind == 'inline')
this.assertHasDeep(key)
const match = this.getClosest(key, parent => parent.kind == 'inline')
return match
},
/**
* Get the furthest inline parent of a node by `key`.
*
* @param {String or Node} key
* @return {Node or Null} parent
*/
getFurthestInline(key) {
key = normalizeKey(key)
this.assertHasDeep(key)
let child = this.getDeep(key)
let furthest = null
let next
while (next = this.getClosestInline(child)) {
furthest = next
child = next
}
return furthest
}, },
/** /**
* Get a child node by `key`. * Get a child node by `key`.
* *
* @param {String} key * @param {String} key
* @return {Node or Null} * @return {Node or Null} node
*/ */
getDeep(key) { getChild(key) {
key = normalizeKey(key) key = normalizeKey(key)
const match = this.findDeep(node => node.key == key) return this.nodes.find(node => node.key == key)
return match || null },
/**
* Get a descendant node by `key`.
*
* @param {String} key
* @return {Node or Null} node
*/
getDescendant(key) {
key = normalizeKey(key)
return this.findDescendant(node => node.key == key)
}, },
/** /**
@@ -352,7 +340,7 @@ const Node = {
getDepth(key, startAt = 1) { getDepth(key, startAt = 1) {
key = normalizeKey(key) key = normalizeKey(key)
this.assertHasDeep(key) this.assertHasDescendant(key)
const shallow = this.nodes.find(node => node.key == key) const shallow = this.nodes.find(node => node.key == key)
if (shallow) return startAt if (shallow) return startAt
@@ -360,7 +348,7 @@ const Node = {
const child = this.nodes.find(node => { const child = this.nodes.find(node => {
return node.kind == 'text' return node.kind == 'text'
? null ? null
: node.hasDeep(key) : node.hasDescendant(key)
}) })
return child return child
@@ -369,41 +357,58 @@ const Node = {
}, },
/** /**
* Get the first text child node. * Get the furthest block parent of a node by `key`.
* *
* @return {Text or Null} text * @param {String or Node} key
* @return {Node or Null} node
*/ */
getFirstText() { getFurthestBlock(key) {
return this.getTextNodes().first() || null let node = this.getDescendant(key)
let furthest = null
while (node = this.getClosestBlock(node)) {
furthest = node
}
return furthest
},
/**
* Get the furthest inline parent of a node by `key`.
*
* @param {String or Node} key
* @return {Node or Null} node
*/
getFurthestInline(key) {
let node = this.getDescendant(key)
let furthest = null
while (node = this.getClosestInline(node)) {
furthest = node
}
return furthest
}, },
/** /**
* Get the closest inline nodes for each text node in a `range`. * Get the closest inline nodes for each text node in a `range`.
* *
* @param {Selection} range * @param {Selection} range
* @return {OrderedMap} nodes * @return {List} nodes
*/ */
getInlinesAtRange(range) { getInlinesAtRange(range) {
range = range.normalize(this) range = range.normalize(this)
const node = this
const texts = node.getTextsAtRange(range)
const inlines = texts
.map(text => node.getClosest(text, p => p.kind == 'inline'))
.filter(inline => inline)
return inlines // If the range isn't set, return an empty list.
}, if (range.isUnset) return Inline.createList()
/** return this
* Get the last text child node. .getTextsAtRange(range)
* .map(text => this.getClosestInline(text))
* @return {Text or Null} text .filter(exists => exists)
*/
getLastText() {
return this.getTextNodes().last() || null
}, },
/** /**
@@ -415,65 +420,54 @@ const Node = {
getMarksAtRange(range) { getMarksAtRange(range) {
range = range.normalize(this) range = range.normalize(this)
const { startKey, startOffset, endKey } = range const { startKey, startOffset } = range
const marks = Mark.createSet()
// If the selection isn't set, return nothing. // If the range isn't set, return an empty set.
if (startKey == null || endKey == null) return new Set() if (range.isUnset) return marks
// If the range is collapsed, and at the start of the node, check the // If the range is collapsed at the start of the node, check the previous.
// previous text node.
if (range.isCollapsed && startOffset == 0) { if (range.isCollapsed && startOffset == 0) {
const previous = this.getPreviousText(startKey) const previous = this.getPreviousText(startKey)
if (!previous) return new Set() if (!previous) return marks
const char = text.characters.get(previous.length - 1) const char = text.characters.get(previous.length - 1)
return char.marks return char.marks
} }
// If the range is collapsed, check the character before the start. // If the range is collapsed, check the character before the start.
if (range.isCollapsed) { if (range.isCollapsed) {
const text = this.getDeep(startKey) const text = this.getDescendant(startKey)
const char = text.characters.get(range.startOffset - 1) const char = text.characters.get(range.startOffset - 1)
return char.marks return char.marks
} }
// Otherwise, get a set of the marks for each character in the range. // Otherwise, get a set of the marks for each character in the range.
const characters = this.getCharactersAtRange(range) this
let set = new Set() .getCharactersAtRange(range)
.reduce((marks, char) => {
characters.forEach((char) => { return marks.union(char.marks)
set = set.union(char.marks) }, marks)
})
return set
}, },
/** /**
* Get the child node after the one by `key`. * Get the node after a descendant by `key`.
* *
* @param {String or Node} key * @param {String or Node} key
* @return {Node or Null} * @return {Node or Null} node
*/ */
getNextSibling(key) { getNextSibling(key) {
key = normalizeKey(key) const node = this.getDescendant(key)
this.assertHasDeep(key) if (!node) return null
return this
const shallow = this.nodes.find(node => node.key == key) .getParent(node)
if (shallow) { .nodes
return this.nodes .skipUntil(child => child == node)
.skipUntil(node => node.key == key) .get(1)
.rest()
.first()
}
return this.nodes
.map(node => node.kind == 'text' ? null : node.getNextSibling(key))
.filter(node => node)
.first()
}, },
/** /**
* Get the text node after a text node by `key`. * Get the text node after a descendant text node by `key`.
* *
* @param {String or Node} key * @param {String or Node} key
* @return {Node or Null} node * @return {Node or Null} node
@@ -481,16 +475,13 @@ const Node = {
getNextText(key) { getNextText(key) {
key = normalizeKey(key) key = normalizeKey(key)
this.assertHasDeep(key)
return this.getTextNodes() return this.getTextNodes()
.skipUntil(text => text.key == key) .skipUntil(text => text.key == key)
.take(2) .get(1)
.last()
}, },
/** /**
* Get the offset for a child text node by `key`. * Get the offset for a descendant text node by `key`.
* *
* @param {String or Node} key * @param {String or Node} key
* @return {Number} offset * @return {Number} offset
@@ -498,16 +489,16 @@ const Node = {
getOffset(key) { getOffset(key) {
key = normalizeKey(key) key = normalizeKey(key)
this.assertHasDeep(key) this.assertHasDescendant(key)
const match = this.getDeep(key) const match = this.getDescendant(key)
// Find the shallow matching child. // Find the shallow matching child.
const child = this.nodes.find((node) => { const child = this.nodes.find((node) => {
if (node == match) return true if (node == match) return true
return node.kind == 'text' return node.kind == 'text'
? false ? false
: node.hasDeep(match) : node.hasDescendant(match)
}) })
// Get all of the nodes that come before the matching child. // Get all of the nodes that come before the matching child.
@@ -529,17 +520,15 @@ const Node = {
* Get the parent of a child node by `key`. * Get the parent of a child node by `key`.
* *
* @param {String or Node} key * @param {String or Node} key
* @return {Node or Null} * @return {Node or Null} node
*/ */
getParent(key) { getParent(key) {
key = normalizeKey(key) key = normalizeKey(key)
// this.assertHasDeep(key) if (this.hasChild(key)) return this
const shallow = this.nodes.find(node => node.key == key)
if (shallow) return this
let node = null let node = null
this.nodes.forEach((child) => { this.nodes.forEach((child) => {
if (child.kind == 'text') return if (child.kind == 'text') return
const match = child.getParent(key) const match = child.getParent(key)
@@ -550,31 +539,24 @@ const Node = {
}, },
/** /**
* Get the child node before the one by `key`. * Get the node before a descendant node by `key`.
* *
* @param {String or Node} key * @param {String or Node} key
* @return {Node or Null} * @return {Node or Null} node
*/ */
getPreviousSibling(key) { getPreviousSibling(key) {
key = normalizeKey(key) const node = this.getDescendant(key)
this.assertHasDeep(key) if (!node) return null
return this
const shallow = this.nodes.find(node => node.key == key) .getParent(node)
if (shallow) { .nodes
return this.nodes .takeUntil(child => child == node)
.takeUntil(node => node.key == key)
.last() .last()
}
return this.nodes
.map(node => node.kind == 'text' ? null : node.getPreviousSibling(key))
.filter(node => node)
.first()
}, },
/** /**
* Get the text node before a text node by `key`. * Get the text node before a descendant text node by `key`.
* *
* @param {String or Node} key * @param {String or Node} key
* @return {Node or Null} node * @return {Node or Null} node
@@ -582,35 +564,32 @@ const Node = {
getPreviousText(key) { getPreviousText(key) {
key = normalizeKey(key) key = normalizeKey(key)
this.assertHasDeep(key)
return this.getTextNodes() return this.getTextNodes()
.takeUntil(text => text.key == key) .takeUntil(text => text.key == key)
.last() .last()
}, },
/** /**
* Get the child text node at an `offset`. * Get the descendent text node at an `offset`.
* *
* @param {String} offset * @param {String} offset
* @return {Node or Null} * @return {Node or Null} node
*/ */
getTextAtOffset(offset) { getTextAtOffset(offset) {
let length = 0 let length = 0
let texts = this.getTextNodes() return this
let match = texts.find((node) => { .getTextNodes()
length += node.length .find((text) => {
length += text.length
return length >= offset return length >= offset
}) })
return match
}, },
/** /**
* Recursively get all of the child text nodes in order of appearance. * Recursively get all of the child text nodes in order of appearance.
* *
* @return {OrderedMap} nodes * @return {List} nodes
*/ */
getTextNodes() { getTextNodes() {
@@ -625,43 +604,49 @@ const Node = {
* Get all of the text nodes in a `range`. * Get all of the text nodes in a `range`.
* *
* @param {Selection} range * @param {Selection} range
* @return {OrderedMap} nodes * @return {List} nodes
*/ */
getTextsAtRange(range) { getTextsAtRange(range) {
range = range.normalize(this) range = range.normalize(this)
// If the selection is unset, return an empty list.
if (range.isUnset) return Block.createList()
const { startKey, endKey } = range const { startKey, endKey } = range
// If the selection is unset, return an empty map.
if (range.isUnset) return new OrderedMap()
// Assert that the nodes exist before searching.
this.assertHasDeep(startKey)
this.assertHasDeep(endKey)
// Return the text nodes after the start offset and before the end offset.
const texts = this.getTextNodes() const texts = this.getTextNodes()
const endNode = this.getDeep(endKey) const startText = this.getDescendant(startKey)
const afterStart = texts.skipUntil(node => node.key == startKey) const endText = this.getDescendant(endKey)
const upToEnd = afterStart.takeUntil(node => node.key == endKey) const start = texts.indexOf(startText)
const matches = upToEnd.push(endNode) const end = texts.indexOf(endText)
return matches return texts.slice(start, end + 1)
},
/**
* Check if a child node exists by `key`.
*
* @param {String or Node} key
* @return {Boolean} exists
*/
hasChild(key) {
key = normalizeKey(key)
return !! this.nodes.find(node => node.key == key)
}, },
/** /**
* Recursively check if a child node exists by `key`. * Recursively check if a child node exists by `key`.
* *
* @param {String or Node} key * @param {String or Node} key
* @return {Boolean} true * @return {Boolean} exists
*/ */
hasDeep(key) { hasDescendant(key) {
key = normalizeKey(key) key = normalizeKey(key)
return !! this.nodes.find((node) => { return !! this.nodes.find((node) => {
return node.kind == 'text' return node.kind == 'text'
? node.key == key ? node.key == key
: node.key == key || node.hasDeep(key) : node.key == key || node.hasDescendant(key)
}) })
}, },
@@ -684,7 +669,7 @@ const Node = {
} }
let { startKey, startOffset } = range let { startKey, startOffset } = range
let startNode = node.getDeep(startKey) let startNode = node.getDescendant(startKey)
let { characters } = startNode let { characters } = startNode
// Create a list of the new characters, with the marks from the previous // Create a list of the new characters, with the marks from the previous
@@ -764,7 +749,7 @@ const Node = {
let node = this let node = this
// See if there are any adjacent text nodes. // See if there are any adjacent text nodes.
let firstAdjacent = node.findDeep((child) => { let firstAdjacent = node.findDescendant((child) => {
if (child.kind != 'text') return if (child.kind != 'text') return
const parent = node.getParent(child) const parent = node.getParent(child)
const next = parent.getNextSibling(child) const next = parent.getNextSibling(child)
@@ -782,7 +767,7 @@ const Node = {
parent = parent.updateDeep(firstAdjacent) parent = parent.updateDeep(firstAdjacent)
// Then remove the second node. // Then remove the second node.
parent = parent.removeDeep(second) parent = parent.removeDescendant(second)
// If the parent isn't this node, it needs to be updated. // If the parent isn't this node, it needs to be updated.
if (parent != node) { if (parent != node) {
@@ -795,18 +780,6 @@ const Node = {
return node.normalize() return node.normalize()
}, },
/**
* Push a new `node` onto the map of nodes.
*
* @param {Node} node
* @return {Node} node
*/
pushNode(node) {
const nodes = this.nodes.push(node)
return this.merge({ nodes })
},
/** /**
* Remove a `node` from the children node map. * Remove a `node` from the children node map.
* *
@@ -814,9 +787,9 @@ const Node = {
* @return {Node} node * @return {Node} node
*/ */
removeDeep(key) { removeDescendant(key) {
key = normalizeKey(key) key = normalizeKey(key)
this.assertHasDeep(key) this.assertHasDescendant(key)
const nodes = this.nodes.filterNot(node => node.key == key) const nodes = this.nodes.filterNot(node => node.key == key)
return this.merge({ nodes }) return this.merge({ nodes })
}, },
@@ -913,14 +886,14 @@ const Node = {
// Find the highest inline elements that were split. // Find the highest inline elements that were split.
const { startKey } = range const { startKey } = range
const firstText = node.getDeep(startKey) const firstText = node.getDescendant(startKey)
const firstChild = node.getFurthestInline(firstText) || firstText const firstChild = node.getFurthestInline(firstText) || firstText
const secondText = node.getNextText(startKey) const secondText = node.getNextText(startKey)
const secondChild = node.getFurthestInline(secondText) || secondText const secondChild = node.getFurthestInline(secondText) || secondText
// Remove the second inline child from the first block. // Remove the second inline child from the first block.
let firstBlock = node.getBlocksAtRange(range).first() let firstBlock = node.getBlocksAtRange(range).first()
firstBlock = firstBlock.removeDeep(secondChild) firstBlock = firstBlock.removeDescendant(secondChild)
// Create a new block with the second inline child in it. // Create a new block with the second inline child in it.
const secondBlock = Block.create({ const secondBlock = Block.create({
@@ -961,7 +934,7 @@ const Node = {
// First split the text nodes. // First split the text nodes.
node = node.splitTextAtRange(range) node = node.splitTextAtRange(range)
let firstChild = node.getDeep(range.startKey) let firstChild = node.getDescendant(range.startKey)
let secondChild = node.getNextText(firstChild) let secondChild = node.getNextText(firstChild)
let parent let parent
@@ -1010,7 +983,7 @@ const Node = {
// Split the text node's characters. // Split the text node's characters.
const { startKey, startOffset } = range const { startKey, startOffset } = range
const text = node.getDeep(startKey) const text = node.getDescendant(startKey)
const { characters } = text const { characters } = text
const firstChars = characters.take(startOffset) const firstChars = characters.take(startOffset)
const secondChars = characters.skip(startOffset) const secondChars = characters.skip(startOffset)
@@ -1082,7 +1055,7 @@ const Node = {
*/ */
updateDeep(node) { updateDeep(node) {
// this.assertHasDeep(key) // this.assertHasDescendant(key)
const shallow = this.nodes.find(child => child.key == node.key) const shallow = this.nodes.find(child => child.key == node.key)
if (shallow) { if (shallow) {
@@ -1235,7 +1208,7 @@ const Node = {
// Determine the new end of the range, and split there. // Determine the new end of the range, and split there.
const { startKey, startOffset, endKey, endOffset } = range const { startKey, startOffset, endKey, endOffset } = range
const firstNode = node.getDeep(startKey) const firstNode = node.getDescendant(startKey)
const nextNode = node.getNextText(startKey) const nextNode = node.getNextText(startKey)
const end = startKey != endKey const end = startKey != endKey
? range.moveToEnd() ? range.moveToEnd()
@@ -1249,7 +1222,7 @@ const Node = {
node = node.splitInlineAtRange(end) node = node.splitInlineAtRange(end)
// Calculate the new range to wrap around. // Calculate the new range to wrap around.
const endNode = node.getDeep(end.anchorKey) const endNode = node.getDescendant(end.anchorKey)
range = Selection.create({ range = Selection.create({
anchorKey: nextNode.key, anchorKey: nextNode.key,
anchorOffset: 0, anchorOffset: 0,

View File

@@ -114,7 +114,7 @@ class Selection extends Record(DEFAULTS) {
isAtStartOf(node) { isAtStartOf(node) {
const { startKey, startOffset } = this const { startKey, startOffset } = this
const first = node.kind == 'text' ? node : node.getFirstText() const first = node.kind == 'text' ? node : node.getTextNodes().first()
return startKey == first.key && startOffset == 0 return startKey == first.key && startOffset == 0
} }
@@ -127,7 +127,7 @@ class Selection extends Record(DEFAULTS) {
isAtEndOf(node) { isAtEndOf(node) {
const { endKey, endOffset } = this const { endKey, endOffset } = this
const last = node.kind == 'text' ? node : node.getLastText() const last = node.kind == 'text' ? node : node.getTextNodes().last()
return endKey == last.key && endOffset == last.length return endKey == last.key && endOffset == last.length
} }
@@ -147,10 +147,10 @@ class Selection extends Record(DEFAULTS) {
if (anchorKey == null || focusKey == null) return selection if (anchorKey == null || focusKey == null) return selection
// Asset that the anchor and focus nodes exist in the node tree. // Asset that the anchor and focus nodes exist in the node tree.
node.assertHasDeep(anchorKey) node.assertHasDescendant(anchorKey)
node.assertHasDeep(focusKey) node.assertHasDescendant(focusKey)
let anchorNode = node.getDeep(anchorKey) let anchorNode = node.getDescendant(anchorKey)
let focusNode = node.getDeep(focusKey) let focusNode = node.getDescendant(focusKey)
// If the anchor node isn't a text node, match it to one. // If the anchor node isn't a text node, match it to one.
if (anchorNode.kind != 'text') { if (anchorNode.kind != 'text') {

View File

@@ -280,7 +280,7 @@ class State extends Record(DEFAULTS) {
// Determine what the selection should be after deleting. // Determine what the selection should be after deleting.
const { startKey } = selection const { startKey } = selection
const startNode = document.getDeep(startKey) const startNode = document.getDescendant(startKey)
if (selection.isExpanded) { if (selection.isExpanded) {
after = selection.moveToStart() after = selection.moveToStart()
@@ -410,7 +410,7 @@ class State extends Record(DEFAULTS) {
// Determine what the selection should be after splitting. // Determine what the selection should be after splitting.
const { startKey } = selection const { startKey } = selection
const startNode = document.getDeep(startKey) const startNode = document.getDescendant(startKey)
const parent = document.getParent(startNode) const parent = document.getParent(startNode)
const next = document.getNext(parent) const next = document.getNext(parent)
const text = next.nodes.first() const text = next.nodes.first()