diff --git a/docs/reference/Readme.md b/docs/reference/Readme.md index 5c52cbd37..21ac63a6a 100644 --- a/docs/reference/Readme.md +++ b/docs/reference/Readme.md @@ -9,19 +9,19 @@ This is the full reference documentation for all of the pieces of Slate, broken - **Models** - [Block](./models/block.md) - [Character](./models/character.md) - - [Data](./data.md) + - [Data](./models/data.md) - [Document](./models/document.md) - [Inline](./models/inline.md) - [Mark](./models/mark.md) - [Node](./models/node.md) - [Selection](./models/selection.md) - [State](./models/state.md) - - [Text](./text.md) + - [Text](./models/text.md) - [Transform](./models/transform.md) - **Serializers** - - [Html](./html.md) - - [Plain](./plain.md) - - [Raw](./raw.md) + - [Html](./serializers/html.md) + - [Plain](./serializers/plain.md) + - [Raw](./serializers/raw.md) - **Plugins** - [Plugins](./plugins/plugins.md) - [Core](./plugins/core.md) diff --git a/examples/rich-text/index.js b/examples/rich-text/index.js index f3a48e327..bc5703504 100644 --- a/examples/rich-text/index.js +++ b/examples/rich-text/index.js @@ -17,7 +17,7 @@ const DEFAULT_NODE = 'paragraph' */ const NODES = { - 'block-quote': props =>
{props.children}
, + 'block-quote': (props) =>
{props.children}
, 'bulleted-list': props => , 'heading-one': props =>

{props.children}

, 'heading-two': props =>

{props.children}

, diff --git a/lib/models/node.js b/lib/models/node.js index 2d27144eb..80f49260b 100644 --- a/lib/models/node.js +++ b/lib/models/node.js @@ -824,16 +824,40 @@ const Node = { }, /** - * Map all children nodes, updating them in their parents. + * Map all child nodes, updating them in their parents. This method is + * optimized to not return a new node if no changes are made. + * + * @param {Function} iterator + * @return {Node} node + */ + + mapChildren(iterator) { + let nodes = this.nodes + + nodes.forEach((node, i) => { + let ret = iterator(node, i, this.nodes) + if (ret != node) nodes = nodes.set(ret.key, ret) + }) + + return this.merge({ nodes }) + }, + + /** + * Map all descendant nodes, updating them in their parents. This method is + * optimized to not return a new node if no changes are made. * * @param {Function} iterator * @return {Node} node */ mapDescendants(iterator) { - const nodes = this.nodes.map((node, i, original) => { - if (node.kind != 'text') node = node.mapDescendants(iterator) - return iterator(node, i, original) + let nodes = this.nodes + + nodes.forEach((node, i) => { + let ret = node + if (ret.kind != 'text') ret = ret.mapDescendants(iterator) + ret = iterator(ret, i, this.nodes) + if (ret != node) nodes = nodes.set(ret.key, ret) }) return this.merge({ nodes }) @@ -952,12 +976,7 @@ const Node = { return this.merge({ nodes }) } - const nodes = this.nodes.map((node) => { - return node.kind == 'text' - ? node - : node.removeDescendant(key) - }) - + const nodes = this.mapChildren(n => n.kind == 'text' ? n : n.removeDescendant(key)) return this.merge({ nodes }) }, @@ -970,19 +989,7 @@ const Node = { updateDescendant(node) { this.assertHasDescendant(node) - - if (this.hasChild(node)) { - const nodes = this.nodes.map(child => child.key == node.key ? node : child) - return this.merge({ nodes }) - } - - const nodes = this.nodes.map((child) => { - if (child.kind == 'text') return child - if (!child.hasDescendant(node)) return child - return child.updateDescendant(node) - }) - - return this.merge({ nodes }) + return this.mapDescendants(d => d.key == node.key ? node : d) } } diff --git a/lib/plugins/core.js b/lib/plugins/core.js index 7b1d5a5e5..e7d5c2ef6 100644 --- a/lib/plugins/core.js +++ b/lib/plugins/core.js @@ -38,6 +38,13 @@ function Plugin(options = {}) { state: React.PropTypes.object.isRequired }; + shouldComponentUpdate = (props, state) => { + return ( + props.node != this.props.node || + props.state.selection.hasEdgeIn(props.node) + ) + } + render = () => { const { attributes, children } = this.props return ( @@ -80,6 +87,13 @@ function Plugin(options = {}) { state: React.PropTypes.object.isRequired }; + shouldComponentUpdate = (props, state) => { + return ( + props.node != this.props.node || + props.state.selection.hasEdgeIn(props.node) + ) + } + render = () => { const { attributes, children } = this.props return {children}