1
0
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:
Ian Storm Taylor 2016-06-21 18:00:18 -07:00
parent 38b85fe720
commit fccf762efd
9 changed files with 110 additions and 53 deletions

View File

@ -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
}
/**

View File

@ -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>
)
}
}

View File

@ -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.

View File

@ -7,8 +7,7 @@ import { OrderedMap, Record } from 'immutable'
*/
const DEFAULTS = {
nodes: new OrderedMap(),
parent: null
nodes: new OrderedMap()
}
/**

View File

@ -1,7 +1,7 @@
import Node from './node'
import uid from 'uid'
import { OrderedMap, Record } from 'immutable'
import { Map, OrderedMap, Record } from 'immutable'
/**
* Record.

View File

@ -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()
}
/**

View File

@ -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
}
}
/**

View File

@ -8,8 +8,7 @@ import { List, Record } from 'immutable'
const DEFAULTS = {
characters: new List(),
key: null,
parent: null
key: null
}
/**

View File

@ -51,7 +51,11 @@ const TRANSFORM_TYPES = [
'split',
'splitAtRange',
'unmark',
'unmarkAtRange'
'unmarkAtRange',
'unwrap',
'unwrapAtRange',
'wrap',
'wrapAtRange'
]
/**