1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-08-01 04:50:27 +02:00

Fix spell check bug (#1753)

* Fix spell check bug by add data-text:true

* Fix spell check bug by spell check add length to a leaf

* Fix tests to use data-text:true for marks

* Rename data-text to data-slate-leaf; Remove setRef; unlift attributes in leaf

* Update examples with data-*

* Add attributes to document

* Fix renderMark in all documents

* Prettier markdown
This commit is contained in:
Jinxuan Zhu
2018-04-27 17:06:24 -04:00
committed by Ian Storm Taylor
parent 9b39a89f20
commit 6e6e9cf710
16 changed files with 101 additions and 59 deletions

View File

@@ -69,22 +69,24 @@ Marks work the same way, except they invoke the `renderMark` function. Like so:
```js
function renderMark(props) {
const { children, mark } = props
const { children, mark, attributes } = props
switch (mark.type) {
case 'bold':
return <strong>{children}</strong>
return <strong {...{ attributes }}>{children}</strong>
case 'italic':
return <em>{children}</em>
return <em {...{ attributes }}>{children}</em>
case 'code':
return <code>{children}</code>
return <code {...{ attributes }}>{children}</code>
case 'underline':
return <u>{children}</u>
return <u {...{ attributes }}>{children}</u>
case 'strikethrough':
return <strike>{children}</strike>
return <strike {...{ attributes }}>{children}</strike>
}
}
```
Be sure to mix `props.attributes` in your `renderMark`. `attributes` provides `data-*` dom attributes for spell-check in non-IE browsers.
That way, if you happen to have a global stylesheet that defines `strong`, `em`, etc. styles then your editor's content will already be formatted!
> 🤖 Be aware though that marks aren't guaranteed to be "contiguous". Which means even though a **word** is bolded, it's not guaranteed to render as a single `<strong>` element. If some of its characters are also italic, it might be split up into multiple elements—one `<strong>wo</strong>` and one `<em><strong>rd</strong></em>`.

View File

@@ -268,13 +268,14 @@ class App extends React.Component {
// Add a `renderMark` method to render marks.
renderMark = props => {
switch (props.mark.type) {
const { mark, attributes } = props
switch (mark.type) {
case 'bold':
return <strong>{props.children}</strong>
return <strong {...{ attributes }}>{props.children}</strong>
case 'italic':
return <em>{props.children}</em>
return <em {...{ attributes }}>{props.children}</em>
case 'underline':
return <u>{props.children}</u>
return <u {...{ attributes }}>{props.children}</u>
}
}
}

View File

@@ -43,7 +43,7 @@ class App extends React.Component {
renderMark = props => {
switch (props.mark.type) {
case 'bold':
return <strong>{props.children}</strong>
return <strong {...{props.attributes}}>{props.children}</strong>
}
}
}

View File

@@ -136,16 +136,32 @@ class CodeHighlighting extends React.Component {
*/
renderMark = props => {
const { children, mark } = props
const { children, mark, attributes } = props
switch (mark.type) {
case 'comment':
return <span style={{ opacity: '0.33' }}>{children}</span>
return (
<span {...attributes} style={{ opacity: '0.33' }}>
{children}
</span>
)
case 'keyword':
return <span style={{ fontWeight: 'bold' }}>{children}</span>
return (
<span {...attributes} style={{ fontWeight: 'bold' }}>
{children}
</span>
)
case 'tag':
return <span style={{ fontWeight: 'bold' }}>{children}</span>
return (
<span {...attributes} style={{ fontWeight: 'bold' }}>
{children}
</span>
)
case 'punctuation':
return <span style={{ opacity: '0.75' }}>{children}</span>
return (
<span {...attributes} style={{ opacity: '0.75' }}>
{children}
</span>
)
}
}

View File

@@ -187,16 +187,16 @@ class HoveringMenu extends React.Component {
*/
renderMark = props => {
const { children, mark } = props
const { children, mark, attributes } = props
switch (mark.type) {
case 'bold':
return <strong>{children}</strong>
return <strong {...attributes}>{children}</strong>
case 'code':
return <code>{children}</code>
return <code {...attributes}>{children}</code>
case 'italic':
return <em>{children}</em>
return <em {...attributes}>{children}</em>
case 'underlined':
return <u>{children}</u>
return <u {...attributes}>{children}</u>
}
}
}

View File

@@ -110,16 +110,16 @@ class HugeDocument extends React.Component {
*/
renderMark = props => {
const { children, mark } = props
const { children, mark, attributes } = props
switch (mark.type) {
case 'bold':
return <strong>{children}</strong>
return <strong {...attributes}>{children}</strong>
case 'code':
return <code>{children}</code>
return <code {...attributes}>{children}</code>
case 'italic':
return <em>{children}</em>
return <em {...attributes}>{children}</em>
case 'underlined':
return <u>{children}</u>
return <u {...attributes}>{children}</u>
}
}
}

View File

@@ -69,19 +69,20 @@ class MarkdownPreview extends React.Component {
*/
renderMark = props => {
const { children, mark } = props
const { children, mark, attributes } = props
switch (mark.type) {
case 'bold':
return <strong>{children}</strong>
return <strong {...attributes}>{children}</strong>
case 'code':
return <code>{children}</code>
return <code {...attributes}>{children}</code>
case 'italic':
return <em>{children}</em>
return <em {...attributes}>{children}</em>
case 'underlined':
return <u>{children}</u>
return <u {...attributes}>{children}</u>
case 'title': {
return (
<span
{...attributes}
style={{
fontWeight: 'bold',
fontSize: '20px',
@@ -94,11 +95,16 @@ class MarkdownPreview extends React.Component {
)
}
case 'punctuation': {
return <span style={{ opacity: 0.2 }}>{children}</span>
return (
<span {...attributes} style={{ opacity: 0.2 }}>
{children}
</span>
)
}
case 'list': {
return (
<span
{...attributes}
style={{
paddingLeft: '10px',
lineHeight: '10px',
@@ -112,6 +118,7 @@ class MarkdownPreview extends React.Component {
case 'hr': {
return (
<span
{...attributes}
style={{
borderBottom: '2px solid #000',
display: 'block',

View File

@@ -257,16 +257,16 @@ class PasteHtml extends React.Component {
*/
renderMark = props => {
const { children, mark } = props
const { children, mark, attributes } = props
switch (mark.type) {
case 'bold':
return <strong>{children}</strong>
return <strong {...attributes}>{children}</strong>
case 'code':
return <code>{children}</code>
return <code {...attributes}>{children}</code>
case 'italic':
return <em>{children}</em>
return <em {...attributes}>{children}</em>
case 'underlined':
return <u>{children}</u>
return <u {...attributes}>{children}</u>
}
}
}

View File

@@ -302,16 +302,16 @@ class RichTextExample extends React.Component {
*/
renderMark = props => {
const { children, mark } = props
const { children, mark, attributes } = props
switch (mark.type) {
case 'bold':
return <strong>{children}</strong>
return <strong {...attributes}>{children}</strong>
case 'code':
return <code>{children}</code>
return <code {...attributes}>{children}</code>
case 'italic':
return <em>{children}</em>
return <em {...attributes}>{children}</em>
case 'underlined':
return <u>{children}</u>
return <u {...attributes}>{children}</u>
}
}
}

View File

@@ -140,10 +140,14 @@ class SearchHighlighting extends React.Component {
*/
renderMark = props => {
const { children, mark } = props
const { children, mark, attributes } = props
switch (mark.type) {
case 'highlight':
return <span style={{ backgroundColor: '#ffeeba' }}>{children}</span>
return (
<span {...attributes} style={{ backgroundColor: '#ffeeba' }}>
{children}
</span>
)
}
}
}

View File

@@ -197,16 +197,16 @@ class SyncingEditor extends React.Component {
*/
renderMark = props => {
const { children, mark } = props
const { children, mark, attributes } = props
switch (mark.type) {
case 'bold':
return <strong>{children}</strong>
return <strong {...attributes}>{children}</strong>
case 'code':
return <code>{children}</code>
return <code {...attributes}>{children}</code>
case 'italic':
return <em>{children}</em>
return <em {...attributes}>{children}</em>
case 'underlined':
return <u>{children}</u>
return <u {...attributes}>{children}</u>
}
}
}

View File

@@ -160,10 +160,10 @@ class Tables extends React.Component {
*/
renderMark = props => {
const { children, mark } = props
const { children, mark, attributes } = props
switch (mark.type) {
case 'bold':
return <strong>{children}</strong>
return <strong {...attributes}>{children}</strong>
}
}
}

View File

@@ -99,9 +99,21 @@ class Leaf extends React.Component {
const { marks, node, offset, text, editor } = this.props
const { stack } = editor
const leaf = this.renderText()
const attributes = {
'data-slate-leaf': true,
}
return marks.reduce((children, mark) => {
const props = { editor, mark, marks, node, offset, text, children }
const props = {
editor,
mark,
marks,
node,
offset,
text,
children,
attributes,
}
const element = stack.find('renderMark', props)
return element || children
}, leaf)

View File

@@ -305,8 +305,8 @@ function AfterPlugin() {
// Get the selection point.
const native = window.getSelection()
const { anchorNode, anchorOffset } = native
const point = findPoint(anchorNode, anchorOffset, value)
const { anchorNode } = native
const point = findPoint(anchorNode, 0, value)
if (!point) return
// Get the text node and leaf in question.
@@ -323,7 +323,7 @@ function AfterPlugin() {
leaves.find(r => {
start = end
end += r.text.length
if (end >= point.offset) return true
if (end > point.offset) return true
}) || lastLeaf
// Get the text information.

View File

@@ -17,7 +17,7 @@ function decorateNode(block) {
}
function Bold(props) {
return React.createElement('strong', null, props.children)
return React.createElement('strong', { ...props.attributes }, props.children)
}
function renderMark(props) {
@@ -45,7 +45,7 @@ export const output = `
<div style="position:relative">
<span>
<span>o</span>
<span><strong>n</strong></span>
<span><strong data-slate-leaf="true">n</strong></span>
<span>e</span>
</span>
</div>

View File

@@ -4,7 +4,7 @@ import React from 'react'
import h from '../../helpers/h'
function Bold(props) {
return React.createElement('strong', null, props.children)
return React.createElement('strong', { ...props.attributes }, props.children)
}
function renderMark(props) {
@@ -33,7 +33,7 @@ export const output = `
<div style="position:relative">
<span>
<span>one</span>
<span><strong>two</strong></span>
<span><strong data-slate-leaf="true">two</strong></span>
<span>three</span>
</span>
</div>