mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-31 19:01:54 +02:00
Merge branch 'master' into schema-normalize
This commit is contained in:
@@ -47,10 +47,10 @@ npm install
|
|||||||
Which will also compile the source files. Then run the tests with:
|
Which will also compile the source files. Then run the tests with:
|
||||||
|
|
||||||
```
|
```
|
||||||
npm test
|
npm run tests
|
||||||
```
|
```
|
||||||
|
|
||||||
If you need to debug something, you can add a `debugger` line to the source, and then run `npm test debug`. Or, if you only want to run a specific test or tests, you can run `npm test -- --fgrep "match this string"` flag which will filter the tests being run.
|
If you need to debug something, you can add a `debugger` line to the source, and then run `npm run tests debug`. Or, if you only want to run a specific test or tests, you can run `npm run tests -- --fgrep "match this string"` flag which will filter the tests being run.
|
||||||
|
|
||||||
To keep the source rebuilding on every file change, you need to run an additional watching command:
|
To keep the source rebuilding on every file change, you need to run an additional watching command:
|
||||||
|
|
||||||
|
@@ -74,7 +74,7 @@ A convenience handler property that will only be called for changes in state whe
|
|||||||
### `plugins`
|
### `plugins`
|
||||||
`Array`
|
`Array`
|
||||||
|
|
||||||
An array of [`Plugins`](../plugins) that define the editor's behavior.
|
An array of [`Plugins`](../plugins/plugin.md) that define the editor's behavior.
|
||||||
|
|
||||||
### `readOnly`
|
### `readOnly`
|
||||||
`Boolean`
|
`Boolean`
|
||||||
@@ -84,7 +84,7 @@ Whether the editor should be in "read-only" mode, where all of the rendering is
|
|||||||
### `state`
|
### `state`
|
||||||
`State`
|
`State`
|
||||||
|
|
||||||
A [`State`](../models/state) object representing the current state of the editor.
|
A [`State`](../models/state.md) object representing the current state of the editor.
|
||||||
|
|
||||||
### `style`
|
### `style`
|
||||||
`Object`
|
`Object`
|
||||||
@@ -120,7 +120,7 @@ An optional dictionary of styles to apply to the default block type's placeholde
|
|||||||
|
|
||||||
## Plugin-like Properties
|
## Plugin-like Properties
|
||||||
|
|
||||||
In addition to its own properties, the editor allows passing any of the properties that a [plugin](../plugins/plugins.md) defines as well.
|
In addition to its own properties, the editor allows passing any of the properties that a [plugin](../plugins/plugin.md) defines as well.
|
||||||
|
|
||||||
These properties are actually just a convenience—an implicit plugin definition. Internally, they are grouped together and turned into a plugin that is given first priority in the plugin stack.
|
These properties are actually just a convenience—an implicit plugin definition. Internally, they are grouped together and turned into a plugin that is given first priority in the plugin stack.
|
||||||
|
|
||||||
@@ -164,7 +164,7 @@ const plugins = [
|
|||||||
### `onSelect`
|
### `onSelect`
|
||||||
### `schema`
|
### `schema`
|
||||||
|
|
||||||
To see how these properties behave, check out the [Plugins reference](../plugins/plugins.md).
|
To see how these properties behave, check out the [Plugins reference](../plugins/plugin.md).
|
||||||
|
|
||||||
|
|
||||||
## Methods
|
## Methods
|
||||||
|
8
examples/focus-blur/Readme.md
Normal file
8
examples/focus-blur/Readme.md
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
# Links Example
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
This example shows you how you can wrap text in "inline" nodes to associate metadata, like an `href`, with a piece of text. This is how you'd add links to Slate, but it's also how you might add hashtags, at-mentions, and many more inline features!
|
||||||
|
|
||||||
|
Check out the [Examples readme](..) to see how to run it!
|
145
examples/focus-blur/index.js
Normal file
145
examples/focus-blur/index.js
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
|
||||||
|
import { Editor, Mark, Raw } from '../..'
|
||||||
|
import React from 'react'
|
||||||
|
import ReactDOM from 'react-dom'
|
||||||
|
import initialState from './state.json'
|
||||||
|
import isUrl from 'is-url'
|
||||||
|
import { Map } from 'immutable'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define a schema.
|
||||||
|
*
|
||||||
|
* @type {Object}
|
||||||
|
*/
|
||||||
|
|
||||||
|
const schema = {
|
||||||
|
nodes: {
|
||||||
|
paragraph: props => <p>{props.children}</p>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The focus and blur example.
|
||||||
|
*
|
||||||
|
* @type {Component}
|
||||||
|
*/
|
||||||
|
|
||||||
|
class FocusBlur extends React.Component {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deserialize the raw initial state.
|
||||||
|
*
|
||||||
|
* @type {Object}
|
||||||
|
*/
|
||||||
|
|
||||||
|
state = {
|
||||||
|
state: Raw.deserialize(initialState, { terse: true })
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On change.
|
||||||
|
*
|
||||||
|
* @param {State} state
|
||||||
|
*/
|
||||||
|
|
||||||
|
onChange = (state) => {
|
||||||
|
this.setState({ state })
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply a focus or blur transform by `name` after a `timeout`.
|
||||||
|
*
|
||||||
|
* @param {String} name
|
||||||
|
* @param {Number} timeout
|
||||||
|
*/
|
||||||
|
|
||||||
|
onClick = (e, name, timeout = 0) => {
|
||||||
|
e.preventDefault()
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
const state = this.state.state
|
||||||
|
.transform()
|
||||||
|
[name]()
|
||||||
|
.apply()
|
||||||
|
|
||||||
|
this.setState({ state })
|
||||||
|
}, timeout)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate focus and blur button handlers.
|
||||||
|
*
|
||||||
|
* @param {Event} e
|
||||||
|
*/
|
||||||
|
|
||||||
|
onClickFocus = e => this.onClick(e, 'focus')
|
||||||
|
onClickFocusDelay = e => this.onClick(e, 'focus', 3000)
|
||||||
|
onClickBlur = e => this.onClick(e, 'blur')
|
||||||
|
onClickBlurDelay = e => this.onClick(e, 'blur', 3000)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render the app.
|
||||||
|
*
|
||||||
|
* @return {Element} element
|
||||||
|
*/
|
||||||
|
|
||||||
|
render = () => {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{this.renderToolbar()}
|
||||||
|
{this.renderEditor()}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render the toolbar.
|
||||||
|
*
|
||||||
|
* @return {Element} element
|
||||||
|
*/
|
||||||
|
|
||||||
|
renderToolbar = () => {
|
||||||
|
return (
|
||||||
|
<div className="menu toolbar-menu">
|
||||||
|
<span className="button" onMouseDown={this.onClickFocus}>
|
||||||
|
<span className="material-icons">done</span> Focus
|
||||||
|
</span>
|
||||||
|
<span className="button" onMouseDown={this.onClickFocusDelay}>
|
||||||
|
<span className="material-icons">timer</span> Focus
|
||||||
|
</span>
|
||||||
|
<span className="button" onMouseDown={this.onClickBlur}>
|
||||||
|
<span className="material-icons">done</span> Blur
|
||||||
|
</span>
|
||||||
|
<span className="button" onMouseDown={this.onClickBlurDelay}>
|
||||||
|
<span className="material-icons">timer</span> Blur
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render the editor.
|
||||||
|
*
|
||||||
|
* @return {Element} element
|
||||||
|
*/
|
||||||
|
|
||||||
|
renderEditor = () => {
|
||||||
|
return (
|
||||||
|
<div className="editor">
|
||||||
|
<Editor
|
||||||
|
schema={schema}
|
||||||
|
state={this.state.state}
|
||||||
|
onChange={this.onChange}
|
||||||
|
onPaste={this.onPaste}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Export.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export default FocusBlur
|
24
examples/focus-blur/state.json
Normal file
24
examples/focus-blur/state.json
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"kind": "block",
|
||||||
|
"type": "paragraph",
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"kind": "text",
|
||||||
|
"text": "This is a testing ground for focusing and blurring in Slate."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": "block",
|
||||||
|
"type": "paragraph",
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"kind": "text",
|
||||||
|
"text": "You can use the toolbar buttons above to focus and blur immediately, or after a short delay."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@@ -79,6 +79,7 @@ input:focus {
|
|||||||
|
|
||||||
.material-icons {
|
.material-icons {
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
|
vertical-align: text-bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -126,7 +127,7 @@ input:focus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.menu > * + * {
|
.menu > * + * {
|
||||||
margin-left: 10px;
|
margin-left: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button {
|
.button {
|
||||||
|
@@ -11,6 +11,7 @@ import AutoMarkdown from './auto-markdown'
|
|||||||
import CodeHighlighting from './code-highlighting'
|
import CodeHighlighting from './code-highlighting'
|
||||||
import Embeds from './embeds'
|
import Embeds from './embeds'
|
||||||
import Emojis from './emojis'
|
import Emojis from './emojis'
|
||||||
|
import FocusBlur from './focus-blur'
|
||||||
import HoveringMenu from './hovering-menu'
|
import HoveringMenu from './hovering-menu'
|
||||||
import Iframes from './iframes'
|
import Iframes from './iframes'
|
||||||
import Images from './images'
|
import Images from './images'
|
||||||
@@ -83,6 +84,7 @@ class App extends React.Component {
|
|||||||
{this.renderTab('RTL', 'rtl')}
|
{this.renderTab('RTL', 'rtl')}
|
||||||
{this.renderTab('Plugins', 'plugins')}
|
{this.renderTab('Plugins', 'plugins')}
|
||||||
{this.renderTab('Iframes', 'iframes')}
|
{this.renderTab('Iframes', 'iframes')}
|
||||||
|
{this.renderTab('Focus & Blur', 'focus-blur')}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -131,6 +133,7 @@ const router = (
|
|||||||
<Route path="code-highlighting" component={CodeHighlighting} />
|
<Route path="code-highlighting" component={CodeHighlighting} />
|
||||||
<Route path="embeds" component={Embeds} />
|
<Route path="embeds" component={Embeds} />
|
||||||
<Route path="emojis" component={Emojis} />
|
<Route path="emojis" component={Emojis} />
|
||||||
|
<Route path="focus-blur" component={FocusBlur} />
|
||||||
<Route path="hovering-menu" component={HoveringMenu} />
|
<Route path="hovering-menu" component={HoveringMenu} />
|
||||||
<Route path="iframes" component={Iframes} />
|
<Route path="iframes" component={Iframes} />
|
||||||
<Route path="images" component={Images} />
|
<Route path="images" component={Images} />
|
||||||
|
10
package.json
10
package.json
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "slate",
|
"name": "slate",
|
||||||
"description": "A completely customizable framework for building rich text editors.",
|
"description": "A completely customizable framework for building rich text editors.",
|
||||||
"version": "0.14.16",
|
"version": "0.14.19",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"repository": "git://github.com/ianstormtaylor/slate.git",
|
"repository": "git://github.com/ianstormtaylor/slate.git",
|
||||||
"main": "./lib/index.js",
|
"main": "./lib/index.js",
|
||||||
@@ -55,10 +55,10 @@
|
|||||||
"np": "^2.9.0",
|
"np": "^2.9.0",
|
||||||
"npm-run-all": "^2.3.0",
|
"npm-run-all": "^2.3.0",
|
||||||
"prismjs": "^1.5.1",
|
"prismjs": "^1.5.1",
|
||||||
"react": "^15.2.0",
|
"react": "~15.2.0",
|
||||||
"react-addons-perf": "^15.2.1",
|
"react-addons-perf": "~15.2.1",
|
||||||
"react-addons-test-utils": "^15.3.0",
|
"react-addons-test-utils": "~15.1.0",
|
||||||
"react-dom": "^15.1.0",
|
"react-dom": "~15.2.0",
|
||||||
"react-frame-aware-selection-plugin": "0.0.5",
|
"react-frame-aware-selection-plugin": "0.0.5",
|
||||||
"react-frame-component": "^0.6.2",
|
"react-frame-component": "^0.6.2",
|
||||||
"react-portal": "^2.2.0",
|
"react-portal": "^2.2.0",
|
||||||
|
@@ -4,11 +4,13 @@ import Debug from 'debug'
|
|||||||
import Node from './node'
|
import Node from './node'
|
||||||
import OffsetKey from '../utils/offset-key'
|
import OffsetKey from '../utils/offset-key'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
import ReactDOM from 'react-dom'
|
||||||
import Selection from '../models/selection'
|
import Selection from '../models/selection'
|
||||||
import Transfer from '../utils/transfer'
|
import Transfer from '../utils/transfer'
|
||||||
import TYPES from '../constants/types'
|
import TYPES from '../constants/types'
|
||||||
import getWindow from 'get-window'
|
import getWindow from 'get-window'
|
||||||
import keycode from 'keycode'
|
import keycode from 'keycode'
|
||||||
|
import noop from '../utils/noop'
|
||||||
import { IS_FIREFOX, IS_MAC } from '../constants/environment'
|
import { IS_FIREFOX, IS_MAC } from '../constants/environment'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -19,14 +21,6 @@ import { IS_FIREFOX, IS_MAC } from '../constants/environment'
|
|||||||
|
|
||||||
const debug = Debug('slate:content')
|
const debug = Debug('slate:content')
|
||||||
|
|
||||||
/**
|
|
||||||
* Noop.
|
|
||||||
*
|
|
||||||
* @type {Function}
|
|
||||||
*/
|
|
||||||
|
|
||||||
function noop() {}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Content.
|
* Content.
|
||||||
*
|
*
|
||||||
@@ -121,16 +115,29 @@ class Content extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When finished rendering, move the `isRendering` flag on next tick.
|
* When finished rendering, move the `isRendering` flag on next tick and
|
||||||
|
* clean up the DOM's activeElement if neccessary.
|
||||||
*
|
*
|
||||||
* @param {Object} props
|
* @param {Object} prevProps
|
||||||
* @param {Object} state
|
* @param {Object} prevState
|
||||||
*/
|
*/
|
||||||
|
|
||||||
componentDidUpdate = (props, state) => {
|
componentDidUpdate = (prevProps, prevState) => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.tmp.isRendering = false
|
this.tmp.isRendering = false
|
||||||
}, 1)
|
}, 1)
|
||||||
|
|
||||||
|
// If the state is blurred now, but was focused before, and the DOM still
|
||||||
|
// has a node inside the editor selected, we need to blur it.
|
||||||
|
if (this.props.state.isBlurred && prevProps.state.isFocused) {
|
||||||
|
const el = ReactDOM.findDOMNode(this)
|
||||||
|
const window = getWindow(el)
|
||||||
|
const native = window.getSelection()
|
||||||
|
if (!el.contains(native.anchorNode)) return
|
||||||
|
|
||||||
|
native.removeAllRanges()
|
||||||
|
el.blur()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -416,6 +423,7 @@ class Content extends React.Component {
|
|||||||
onInput = (e) => {
|
onInput = (e) => {
|
||||||
if (this.tmp.isRendering) return
|
if (this.tmp.isRendering) return
|
||||||
if (this.tmp.isComposing) return
|
if (this.tmp.isComposing) return
|
||||||
|
if (this.props.state.isBlurred) return
|
||||||
if (isNonEditable(e)) return
|
if (isNonEditable(e)) return
|
||||||
debug('onInput')
|
debug('onInput')
|
||||||
|
|
||||||
|
@@ -4,6 +4,7 @@ import CorePlugin from '../plugins/core'
|
|||||||
import Debug from 'debug'
|
import Debug from 'debug'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import Schema from '../models/schema'
|
import Schema from '../models/schema'
|
||||||
|
import noop from '../utils/noop'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Debug.
|
* Debug.
|
||||||
@@ -11,14 +12,6 @@ import Schema from '../models/schema'
|
|||||||
|
|
||||||
const debug = Debug('slate:editor')
|
const debug = Debug('slate:editor')
|
||||||
|
|
||||||
/**
|
|
||||||
* Noop.
|
|
||||||
*
|
|
||||||
* @type {Function}
|
|
||||||
*/
|
|
||||||
|
|
||||||
function noop() {}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Event handlers to mix in to the editor.
|
* Event handlers to mix in to the editor.
|
||||||
*
|
*
|
||||||
|
@@ -156,9 +156,17 @@ class Leaf extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// We have a selection to render, so prepare a few things...
|
// We have a selection to render, so prepare a few things...
|
||||||
const el = findDeepestNode(ReactDOM.findDOMNode(this))
|
const ref = ReactDOM.findDOMNode(this)
|
||||||
|
const el = findDeepestNode(ref)
|
||||||
const window = getWindow(el)
|
const window = getWindow(el)
|
||||||
const native = window.getSelection()
|
const native = window.getSelection()
|
||||||
|
const parent = ref.closest('[contenteditable]')
|
||||||
|
|
||||||
|
// COMPAT: In Firefox, it's not enough to create a range, you also need to
|
||||||
|
// focus the contenteditable element. (2016/11/16)
|
||||||
|
function focus() {
|
||||||
|
if (parent) setTimeout(() => parent.focus())
|
||||||
|
}
|
||||||
|
|
||||||
// If both the start and end are here, set the selection all at once.
|
// If both the start and end are here, set the selection all at once.
|
||||||
if (hasAnchor && hasFocus) {
|
if (hasAnchor && hasFocus) {
|
||||||
@@ -167,41 +175,46 @@ class Leaf extends React.Component {
|
|||||||
range.setStart(el, anchorOffset - start)
|
range.setStart(el, anchorOffset - start)
|
||||||
native.addRange(range)
|
native.addRange(range)
|
||||||
native.extend(el, focusOffset - start)
|
native.extend(el, focusOffset - start)
|
||||||
return
|
focus()
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the selection is forward, we can set things in sequence. In
|
// Otherwise we need to set the selection across two different leaves.
|
||||||
// the first leaf to render, reset the selection and set the new start. And
|
|
||||||
// then in the second leaf to render, extend to the new end.
|
|
||||||
if (selection.isForward) {
|
|
||||||
if (hasAnchor) {
|
|
||||||
native.removeAllRanges()
|
|
||||||
const range = window.document.createRange()
|
|
||||||
range.setStart(el, anchorOffset - start)
|
|
||||||
native.addRange(range)
|
|
||||||
} else if (hasFocus) {
|
|
||||||
native.extend(el, focusOffset - start)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, if the selection is backward, we need to hack the order a bit.
|
|
||||||
// In the first leaf to render, set a phony start anchor to store the true
|
|
||||||
// end position. And then in the second leaf to render, set the start and
|
|
||||||
// extend the end to the stored value.
|
|
||||||
else {
|
else {
|
||||||
if (hasFocus) {
|
// If the selection is forward, we can set things in sequence. In the
|
||||||
native.removeAllRanges()
|
// first leaf to render, reset the selection and set the new start. And
|
||||||
const range = window.document.createRange()
|
// then in the second leaf to render, extend to the new end.
|
||||||
range.setStart(el, focusOffset - start)
|
if (selection.isForward) {
|
||||||
native.addRange(range)
|
if (hasAnchor) {
|
||||||
} else if (hasAnchor) {
|
native.removeAllRanges()
|
||||||
const endNode = native.focusNode
|
const range = window.document.createRange()
|
||||||
const endOffset = native.focusOffset
|
range.setStart(el, anchorOffset - start)
|
||||||
native.removeAllRanges()
|
native.addRange(range)
|
||||||
const range = window.document.createRange()
|
} else if (hasFocus) {
|
||||||
range.setStart(el, anchorOffset - start)
|
native.extend(el, focusOffset - start)
|
||||||
native.addRange(range)
|
focus()
|
||||||
native.extend(endNode, endOffset)
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, if the selection is backward, we need to hack the order a bit.
|
||||||
|
// In the first leaf to render, set a phony start anchor to store the true
|
||||||
|
// end position. And then in the second leaf to render, set the start and
|
||||||
|
// extend the end to the stored value.
|
||||||
|
else {
|
||||||
|
if (hasFocus) {
|
||||||
|
native.removeAllRanges()
|
||||||
|
const range = window.document.createRange()
|
||||||
|
range.setStart(el, focusOffset - start)
|
||||||
|
native.addRange(range)
|
||||||
|
} else if (hasAnchor) {
|
||||||
|
const endNode = native.focusNode
|
||||||
|
const endOffset = native.focusOffset
|
||||||
|
native.removeAllRanges()
|
||||||
|
const range = window.document.createRange()
|
||||||
|
range.setStart(el, anchorOffset - start)
|
||||||
|
native.addRange(range)
|
||||||
|
native.extend(endNode, endOffset)
|
||||||
|
focus()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -3,16 +3,9 @@ import Leaf from './leaf'
|
|||||||
import Mark from '../models/mark'
|
import Mark from '../models/mark'
|
||||||
import OffsetKey from '../utils/offset-key'
|
import OffsetKey from '../utils/offset-key'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
import noop from '../utils/noop'
|
||||||
import { IS_FIREFOX } from '../constants/environment'
|
import { IS_FIREFOX } from '../constants/environment'
|
||||||
|
|
||||||
/**
|
|
||||||
* Noop.
|
|
||||||
*
|
|
||||||
* @type {Function}
|
|
||||||
*/
|
|
||||||
|
|
||||||
function noop() {}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Void.
|
* Void.
|
||||||
*
|
*
|
||||||
|
@@ -36,7 +36,7 @@ The `Document` is where all of the content in the editor is stored. It is a recu
|
|||||||
|
|
||||||
#### Inline
|
#### Inline
|
||||||
|
|
||||||
Similar to [`Block`](#block) nodes, but containing inline content instead of block-level contain. They too can be nested to any depth, but at the lowest level will always contain a single [`Text`](#text) node.
|
Similar to [`Block`](#block) nodes, but containing inline content instead of block-level content. They too can be nested to any depth, but at the lowest level will always contain a single [`Text`](#text) node.
|
||||||
|
|
||||||
|
|
||||||
#### Mark
|
#### Mark
|
||||||
|
14
src/utils/noop.js
Normal file
14
src/utils/noop.js
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
|
||||||
|
/**
|
||||||
|
* Noop.
|
||||||
|
*
|
||||||
|
* @return {Undefined}
|
||||||
|
*/
|
||||||
|
|
||||||
|
function noop() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Export.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export default noop
|
Reference in New Issue
Block a user