1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-08-30 18:39:51 +02:00

add the ability to render based on multiple marks (#138)

closes #33
This commit is contained in:
Ian Storm Taylor
2016-07-20 15:11:13 -07:00
committed by GitHub
parent 8654dfc929
commit d0c8ce0c08
6 changed files with 61 additions and 6 deletions

View File

@@ -102,14 +102,14 @@ If no other plugin handles this event, it will be handled by the [Core plugin](.
To customize the renderer output of the editor, plugins can define a set of "renderer" properties.
### `renderDecorations`
`Function renderDecorations(text: Text) => Characters || Void`
`Function renderDecorations(text: Text, state: State, editor: Editor) => Characters || Void`
The `renderDecorations` handler allows you to add dynamic, content-aware [`Marks`](../models/mark.md) to ranges of text, without having them show up in the serialized state of the editor. This is useful for things like code highlighting, where the marks will change as the user types.
`renderDecorations` is called for every `text` node in the document, and should return a set of updated [`Characters`](../models/character.md) for the text node in question. Every plugin's decoration logic is called, and the resulting characters are unioned, such that multiple plugins can apply decorations to the same pieces of text.
### `renderMark`
`Function renderMark(mark: Mark) => Object || Void`
`Function renderMark(mark: Mark, marks: Set, state: State, editor: Editor) => Object || Void`
The `renderMark` handler allows you to define the styles that each mark should be rendered with. It takes a [`Mark`](../models/mark.md) object, and should return a dictionary of styles that will be applied via React's `style=` property. For example:
@@ -121,7 +121,7 @@ The `renderMark` handler allows you to define the styles that each mark should b
```
### `renderNode`
`Function renderNode(node: Block || Inline) => Component || Void`
`Function renderNode(node: Block || Inline, state: State, editor: Editor) => Component || Void`
The `renderNode` handler allows you to define the component that will be used to render a node—both blocks and inlines. It takes a [`Node`](../models/node.md) object, and should return a React component.

View File

@@ -233,13 +233,14 @@ class Editor extends React.Component {
* Render a `mark`, cascading through the plugins.
*
* @param {Mark} mark
* @param {Set} marks
* @return {Object} style
*/
renderMark = (mark) => {
renderMark = (mark, marks) => {
for (const plugin of this.state.plugins) {
if (!plugin.renderMark) continue
const style = plugin.renderMark(mark, this.state.state, this)
const style = plugin.renderMark(mark, marks, this.state.state, this)
if (style) return style
}
}

View File

@@ -129,7 +129,7 @@ class Leaf extends React.Component {
const style = marks.reduce((memo, mark) => {
return {
...memo,
...renderMark(mark),
...renderMark(mark, marks),
}
}, {})

View File

@@ -0,0 +1,27 @@
import React from 'react'
const BOLD = {
fontWeight: 'bold'
}
const ITALIC = {
fontStyle: 'italic'
}
const BOLD_ITALIC = {
fontFamily: 'bold-italic'
}
export function renderMark(mark, marks) {
if (
marks.size > 1 &&
marks.some(m => m.type == 'bold') &&
marks.some(m => m.type == 'italic')
) {
return BOLD_ITALIC
}
if (mark.type == 'bold') return BOLD
if (mark.type == 'italic') return ITALIC
}

View File

@@ -0,0 +1,17 @@
nodes:
- kind: block
type: default
nodes:
- kind: text
ranges:
- text: one
marks:
- type: bold
- text: two
marks:
- type: italic
- text: three
marks:
- type: bold
- type: italic

View File

@@ -0,0 +1,10 @@
<div contenteditable="true">
<div>
<span>
<span style="font-weight:bold;">one</span>
<span style="font-style:italic;">two</span>
<span style="font-family:bold-italic;">three</span>
</span>
</div>
</div>