mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-31 19:01:54 +02:00
add linting to examples
This commit is contained in:
20
.eslintrc
20
.eslintrc
@@ -1,7 +1,10 @@
|
|||||||
{
|
{
|
||||||
"env": {
|
"plugins": [
|
||||||
"browser": true,
|
"import",
|
||||||
"node": true
|
"react"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"import/extensions": [".js"]
|
||||||
},
|
},
|
||||||
"parser": "babel-eslint",
|
"parser": "babel-eslint",
|
||||||
"parserOptions": {
|
"parserOptions": {
|
||||||
@@ -9,10 +12,10 @@
|
|||||||
"jsx": true
|
"jsx": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"plugins": [
|
"env": {
|
||||||
"import",
|
"browser": true,
|
||||||
"react"
|
"node": true
|
||||||
],
|
},
|
||||||
"rules": {
|
"rules": {
|
||||||
"block-spacing": "error",
|
"block-spacing": "error",
|
||||||
"comma-dangle": ["error", "only-multiline"],
|
"comma-dangle": ["error", "only-multiline"],
|
||||||
@@ -25,9 +28,7 @@
|
|||||||
"dot-notation": ["error", { "allowKeywords": true }],
|
"dot-notation": ["error", { "allowKeywords": true }],
|
||||||
"eol-last": "error",
|
"eol-last": "error",
|
||||||
"func-style": ["error", "declaration"],
|
"func-style": ["error", "declaration"],
|
||||||
"import/default": "error",
|
|
||||||
"import/export": "error",
|
"import/export": "error",
|
||||||
"import/named": "error",
|
|
||||||
"import/namespace": "error",
|
"import/namespace": "error",
|
||||||
"import/newline-after-import": "error",
|
"import/newline-after-import": "error",
|
||||||
"import/no-deprecated": "error",
|
"import/no-deprecated": "error",
|
||||||
@@ -41,7 +42,6 @@
|
|||||||
"new-parens": "error",
|
"new-parens": "error",
|
||||||
"no-array-constructor": "error",
|
"no-array-constructor": "error",
|
||||||
"no-class-assign": "error",
|
"no-class-assign": "error",
|
||||||
"no-console": "warn",
|
|
||||||
"no-const-assign": "error",
|
"no-const-assign": "error",
|
||||||
"no-debugger": "warn",
|
"no-debugger": "warn",
|
||||||
"no-dupe-args": "error",
|
"no-dupe-args": "error",
|
||||||
|
11
Makefile
11
Makefile
@@ -47,16 +47,19 @@ examples:
|
|||||||
install:
|
install:
|
||||||
@ npm install
|
@ npm install
|
||||||
|
|
||||||
# Lint the sources files with Standard JS.
|
# Lint the source files.
|
||||||
lint:
|
lint:
|
||||||
@ $(eslint) "lib/**/*.js"
|
@ $(eslint) \
|
||||||
|
"lib/**/*.js" \
|
||||||
|
"examples/**/*.js" --ignore-pattern "build.js"
|
||||||
|
|
||||||
# Build the test source.
|
# Build the test source.
|
||||||
test/browser/support/build.js: $(shell find ./lib) ./test/browser.js
|
test/support/build.js: $(shell find ./lib) ./test/browser.js
|
||||||
@ $(browserify) \
|
@ $(browserify) \
|
||||||
|
./test/browser.js \
|
||||||
--debug \
|
--debug \
|
||||||
--transform babelify \
|
--transform babelify \
|
||||||
--outfile ./test/support/build.js ./test/browser.js
|
--outfile ./test/support/build.js
|
||||||
|
|
||||||
# Run the tests.
|
# Run the tests.
|
||||||
test: test-browser test-server
|
test: test-browser test-server
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
import { Editor, Raw } from '../..'
|
import { Editor, Raw } from '../..'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import keycode from 'keycode'
|
import keycode from 'keycode'
|
||||||
import state from './state.json'
|
import initialState from './state.json'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Node renderers.
|
* Node renderers.
|
||||||
@@ -38,7 +38,7 @@ class AutoMarkdown extends React.Component {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
state: Raw.deserialize(state)
|
state: Raw.deserialize(initialState)
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -48,7 +48,7 @@ class AutoMarkdown extends React.Component {
|
|||||||
* @return {String} block
|
* @return {String} block
|
||||||
*/
|
*/
|
||||||
|
|
||||||
getType(chars) {
|
getType = (chars) => {
|
||||||
switch (chars) {
|
switch (chars) {
|
||||||
case '*':
|
case '*':
|
||||||
case '-':
|
case '-':
|
||||||
@@ -71,26 +71,45 @@ class AutoMarkdown extends React.Component {
|
|||||||
* @return {Component} component
|
* @return {Component} component
|
||||||
*/
|
*/
|
||||||
|
|
||||||
render() {
|
render = () => {
|
||||||
return (
|
return (
|
||||||
<div className="editor">
|
<div className="editor">
|
||||||
<Editor
|
<Editor
|
||||||
state={this.state.state}
|
state={this.state.state}
|
||||||
renderNode={node => NODES[node.type]}
|
onChange={this.onChange}
|
||||||
onKeyDown={(e, state) => this.onKeyDown(e, state)}
|
onKeyDown={this.onKeyDown}
|
||||||
onChange={(state) => {
|
renderNode={this.renderNode}
|
||||||
console.groupCollapsed('Change!')
|
|
||||||
console.log('Document:', state.document.toJS())
|
|
||||||
console.log('Selection:', state.selection.toJS())
|
|
||||||
console.log('Content:', Raw.serialize(state))
|
|
||||||
console.groupEnd()
|
|
||||||
this.setState({ state })
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render a `node`.
|
||||||
|
*
|
||||||
|
* @param {Node} node
|
||||||
|
* @return {Element}
|
||||||
|
*/
|
||||||
|
|
||||||
|
renderNode = (node) => {
|
||||||
|
return NODES[node.type]
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On change.
|
||||||
|
*
|
||||||
|
* @param {State} state
|
||||||
|
*/
|
||||||
|
|
||||||
|
onChange = (state) => {
|
||||||
|
console.groupCollapsed('Change!')
|
||||||
|
console.log('Document:', state.document.toJS())
|
||||||
|
console.log('Selection:', state.selection.toJS())
|
||||||
|
console.log('Content:', Raw.serialize(state))
|
||||||
|
console.groupEnd()
|
||||||
|
this.setState({ state })
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* On key down, check for our specific key shortcuts.
|
* On key down, check for our specific key shortcuts.
|
||||||
*
|
*
|
||||||
@@ -99,7 +118,7 @@ class AutoMarkdown extends React.Component {
|
|||||||
* @return {State or Null} state
|
* @return {State or Null} state
|
||||||
*/
|
*/
|
||||||
|
|
||||||
onKeyDown(e, state) {
|
onKeyDown = (e, state) => {
|
||||||
const key = keycode(e.which)
|
const key = keycode(e.which)
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case 'space': return this.onSpace(e, state)
|
case 'space': return this.onSpace(e, state)
|
||||||
@@ -117,7 +136,7 @@ class AutoMarkdown extends React.Component {
|
|||||||
* @return {State or Null} state
|
* @return {State or Null} state
|
||||||
*/
|
*/
|
||||||
|
|
||||||
onSpace(e, state) {
|
onSpace = (e, state) => {
|
||||||
if (state.isExpanded) return
|
if (state.isExpanded) return
|
||||||
let { selection } = state
|
let { selection } = state
|
||||||
const { startText, startBlock, startOffset } = state
|
const { startText, startBlock, startOffset } = state
|
||||||
@@ -151,7 +170,7 @@ class AutoMarkdown extends React.Component {
|
|||||||
* @return {State or Null} state
|
* @return {State or Null} state
|
||||||
*/
|
*/
|
||||||
|
|
||||||
onBackspace(e, state) {
|
onBackspace = (e, state) => {
|
||||||
if (state.isExpanded) return
|
if (state.isExpanded) return
|
||||||
if (state.startOffset != 0) return
|
if (state.startOffset != 0) return
|
||||||
const { startBlock } = state
|
const { startBlock } = state
|
||||||
@@ -178,7 +197,7 @@ class AutoMarkdown extends React.Component {
|
|||||||
* @return {State or Null} state
|
* @return {State or Null} state
|
||||||
*/
|
*/
|
||||||
|
|
||||||
onEnter(e, state) {
|
onEnter = (e, state) => {
|
||||||
if (state.isExpanded) return
|
if (state.isExpanded) return
|
||||||
const { startBlock, startOffset, endOffset } = state
|
const { startBlock, startOffset, endOffset } = state
|
||||||
if (startOffset == 0 && startBlock.length == 0) return this.onBackspace(e, state)
|
if (startOffset == 0 && startBlock.length == 0) return this.onBackspace(e, state)
|
||||||
|
@@ -3,7 +3,7 @@ import { Editor, Mark, Raw, Selection } from '../..'
|
|||||||
import Prism from 'prismjs'
|
import Prism from 'prismjs'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import keycode from 'keycode'
|
import keycode from 'keycode'
|
||||||
import state from './state.json'
|
import initialState from './state.json'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Node renderers.
|
* Node renderers.
|
||||||
@@ -43,10 +43,19 @@ const MARKS = {
|
|||||||
class CodeHighlighting extends React.Component {
|
class CodeHighlighting extends React.Component {
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
state: Raw.deserialize(state)
|
state: Raw.deserialize(initialState)
|
||||||
};
|
};
|
||||||
|
|
||||||
onKeyDown(e, state, editor) {
|
onChange = (state) => {
|
||||||
|
console.groupCollapsed('Change!')
|
||||||
|
console.log('Document:', state.document.toJS())
|
||||||
|
console.log('Selection:', state.selection.toJS())
|
||||||
|
console.log('Content:', Raw.serialize(state))
|
||||||
|
console.groupEnd()
|
||||||
|
this.setState({ state })
|
||||||
|
}
|
||||||
|
|
||||||
|
onKeyDown = (e, state, editor) => {
|
||||||
const key = keycode(e.which)
|
const key = keycode(e.which)
|
||||||
if (key != 'enter') return
|
if (key != 'enter') return
|
||||||
const { startBlock } = state
|
const { startBlock } = state
|
||||||
@@ -59,29 +68,30 @@ class CodeHighlighting extends React.Component {
|
|||||||
return transform.apply()
|
return transform.apply()
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render = () => {
|
||||||
return (
|
return (
|
||||||
<div className="editor">
|
<div className="editor">
|
||||||
<Editor
|
<Editor
|
||||||
state={this.state.state}
|
state={this.state.state}
|
||||||
renderNode={node => NODES[node.type]}
|
renderNode={this.renderNode}
|
||||||
renderMark={mark => MARKS[mark.type] || {}}
|
renderMark={this.renderMark}
|
||||||
renderDecorations={(...args) => this.renderDecorations(...args)}
|
renderDecorations={this.renderDecorations}
|
||||||
onKeyDown={(...args) => this.onKeyDown(...args)}
|
onKeyDown={this.onKeyDown}
|
||||||
onChange={(state) => {
|
onChange={this.onChange}
|
||||||
console.groupCollapsed('Change!')
|
|
||||||
console.log('Document:', state.document.toJS())
|
|
||||||
console.log('Selection:', state.selection.toJS())
|
|
||||||
console.log('Content:', Raw.serialize(state))
|
|
||||||
console.groupEnd()
|
|
||||||
this.setState({ state })
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
renderDecorations(text, state, editor) {
|
renderNode = (node) => {
|
||||||
|
return NODES[node.type]
|
||||||
|
}
|
||||||
|
|
||||||
|
renderMark = (mark) => {
|
||||||
|
return MARKS[mark.type] || {}
|
||||||
|
}
|
||||||
|
|
||||||
|
renderDecorations = (text, state, editor) => {
|
||||||
let characters = text.characters
|
let characters = text.characters
|
||||||
const { document } = state
|
const { document } = state
|
||||||
const block = document.getClosestBlock(text)
|
const block = document.getClosestBlock(text)
|
||||||
|
@@ -3,7 +3,7 @@ import { Editor, Mark, Raw } from '../..'
|
|||||||
import Portal from 'react-portal'
|
import Portal from 'react-portal'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import position from 'selection-position'
|
import position from 'selection-position'
|
||||||
import state from './state.json'
|
import initialState from './state.json'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Node renderers.
|
* Node renderers.
|
||||||
@@ -48,37 +48,74 @@ const MARKS = {
|
|||||||
class HoveringMenu extends React.Component {
|
class HoveringMenu extends React.Component {
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
state: Raw.deserialize(state)
|
state: Raw.deserialize(initialState)
|
||||||
};
|
};
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount = () => {
|
||||||
this.updateMenu()
|
this.updateMenu()
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate() {
|
componentDidUpdate = () => {
|
||||||
this.updateMenu()
|
this.updateMenu()
|
||||||
}
|
}
|
||||||
|
|
||||||
hasMark(type) {
|
render = () => {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{this.renderMenu()}
|
||||||
|
{this.renderEditor()}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
renderMenu = () => {
|
||||||
const { state } = this.state
|
const { state } = this.state
|
||||||
const { marks } = state
|
const isOpen = state.isExpanded && state.isFocused
|
||||||
return marks.some(mark => mark.type == type)
|
return (
|
||||||
|
<Portal isOpened onOpen={this.onOpen}>
|
||||||
|
<div className="menu hover-menu">
|
||||||
|
{this.renderMarkButton('bold', 'format_bold')}
|
||||||
|
{this.renderMarkButton('italic', 'format_italic')}
|
||||||
|
{this.renderMarkButton('underlined', 'format_underlined')}
|
||||||
|
{this.renderMarkButton('code', 'code')}
|
||||||
|
</div>
|
||||||
|
</Portal>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
onClickMark(e, type) {
|
renderMarkButton = (type, icon) => {
|
||||||
e.preventDefault()
|
|
||||||
const isActive = this.hasMark(type)
|
const isActive = this.hasMark(type)
|
||||||
let { state } = this.state
|
const onMouseDown = e => this.onClickMark(e, type)
|
||||||
|
|
||||||
state = state
|
return (
|
||||||
.transform()
|
<span className="button" onMouseDown={onMouseDown} data-active={isActive}>
|
||||||
[isActive ? 'unmark' : 'mark'](type)
|
<span className="material-icons">{icon}</span>
|
||||||
.apply()
|
</span>
|
||||||
|
)
|
||||||
this.setState({ state })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
updateMenu() {
|
renderEditor = () => {
|
||||||
|
return (
|
||||||
|
<div className="editor">
|
||||||
|
<Editor
|
||||||
|
state={this.state.state}
|
||||||
|
renderNode={this.renderNode}
|
||||||
|
renderMark={this.renderMark}
|
||||||
|
onChange={this.onChange}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
renderNode = (node) => {
|
||||||
|
return NODES[node.type]
|
||||||
|
}
|
||||||
|
|
||||||
|
renderMark = (mark) => {
|
||||||
|
return MARKS[mark.type]
|
||||||
|
}
|
||||||
|
|
||||||
|
updateMenu = () => {
|
||||||
const { menu, state } = this.state
|
const { menu, state } = this.state
|
||||||
if (!menu) return
|
if (!menu) return
|
||||||
|
|
||||||
@@ -93,61 +130,35 @@ class HoveringMenu extends React.Component {
|
|||||||
menu.style.left = `${rect.left + window.scrollX - menu.offsetWidth / 2 + rect.width / 2}px`
|
menu.style.left = `${rect.left + window.scrollX - menu.offsetWidth / 2 + rect.width / 2}px`
|
||||||
}
|
}
|
||||||
|
|
||||||
onOpen(el) {
|
hasMark = (type) => {
|
||||||
this.setState({ menu: el.firstChild })
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
{this.renderMenu()}
|
|
||||||
{this.renderEditor()}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
renderMenu() {
|
|
||||||
const { state } = this.state
|
const { state } = this.state
|
||||||
const isOpen = state.isExpanded && state.isFocused
|
return state.marks.some(mark => mark.type == type)
|
||||||
return (
|
|
||||||
<Portal isOpened={true} onOpen={el => this.onOpen(el)} >
|
|
||||||
<div className="menu hover-menu">
|
|
||||||
{this.renderMarkButton('bold', 'format_bold')}
|
|
||||||
{this.renderMarkButton('italic', 'format_italic')}
|
|
||||||
{this.renderMarkButton('underlined', 'format_underlined')}
|
|
||||||
{this.renderMarkButton('code', 'code')}
|
|
||||||
</div>
|
|
||||||
</Portal>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
renderMarkButton(type, icon) {
|
onChange = (state) => {
|
||||||
|
console.groupCollapsed('Change!')
|
||||||
|
console.log('Document:', state.document.toJS())
|
||||||
|
console.log('Selection:', state.selection.toJS())
|
||||||
|
console.log('Content:', Raw.serialize(state))
|
||||||
|
console.groupEnd()
|
||||||
|
this.setState({ state })
|
||||||
|
}
|
||||||
|
|
||||||
|
onClickMark = (e, type) => {
|
||||||
|
e.preventDefault()
|
||||||
const isActive = this.hasMark(type)
|
const isActive = this.hasMark(type)
|
||||||
return (
|
let { state } = this.state
|
||||||
<span className="button" onMouseDown={e => this.onClickMark(e, type)} data-active={isActive}>
|
|
||||||
<span className="material-icons">{icon}</span>
|
state = state
|
||||||
</span>
|
.transform()
|
||||||
)
|
[isActive ? 'unmark' : 'mark'](type)
|
||||||
|
.apply()
|
||||||
|
|
||||||
|
this.setState({ state })
|
||||||
}
|
}
|
||||||
|
|
||||||
renderEditor() {
|
onOpen = (el) => {
|
||||||
return (
|
this.setState({ menu: el.firstChild })
|
||||||
<div className="editor">
|
|
||||||
<Editor
|
|
||||||
state={this.state.state}
|
|
||||||
renderNode={node => NODES[node.type]}
|
|
||||||
renderMark={mark => MARKS[mark.type]}
|
|
||||||
onChange={(state) => {
|
|
||||||
console.groupCollapsed('Change!')
|
|
||||||
console.log('Document:', state.document.toJS())
|
|
||||||
console.log('Selection:', state.selection.toJS())
|
|
||||||
console.log('Content:', Raw.serialize(state))
|
|
||||||
console.groupEnd()
|
|
||||||
this.setState({ state })
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
import { Editor, Mark, Raw } from '../..'
|
import { Editor, Mark, Raw } from '../..'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import ReactDOM from 'react-dom'
|
import ReactDOM from 'react-dom'
|
||||||
import state from './state.json'
|
import initialState from './state.json'
|
||||||
import { Map } from 'immutable'
|
import { Map } from 'immutable'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -31,16 +31,104 @@ const NODES = {
|
|||||||
class Images extends React.Component {
|
class Images extends React.Component {
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
state: Raw.deserialize(state)
|
state: Raw.deserialize(initialState)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.onClickImage}>
|
||||||
|
<span className="material-icons">image</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render the editor.
|
||||||
|
*
|
||||||
|
* @return {Element} element
|
||||||
|
*/
|
||||||
|
|
||||||
|
renderEditor = () => {
|
||||||
|
return (
|
||||||
|
<div className="editor">
|
||||||
|
<Editor
|
||||||
|
state={this.state.state}
|
||||||
|
renderNode={this.renderNode}
|
||||||
|
onChange={this.onChange}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render a `node`.
|
||||||
|
*
|
||||||
|
* @param {Node} node
|
||||||
|
* @return {Element}
|
||||||
|
*/
|
||||||
|
|
||||||
|
renderNode = (node) => {
|
||||||
|
return NODES[node.type]
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On change.
|
||||||
|
*
|
||||||
|
* @param {State} state
|
||||||
|
*/
|
||||||
|
|
||||||
|
onChange = (state) => {
|
||||||
|
console.groupCollapsed('Change!')
|
||||||
|
console.log('Document:', state.document.toJS())
|
||||||
|
console.log('Selection:', state.selection.toJS())
|
||||||
|
console.log('Content:', Raw.serialize(state))
|
||||||
|
console.groupEnd()
|
||||||
|
this.setState({ state })
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On clicking the image button, prompt for an image and insert it.
|
||||||
|
*
|
||||||
|
* @param {Event} e
|
||||||
|
*/
|
||||||
|
|
||||||
|
onClickImage = (e) => {
|
||||||
|
e.preventDefault()
|
||||||
|
const src = window.prompt('Enter the URL of the image:')
|
||||||
|
if (!src) return
|
||||||
|
this.insertImage(src)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert an image with `src` at the current selection.
|
* Insert an image with `src` at the current selection.
|
||||||
*
|
*
|
||||||
* @param {String} src
|
* @param {String} src
|
||||||
*/
|
*/
|
||||||
|
|
||||||
insertImage(src) {
|
insertImage = (src) => {
|
||||||
let { state } = this.state
|
let { state } = this.state
|
||||||
|
|
||||||
if (state.isExpanded) {
|
if (state.isExpanded) {
|
||||||
@@ -74,75 +162,6 @@ class Images extends React.Component {
|
|||||||
this.setState({ state })
|
this.setState({ state })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* On clicking the image button, prompt for an image and insert it.
|
|
||||||
*
|
|
||||||
* @param {Event} e
|
|
||||||
*/
|
|
||||||
|
|
||||||
onClickImage(e) {
|
|
||||||
e.preventDefault()
|
|
||||||
const src = window.prompt('Enter the URL of the image:')
|
|
||||||
if (!src) return
|
|
||||||
this.insertImage(src)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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={e => this.onClickImage(e)}>
|
|
||||||
<span className="material-icons">image</span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Render the editor.
|
|
||||||
*
|
|
||||||
* @return {Element} element
|
|
||||||
*/
|
|
||||||
|
|
||||||
renderEditor() {
|
|
||||||
return (
|
|
||||||
<div className="editor">
|
|
||||||
<Editor
|
|
||||||
state={this.state.state}
|
|
||||||
renderNode={node => NODES[node.type]}
|
|
||||||
onChange={(state) => {
|
|
||||||
console.groupCollapsed('Change!')
|
|
||||||
console.log('Document:', state.document.toJS())
|
|
||||||
console.log('Selection:', state.selection.toJS())
|
|
||||||
console.log('Content:', Raw.serialize(state))
|
|
||||||
console.groupEnd()
|
|
||||||
this.setState({ state })
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
import { Editor, Mark, Raw } from '../..'
|
import { Editor, Mark, Raw } from '../..'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import ReactDOM from 'react-dom'
|
import ReactDOM from 'react-dom'
|
||||||
import state from './state.json'
|
import initialState from './state.json'
|
||||||
import { Map } from 'immutable'
|
import { Map } from 'immutable'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -29,7 +29,7 @@ const NODES = {
|
|||||||
class Links extends React.Component {
|
class Links extends React.Component {
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
state: Raw.deserialize(state)
|
state: Raw.deserialize(initialState)
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -38,10 +38,9 @@ class Links extends React.Component {
|
|||||||
* @return {Boolean} hasLinks
|
* @return {Boolean} hasLinks
|
||||||
*/
|
*/
|
||||||
|
|
||||||
hasLinks() {
|
hasLinks = () => {
|
||||||
const { state } = this.state
|
const { state } = this.state
|
||||||
const { inlines } = state
|
return state.inlines.some(inline => inline.type == 'link')
|
||||||
return inlines.some(inline => inline.type == 'link')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -51,7 +50,7 @@ class Links extends React.Component {
|
|||||||
* @param {Event} e
|
* @param {Event} e
|
||||||
*/
|
*/
|
||||||
|
|
||||||
onClickLink(e) {
|
onClickLink = (e) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
let { state } = this.state
|
let { state } = this.state
|
||||||
const hasLinks = this.hasLinks()
|
const hasLinks = this.hasLinks()
|
||||||
@@ -92,7 +91,7 @@ class Links extends React.Component {
|
|||||||
* @return {Element} element
|
* @return {Element} element
|
||||||
*/
|
*/
|
||||||
|
|
||||||
render() {
|
render = () => {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{this.renderToolbar()}
|
{this.renderToolbar()}
|
||||||
@@ -107,11 +106,11 @@ class Links extends React.Component {
|
|||||||
* @return {Element} element
|
* @return {Element} element
|
||||||
*/
|
*/
|
||||||
|
|
||||||
renderToolbar() {
|
renderToolbar = () => {
|
||||||
const hasLinks = this.hasLinks()
|
const hasLinks = this.hasLinks()
|
||||||
return (
|
return (
|
||||||
<div className="menu toolbar-menu">
|
<div className="menu toolbar-menu">
|
||||||
<span className="button" onMouseDown={e => this.onClickLink(e)} data-active={hasLinks}>
|
<span className="button" onMouseDown={this.onClickLink} data-active={hasLinks}>
|
||||||
<span className="material-icons">link</span>
|
<span className="material-icons">link</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -124,25 +123,44 @@ class Links extends React.Component {
|
|||||||
* @return {Element} element
|
* @return {Element} element
|
||||||
*/
|
*/
|
||||||
|
|
||||||
renderEditor() {
|
renderEditor = () => {
|
||||||
return (
|
return (
|
||||||
<div className="editor">
|
<div className="editor">
|
||||||
<Editor
|
<Editor
|
||||||
state={this.state.state}
|
state={this.state.state}
|
||||||
renderNode={node => NODES[node.type]}
|
renderNode={this.renderNode}
|
||||||
onChange={(state) => {
|
onChange={this.onChange}
|
||||||
console.groupCollapsed('Change!')
|
|
||||||
console.log('Document:', state.document.toJS())
|
|
||||||
console.log('Selection:', state.selection.toJS())
|
|
||||||
console.log('Content:', Raw.serialize(state))
|
|
||||||
console.groupEnd()
|
|
||||||
this.setState({ state })
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render a `node`.
|
||||||
|
*
|
||||||
|
* @param {Node} node
|
||||||
|
* @return {Element}
|
||||||
|
*/
|
||||||
|
|
||||||
|
renderNode = (node) => {
|
||||||
|
return NODES[node.type]
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On change.
|
||||||
|
*
|
||||||
|
* @param {State} state
|
||||||
|
*/
|
||||||
|
|
||||||
|
onChange = (state) => {
|
||||||
|
console.groupCollapsed('Change!')
|
||||||
|
console.log('Document:', state.document.toJS())
|
||||||
|
console.log('Selection:', state.selection.toJS())
|
||||||
|
console.log('Content:', Raw.serialize(state))
|
||||||
|
console.groupEnd()
|
||||||
|
this.setState({ state })
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
import { Editor, Html, Raw } from '../..'
|
import { Editor, Html, Raw } from '../..'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import state from './state.json'
|
import initialState from './state.json'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Node renderers.
|
* Node renderers.
|
||||||
@@ -166,10 +166,41 @@ const serializer = new Html(RULES)
|
|||||||
class PasteHtml extends React.Component {
|
class PasteHtml extends React.Component {
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
state: Raw.deserialize(state)
|
state: Raw.deserialize(initialState)
|
||||||
};
|
};
|
||||||
|
|
||||||
onPaste(e, paste, state, editor) {
|
render = () => {
|
||||||
|
return (
|
||||||
|
<div className="editor">
|
||||||
|
<Editor
|
||||||
|
state={this.state.state}
|
||||||
|
renderNode={this.renderNode}
|
||||||
|
renderMark={this.renderMark}
|
||||||
|
onPaste={this.onPaste}
|
||||||
|
onChange={this.onChange}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
renderNode = (node) => {
|
||||||
|
return NODES[node.type]
|
||||||
|
}
|
||||||
|
|
||||||
|
renderMark = (mark) => {
|
||||||
|
return MARKS[mark.type]
|
||||||
|
}
|
||||||
|
|
||||||
|
onChange = (state) => {
|
||||||
|
console.groupCollapsed('Change!')
|
||||||
|
console.log('Document:', state.document.toJS())
|
||||||
|
console.log('Selection:', state.selection.toJS())
|
||||||
|
console.log('Content:', Raw.serialize(state))
|
||||||
|
console.groupEnd()
|
||||||
|
this.setState({ state })
|
||||||
|
}
|
||||||
|
|
||||||
|
onPaste = (e, paste, state, editor) => {
|
||||||
if (paste.type != 'html') return
|
if (paste.type != 'html') return
|
||||||
const { html } = paste
|
const { html } = paste
|
||||||
const { document } = serializer.deserialize(html)
|
const { document } = serializer.deserialize(html)
|
||||||
@@ -180,27 +211,6 @@ class PasteHtml extends React.Component {
|
|||||||
.apply()
|
.apply()
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<div className="editor">
|
|
||||||
<Editor
|
|
||||||
state={this.state.state}
|
|
||||||
renderNode={node => NODES[node.type]}
|
|
||||||
renderMark={mark => MARKS[mark.type]}
|
|
||||||
onPaste={(...args) => this.onPaste(...args)}
|
|
||||||
onChange={(state) => {
|
|
||||||
console.groupCollapsed('Change!')
|
|
||||||
console.log('Document:', state.document.toJS())
|
|
||||||
console.log('Selection:', state.selection.toJS())
|
|
||||||
console.log('Content:', Raw.serialize(state))
|
|
||||||
console.groupEnd()
|
|
||||||
this.setState({ state })
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
import { Block, Character, Document, Editor, State, Text } from '../..'
|
import { Block, Character, Document, Editor, State, Text } from '../..'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import state from './state.json'
|
import initialState from './state.json'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A helper to deserialize a string into an editor state.
|
* A helper to deserialize a string into an editor state.
|
||||||
@@ -54,7 +54,7 @@ class PlainText extends React.Component {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
state: deserialize(state)
|
state: deserialize(initialState)
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -63,22 +63,30 @@ class PlainText extends React.Component {
|
|||||||
* @return {Component} component
|
* @return {Component} component
|
||||||
*/
|
*/
|
||||||
|
|
||||||
render() {
|
render = () => {
|
||||||
return (
|
return (
|
||||||
<Editor
|
<Editor
|
||||||
state={this.state.state}
|
state={this.state.state}
|
||||||
onChange={(state) => {
|
onChange={this.onChange}
|
||||||
console.groupCollapsed('Change!')
|
|
||||||
console.log('Document:', state.document.toJS())
|
|
||||||
console.log('Selection:', state.selection.toJS())
|
|
||||||
console.log('Content:', serialize(state))
|
|
||||||
console.groupEnd()
|
|
||||||
this.setState({ state })
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On change.
|
||||||
|
*
|
||||||
|
* @param {State} state
|
||||||
|
*/
|
||||||
|
|
||||||
|
onChange = (state) => {
|
||||||
|
console.groupCollapsed('Change!')
|
||||||
|
console.log('Document:', state.document.toJS())
|
||||||
|
console.log('Selection:', state.selection.toJS())
|
||||||
|
console.log('Content:', serialize(state))
|
||||||
|
console.groupEnd()
|
||||||
|
this.setState({ state })
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
import { Editor, Mark, Raw } from '../..'
|
import { Editor, Mark, Raw } from '../..'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import state from './state.json'
|
import initialState from './state.json'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Node renderers.
|
* Node renderers.
|
||||||
@@ -52,22 +52,20 @@ const MARKS = {
|
|||||||
class RichText extends React.Component {
|
class RichText extends React.Component {
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
state: Raw.deserialize(state)
|
state: Raw.deserialize(initialState)
|
||||||
};
|
};
|
||||||
|
|
||||||
hasMark(type) {
|
hasMark = (type) => {
|
||||||
const { state } = this.state
|
const { state } = this.state
|
||||||
const { marks } = state
|
return state.marks.some(mark => mark.type == type)
|
||||||
return marks.some(mark => mark.type == type)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hasBlock(type) {
|
hasBlock = (type) => {
|
||||||
const { state } = this.state
|
const { state } = this.state
|
||||||
const { blocks } = state
|
return state.blocks.some(node => node.type == type)
|
||||||
return blocks.some(node => node.type == type)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onClickMark(e, type) {
|
onClickMark = (e, type) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
const isActive = this.hasMark(type)
|
const isActive = this.hasMark(type)
|
||||||
let { state } = this.state
|
let { state } = this.state
|
||||||
@@ -80,7 +78,7 @@ class RichText extends React.Component {
|
|||||||
this.setState({ state })
|
this.setState({ state })
|
||||||
}
|
}
|
||||||
|
|
||||||
onClickBlock(e, type) {
|
onClickBlock = (e, type) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
const isActive = this.hasBlock(type)
|
const isActive = this.hasBlock(type)
|
||||||
let { state } = this.state
|
let { state } = this.state
|
||||||
@@ -93,7 +91,7 @@ class RichText extends React.Component {
|
|||||||
this.setState({ state })
|
this.setState({ state })
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render = () => {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{this.renderToolbar()}
|
{this.renderToolbar()}
|
||||||
@@ -102,7 +100,7 @@ class RichText extends React.Component {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
renderToolbar() {
|
renderToolbar = () => {
|
||||||
return (
|
return (
|
||||||
<div className="menu toolbar-menu">
|
<div className="menu toolbar-menu">
|
||||||
{this.renderMarkButton('bold', 'format_bold')}
|
{this.renderMarkButton('bold', 'format_bold')}
|
||||||
@@ -118,43 +116,58 @@ class RichText extends React.Component {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
renderMarkButton(type, icon) {
|
renderMarkButton = (type, icon) => {
|
||||||
const isActive = this.hasMark(type)
|
const isActive = this.hasMark(type)
|
||||||
|
const onMouseDown = e => this.onClickMark(e, type)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<span className="button" onMouseDown={e => this.onClickMark(e, type)} data-active={isActive}>
|
<span className="button" onMouseDown={onMouseDown} data-active={isActive}>
|
||||||
<span className="material-icons">{icon}</span>
|
<span className="material-icons">{icon}</span>
|
||||||
</span>
|
</span>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
renderBlockButton(type, icon) {
|
renderBlockButton = (type, icon) => {
|
||||||
const isActive = this.hasBlock(type)
|
const isActive = this.hasBlock(type)
|
||||||
|
const onMouseDown = e => this.onClickBlock(e, type)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<span className="button" onMouseDown={e => this.onClickBlock(e, type)} data-active={isActive}>
|
<span className="button" onMouseDown={onMouseDown} data-active={isActive}>
|
||||||
<span className="material-icons">{icon}</span>
|
<span className="material-icons">{icon}</span>
|
||||||
</span>
|
</span>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
renderEditor() {
|
renderEditor = () => {
|
||||||
return (
|
return (
|
||||||
<div className="editor">
|
<div className="editor">
|
||||||
<Editor
|
<Editor
|
||||||
state={this.state.state}
|
state={this.state.state}
|
||||||
renderNode={node => NODES[node.type]}
|
renderNode={this.renderNode}
|
||||||
renderMark={mark => MARKS[mark.type]}
|
renderMark={this.renderMark}
|
||||||
onChange={(state) => {
|
onChange={this.onChange}
|
||||||
console.groupCollapsed('Change!')
|
|
||||||
console.log('Document:', state.document.toJS())
|
|
||||||
console.log('Selection:', state.selection.toJS())
|
|
||||||
console.log('Content:', Raw.serialize(state))
|
|
||||||
console.groupEnd()
|
|
||||||
this.setState({ state })
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderNode = (node) => {
|
||||||
|
return NODES[node.type]
|
||||||
|
}
|
||||||
|
|
||||||
|
renderMark = (mark) => {
|
||||||
|
return MARKS[mark.type]
|
||||||
|
}
|
||||||
|
|
||||||
|
onChange = (state) => {
|
||||||
|
console.groupCollapsed('Change!')
|
||||||
|
console.log('Document:', state.document.toJS())
|
||||||
|
console.log('Selection:', state.selection.toJS())
|
||||||
|
console.log('Content:', Raw.serialize(state))
|
||||||
|
console.groupEnd()
|
||||||
|
this.setState({ state })
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
|
|
||||||
import { Editor, Raw } from '../..'
|
import { Editor, Raw } from '../..'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
import initialState from './state.json'
|
||||||
import keycode from 'keycode'
|
import keycode from 'keycode'
|
||||||
import state from './state.json'
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Node renderers.
|
* Node renderers.
|
||||||
@@ -44,7 +44,7 @@ class Tables extends React.Component {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
state: Raw.deserialize(state)
|
state: Raw.deserialize(initialState)
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -53,27 +53,57 @@ class Tables extends React.Component {
|
|||||||
* @return {Component} component
|
* @return {Component} component
|
||||||
*/
|
*/
|
||||||
|
|
||||||
render() {
|
render = () => {
|
||||||
return (
|
return (
|
||||||
<div className="editor">
|
<div className="editor">
|
||||||
<Editor
|
<Editor
|
||||||
state={this.state.state}
|
state={this.state.state}
|
||||||
renderNode={node => NODES[node.type]}
|
renderNode={this.renderNode}
|
||||||
renderMark={mark => MARKS[mark.type]}
|
renderMark={this.renderMark}
|
||||||
onKeyDown={(e, state) => this.onKeyDown(e, state)}
|
onKeyDown={this.onKeyDown}
|
||||||
onChange={(state) => {
|
onChange={this.onChange}
|
||||||
console.groupCollapsed('Change!')
|
|
||||||
console.log('Document:', state.document.toJS())
|
|
||||||
console.log('Selection:', state.selection.toJS())
|
|
||||||
console.log('Content:', Raw.serialize(state))
|
|
||||||
console.groupEnd()
|
|
||||||
this.setState({ state })
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render a `node`.
|
||||||
|
*
|
||||||
|
* @param {Node} node
|
||||||
|
* @return {Element}
|
||||||
|
*/
|
||||||
|
|
||||||
|
renderNode = (node) => {
|
||||||
|
return NODES[node.type]
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render a `mark`.
|
||||||
|
*
|
||||||
|
* @param {Mark} mark
|
||||||
|
* @return {Element}
|
||||||
|
*/
|
||||||
|
|
||||||
|
renderMark = (mark) => {
|
||||||
|
return MARKS[mark.type]
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On change.
|
||||||
|
*
|
||||||
|
* @param {State} state
|
||||||
|
*/
|
||||||
|
|
||||||
|
onChange = (state) => {
|
||||||
|
console.groupCollapsed('Change!')
|
||||||
|
console.log('Document:', state.document.toJS())
|
||||||
|
console.log('Selection:', state.selection.toJS())
|
||||||
|
console.log('Content:', Raw.serialize(state))
|
||||||
|
console.groupEnd()
|
||||||
|
this.setState({ state })
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* On key down, check for our specific key shortcuts.
|
* On key down, check for our specific key shortcuts.
|
||||||
*
|
*
|
||||||
@@ -82,11 +112,9 @@ class Tables extends React.Component {
|
|||||||
* @return {State or Null} state
|
* @return {State or Null} state
|
||||||
*/
|
*/
|
||||||
|
|
||||||
onKeyDown(e, state) {
|
onKeyDown = (e, state) => {
|
||||||
if (state.startBlock.type != 'table-cell') return
|
if (state.startBlock.type != 'table-cell') return
|
||||||
|
switch (keycode(e.which)) {
|
||||||
const key = keycode(e.which)
|
|
||||||
switch (key) {
|
|
||||||
case 'backspace': return this.onBackspace(e, state)
|
case 'backspace': return this.onBackspace(e, state)
|
||||||
case 'delete': return this.onDelete(e, state)
|
case 'delete': return this.onDelete(e, state)
|
||||||
case 'enter': return this.onEnter(e, state)
|
case 'enter': return this.onEnter(e, state)
|
||||||
@@ -101,7 +129,7 @@ class Tables extends React.Component {
|
|||||||
* @return {State or Null} state
|
* @return {State or Null} state
|
||||||
*/
|
*/
|
||||||
|
|
||||||
onBackspace(e, state) {
|
onBackspace = (e, state) => {
|
||||||
if (state.startOffset != 0) return
|
if (state.startOffset != 0) return
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
return state
|
return state
|
||||||
@@ -115,7 +143,7 @@ class Tables extends React.Component {
|
|||||||
* @return {State or Null} state
|
* @return {State or Null} state
|
||||||
*/
|
*/
|
||||||
|
|
||||||
onDelete(e, state) {
|
onDelete = (e, state) => {
|
||||||
if (state.endOffset != state.startText.length) return
|
if (state.endOffset != state.startText.length) return
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
return state
|
return state
|
||||||
@@ -129,7 +157,7 @@ class Tables extends React.Component {
|
|||||||
* @return {State or Null} state
|
* @return {State or Null} state
|
||||||
*/
|
*/
|
||||||
|
|
||||||
onEnter(e, state) {
|
onEnter = (e, state) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
return state
|
return state
|
||||||
}
|
}
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"prepublish": "make dist",
|
"prepublish": "make dist",
|
||||||
"test": "make test"
|
"test": "make check"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"cheerio": "^0.20.0",
|
"cheerio": "^0.20.0",
|
||||||
|
Reference in New Issue
Block a user