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