mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-07-31 12:30:11 +02:00
add wrap transform
This commit is contained in:
@@ -63,7 +63,7 @@ class App extends React.Component {
|
|||||||
return (props) => <blockquote>{props.children}</blockquote>
|
return (props) => <blockquote>{props.children}</blockquote>
|
||||||
}
|
}
|
||||||
case 'bulleted-list': {
|
case 'bulleted-list': {
|
||||||
return (props) => <ul>{props.chidlren}</ul>
|
return (props) => <ul>{props.children}</ul>
|
||||||
}
|
}
|
||||||
case 'heading-one': {
|
case 'heading-one': {
|
||||||
return (props) => <h1>{props.children}</h1>
|
return (props) => <h1>{props.children}</h1>
|
||||||
@@ -84,10 +84,7 @@ class App extends React.Component {
|
|||||||
return (props) => <h6>{props.children}</h6>
|
return (props) => <h6>{props.children}</h6>
|
||||||
}
|
}
|
||||||
case 'list-item': {
|
case 'list-item': {
|
||||||
return (props) => <li>{props.chidlren}</li>
|
return (props) => <li>{props.children}</li>
|
||||||
}
|
|
||||||
case 'numbered-list': {
|
|
||||||
return (props) => <ol>{props.children}</ol>
|
|
||||||
}
|
}
|
||||||
case 'paragraph': {
|
case 'paragraph': {
|
||||||
return (props) => <p>{props.children}</p>
|
return (props) => <p>{props.children}</p>
|
||||||
@@ -153,24 +150,28 @@ class App extends React.Component {
|
|||||||
case '>':
|
case '>':
|
||||||
transform = transform.setType('block-quote')
|
transform = transform.setType('block-quote')
|
||||||
break
|
break
|
||||||
|
case '*':
|
||||||
case '-':
|
case '-':
|
||||||
transform = transform.setType('list-item')
|
case '+':
|
||||||
const wrapper = document.getParentNode(node)
|
if (node.type == 'list-item') break
|
||||||
if (wrapper.type == 'paragraph') transform = transform.setType('bulleted-list')
|
transform = node.type == 'list-item'
|
||||||
if (wrapper.type == 'bulleted-list') transform = transform.wrap('list-item')
|
? transform
|
||||||
if (wrapper.type == 'list-item') transform = transform.wrap('unordered-list')
|
: transform
|
||||||
|
.setType('list-item')
|
||||||
|
.wrap('bulleted-list')
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
e.preventDefault()
|
||||||
|
|
||||||
state = transform
|
state = transform
|
||||||
.deleteAtRange(selection.extendBackwardToStartOf(node))
|
.deleteAtRange(selection.extendBackwardToStartOf(node))
|
||||||
.apply()
|
.apply()
|
||||||
|
|
||||||
selection = selection.moveToStartOf(node)
|
selection = selection.moveToStartOf(node)
|
||||||
state = state.merge({ selection })
|
state = state.merge({ selection })
|
||||||
e.preventDefault()
|
|
||||||
return state
|
return state
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,12 +190,16 @@ class App extends React.Component {
|
|||||||
const node = state.currentBlockNodes.first()
|
const node = state.currentBlockNodes.first()
|
||||||
if (!node) debugger
|
if (!node) debugger
|
||||||
if (node.type == 'paragraph') return
|
if (node.type == 'paragraph') return
|
||||||
|
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
return state
|
|
||||||
|
let transform = state
|
||||||
.transform()
|
.transform()
|
||||||
.setType('paragraph')
|
.setType('paragraph')
|
||||||
.apply()
|
|
||||||
|
if (node.type == 'list-item') transform = transform.unwrap('bulleted-list')
|
||||||
|
|
||||||
|
state = transform.apply()
|
||||||
|
return state
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -145,7 +145,6 @@ class Content extends React.Component {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
console.log('Rendered content.')
|
|
||||||
const { state } = this.props
|
const { state } = this.props
|
||||||
const { document } = state
|
const { document } = state
|
||||||
const children = document.nodes
|
const children = document.nodes
|
||||||
@@ -175,39 +174,65 @@ class Content extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render a single `node`.
|
* Render a `node`.
|
||||||
*
|
*
|
||||||
* @param {Node} node
|
* @param {Node} node
|
||||||
* @return {Component} component
|
* @return {Component} component
|
||||||
*/
|
*/
|
||||||
|
|
||||||
renderNode(node) {
|
renderNode(node) {
|
||||||
const { renderMark, renderNode, state } = this.props
|
switch (node.kind) {
|
||||||
|
case 'text':
|
||||||
if (node instanceof TextModel) {
|
return this.renderText(node)
|
||||||
return (
|
case 'block':
|
||||||
<Text
|
case 'inline':
|
||||||
key={node.key}
|
return this.renderElement(node)
|
||||||
node={node}
|
|
||||||
renderMark={renderMark}
|
|
||||||
state={state}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render a text `node`.
|
||||||
|
*
|
||||||
|
* @param {Node} node
|
||||||
|
* @return {Component} component
|
||||||
|
*/
|
||||||
|
|
||||||
|
renderText(node) {
|
||||||
|
const { renderMark, renderNode, state } = this.props
|
||||||
|
return (
|
||||||
|
<Text
|
||||||
|
key={node.key}
|
||||||
|
node={node}
|
||||||
|
renderMark={renderMark}
|
||||||
|
state={state}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render an element `node`.
|
||||||
|
*
|
||||||
|
* @param {Node} node
|
||||||
|
* @return {Component} component
|
||||||
|
*/
|
||||||
|
|
||||||
|
renderElement(node) {
|
||||||
|
const { renderNode, state } = this.props
|
||||||
const Component = renderNode(node)
|
const Component = renderNode(node)
|
||||||
const children = node.nodes
|
const children = node.nodes
|
||||||
.map(node => this.renderNode(node))
|
.map(child => this.renderNode(child))
|
||||||
.toArray()
|
.toArray()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Component
|
<Component
|
||||||
{...node}
|
|
||||||
key={node.key}
|
key={node.key}
|
||||||
children={children}
|
node={node}
|
||||||
state={state}
|
state={state}
|
||||||
/>
|
>
|
||||||
|
{children}
|
||||||
|
</Component>
|
||||||
)
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
import Node from './node'
|
import Node from './node'
|
||||||
import uid from 'uid'
|
import uid from 'uid'
|
||||||
import { OrderedMap, Record } from 'immutable'
|
import { Map, OrderedMap, Record } from 'immutable'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default properties.
|
* Default properties.
|
||||||
|
@@ -7,8 +7,7 @@ import { OrderedMap, Record } from 'immutable'
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
const DEFAULTS = {
|
const DEFAULTS = {
|
||||||
nodes: new OrderedMap(),
|
nodes: new OrderedMap()
|
||||||
parent: null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
import Node from './node'
|
import Node from './node'
|
||||||
import uid from 'uid'
|
import uid from 'uid'
|
||||||
import { OrderedMap, Record } from 'immutable'
|
import { Map, OrderedMap, Record } from 'immutable'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Record.
|
* Record.
|
||||||
|
@@ -886,32 +886,42 @@ const Node = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrap all of the nodes in a `range` in a new `parent` node.
|
* Wrap all of the nodes in a `range` in a new parent node of `type`.
|
||||||
*
|
*
|
||||||
* @param {Selection} range
|
* @param {Selection} range
|
||||||
* @param {Node or String} parent
|
* @param {String} type
|
||||||
* @return {Node} node
|
* @return {Node} node
|
||||||
*/
|
*/
|
||||||
|
|
||||||
wrapAtRange(range, parent) {
|
wrapAtRange(range, type) {
|
||||||
|
range = range.normalize(this)
|
||||||
let node = this
|
let node = this
|
||||||
range = range.normalize(node)
|
let blocks = node.getBlockNodesAtRange(range)
|
||||||
|
|
||||||
// Allow for the parent to by just a type.
|
// Iterate each of the block nodes, wrapping them.
|
||||||
if (typeof parent == 'string') {
|
blocks.forEach((block) => {
|
||||||
parent = Block.create({ type: parent })
|
let isDirectChild = node.nodes.has(block.key)
|
||||||
}
|
let parent = isDirectChild ? node : node.getParentNode(block)
|
||||||
|
|
||||||
// Add the child to the parent's nodes.
|
// Create a new wrapper containing the block.
|
||||||
const child = node.findNode(key)
|
let nodes = Block.createMap([ block ])
|
||||||
parent = node.nodes.set(child.key, child)
|
let wrapper = Block.create({ type, nodes })
|
||||||
|
|
||||||
// Remove the child from this node.
|
// Replace the block in it's parent with the wrapper.
|
||||||
node = node.removeNode(child)
|
nodes = parent.nodes.takeUntil(node => node == block)
|
||||||
|
.set(wrapper.key, wrapper)
|
||||||
|
.concat(parent.nodes.skipUntil(node => node == block).rest())
|
||||||
|
|
||||||
// Add the parent to this node.
|
// Update the parent.
|
||||||
|
if (isDirectChild) {
|
||||||
|
node = node.merge({ nodes })
|
||||||
|
} else {
|
||||||
|
parent = parent.merge({ nodes })
|
||||||
|
node = node.updateNode(parent)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
return node
|
return node.normalize()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -338,6 +338,21 @@ class State extends Record(DEFAULTS) {
|
|||||||
return state
|
return state
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrap the block nodes in the current selection in new nodes of `type`.
|
||||||
|
*
|
||||||
|
* @param {String} type
|
||||||
|
* @return {State} state
|
||||||
|
*/
|
||||||
|
|
||||||
|
wrap(type) {
|
||||||
|
let state = this
|
||||||
|
let { document, selection } = state
|
||||||
|
document = document.wrapAtRange(selection, type)
|
||||||
|
state = state.merge({ document })
|
||||||
|
return state
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -8,8 +8,7 @@ import { List, Record } from 'immutable'
|
|||||||
|
|
||||||
const DEFAULTS = {
|
const DEFAULTS = {
|
||||||
characters: new List(),
|
characters: new List(),
|
||||||
key: null,
|
key: null
|
||||||
parent: null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -51,7 +51,11 @@ const TRANSFORM_TYPES = [
|
|||||||
'split',
|
'split',
|
||||||
'splitAtRange',
|
'splitAtRange',
|
||||||
'unmark',
|
'unmark',
|
||||||
'unmarkAtRange'
|
'unmarkAtRange',
|
||||||
|
'unwrap',
|
||||||
|
'unwrapAtRange',
|
||||||
|
'wrap',
|
||||||
|
'wrapAtRange'
|
||||||
]
|
]
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user