1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-08-10 01:06:37 +02:00

add rendering of marks from schema

This commit is contained in:
Ian Storm Taylor
2016-08-13 17:11:22 -07:00
parent eeb97c0611
commit 722bf0cf83
7 changed files with 62 additions and 47 deletions

View File

@@ -23,16 +23,8 @@ const schema = {
'heading-two': props => <h2 {...props.attributes}>{props.children}</h2>, 'heading-two': props => <h2 {...props.attributes}>{props.children}</h2>,
'list-item': props => <li {...props.attributes}>{props.children}</li>, 'list-item': props => <li {...props.attributes}>{props.children}</li>,
'numbered-list': props => <ol {...props.attributes}>{props.children}</ol>, 'numbered-list': props => <ol {...props.attributes}>{props.children}</ol>,
} },
} marks: {
/**
* Define a set of mark renderers.
*
* @type {Object}
*/
const MARKS = {
bold: { bold: {
fontWeight: 'bold' fontWeight: 'bold'
}, },
@@ -49,6 +41,7 @@ const MARKS = {
textDecoration: 'underline' textDecoration: 'underline'
} }
} }
}
/** /**
* The rich text example. * The rich text example.

View File

@@ -56,7 +56,6 @@ class Content extends React.Component {
onSelect: React.PropTypes.func.isRequired, onSelect: React.PropTypes.func.isRequired,
readOnly: React.PropTypes.bool.isRequired, readOnly: React.PropTypes.bool.isRequired,
renderDecorations: React.PropTypes.func.isRequired, renderDecorations: React.PropTypes.func.isRequired,
renderMark: React.PropTypes.func.isRequired,
schema: React.PropTypes.object, schema: React.PropTypes.object,
spellCheck: React.PropTypes.bool.isRequired, spellCheck: React.PropTypes.bool.isRequired,
state: React.PropTypes.object.isRequired, state: React.PropTypes.object.isRequired,
@@ -684,7 +683,7 @@ class Content extends React.Component {
*/ */
renderNode = (node) => { renderNode = (node) => {
const { editor, renderDecorations, renderMark, schema, state } = this.props const { editor, renderDecorations, schema, state } = this.props
return ( return (
<Node <Node
@@ -694,7 +693,6 @@ class Content extends React.Component {
state={state} state={state}
editor={editor} editor={editor}
renderDecorations={renderDecorations} renderDecorations={renderDecorations}
renderMark={renderMark}
/> />
) )
} }

View File

@@ -63,8 +63,6 @@ class Editor extends React.Component {
plugins: React.PropTypes.array, plugins: React.PropTypes.array,
readOnly: React.PropTypes.bool, readOnly: React.PropTypes.bool,
renderDecorations: React.PropTypes.func, renderDecorations: React.PropTypes.func,
renderMark: React.PropTypes.func,
renderNode: React.PropTypes.func,
schema: React.PropTypes.object, schema: React.PropTypes.object,
spellCheck: React.PropTypes.bool, spellCheck: React.PropTypes.bool,
state: React.PropTypes.object.isRequired, state: React.PropTypes.object.isRequired,
@@ -267,7 +265,6 @@ class Editor extends React.Component {
onChange={this.onChange} onChange={this.onChange}
readOnly={this.props.readOnly} readOnly={this.props.readOnly}
renderDecorations={this.renderDecorations} renderDecorations={this.renderDecorations}
renderMark={this.renderMark}
schema={this.state.schema} schema={this.state.schema}
spellCheck={this.props.spellCheck} spellCheck={this.props.spellCheck}
state={this.state.state} state={this.state.state}

View File

@@ -33,7 +33,7 @@ class Leaf extends React.Component {
marks: React.PropTypes.object.isRequired, marks: React.PropTypes.object.isRequired,
node: React.PropTypes.object.isRequired, node: React.PropTypes.object.isRequired,
ranges: React.PropTypes.object.isRequired, ranges: React.PropTypes.object.isRequired,
renderMark: React.PropTypes.func.isRequired, schema: React.PropTypes.object.isRequired,
state: React.PropTypes.object.isRequired, state: React.PropTypes.object.isRequired,
text: React.PropTypes.string.isRequired text: React.PropTypes.string.isRequired
}; };
@@ -83,7 +83,7 @@ class Leaf extends React.Component {
if ( if (
props.index != this.props.index || props.index != this.props.index ||
props.marks != this.props.marks || props.marks != this.props.marks ||
props.renderMark != this.props.renderMark || props.schema != this.props.schema ||
props.text != this.props.text props.text != this.props.text
) { ) {
return true return true
@@ -257,11 +257,11 @@ class Leaf extends React.Component {
*/ */
renderMarks(props) { renderMarks(props) {
const { marks, renderMark } = props const { marks, schema } = props
const text = this.renderText(props) const text = this.renderText(props)
return marks.reduce((children, mark) => { return marks.reduce((children, mark) => {
const Component = renderMark(mark, marks) const Component = mark.getComponent(schema)
if (!Component) return children if (!Component) return children
return <Component mark={mark} marks={marks}>{children}</Component> return <Component mark={mark} marks={marks}>{children}</Component>
}, text) }, text)

View File

@@ -35,7 +35,6 @@ class Node extends React.Component {
editor: React.PropTypes.object.isRequired, editor: React.PropTypes.object.isRequired,
node: React.PropTypes.object.isRequired, node: React.PropTypes.object.isRequired,
renderDecorations: React.PropTypes.func.isRequired, renderDecorations: React.PropTypes.func.isRequired,
renderMark: React.PropTypes.func.isRequired,
schema: React.PropTypes.object.isRequired, schema: React.PropTypes.object.isRequired,
state: React.PropTypes.object.isRequired state: React.PropTypes.object.isRequired
}; };
@@ -214,7 +213,7 @@ class Node extends React.Component {
*/ */
renderNode = (child) => { renderNode = (child) => {
const { editor, node, renderDecorations, renderMark, schema, state } = this.props const { editor, node, renderDecorations, schema, state } = this.props
const block = node.kind == 'block' ? node : this.props.block const block = node.kind == 'block' ? node : this.props.block
return ( return (
<Node <Node
@@ -225,7 +224,6 @@ class Node extends React.Component {
state={state} state={state}
editor={editor} editor={editor}
renderDecorations={renderDecorations} renderDecorations={renderDecorations}
renderMark={renderMark}
/> />
) )
} }
@@ -309,7 +307,7 @@ class Node extends React.Component {
*/ */
renderLeaf = (ranges, range, index, offset) => { renderLeaf = (ranges, range, index, offset) => {
const { node, renderMark, state } = this.props const { node, schema, state } = this.props
const text = range.text const text = range.text
const marks = range.marks const marks = range.marks
@@ -317,12 +315,12 @@ class Node extends React.Component {
<Leaf <Leaf
key={`${node.key}-${index}`} key={`${node.key}-${index}`}
index={index} index={index}
state={state}
node={node}
text={text}
marks={marks} marks={marks}
node={node}
ranges={ranges} ranges={ranges}
renderMark={renderMark} schema={schema}
state={state}
text={text}
/> />
) )
} }

View File

@@ -1,5 +1,6 @@
import Data from './data' import Data from './data'
import memoize from '../utils/memoize'
import { Map, Record, Set } from 'immutable' import { Map, Record, Set } from 'immutable'
/** /**
@@ -66,6 +67,14 @@ class Mark extends new Record(DEFAULTS) {
} }
/**
* Memoize read methods.
*/
memoize(Mark.prototype, [
'getComponent',
])
/** /**
* Export. * Export.
*/ */

View File

@@ -1,6 +1,8 @@
import React from 'react'
import RULES from '../constants/rules' import RULES from '../constants/rules'
import includes from 'lodash/includes' import includes from 'lodash/includes'
import isReactComponent from '../utils/is-react-component'
import typeOf from 'type-of' import typeOf from 'type-of'
import memoize from '../utils/memoize' import memoize from '../utils/memoize'
import { Record } from 'immutable' import { Record } from 'immutable'
@@ -150,7 +152,24 @@ class Schema extends new Record(DEFAULTS) {
__getComponent(object) { __getComponent(object) {
const match = this.rules.find(rule => rule.match(object) && rule.component) const match = this.rules.find(rule => rule.match(object) && rule.component)
if (!match) return if (!match) return
return match.component
const { component } = match
// Marks need special handling to normalize components.
if (object.kind != 'mark') return match.component
// If it's a React component, we're good.
if (isReactComponent(component)) return component
// Handle all other types...
switch (typeOf(component)) {
case 'function':
return component
case 'object':
return props => <span style={component}>{props.children}</span>
case 'string':
return props => <span className={component}>{props.children}</span>
}
} }
/** /**
@@ -331,18 +350,19 @@ function normalizeSpec(obj, giveReason) {
const fail = CHECKS[key] const fail = CHECKS[key]
const failure = fail(node, value) const failure = fail(node, value)
if (failure === undefined) continue
if (!giveReason) { if (giveReason) {
return !failure
}
if (failure != undefined) {
return { return {
type: key, type: key,
value: failure value: failure
} }
} else {
return false
} }
} }
return giveReason ? undefined : true
} }
} }