1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-09-01 03:11:44 +02:00

fix style, rename warning to warn

This commit is contained in:
Ian Storm Taylor
2016-11-17 16:32:03 -08:00
parent 53751ca605
commit 4036753335
46 changed files with 683 additions and 543 deletions

View File

@@ -82,7 +82,7 @@ class Content extends React.Component {
*
* @param {Object} props
* @param {Object} state
* @return {Boolean} shouldUpdate
* @return {Boolean}
*/
shouldComponentUpdate = (props, state) => {
@@ -625,7 +625,7 @@ class Content extends React.Component {
/**
* Render the editor content.
*
* @return {Element} element
* @return {Element}
*/
render = () => {
@@ -690,7 +690,7 @@ class Content extends React.Component {
* Render a `node`.
*
* @param {Node} node
* @return {Element} element
* @return {Element}
*/
renderNode = (node) => {
@@ -725,6 +725,8 @@ function isNonEditable(event) {
/**
* Export.
*
* @type {Component}
*/
export default Content

View File

@@ -8,6 +8,8 @@ import noop from '../utils/noop'
/**
* Debug.
*
* @type {Function}
*/
const debug = Debug('slate:editor')
@@ -38,7 +40,9 @@ const EVENT_HANDLERS = [
class Editor extends React.Component {
/**
* Properties.
* Property types.
*
* @type {Object}
*/
static propTypes = {
@@ -60,6 +64,8 @@ class Editor extends React.Component {
/**
* Default properties.
*
* @type {Object}
*/
static defaultProps = {
@@ -167,7 +173,7 @@ class Editor extends React.Component {
* When the editor receives a new 'state'
*
* @param {State} state
* @return {State} newState
* @return {State}
*/
onBeforeChange = (state) => {
@@ -275,6 +281,7 @@ class Editor extends React.Component {
*/
resolvePlugins = (props) => {
// eslint-disable-next-line no-unused-vars
const { onChange, plugins, ...editorPlugin } = props
const corePlugin = CorePlugin(props)
return [
@@ -316,6 +323,8 @@ for (const property of EVENT_HANDLERS) {
/**
* Export.
*
* @type {Component}
*/
export default Editor

View File

@@ -316,6 +316,8 @@ function findDeepestNode(element) {
/**
* Export.
*
* @type {Component}
*/
export default Leaf

View File

@@ -9,7 +9,7 @@ import IS_DEV from '../constants/is-dev'
import Leaf from './leaf'
import Void from './void'
import scrollTo from '../utils/scroll-to'
import warning from '../utils/warning'
import warn from '../utils/warn'
/**
* Debug.
@@ -104,7 +104,7 @@ class Node extends React.Component {
if (!IS_DEV || !Immutable.is(nextProps.node, this.props.node)) {
return true
} else {
warning('Encountered different references for identical node values in "shouldComponentUpdate". Check that you are preserving references for the following node:\n', nextProps.node)
warn('Encountered different references for identical node values in "shouldComponentUpdate". Check that you are preserving references for the following node:\n', nextProps.node)
}
}
@@ -227,7 +227,7 @@ class Node extends React.Component {
/**
* Render.
*
* @return {Element} element
* @return {Element}
*/
render = () => {
@@ -243,7 +243,7 @@ class Node extends React.Component {
* Render a `child` node.
*
* @param {Node} child
* @return {Element} element
* @return {Element}
*/
renderNode = (child) => {
@@ -262,7 +262,7 @@ class Node extends React.Component {
/**
* Render an element `node`.
*
* @return {Element} element
* @return {Element}
*/
renderElement = () => {
@@ -307,7 +307,7 @@ class Node extends React.Component {
/**
* Render a text node.
*
* @return {Element} element
* @return {Element}
*/
renderText = () => {
@@ -333,7 +333,7 @@ class Node extends React.Component {
/**
* Render a single leaf node given a `range` and `offset`.
*
* @param {List} ranges
* @param {List<Range>} ranges
* @param {Range} range
* @param {Number} index
* @param {Number} offset

View File

@@ -3,12 +3,16 @@ import React from 'react'
/**
* Placeholder.
*
* @type {Component}
*/
class Placeholder extends React.Component {
/**
* Properties.
* Property types.
*
* @type {Object}
*/
static propTypes = {
@@ -48,10 +52,7 @@ class Placeholder extends React.Component {
const { node, parent } = this.props
if (node.text) return false
if (parent.nodes.size > 1) return false
const isFirst = parent.nodes.first() === node
if (isFirst) return true
if (parent.nodes.first() === node) return true
return false
}
@@ -61,7 +62,7 @@ class Placeholder extends React.Component {
* If the placeholder is a string, and no `className` or `style` has been
* passed, give it a default style of lowered opacity.
*
* @return {Element} element
* @return {Element}
*/
render = () => {
@@ -98,6 +99,8 @@ class Placeholder extends React.Component {
/**
* Export.
*
* @type {Component}
*/
export default Placeholder

View File

@@ -16,6 +16,8 @@ class Void extends React.Component {
/**
* Property types.
*
* @type {Object}
*/
static propTypes = {
@@ -152,6 +154,8 @@ class Void extends React.Component {
/**
* Export.
*
* @type {Component}
*/
export default Void

View File

@@ -5,6 +5,8 @@ import includes from 'lodash/includes'
/**
* Export.
*
* @type {Object}
*/
export const IS_ANDROID = process.browser && browser.name == 'android'

View File

@@ -1,3 +1,10 @@
/**
* Is in development?
*
* @type {Boolean}
*/
const IS_DEV = (
typeof process !== 'undefined' &&
process.env &&
@@ -5,7 +12,8 @@ const IS_DEV = (
)
/**
* True if running slate in development mode
* Export.
*
* @type {Boolean}
*/

View File

@@ -12,6 +12,8 @@ const TYPES = {
/**
* Export.
*
* @type {Object}
*/
export default TYPES

View File

@@ -1,6 +1,6 @@
/**
* Prevent circuit.
* Prevent circular dependencies.
*/
import './document'
@@ -19,6 +19,8 @@ import { Map, List, Record } from 'immutable'
/**
* Default properties.
*
* @type {Object}
*/
const DEFAULTS = {
@@ -31,6 +33,8 @@ const DEFAULTS = {
/**
* Block.
*
* @type {Block}
*/
class Block extends new Record(DEFAULTS) {
@@ -38,8 +42,8 @@ class Block extends new Record(DEFAULTS) {
/**
* Create a new `Block` with `properties`.
*
* @param {Object} properties
* @return {Block} element
* @param {Object|Block} properties
* @return {Block}
*/
static create(properties = {}) {
@@ -63,8 +67,8 @@ class Block extends new Record(DEFAULTS) {
/**
* Create a list of `Blocks` from an array.
*
* @param {Array} elements
* @return {List} list
* @param {Array<Object|Block>} elements
* @return {List<Block>}
*/
static createList(elements = []) {
@@ -75,7 +79,7 @@ class Block extends new Record(DEFAULTS) {
/**
* Get the node's kind.
*
* @return {String} kind
* @return {String}
*/
get kind() {
@@ -85,7 +89,7 @@ class Block extends new Record(DEFAULTS) {
/**
* Is the node empty?
*
* @return {Boolean} isEmpty
* @return {Boolean}
*/
get isEmpty() {
@@ -95,7 +99,7 @@ class Block extends new Record(DEFAULTS) {
/**
* Get the length of the concatenated text of the node.
*
* @return {Number} length
* @return {Number}
*/
get length() {
@@ -105,7 +109,7 @@ class Block extends new Record(DEFAULTS) {
/**
* Get the concatenated text `string` of all child nodes.
*
* @return {String} text
* @return {String}
*/
get text() {
@@ -125,6 +129,8 @@ for (const method in Node) {
/**
* Export.
*
* @type {Block}
*/
export default Block

View File

@@ -3,25 +3,29 @@ import Mark from './mark'
import { List, Record, Set } from 'immutable'
/**
* Record.
* Default properties.
*
* @type {Object}
*/
const CharacterRecord = new Record({
const DEFAULTS = {
marks: new Set(),
text: ''
})
}
/**
* Character.
*
* @type {Character}
*/
class Character extends CharacterRecord {
class Character extends new Record(DEFAULTS) {
/**
* Create a character record with `properties`.
*
* @param {Object} properties
* @return {Character} character
* @param {Object|Character} properties
* @return {Character}
*/
static create(properties = {}) {
@@ -33,8 +37,8 @@ class Character extends CharacterRecord {
/**
* Create a characters list from an array of characters.
*
* @param {Array} array
* @return {List} characters
* @param {Array<Object|Character>} array
* @return {List<Character>}
*/
static createList(array = []) {
@@ -46,8 +50,8 @@ class Character extends CharacterRecord {
* Create a characters list from a `string` and optional `marks`.
*
* @param {String} string
* @param {Set} marks (optional)
* @return {List}
* @param {Set<Mark>} marks (optional)
* @return {List<Character>}
*/
static createListFromText(string, marks) {
@@ -59,7 +63,7 @@ class Character extends CharacterRecord {
/**
* Get the kind.
*
* @return {String} kind
* @return {String}
*/
get kind() {
@@ -70,6 +74,8 @@ class Character extends CharacterRecord {
/**
* Export.
*
* @type {Character}
*/
export default Character

View File

@@ -6,6 +6,8 @@ import { Map } from 'immutable'
*
* This isn't an immutable record, it's just a thin wrapper around `Map` so that
* we can allow for more convenient creation.
*
* @type {Object}
*/
const Data = {
@@ -27,6 +29,8 @@ const Data = {
/**
* Export.
*
* @type {Object}
*/
export default Data

View File

@@ -1,6 +1,6 @@
/**
* Prevent circuit.
* Prevent circular dependencies.
*/
import './block'
@@ -16,7 +16,9 @@ import generateKey from '../utils/generate-key'
import { OrderedMap, Record } from 'immutable'
/**
* Defaults.
* Default properties.
*
* @type {Object}
*/
const DEFAULTS = {
@@ -26,6 +28,8 @@ const DEFAULTS = {
/**
* Document.
*
* @type {Document}
*/
class Document extends new Record(DEFAULTS) {
@@ -33,8 +37,8 @@ class Document extends new Record(DEFAULTS) {
/**
* Create a new `Document` with `properties`.
*
* @param {Objetc} properties
* @return {Document} document
* @param {Object|Document} properties
* @return {Document}
*/
static create(properties = {}) {
@@ -49,7 +53,7 @@ class Document extends new Record(DEFAULTS) {
/**
* Get the node's kind.
*
* @return {String} kind
* @return {String}
*/
get kind() {
@@ -59,7 +63,7 @@ class Document extends new Record(DEFAULTS) {
/**
* Is the document empty?
*
* @return {Boolean} isEmpty
* @return {Boolean}
*/
get isEmpty() {
@@ -69,7 +73,7 @@ class Document extends new Record(DEFAULTS) {
/**
* Get the length of the concatenated text of the document.
*
* @return {Number} length
* @return {Number}
*/
get length() {
@@ -79,7 +83,7 @@ class Document extends new Record(DEFAULTS) {
/**
* Get the concatenated text `string` of all child nodes.
*
* @return {String} text
* @return {String}
*/
get text() {
@@ -98,6 +102,8 @@ for (const method in Node) {
/**
* Export.
*
* @type {Document}
*/
export default Document

View File

@@ -1,6 +1,6 @@
/**
* Prevent circuit.
* Prevent circular dependencies.
*/
import './block'
@@ -18,7 +18,9 @@ import generateKey from '../utils/generate-key'
import { List, Map, Record } from 'immutable'
/**
* Record.
* Default properties.
*
* @type {Object}
*/
const DEFAULTS = {
@@ -31,6 +33,8 @@ const DEFAULTS = {
/**
* Inline.
*
* @type {Inline}
*/
class Inline extends new Record(DEFAULTS) {
@@ -38,8 +42,8 @@ class Inline extends new Record(DEFAULTS) {
/**
* Create a new `Inline` with `properties`.
*
* @param {Object} properties
* @return {Inline} element
* @param {Object|Inline} properties
* @return {Inline}
*/
static create(properties = {}) {
@@ -63,8 +67,8 @@ class Inline extends new Record(DEFAULTS) {
/**
* Create a list of `Inlines` from an array.
*
* @param {Array} elements
* @return {List} map
* @param {Array<Object|Inline>} elements
* @return {List<Inline>}
*/
static createList(elements = []) {
@@ -75,7 +79,7 @@ class Inline extends new Record(DEFAULTS) {
/**
* Get the node's kind.
*
* @return {String} kind
* @return {String}
*/
get kind() {
@@ -85,7 +89,7 @@ class Inline extends new Record(DEFAULTS) {
/**
* Is the node empty?
*
* @return {Boolean} isEmpty
* @return {Boolean}
*/
get isEmpty() {
@@ -95,7 +99,7 @@ class Inline extends new Record(DEFAULTS) {
/**
* Get the length of the concatenated text of the node.
*
* @return {Number} length
* @return {Number}
*/
get length() {
@@ -105,7 +109,7 @@ class Inline extends new Record(DEFAULTS) {
/**
* Get the concatenated text `string` of all child nodes.
*
* @return {String} text
* @return {String}
*/
get text() {
@@ -122,9 +126,10 @@ for (const method in Node) {
Inline.prototype[method] = Node[method]
}
/**
* Export.
*
* @type {Inline}
*/
export default Inline

View File

@@ -4,7 +4,9 @@ import memoize from '../utils/memoize'
import { Map, Record, Set } from 'immutable'
/**
* Record.
* Default properties.
*
* @type {Object}
*/
const DEFAULTS = {
@@ -14,6 +16,8 @@ const DEFAULTS = {
/**
* Mark.
*
* @type {Mark}
*/
class Mark extends new Record(DEFAULTS) {
@@ -21,8 +25,8 @@ class Mark extends new Record(DEFAULTS) {
/**
* Create a new `Mark` with `properties`.
*
* @param {Object} properties
* @return {Mark} mark
* @param {Object|Mark} properties
* @return {Mark}
*/
static create(properties = {}) {
@@ -35,8 +39,8 @@ class Mark extends new Record(DEFAULTS) {
/**
* Create a marks set from an array of marks.
*
* @param {Array} array
* @return {Set} marks
* @param {Array<Object|Mark>} array
* @return {Set<Mark>}
*/
static createSet(array = []) {
@@ -47,7 +51,7 @@ class Mark extends new Record(DEFAULTS) {
/**
* Get the kind.
*
* @return {String} kind
* @return {String}
*/
get kind() {
@@ -58,7 +62,7 @@ class Mark extends new Record(DEFAULTS) {
* Get the component for the node from a `schema`.
*
* @param {Schema} schema
* @return {Component || Void}
* @return {Component|Void}
*/
getComponent(schema) {
@@ -77,6 +81,8 @@ memoize(Mark.prototype, [
/**
* Export.
*
* @type {Mark}
*/
export default Mark

View File

@@ -10,12 +10,13 @@ import memoize from '../utils/memoize'
import generateKey from '../utils/generate-key'
import { List, Set } from 'immutable'
/**
* Node.
*
* And interface that `Document`, `Block` and `Inline` all implement, to make
* working with the recursive node tree easier.
*
* @type {Object}
*/
const Node = {
@@ -23,7 +24,7 @@ const Node = {
/**
* Return a set of all keys in the node.
*
* @return {Set<Node>} keys
* @return {Set<Node>}
*/
getKeys() {
@@ -39,18 +40,19 @@ const Node = {
/**
* Get the concatenated text `string` of all child nodes.
*
* @return {String} text
* @return {String}
*/
getText() {
return this.nodes
.reduce((result, node) => result + node.text, '')
return this.nodes.reduce((result, node) => {
return result + node.text
}, '')
},
/**
* Assert that a node has a child by `key` and return it.
*
* @param {String or Node} key
* @param {String} key
* @return {Node}
*/
@@ -68,7 +70,7 @@ const Node = {
/**
* Assert that a node has a descendant by `key` and return it.
*
* @param {String or Node} key
* @param {String} key
* @return {Node}
*/
@@ -103,8 +105,8 @@ const Node = {
/**
* Concat children `nodes` on to the end of the node.
*
* @param {List} nodes
* @return {Node} node
* @param {List<Node>} nodes
* @return {Node}
*/
concatChildren(nodes) {
@@ -116,7 +118,7 @@ const Node = {
* Decorate all of the text nodes with a `decorator` function.
*
* @param {Function} decorator
* @return {Node} node
* @return {Node}
*/
decorateTexts(decorator) {
@@ -131,7 +133,7 @@ const Node = {
* Recursively find all descendant nodes by `iterator`. Breadth first.
*
* @param {Function} iterator
* @return {Node or Null} node
* @return {Node|Null}
*/
findDescendant(iterator) {
@@ -155,7 +157,7 @@ const Node = {
* Recursively find all descendant nodes by `iterator`. Depth first.
*
* @param {Function} iterator
* @return {Node or Null} node
* @return {Node|Null}
*/
findDescendantDeep(iterator) {
@@ -178,28 +180,29 @@ const Node = {
*/
forEachDescendant(iterator) {
let returned // Returned value of iterator. False to break from loop
// If the iterator returns false it will break the loop.
let ret
this.nodes.forEach((child, i, nodes) => {
if (iterator(child, i, nodes) === false) {
returned = false
ret = false
return false
}
if (child.kind != 'text') {
returned = child.forEachDescendant(iterator)
return returned
ret = child.forEachDescendant(iterator)
return ret
}
})
return returned
return ret
},
/**
* Recursively filter all descendant nodes with `iterator`.
*
* @param {Function} iterator
* @return {List} nodes
* @return {List<Node>}
*/
filterDescendants(iterator) {
@@ -217,7 +220,7 @@ const Node = {
* It is different from `filterDescendants` in regard of the order of results.
*
* @param {Function} iterator
* @return {List} nodes
* @return {List<Node>}
*/
filterDescendantsDeep(iterator) {
@@ -231,7 +234,7 @@ const Node = {
/**
* Get the closest block nodes for each text node in the node.
*
* @return {List} nodes
* @return {List<Node>}
*/
getBlocks() {
@@ -246,7 +249,7 @@ const Node = {
* Get the closest block nodes for each text node in a `range`.
*
* @param {Selection} range
* @return {List} nodes
* @return {List<Node>}
*/
getBlocksAtRange(range) {
@@ -259,7 +262,7 @@ const Node = {
* Get a list of the characters in a `range`.
*
* @param {Selection} range
* @return {List} characters
* @return {List<Node>} characters
*/
getCharactersAtRange(range) {
@@ -274,9 +277,9 @@ const Node = {
/**
* Get children between two child keys.
*
* @param {String or Node} start
* @param {String or Node} end
* @return {Node} node
* @param {String} start
* @param {String} end
* @return {Node}
*/
getChildrenBetween(start, end) {
@@ -290,9 +293,9 @@ const Node = {
/**
* Get children between two child keys, including the two children.
*
* @param {String or Node} start
* @param {String or Node} end
* @return {Node} node
* @param {String} start
* @param {String} end
* @return {Node}
*/
getChildrenBetweenIncluding(start, end) {
@@ -306,9 +309,9 @@ const Node = {
/**
* Get closest parent of node by `key` that matches `iterator`.
*
* @param {String or Node} key
* @param {String} key
* @param {Function} iterator
* @return {Node or Null} node
* @return {Node|Null}
*/
getClosest(key, iterator) {
@@ -325,8 +328,8 @@ const Node = {
/**
* Get the closest block parent of a `node`.
*
* @param {String or Node} key
* @return {Node or Null} node
* @param {String} key
* @return {Node|Null}
*/
getClosestBlock(key) {
@@ -336,8 +339,8 @@ const Node = {
/**
* Get the closest inline parent of a `node`.
*
* @param {String or Node} key
* @return {Node or Null} node
* @param {String} key
* @return {Node|Null}
*/
getClosestInline(key) {
@@ -347,8 +350,8 @@ const Node = {
/**
* Get a child node by `key`.
*
* @param {String or Node} key
* @return {Node or Null} node
* @param {String} key
* @return {Node|Null}
*/
getChild(key) {
@@ -359,8 +362,8 @@ const Node = {
/**
* Get the common ancestor of nodes `one` and `two` by keys.
*
* @param {String or Node} one
* @param {String or Node} two
* @param {String} one
* @param {String} two
* @return {Node}
*/
@@ -386,7 +389,7 @@ const Node = {
* Get the component for the node from a `schema`.
*
* @param {Schema} schema
* @return {Component || Void}
* @return {Component|Void}
*/
getComponent(schema) {
@@ -434,7 +437,7 @@ const Node = {
* Get a descendant node by `key`.
*
* @param {String} key
* @return {Node or Null} node
* @return {Node|Null}
*/
getDescendant(key) {
@@ -464,7 +467,7 @@ const Node = {
* Get a descendant by `path`.
*
* @param {Array} path
* @return {Node || Void}
* @return {Node|Null}
*/
getDescendantAtPath(path) {
@@ -507,7 +510,7 @@ const Node = {
/**
* Get the depth of a child node by `key`, with optional `startAt`.
*
* @param {String or Node} key
* @param {String} key
* @param {Number} startAt (optional)
* @return {Number} depth
*/
@@ -525,7 +528,7 @@ const Node = {
* Get a fragment of the node at a `range`.
*
* @param {Selection} range
* @return {List} nodes
* @return {List<Node>}
*/
getFragmentAtRange(range) {
@@ -565,9 +568,9 @@ const Node = {
/**
* Get the furthest parent of a node by `key` that matches an `iterator`.
*
* @param {String or Node} key
* @param {String} key
* @param {Function} iterator
* @return {Node or Null}
* @return {Node|Null}
*/
getFurthest(key, iterator) {
@@ -584,8 +587,8 @@ const Node = {
/**
* Get the furthest block parent of a node by `key`.
*
* @param {String or Node} key
* @return {Node or Null} node
* @param {String} key
* @return {Node|Null}
*/
getFurthestBlock(key) {
@@ -595,8 +598,8 @@ const Node = {
/**
* Get the furthest inline parent of a node by `key`.
*
* @param {String or Node} key
* @return {Node or Null} node
* @param {String} key
* @return {Node|Null}
*/
getFurthestInline(key) {
@@ -606,8 +609,8 @@ const Node = {
/**
* Get the highest child ancestor of a node by `key`.
*
* @param {String or Node} key
* @return {Node or Null} node
* @param {String} key
* @return {Node|Null}
*/
getHighestChild(key) {
@@ -622,8 +625,8 @@ const Node = {
/**
* Get the highest parent of a node by `key` which has an only child.
*
* @param {String or Node} key
* @return {Node or Null}
* @param {String} key
* @return {Node|Null}
*/
getHighestOnlyChildParent(key) {
@@ -641,7 +644,7 @@ const Node = {
/**
* Get the furthest inline nodes for each text node in the node.
*
* @return {List} nodes
* @return {List<Node>}
*/
getInlines() {
@@ -657,7 +660,7 @@ const Node = {
* Get the closest inline nodes for each text node in a `range`.
*
* @param {Selection} range
* @return {List} nodes
* @return {List<Node>}
*/
getInlinesAtRange(range) {
@@ -673,7 +676,7 @@ const Node = {
* Get a set of the marks in a `range`.
*
* @param {Selection} range
* @return {Set} marks
* @return {Set<Mark>}
*/
getMarksAtRange(range) {
@@ -707,8 +710,8 @@ const Node = {
/**
* Get the block node before a descendant text node by `key`.
*
* @param {String or Node} key
* @return {Node or Null} node
* @param {String} key
* @return {Node|Null}
*/
getNextBlock(key) {
@@ -731,8 +734,8 @@ const Node = {
/**
* Get the node after a descendant by `key`.
*
* @param {String or Node} key
* @return {Node or Null} node
* @param {String} key
* @return {Node|Null}
*/
getNextSibling(key) {
@@ -751,8 +754,8 @@ const Node = {
/**
* Get the text node after a descendant text node by `key`.
*
* @param {String or Node} key
* @return {Node or Null} node
* @param {String} key
* @return {Node|Null}
*/
getNextText(key) {
@@ -765,8 +768,8 @@ const Node = {
/**
* Get the offset for a descendant text node by `key`.
*
* @param {String or Node} key
* @return {Number} offset
* @param {String} key
* @return {Number}
*/
getOffset(key) {
@@ -788,7 +791,7 @@ const Node = {
* Get the offset from a `range`.
*
* @param {Selection} range
* @return {Number} offset
* @return {Number}
*/
getOffsetAtRange(range) {
@@ -805,8 +808,8 @@ const Node = {
/**
* Get the parent of a child node by `key`.
*
* @param {String or Node} key
* @return {Node or Null} node
* @param {String} key
* @return {Node|Null}
*/
getParent(key) {
@@ -829,7 +832,7 @@ const Node = {
/**
* Get the path of a descendant node by `key`.
*
* @param {String || Node} key
* @param {String|Node} key
* @return {Array}
*/
@@ -860,8 +863,8 @@ const Node = {
/**
* Get the path of ancestors of a descendant node by `key`.
*
* @param {String || Node} node
* @return {List<Node> or Null}
* @param {String|Node} key
* @return {List<Node>|Null}
*/
getAncestors(key) {
@@ -887,8 +890,8 @@ const Node = {
/**
* Get the node before a descendant node by `key`.
*
* @param {String or Node} key
* @return {Node or Null} node
* @param {String} key
* @return {Node|Null}
*/
getPreviousSibling(key) {
@@ -907,8 +910,8 @@ const Node = {
/**
* Get the text node before a descendant text node by `key`.
*
* @param {String or Node} key
* @return {Node or Null} node
* @param {String} key
* @return {Node|Null}
*/
getPreviousText(key) {
@@ -921,8 +924,8 @@ const Node = {
/**
* Get the block node before a descendant text node by `key`.
*
* @param {String or Node} key
* @return {Node or Null} node
* @param {String} key
* @return {Node|Null}
*/
getPreviousBlock(key) {
@@ -946,7 +949,7 @@ const Node = {
* Get the descendent text node at an `offset`.
*
* @param {String} offset
* @return {Node or Null} node
* @return {Node|Null}
*/
getTextAtOffset(offset) {
@@ -962,7 +965,7 @@ const Node = {
/**
* Get the direction of the node's text.
*
* @return {String} direction
* @return {String}
*/
getTextDirection() {
@@ -976,21 +979,14 @@ const Node = {
/**
* Recursively get all of the child text nodes in order of appearance.
*
* @return {List} nodes
* @return {List<Node>}
*/
getTexts() {
return List(this._getTexts())
},
/**
* Recursively get all of the child text nodes in order of appearance.
*
* @return {Array} nodes
*/
// This one is memoized
// This one is memoized for performance.
_getTexts() {
return this.nodes.reduce((texts, node) => {
if (node.kind == 'text') {
@@ -1005,7 +1001,7 @@ const Node = {
/**
* Get the first child text node.
*
* @return {Node || Null} node
* @return {Node|Null}
*/
getFirstText() {
@@ -1023,7 +1019,7 @@ const Node = {
/**
* Get the last child text node.
*
* @return {Node} node
* @return {Node|Null}
*/
getLastText() {
@@ -1042,7 +1038,7 @@ const Node = {
* Get all of the text nodes in a `range`.
*
* @param {Selection} range
* @return {List} nodes
* @return {List<Node>}
*/
getTextsAtRange(range) {
@@ -1059,8 +1055,8 @@ const Node = {
/**
* Check if a child node exists by `key`.
*
* @param {String or Node} key
* @return {Boolean} exists
* @param {String} key
* @return {Boolean}
*/
hasChild(key) {
@@ -1070,8 +1066,8 @@ const Node = {
/**
* Recursively check if a child node exists by `key`.
*
* @param {String or Node} key
* @return {Boolean} exists
* @param {String} key
* @return {Boolean}
*/
hasDescendant(key) {
@@ -1081,7 +1077,7 @@ const Node = {
/**
* Check if a node has a void parent by `key`.
*
* @param {String or Node} key
* @param {String} key
* @return {Boolean}
*/
@@ -1120,7 +1116,7 @@ const Node = {
* Check if the inline nodes are split at a `range`.
*
* @param {Selection} range
* @return {Boolean} isSplit
* @return {Boolean}
*/
isInlineSplitAtRange(range) {
@@ -1180,7 +1176,7 @@ const Node = {
* optimized to not return a new node if no changes are made.
*
* @param {Function} iterator
* @return {Node} node
* @return {Node}
*/
mapChildren(iterator) {
@@ -1199,7 +1195,7 @@ const Node = {
* optimized to not return a new node if no changes are made.
*
* @param {Function} iterator
* @return {Node} node
* @return {Node}
*/
mapDescendants(iterator) {
@@ -1221,7 +1217,7 @@ const Node = {
/**
* Regenerate the node's key.
*
* @return {Node} node
* @return {Node}
*/
regenerateKey() {
@@ -1231,8 +1227,8 @@ const Node = {
/**
* Remove a `node` from the children node map.
*
* @param {String or Node} key
* @return {Node} node
* @param {String} key
* @return {Node}
*/
removeDescendant(key) {
@@ -1387,7 +1383,7 @@ const Node = {
* Set a new value for a child node by `key`.
*
* @param {Node} node
* @return {Node} node
* @return {Node}
*/
updateDescendant(node) {
@@ -1413,7 +1409,7 @@ const Node = {
* Validate the node against a `schema`.
*
* @param {Schema} schema
* @return {Object || Void}
* @return {Object|Null}
*/
validate(schema) {
@@ -1470,6 +1466,8 @@ memoize(Node, [
/**
* Export.
*
* @type {Object}
*/
export default Node

View File

@@ -5,6 +5,8 @@ import { Record, Set } from 'immutable'
/**
* Default properties.
*
* @type {Object}
*/
const DEFAULTS = {
@@ -14,6 +16,8 @@ const DEFAULTS = {
/**
* Range.
*
* @type {Range}
*/
class Range extends new Record(DEFAULTS) {
@@ -21,7 +25,7 @@ class Range extends new Record(DEFAULTS) {
/**
* Create a new `Range` with `properties`.
*
* @param {Object} properties
* @param {Object|Range} properties
* @return {Range}
*/
@@ -35,7 +39,7 @@ class Range extends new Record(DEFAULTS) {
/**
* Get the node's kind.
*
* @return {String} kind
* @return {String}
*/
get kind() {
@@ -45,7 +49,7 @@ class Range extends new Record(DEFAULTS) {
/**
* Return range as a list of characters
*
* @return {List<Character>} characters
* @return {List<Character>}
*/
getCharacters() {
@@ -64,6 +68,8 @@ class Range extends new Record(DEFAULTS) {
/**
* Export.
*
* @type {Range}
*/
export default Range

View File

@@ -17,7 +17,7 @@ const DEFAULTS = {
/**
* Schema.
*
* @type {Record}
* @type {Schema}
*/
class Schema extends new Record(DEFAULTS) {
@@ -25,8 +25,8 @@ class Schema extends new Record(DEFAULTS) {
/**
* Create a new `Schema` with `properties`.
*
* @param {Object} properties
* @return {Schema} mark
* @param {Object|Schema} properties
* @return {Schema}
*/
static create(properties = {}) {
@@ -37,7 +37,7 @@ class Schema extends new Record(DEFAULTS) {
/**
* Get the kind.
*
* @return {String} kind
* @return {String}
*/
get kind() {
@@ -47,7 +47,7 @@ class Schema extends new Record(DEFAULTS) {
/**
* Return true if one rule can normalize the document
*
* @return {Boolean} isNormalization
* @return {Boolean}
*/
get hasValidators() {
@@ -58,7 +58,7 @@ class Schema extends new Record(DEFAULTS) {
/**
* Return true if one rule can decorate text nodes
*
* @return {Boolean} hasDecorators
* @return {Boolean}
*/
get hasDecorators() {
@@ -74,7 +74,7 @@ class Schema extends new Record(DEFAULTS) {
* much better performance.
*
* @param {Mixed} object
* @return {Component || Void}
* @return {Component|Void}
*/
__getComponent(object) {
@@ -113,7 +113,7 @@ class Schema extends new Record(DEFAULTS) {
* much better performance.
*
* @param {Mixed} object
* @return {Object || Void}
* @return {Object|Void}
*/
__validate(object) {
@@ -218,7 +218,7 @@ function normalizeMarks(marks) {
/**
* Normalize a mark `render` property.
*
* @param {Component || Function || Object || String} render
* @param {Component|Function|Object|String} render
* @return {Component}
*/
@@ -238,7 +238,7 @@ function normalizeMarkComponent(render) {
/**
* Export.
*
* @type {Record}
* @type {Schema}
*/
export default Schema

View File

@@ -1,10 +1,12 @@
import getLeafText from '../utils/get-leaf-text'
import warning from '../utils/warning'
import warn from '../utils/warn'
import { Record } from 'immutable'
/**
* Start-end-and-edge convenience methods to auto-generate.
*
* @type {Array}
*/
const EDGE_METHODS = [
@@ -16,6 +18,8 @@ const EDGE_METHODS = [
/**
* Default properties.
*
* @type {Object}
*/
const DEFAULTS = {
@@ -30,6 +34,8 @@ const DEFAULTS = {
/**
* Selection.
*
* @type {Selection}
*/
class Selection extends new Record(DEFAULTS) {
@@ -37,8 +43,8 @@ class Selection extends new Record(DEFAULTS) {
/**
* Create a new `Selection` with `properties`.
*
* @param {Object} properties
* @return {Selection} selection
* @param {Object|Selection} properties
* @return {Selection}
*/
static create(properties = {}) {
@@ -49,7 +55,7 @@ class Selection extends new Record(DEFAULTS) {
/**
* Get the kind.
*
* @return {String} kind
* @return {String}
*/
get kind() {
@@ -59,7 +65,7 @@ class Selection extends new Record(DEFAULTS) {
/**
* Get whether the selection is blurred.
*
* @return {Boolean} isBlurred
* @return {Boolean}
*/
get isBlurred() {
@@ -69,7 +75,7 @@ class Selection extends new Record(DEFAULTS) {
/**
* Get whether the selection is collapsed.
*
* @return {Boolean} isCollapsed
* @return {Boolean}
*/
get isCollapsed() {
@@ -82,7 +88,7 @@ class Selection extends new Record(DEFAULTS) {
/**
* Get whether the selection is expanded.
*
* @return {Boolean} isExpanded
* @return {Boolean}
*/
get isExpanded() {
@@ -92,7 +98,7 @@ class Selection extends new Record(DEFAULTS) {
/**
* Get whether the selection is forward.
*
* @return {Boolean} isForward
* @return {Boolean}
*/
get isForward() {
@@ -112,7 +118,7 @@ class Selection extends new Record(DEFAULTS) {
/**
* Get the start key.
*
* @return {String} startKey
* @return {String}
*/
get startKey() {
@@ -259,7 +265,7 @@ class Selection extends new Record(DEFAULTS) {
* Check whether the selection is at the start of a `node`.
*
* @param {Node} node
* @return {Boolean} isAtStart
* @return {Boolean}
*/
isAtStartOf(node) {
@@ -274,7 +280,7 @@ class Selection extends new Record(DEFAULTS) {
* Check whether the selection is at the end of a `node`.
*
* @param {Node} node
* @return {Boolean} isAtEnd
* @return {Boolean}
*/
isAtEndOf(node) {
@@ -289,7 +295,7 @@ class Selection extends new Record(DEFAULTS) {
* and focus nodes of the selection always refer to leaf text nodes.
*
* @param {Node} node
* @return {Selection} selection
* @return {Selection}
*/
normalize(node) {
@@ -319,7 +325,7 @@ class Selection extends new Record(DEFAULTS) {
// If the anchor node isn't a text node, match it to one.
if (anchorNode.kind != 'text') {
warning('Selection anchor is on a non text node, matching to leaf')
warn('Selection anchor is on a non text node, matching to leaf')
let anchorText = anchorNode.getTextAtOffset(anchorOffset)
let offset = anchorNode.getOffset(anchorText)
anchorOffset = anchorOffset - offset
@@ -328,7 +334,7 @@ class Selection extends new Record(DEFAULTS) {
// If the focus node isn't a text node, match it to one.
if (focusNode.kind != 'text') {
warning('Selection focus is on a non text node, matching to leaf')
warn('Selection focus is on a non text node, matching to leaf')
let focusText = focusNode.getTextAtOffset(focusOffset)
let offset = focusNode.getOffset(focusText)
focusOffset = focusOffset - offset
@@ -357,7 +363,7 @@ class Selection extends new Record(DEFAULTS) {
/**
* Focus the selection.
*
* @return {Selection} selection
* @return {Selection}
*/
focus() {
@@ -369,7 +375,7 @@ class Selection extends new Record(DEFAULTS) {
/**
* Blur the selection.
*
* @return {Selection} selection
* @return {Selection}
*/
blur() {
@@ -381,7 +387,7 @@ class Selection extends new Record(DEFAULTS) {
/**
* Move the focus point to the anchor point.
*
* @return {Selection} selection
* @return {Selection}
*/
collapseToAnchor() {
@@ -395,7 +401,7 @@ class Selection extends new Record(DEFAULTS) {
/**
* Move the anchor point to the focus point.
*
* @return {Selection} selection
* @return {Selection}
*/
collapseToFocus() {
@@ -409,7 +415,7 @@ class Selection extends new Record(DEFAULTS) {
/**
* Move the end point to the start point.
*
* @return {Selection} selection
* @return {Selection}
*/
collapseToStart() {
@@ -425,7 +431,7 @@ class Selection extends new Record(DEFAULTS) {
/**
* Move the end point to the start point.
*
* @return {Selection} selection
* @return {Selection}
*/
collapseToEnd() {
@@ -442,7 +448,7 @@ class Selection extends new Record(DEFAULTS) {
* Move to the start of a `node`.
*
* @param {Node} node
* @return {Selection} selection
* @return {Selection}
*/
collapseToStartOf(node) {
@@ -460,7 +466,7 @@ class Selection extends new Record(DEFAULTS) {
/**
* Move to the end of a `node`.
*
* @return {Selection} selection
* @return {Selection}
*/
collapseToEndOf(node) {
@@ -481,7 +487,7 @@ class Selection extends new Record(DEFAULTS) {
* @param {Node} start
* @param {Node} end (optional)
* @param {Document} document
* @return {Selection} selection
* @return {Selection}
*/
moveToRangeOf(start, end = start) {
@@ -501,7 +507,7 @@ class Selection extends new Record(DEFAULTS) {
* Move the selection forward `n` characters.
*
* @param {Number} n (optional)
* @return {Selection} selection
* @return {Selection}
*/
moveForward(n = 1) {
@@ -515,7 +521,7 @@ class Selection extends new Record(DEFAULTS) {
* Move the selection backward `n` characters.
*
* @param {Number} n (optional)
* @return {Selection} selection
* @return {Selection}
*/
moveBackward(n = 1) {
@@ -530,7 +536,7 @@ class Selection extends new Record(DEFAULTS) {
*
* @param {Number} anchor
* @param {Number} focus (optional)
* @return {Selection} selection
* @return {Selection}
*/
moveToOffsets(anchor, focus = anchor) {
@@ -549,7 +555,7 @@ class Selection extends new Record(DEFAULTS) {
* Extend the focus point forward `n` characters.
*
* @param {Number} n (optional)
* @return {Selection} selection
* @return {Selection}
*/
extendForward(n = 1) {
@@ -563,7 +569,7 @@ class Selection extends new Record(DEFAULTS) {
* Extend the focus point backward `n` characters.
*
* @param {Number} n (optional)
* @return {Selection} selection
* @return {Selection}
*/
extendBackward(n = 1) {
@@ -577,7 +583,7 @@ class Selection extends new Record(DEFAULTS) {
* Extend the start point forward `n` characters.
*
* @param {Number} n (optional)
* @return {Selection} selection
* @return {Selection}
*/
moveStartOffset(n = 1) {
@@ -590,7 +596,7 @@ class Selection extends new Record(DEFAULTS) {
* Extend the end point forward `n` characters.
*
* @param {Number} n (optional)
* @return {Selection} selection
* @return {Selection}
*/
moveEndOffset(n = 1) {
@@ -603,7 +609,7 @@ class Selection extends new Record(DEFAULTS) {
* Move the start key, while preserving the direction
*
* @param {String} key
* @return {Selection} selection
* @return {Selection}
*/
moveStartTo(key, offset = 0) {
@@ -616,7 +622,7 @@ class Selection extends new Record(DEFAULTS) {
* Move the end key, while preserving the direction
*
* @param {String} key
* @return {Selection} selection
* @return {Selection}
*/
moveEndTo(key, offset = 0) {
@@ -629,7 +635,7 @@ class Selection extends new Record(DEFAULTS) {
* Extend the focus point to the start of a `node`.
*
* @param {Node} node
* @return {Selection} selection
* @return {Selection}
*/
extendToStartOf(node) {
@@ -644,7 +650,7 @@ class Selection extends new Record(DEFAULTS) {
* Extend the focus point to the end of a `node`.
*
* @param {Node} node
* @return {Selection} selection
* @return {Selection}
*/
extendToEndOf(node) {
@@ -658,7 +664,7 @@ class Selection extends new Record(DEFAULTS) {
/**
* Unset the selection
*
* @return {Selection} selection
* @return {Selection}
*/
unset() {
@@ -705,6 +711,8 @@ EDGE_METHODS.forEach((pattern) => {
/**
* Export.
*
* @type {Selection}
*/
export default Selection

View File

@@ -7,6 +7,8 @@ import { Record, Set, Stack, List } from 'immutable'
/**
* History.
*
* @type {History}
*/
const History = new Record({
@@ -16,6 +18,8 @@ const History = new Record({
/**
* Default properties.
*
* @type {Object}
*/
const DEFAULTS = {
@@ -27,6 +31,8 @@ const DEFAULTS = {
/**
* State.
*
* @type {State}
*/
class State extends new Record(DEFAULTS) {
@@ -34,8 +40,8 @@ class State extends new Record(DEFAULTS) {
/**
* Create a new `State` with `properties`.
*
* @param {Object} properties
* @return {State} state
* @param {Object|State} properties
* @return {State}
*/
static create(properties = {}) {
@@ -58,7 +64,7 @@ class State extends new Record(DEFAULTS) {
/**
* Get the kind.
*
* @return {String} kind
* @return {String}
*/
get kind() {
@@ -68,7 +74,7 @@ class State extends new Record(DEFAULTS) {
/**
* Are there undoable events?
*
* @return {Boolean} hasUndos
* @return {Boolean}
*/
get hasUndos() {
@@ -78,7 +84,7 @@ class State extends new Record(DEFAULTS) {
/**
* Are there redoable events?
*
* @return {Boolean} hasRedos
* @return {Boolean}
*/
get hasRedos() {
@@ -88,7 +94,7 @@ class State extends new Record(DEFAULTS) {
/**
* Is the current selection blurred?
*
* @return {Boolean} isBlurred
* @return {Boolean}
*/
get isBlurred() {
@@ -98,7 +104,7 @@ class State extends new Record(DEFAULTS) {
/**
* Is the current selection focused?
*
* @return {Boolean} isFocused
* @return {Boolean}
*/
get isFocused() {
@@ -108,7 +114,7 @@ class State extends new Record(DEFAULTS) {
/**
* Is the current selection collapsed?
*
* @return {Boolean} isCollapsed
* @return {Boolean}
*/
get isCollapsed() {
@@ -118,7 +124,7 @@ class State extends new Record(DEFAULTS) {
/**
* Is the current selection expanded?
*
* @return {Boolean} isExpanded
* @return {Boolean}
*/
get isExpanded() {
@@ -138,7 +144,7 @@ class State extends new Record(DEFAULTS) {
/**
* Is the current selection forward?
*
* @return {Boolean} isForward
* @return {Boolean}
*/
get isForward() {
@@ -148,7 +154,7 @@ class State extends new Record(DEFAULTS) {
/**
* Get the current start key.
*
* @return {String} startKey
* @return {String}
*/
get startKey() {
@@ -158,7 +164,7 @@ class State extends new Record(DEFAULTS) {
/**
* Get the current end key.
*
* @return {String} endKey
* @return {String}
*/
get endKey() {
@@ -168,7 +174,7 @@ class State extends new Record(DEFAULTS) {
/**
* Get the current start offset.
*
* @return {String} startOffset
* @return {String}
*/
get startOffset() {
@@ -178,7 +184,7 @@ class State extends new Record(DEFAULTS) {
/**
* Get the current end offset.
*
* @return {String} endOffset
* @return {String}
*/
get endOffset() {
@@ -188,7 +194,7 @@ class State extends new Record(DEFAULTS) {
/**
* Get the current anchor key.
*
* @return {String} anchorKey
* @return {String}
*/
get anchorKey() {
@@ -198,7 +204,7 @@ class State extends new Record(DEFAULTS) {
/**
* Get the current focus key.
*
* @return {String} focusKey
* @return {String}
*/
get focusKey() {
@@ -208,7 +214,7 @@ class State extends new Record(DEFAULTS) {
/**
* Get the current anchor offset.
*
* @return {String} anchorOffset
* @return {String}
*/
get anchorOffset() {
@@ -218,7 +224,7 @@ class State extends new Record(DEFAULTS) {
/**
* Get the current focus offset.
*
* @return {String} focusOffset
* @return {String}
*/
get focusOffset() {
@@ -228,7 +234,7 @@ class State extends new Record(DEFAULTS) {
/**
* Get the current start text node's closest block parent.
*
* @return {Block} block
* @return {Block}
*/
get startBlock() {
@@ -238,7 +244,7 @@ class State extends new Record(DEFAULTS) {
/**
* Get the current end text node's closest block parent.
*
* @return {Block} block
* @return {Block}
*/
get endBlock() {
@@ -248,7 +254,7 @@ class State extends new Record(DEFAULTS) {
/**
* Get the current anchor text node's closest block parent.
*
* @return {Block} block
* @return {Block}
*/
get anchorBlock() {
@@ -258,7 +264,7 @@ class State extends new Record(DEFAULTS) {
/**
* Get the current focus text node's closest block parent.
*
* @return {Block} block
* @return {Block}
*/
get focusBlock() {
@@ -268,7 +274,7 @@ class State extends new Record(DEFAULTS) {
/**
* Get the current start text node's closest inline parent.
*
* @return {Inline} inline
* @return {Inline}
*/
get startInline() {
@@ -278,7 +284,7 @@ class State extends new Record(DEFAULTS) {
/**
* Get the current end text node's closest inline parent.
*
* @return {Inline} inline
* @return {Inline}
*/
get endInline() {
@@ -288,7 +294,7 @@ class State extends new Record(DEFAULTS) {
/**
* Get the current anchor text node's closest inline parent.
*
* @return {Inline} inline
* @return {Inline}
*/
get anchorInline() {
@@ -298,7 +304,7 @@ class State extends new Record(DEFAULTS) {
/**
* Get the current focus text node's closest inline parent.
*
* @return {Inline} inline
* @return {Inline}
*/
get focusInline() {
@@ -308,7 +314,7 @@ class State extends new Record(DEFAULTS) {
/**
* Get the current start text node.
*
* @return {Text} text
* @return {Text}
*/
get startText() {
@@ -318,7 +324,7 @@ class State extends new Record(DEFAULTS) {
/**
* Get the current end node.
*
* @return {Text} text
* @return {Text}
*/
get endText() {
@@ -328,7 +334,7 @@ class State extends new Record(DEFAULTS) {
/**
* Get the current anchor node.
*
* @return {Text} text
* @return {Text}
*/
get anchorText() {
@@ -338,7 +344,7 @@ class State extends new Record(DEFAULTS) {
/**
* Get the current focus node.
*
* @return {Text} text
* @return {Text}
*/
get focusText() {
@@ -348,7 +354,7 @@ class State extends new Record(DEFAULTS) {
/**
* Get the characters in the current selection.
*
* @return {List} characters
* @return {List<Character>}
*/
get characters() {
@@ -358,7 +364,7 @@ class State extends new Record(DEFAULTS) {
/**
* Get the marks of the current selection.
*
* @return {Set} marks
* @return {Set<Mark>}
*/
get marks() {
@@ -370,7 +376,7 @@ class State extends new Record(DEFAULTS) {
/**
* Get the block nodes in the current selection.
*
* @return {List} nodes
* @return {List<Block>}
*/
get blocks() {
@@ -382,7 +388,7 @@ class State extends new Record(DEFAULTS) {
/**
* Get the fragment of the current selection.
*
* @return {List} nodes
* @return {Document}
*/
get fragment() {
@@ -394,7 +400,7 @@ class State extends new Record(DEFAULTS) {
/**
* Get the inline nodes in the current selection.
*
* @return {List} nodes
* @return {List<Inline>}
*/
get inlines() {
@@ -406,7 +412,7 @@ class State extends new Record(DEFAULTS) {
/**
* Get the text nodes in the current selection.
*
* @return {List} nodes
* @return {List<Text>}
*/
get texts() {
@@ -419,7 +425,7 @@ class State extends new Record(DEFAULTS) {
* Return a new `Transform` with the current state as a starting point.
*
* @param {Object} properties
* @return {Transform} transform
* @return {Transform}
*/
transform(properties = {}) {

View File

@@ -8,6 +8,8 @@ import { List, Record, Set } from 'immutable'
/**
* Default properties.
*
* @type {Object}
*/
const DEFAULTS = {
@@ -17,6 +19,8 @@ const DEFAULTS = {
/**
* Text.
*
* @type {Text}
*/
class Text extends new Record(DEFAULTS) {
@@ -24,7 +28,7 @@ class Text extends new Record(DEFAULTS) {
/**
* Create a new `Text` with `properties`.
*
* @param {Object} properties
* @param {Object|Text} properties
* @return {Text}
*/
@@ -52,7 +56,7 @@ class Text extends new Record(DEFAULTS) {
/**
* Create a new `Text` from a list of ranges
*
* @param {List<Range> | Array<Range>} ranges
* @param {List<Range>|Array<Range>} ranges
* @return {Text}
*/
@@ -69,7 +73,7 @@ class Text extends new Record(DEFAULTS) {
* Create a list of `Texts` from an array.
*
* @param {Array} elements
* @return {List} map
* @return {List<Text>}
*/
static createList(elements = []) {
@@ -80,7 +84,7 @@ class Text extends new Record(DEFAULTS) {
/**
* Get the node's kind.
*
* @return {String} kind
* @return {String}
*/
get kind() {
@@ -90,7 +94,7 @@ class Text extends new Record(DEFAULTS) {
/**
* Is the node empty?
*
* @return {Boolean} isEmpty
* @return {Boolean}
*/
get isEmpty() {
@@ -100,7 +104,7 @@ class Text extends new Record(DEFAULTS) {
/**
* Get the length of the concatenated text of the node.
*
* @return {Number} length
* @return {Number}
*/
get length() {
@@ -110,7 +114,7 @@ class Text extends new Record(DEFAULTS) {
/**
* Get the concatenated text of the node.
*
* @return {String} text
* @return {String}
*/
get text() {
@@ -144,7 +148,7 @@ class Text extends new Record(DEFAULTS) {
* Derive a set of decorated characters with `decorators`.
*
* @param {Array} decorators
* @return {List}
* @return {List<Character>}
*/
getDecorations(decorators) {
@@ -175,7 +179,7 @@ class Text extends new Record(DEFAULTS) {
* Get the marks on the text at `index`.
*
* @param {Number} index
* @return {Set}
* @return {Set<Mark>}
*/
getMarksAtIndex(index) {
@@ -189,8 +193,8 @@ class Text extends new Record(DEFAULTS) {
/**
* Derive the ranges for a list of `characters`.
*
* @param {Array || Void} decorators (optional)
* @return {List}
* @param {Array|Void} decorators (optional)
* @return {List<Range>}
*/
getRanges(decorators = []) {
@@ -334,7 +338,7 @@ class Text extends new Record(DEFAULTS) {
* Validate the text node against a `schema`.
*
* @param {Schema} schema
* @return {Object || Void}
* @return {Object|Void}
*/
validate(schema) {
@@ -356,6 +360,8 @@ memoize(Text.prototype, [
/**
* Export.
*
* @type {Text}
*/
export default Text

View File

@@ -36,7 +36,7 @@ class Transform {
/**
* Get the kind.
*
* @return {String} kind
* @return {String}
*/
get kind() {
@@ -50,7 +50,7 @@ class Transform {
* @property {Boolean} isNative
* @property {Boolean} merge
* @property {Boolean} save
* @return {State} state
* @return {State}
*/
apply(options = {}) {

View File

@@ -81,11 +81,12 @@ function Plugin(options = {}) {
const nextChar = startOffset === initialChars.size ? null : initialChars.get(startOffset)
const char = Character.create({
text: e.data,
marks: (prevChar && prevChar.marks)
// When cursor is at start of a range of marks, without
// preceding text, the native behavior is to insert inside the
// range of marks.
|| (!prevChar && nextChar && nextChar.marks)
// When cursor is at start of a range of marks, without preceding text,
// the native behavior is to insert inside the range of marks.
marks: (
(prevChar && prevChar.marks) ||
(!prevChar && nextChar && nextChar.marks)
)
})
const chars = initialChars.insert(startOffset, char)
@@ -692,15 +693,11 @@ function Plugin(options = {}) {
return state
.transform()
.moveTo(selection)
// Since the document has not changed, We only normalize the selection
// This is done in transform.apply
// Since the document has not changed, we only need to normalize the
// selection and this is done automatically in `transform.apply()`.
.apply()
}
/**
* Extend core schema with rendering
*/
/**
* A default schema rule to render block nodes.
*
@@ -750,6 +747,12 @@ function Plugin(options = {}) {
}
}
/**
* Extend the core schema with rendering rules.
*
* @type {Object}
*/
const schema = {
rules: [
BLOCK_RENDER_RULE,
@@ -759,6 +762,8 @@ function Plugin(options = {}) {
/**
* Return the core plugin.
*
* @type {Object}
*/
return {
@@ -777,6 +782,8 @@ function Plugin(options = {}) {
/**
* Export.
*
* @type {Object}
*/
export default Plugin

View File

@@ -1,17 +1,10 @@
import Schema from '../models/schema'
import Text from '../models/text'
import { List } from 'immutable'
/*
* This module contains the default schema to normalize documents
*/
function isInlineVoid(node) {
return (node.kind == 'inline' && node.isVoid)
}
/**
* A default schema rule to only allow block nodes in documents.
* Only allow block nodes in documents.
*
* @type {Object}
*/
@@ -31,7 +24,7 @@ const DOCUMENT_CHILDREN_RULE = {
}
/**
* A default schema rule to only allow block, inline and text nodes in blocks.
* Only allow block, inline and text nodes in blocks.
*
* @type {Object}
*/
@@ -51,7 +44,7 @@ const BLOCK_CHILDREN_RULE = {
}
/**
* A default schema rule to have at least one text node in blocks/inlines
* Ensure that block and inline nodes have at least one text child.
*
* @type {Object}
*/
@@ -65,12 +58,13 @@ const MIN_TEXT_RULE = {
return nodes.size === 0 ? true : null
},
normalize: (transform, node) => {
return transform.insertNodeByKey(node.key, 0, Text.create(), { normalize: false })
const text = Text.create()
return transform.insertNodeByKey(node.key, 0, text, { normalize: false })
}
}
/**
* A default schema rule to only allow inline and text nodes in inlines.
* Only allow inline and text nodes in inlines.
*
* @type {Object}
*/
@@ -90,12 +84,12 @@ const INLINE_CHILDREN_RULE = {
}
/**
* A default schema rule to ensure that inline nodes are not empty.
* Ensure that inline nodes are never empty.
*
* This rule is applied to all blocks, because when they contain an
* empty inline, we need to remove the inline from that parent
* block. If `validate` was to be memoized, it should be against the
* parent node, not the inline themselves.
* This rule is applied to all blocks, because when they contain an empty
* inline, we need to remove the inline from that parent block. If `validate`
* was to be memoized, it should be against the parent node, not the inline
* themselves.
*
* @type {Object}
*/
@@ -123,7 +117,7 @@ const INLINE_NO_EMPTY = {
}
/**
* A default schema rule to ensure that void nodes contain a single space of content.
* Ensure that void nodes contain a single space of content.
*
* @type {Object}
*/
@@ -145,7 +139,7 @@ const VOID_TEXT_RULE = {
}
/**
* A default schema rule to ensure that inline void nodes are surrounded with text nodes
* Ensure that inline void nodes are surrounded with text nodes.
*
* @type {Object}
*/
@@ -221,16 +215,15 @@ const NO_ADJACENT_TEXT_RULE = {
},
normalize: (transform, node, pairs) => {
return pairs
// We reverse the list since we want to handle 3 consecutive text nodes
.reverse()
.reduce((t, pair) => {
const [ first, second ] = pair
return t.joinNodeByKey(second.key, first.key, { normalize: false })
}, transform)
// We reverse the list since we want to handle 3 consecutive text nodes.
.reverse()
.reduce((t, pair) => {
const [ first, second ] = pair
return t.joinNodeByKey(second.key, first.key, { normalize: false })
}, transform)
}
}
/**
* Prevent extra empty text nodes.
*
@@ -248,32 +241,31 @@ const NO_EMPTY_TEXT_RULE = {
return
}
const invalids = nodes
.filter((desc, i) => {
const invalids = nodes.filter((desc, i) => {
if (desc.kind != 'text' || desc.length > 0) {
return
}
// Empty text nodes are only allowed near inline void node
// Empty text nodes are only allowed near inline void node.
const next = nodes.get(i + 1)
const prev = i > 0 ? nodes.get(i - 1) : null
// If last one and previous is an inline void, we need to preserve it
// If last one and previous is an inline void, we need to preserve it.
if (!next && isInlineVoid(prev)) {
return
}
// If first one and next one is an inline, we preserve it
// If first one and next one is an inline, we preserve it.
if (!prev && isInlineVoid(next)) {
return
}
// If surrounded by inline void, we preserve it
// If surrounded by inline void, we preserve it.
if (next && prev && isInlineVoid(next) && isInlineVoid(prev)) {
return
}
// Otherwise we remove it
// Otherwise we remove it.
return true
})
@@ -286,10 +278,21 @@ const NO_EMPTY_TEXT_RULE = {
}
}
/**
* Test if a `node` is an inline void node.
*
* @param {Node} node
* @return {Boolean}
*/
function isInlineVoid(node) {
return (node.kind == 'inline' && node.isVoid)
}
/**
* The default schema.
*
* @type {Object}
* @type {Schema}
*/
const schema = Schema.create({
@@ -306,4 +309,10 @@ const schema = Schema.create({
]
})
/**
* Export.
*
* @type {Schema}
*/
export default schema

View File

@@ -5,7 +5,7 @@ import Raw from './raw'
* Encode a JSON `object` as base-64 `string`.
*
* @param {Object} object
* @return {String} encoded
* @return {String}
*/
function encode(object) {
@@ -18,7 +18,7 @@ function encode(object) {
* Decode a base-64 `string` to a JSON `object`.
*
* @param {String} string
* @return {Object} object
* @return {Object}
*/
function decode(string) {
@@ -31,7 +31,7 @@ function decode(string) {
* Deserialize a State `string`.
*
* @param {String} string
* @return {State} state
* @return {State}
*/
function deserialize(string) {
@@ -44,7 +44,7 @@ function deserialize(string) {
* Deserialize a Node `string`.
*
* @param {String} string
* @return {Node} node
* @return {Node}
*/
function deserializeNode(string) {
@@ -57,7 +57,7 @@ function deserializeNode(string) {
* Serialize a `state`.
*
* @param {State} state
* @return {String} encoded
* @return {String}
*/
function serialize(state) {
@@ -70,7 +70,7 @@ function serialize(state) {
* Serialize a `node`.
*
* @param {Node} node
* @return {String} encoded
* @return {String}
*/
function serializeNode(node) {
@@ -81,6 +81,8 @@ function serializeNode(node) {
/**
* Export.
*
* @type {Object}
*/
export default {

View File

@@ -8,6 +8,8 @@ import { Record } from 'immutable'
/**
* String.
*
* @type {String}
*/
const String = new Record({
@@ -67,7 +69,6 @@ class Html {
*
* @param {Object} options
* @property {Array} rules
* @return {Html} serializer
*/
constructor(options = {}) {
@@ -81,7 +82,7 @@ class Html {
* Deserialize pasted HTML.
*
* @param {String} html
* @return {State} state
* @return {State}
*/
deserialize = (html) => {
@@ -120,7 +121,7 @@ class Html {
* Deserialize an array of Cheerio `elements`.
*
* @param {Array} elements
* @return {Array} nodes
* @return {Array}
*/
deserializeElements = (elements = []) => {
@@ -150,7 +151,7 @@ class Html {
* Deserialize a Cheerio `element`.
*
* @param {Object} element
* @return {Mixed} node
* @return {Any}
*/
deserializeElement = (element) => {
@@ -185,7 +186,7 @@ class Html {
* Deserialize a `mark` object.
*
* @param {Object} mark
* @return {Array} nodes
* @return {Array}
*/
deserializeMark = (mark) => {
@@ -226,7 +227,7 @@ class Html {
* @param {State} state
* @param {Object} options
* @property {Boolean} render
* @return {String|Array} html
* @return {String|Array}
*/
serialize = (state, options = {}) => {
@@ -317,6 +318,8 @@ function addKey(element) {
/**
* Export.
*
* @type {Html}
*/
export default Html

View File

@@ -63,6 +63,8 @@ function serialize(state) {
/**
* Export.
*
* @type {Object}
*/
export default {

View File

@@ -94,7 +94,7 @@ const Raw = {
*
* @param {Object} object
* @param {Object} options (optional)
* @return {Mark} mark
* @return {Mark}
*/
deserializeMark(object, options) {
@@ -106,7 +106,7 @@ const Raw = {
*
* @param {Object} object
* @param {Object} options (optional)
* @return {Text}
* @return {Node}
*/
deserializeNode(object, options) {
@@ -126,7 +126,7 @@ const Raw = {
*
* @param {Object} object
* @param {Object} options (optional)
* @return {List}
* @return {List<Character>}
*/
deserializeRange(object, options = {}) {
@@ -280,7 +280,7 @@ const Raw = {
*
* @param {Mark} mark
* @param {Object} options (optional)
* @return {Object} Object
* @return {Object}
*/
serializeMark(mark, options = {}) {
@@ -300,7 +300,7 @@ const Raw = {
*
* @param {Node} node
* @param {Object} options (optional)
* @return {Object} object
* @return {Object}
*/
serializeNode(node, options) {
@@ -603,6 +603,8 @@ const Raw = {
/**
* Export.
*
* @type {Object}
*/
export default Raw

View File

@@ -1,6 +1,6 @@
import Debug from 'debug'
import warning from '../utils/warning'
import warn from '../utils/warn'
/**
* Debug.
@@ -352,10 +352,10 @@ function setNode(state, operation) {
// Deprecate using setNode for updating children, or keys
if (properties.nodes && properties.nodes != node.nodes) {
warning('Updating Node.nodes through setNode is not allowed. Use appropriate insertion and removal functions.')
warn('Updating Node.nodes through setNode is not allowed. Use appropriate insertion and removal functions.')
delete properties.nodes
} else if (properties.key && properties.key != node.key) {
warning('Updating Node.key through setNode is not allowed. You should not have to update keys yourself.')
warn('Updating Node.key through setNode is not allowed. You should not have to update keys yourself.')
delete properties.key
}

View File

@@ -123,7 +123,7 @@ export function deleteForward(transform, n = 1) {
* Insert a `block` at the current selection.
*
* @param {Transform} transform
* @param {String || Object || Block} block
* @param {String|Object|Block} block
* @return {Transform}
*/
@@ -195,7 +195,7 @@ export function insertFragment(transform, fragment) {
* Insert a `inline` at the current selection.
*
* @param {Transform} transform
* @param {String || Object || Block} inline
* @param {String|Object|Block} inline
* @return {Transform}
*/
@@ -235,7 +235,7 @@ export function insertInline(transform, inline) {
*
* @param {Transform} transform
* @param {String} text
* @param {Set} marks (optional)
* @param {Set<Mark>} marks (optional)
* @return {Transform}
*/
@@ -427,7 +427,7 @@ export function toggleMark(transform, mark) {
* Unwrap the current selection from a block parent with `properties`.
*
* @param {Transform} transform
* @param {Object or String} properties
* @param {Object|String} properties
* @return {Transform}
*/
@@ -441,7 +441,7 @@ export function unwrapBlock(transform, properties) {
* Unwrap the current selection from an inline parent with `properties`.
*
* @param {Transform} transform
* @param {Object or String} properties
* @param {Object|String} properties
* @return {Transform}
*/
@@ -456,7 +456,7 @@ export function unwrapInline(transform, properties) {
* `properties`.
*
* @param {Transform} transform
* @param {Object or String} properties
* @param {Object|String} properties
* @return {Transform}
*/
@@ -470,7 +470,7 @@ export function wrapBlock(transform, properties) {
* Wrap the current selection in new inline nodes with `properties`.
*
* @param {Transform} transform
* @param {Object or String} properties
* @param {Object|String} properties
* @return {Transform}
*/

View File

@@ -10,7 +10,7 @@ import Normalize from '../utils/normalize'
* @param {Selection} range
* @param {Mixed} mark
* @param {Object} options
* @param {Boolean} normalize
* @property {Boolean} normalize
* @return {Transform}
*/
@@ -46,7 +46,7 @@ export function addMarkAtRange(transform, range, mark, options = {}) {
* @param {Transform} transform
* @param {Selection} range
* @param {Object} options
* @param {Boolean} normalize
* @property {Boolean} normalize
* @return {Transform}
*/
@@ -124,7 +124,7 @@ export function deleteAtRange(transform, range, options = {}) {
* @param {Selection} range
* @param {Number} n (optional)
* @param {Object} options
* @param {Boolean} normalize
* @property {Boolean} normalize
* @return {Transform}
*/
@@ -189,7 +189,7 @@ export function deleteBackwardAtRange(transform, range, n = 1, options = {}) {
* @param {Selection} range
* @param {Number} n (optional)
* @param {Object} options
* @param {Boolean} normalize
* @property {Boolean} normalize
* @return {Transform}
*/
@@ -251,9 +251,9 @@ export function deleteForwardAtRange(transform, range, n = 1, options = {}) {
*
* @param {Transform} transform
* @param {Selection} range
* @param {Block or String or Object} block
* @param {Block|String|Object} block
* @param {Object} options
* @param {Boolean} normalize
* @property {Boolean} normalize
* @return {Transform}
*/
@@ -311,7 +311,7 @@ export function insertBlockAtRange(transform, range, block, options = {}) {
* @param {Selection} range
* @param {Document} fragment
* @param {Object} options
* @param {Boolean} normalize
* @property {Boolean} normalize
* @return {Transform}
*/
@@ -404,9 +404,9 @@ export function insertFragmentAtRange(transform, range, fragment, options = {})
*
* @param {Transform} transform
* @param {Selection} range
* @param {Inline or String or Object} inline
* @param {Inline|String|Object} inline
* @param {Object} options
* @param {Boolean} normalize
* @property {Boolean} normalize
* @return {Transform}
*/
@@ -446,9 +446,9 @@ export function insertInlineAtRange(transform, range, inline, options = {}) {
* @param {Transform} transform
* @param {Selection} range
* @param {String} text
* @param {Set} marks (optional)
* @param {Set<Mark>} marks (optional)
* @param {Object} options
* @param {Boolean} normalize
* @property {Boolean} normalize
* @return {Transform}
*/
@@ -480,9 +480,9 @@ export function insertTextAtRange(transform, range, text, marks, options = {}) {
*
* @param {Transform} transform
* @param {Selection} range
* @param {Mark or String} mark (optional)
* @param {Mark|String} mark (optional)
* @param {Object} options
* @param {Boolean} normalize
* @property {Boolean} normalize
* @return {Transform}
*/
@@ -517,9 +517,9 @@ export function removeMarkAtRange(transform, range, mark, options = {}) {
*
* @param {Transform} transform
* @param {Selection} range
* @param {Object || String} properties
* @param {Object|String} properties
* @param {Object} options
* @param {Boolean} normalize
* @property {Boolean} normalize
* @return {Transform}
*/
@@ -541,9 +541,9 @@ export function setBlockAtRange(transform, range, properties, options = {}) {
*
* @param {Transform} transform
* @param {Selection} range
* @param {Object || String} properties
* @param {Object|String} properties
* @param {Object} options
* @param {Boolean} normalize
* @property {Boolean} normalize
* @return {Transform}
*/
@@ -567,7 +567,7 @@ export function setInlineAtRange(transform, range, properties, options = {}) {
* @param {Selection} range
* @param {Number} height (optional)
* @param {Object} options
* @param {Boolean} normalize
* @property {Boolean} normalize
* @return {Transform}
*/
@@ -605,7 +605,7 @@ export function splitBlockAtRange(transform, range, height = 1, options = {}) {
* @param {Selection} range
* @param {Number} height (optional)
* @param {Object} options
* @param {Boolean} normalize
* @property {Boolean} normalize
* @return {Transform}
*/
@@ -642,7 +642,7 @@ export function splitInlineAtRange(transform, range, height = Infinity, options
* @param {Selection} range
* @param {Mixed} mark
* @param {Object} options
* @param {Boolean} normalize
* @property {Boolean} normalize
* @return {Transform}
*/
@@ -673,9 +673,9 @@ export function toggleMarkAtRange(transform, range, mark, options = {}) {
*
* @param {Transform} transform
* @param {Selection} range
* @param {String or Object} properties
* @param {String|Object} properties
* @param {Object} options
* @param {Boolean} normalize
* @property {Boolean} normalize
* @return {Transform}
*/
@@ -767,9 +767,9 @@ export function unwrapBlockAtRange(transform, range, properties, options = {}) {
*
* @param {Transform} transform
* @param {Selection} range
* @param {String or Object} properties
* @param {String|Object} properties
* @param {Object} options
* @param {Boolean} normalize
* @property {Boolean} normalize
* @return {Transform}
*/
@@ -816,9 +816,9 @@ export function unwrapInlineAtRange(transform, range, properties, options = {})
*
* @param {Transform} transform
* @param {Selection} range
* @param {Block || Object || String} block
* @param {Block|Object|String} block
* @param {Object} options
* @param {Boolean} normalize
* @property {Boolean} normalize
* @return {Transform}
*/
@@ -888,9 +888,9 @@ export function wrapBlockAtRange(transform, range, block, options = {}) {
*
* @param {Transform} transform
* @param {Selection} range
* @param {Inline || Object || String} inline
* @param {Inline|Object|String} inline
* @param {Object} options
* @param {Boolean} normalize
* @property {Boolean} normalize
* @return {Transform}
*/
@@ -1015,7 +1015,7 @@ export function wrapInlineAtRange(transform, range, inline, options = {}) {
* @param {String} prefix
* @param {String} suffix (optional)
* @param {Object} options
* @param {Boolean} normalize
* @property {Boolean} normalize
* @return {Transform}
*/

View File

@@ -62,7 +62,7 @@ export function insertNodeByKey(transform, key, index, node, options = {}) {
* @param {String} key
* @param {Number} offset
* @param {String} text
* @param {Set} marks (optional)
* @param {Set<Mark>} marks (optional)
* @param {Object} options
* @param {Boolean} normalize
* @return {Transform}
@@ -267,7 +267,7 @@ export function setMarkByKey(transform, key, offset, length, mark, properties, o
*
* @param {Transform} transform
* @param {String} key
* @param {Object || String} properties
* @param {Object|String} properties
* @param {Object} options
* @param {Boolean} normalize
* @return {Transform}
@@ -330,7 +330,7 @@ export function splitNodeByKey(transform, key, offset, options = {}) {
*
* @param {Transform} transform
* @param {String} key
* @param {Object or String} properties
* @param {Object|String} properties
* @param {Object} options
* @param {Boolean} normalize
* @return {Transform}
@@ -349,7 +349,7 @@ export function unwrapInlineByKey(transform, key, properties, options) {
*
* @param {Transform} transform
* @param {String} key
* @param {Object or String} properties
* @param {Object|String} properties
* @param {Object} options
* @param {Boolean} normalize
* @return {Transform}
@@ -368,7 +368,7 @@ export function unwrapBlockByKey(transform, key, properties, options) {
*
* @param {Transform} transform
* @param {String} key The node to wrap
* @param {Block || Object || String} block The wrapping block (its children are discarded)
* @param {Block|Object|String} block The wrapping block (its children are discarded)
* @param {Object} options
* @param {Boolean} normalize
* @return {Transform}

View File

@@ -1,33 +1,40 @@
import warning from '../utils/warning'
import { default as defaultSchema } from '../plugins/schema'
import Normalize from '../utils/normalize'
// Maximum recursive calls for normalization
const MAX_CALLS = 50
import Normalize from '../utils/normalize'
import warn from '../utils/warn'
import { default as coreSchema } from '../plugins/schema'
/**
* Normalize a node (itself and its children) using a schema.
* Maximum recursive calls for normalization. Without a maximum, it is easy for
* a transform function of a schema rule to not fully validate the document,
* leading to an infinitely invalid loop.
*
* @param {Transform} transform
* @param {Schema} schema
* @param {Node} node
* @type {Number}
*/
const MAX_ITERATIONS = 50
/**
* Normalize a `node` and its children with a `schema`.
*
* @param {Transform} transform
* @param {Schema} schema
* @param {Node} node
* @return {Transform}
*/
export function normalizeNodeWith(transform, schema, node) {
// For performance considerations, we will check if the transform was changed
// For performance considerations, we will check if the transform was changed.
const opCount = transform.operations.length
// Iterate over its children
// Iterate over its children.
normalizeChildrenWith(transform, schema, node)
const hasChanged = transform.operations.length != opCount
if (hasChanged) {
// Refresh the node reference
node = refreshNode(transform, node)
// Re-find the node reference if necessary
if (transform.operations.length != opCount) {
node = refindNode(transform, node)
}
// Now normalize the node itself if it still exist
// Now normalize the node itself if it still exists.
if (node) {
normalizeNodeOnly(transform, schema, node)
}
@@ -36,24 +43,25 @@ export function normalizeNodeWith(transform, schema, node) {
}
/**
* Normalize a node its parents using a schema.
* Normalize a `node` its parents with a `schema`.
*
* @param {Transform} transform
* @param {Schema} schema
* @param {Node} node
* @param {Transform} transform
* @param {Schema} schema
* @param {Node} node
* @return {Transform}
*/
export function normalizeParentsWith(transform, schema, node) {
normalizeNodeOnly(transform, schema, node)
// Normalize went back up to the document
// Normalize went back up to the very top of the document.
if (node.kind == 'document') {
return transform
}
// We search for the new parent
node = refreshNode(transform, node)
// Re-find the node first.
node = refindNode(transform, node)
if (!node) {
return transform
}
@@ -66,19 +74,19 @@ export function normalizeParentsWith(transform, schema, node) {
}
/**
* Normalize state using a schema.
* Normalize state with a `schema`.
*
* @param {Transform} transform
* @param {Schema} schema
* @return {Transform} transform
* @param {Transform} transform
* @param {Schema} schema
* @return {Transform}
*/
export function normalizeWith(transform, schema) {
const { state } = transform
const { document } = state
// If the schema has no validation rules, there's nothing to normalize.
if (!schema.hasValidators) {
// Schema has no normalization rules
return transform
}
@@ -86,55 +94,53 @@ export function normalizeWith(transform, schema) {
}
/**
* Normalize the state using the core schema.
* Normalize the document and selection with the core schema.
*
* @param {Transform} transform
* @return {Transform} transform
* @param {Transform} transform
* @return {Transform}
*/
export function normalize(transform) {
transform
return transform
.normalizeDocument()
.normalizeSelection()
return transform
}
/**
* Normalize only the document
* Normalize the document with the core schema.
*
* @param {Transform} transform
* @return {Transform} transform
* @param {Transform} transform
* @return {Transform}
*/
export function normalizeDocument(transform) {
return transform.normalizeWith(defaultSchema)
return transform.normalizeWith(coreSchema)
}
/**
* Normalize a node and its children using core schema
* Normalize a `node` and its children with the core schema.
*
* @param {Transform} transform
* @param {Node or String} key
* @return {Transform} transform
* @param {Transform} transform
* @param {Node|String} key
* @return {Transform}
*/
export function normalizeNodeByKey(transform, key) {
key = Normalize.key(key)
const { state } = transform
const { document } = state
const node = document.key == key ? document : document.assertDescendant(key)
transform.normalizeNodeWith(defaultSchema, node)
transform.normalizeNodeWith(coreSchema, node)
return transform
}
/**
* Normalize a node and its parent using core schema
*
* @param {Transform} transform
* @param {Node or String} key
* @return {Transform} transform
* @param {Transform} transform
* @param {Node|String} key
* @return {Transform}
*/
export function normalizeParentsByKey(transform, key) {
@@ -143,15 +149,15 @@ export function normalizeParentsByKey(transform, key) {
const { document } = state
const node = document.key == key ? document : document.assertDescendant(key)
transform.normalizeParentsWith(defaultSchema, node)
transform.normalizeParentsWith(coreSchema, node)
return transform
}
/**
* Normalize only the selection.
*
* @param {Transform} transform
* @return {Transform} transform
* @param {Transform} transform
* @return {Transform}
*/
export function normalizeSelection(transform) {
@@ -159,13 +165,14 @@ export function normalizeSelection(transform) {
let { document, selection } = state
selection = selection.normalize(document)
// If the selection is nulled (not normal)
// If the selection is unset, or the anchor or focus key in the selection are
// pointing to nodes that no longer exist, warn and reset the selection.
if (
selection.isUnset ||
!document.hasDescendant(selection.anchorKey) ||
!document.hasDescendant(selection.focusKey)
) {
warning('Selection was invalid and reset to start of the document')
warn('Selection was invalid and reset to start of the document')
const firstText = document.getFirstText()
selection = selection.merge({
anchorKey: firstText.key,
@@ -181,15 +188,15 @@ export function normalizeSelection(transform) {
return transform
}
/**
* Refresh a reference to a node that have been modified in a transform.
* @param {Transform} transform
* @param {Node} node
* @return {Node} newNode
* Re-find a reference to a node that may have been modified in a transform.
*
* @param {Transform} transform
* @param {Node} node
* @return {Node}
*/
function refreshNode(transform, node) {
function refindNode(transform, node) {
const { state } = transform
const { document } = state
@@ -201,66 +208,60 @@ function refreshNode(transform, node) {
}
/**
* Normalize all children of a node
* @param {Transform} transform
* @param {Schema} schema
* @param {Node} node
* @return {Transform} transform
* Normalize the children of a `node` with a `schema`.
*
* @param {Transform} transform
* @param {Schema} schema
* @param {Node} node
* @return {Transform}
*/
function normalizeChildrenWith(transform, schema, node) {
if (node.kind == 'text') {
return transform
}
if (node.kind == 'text') return transform
return node.nodes.reduce(
(t, child) => t.normalizeNodeWith(schema, child),
transform
)
node.nodes.forEach((child) => {
transform.normalizeNodeWith(schema, child)
})
return transform
}
/**
* Normalize a node, but not its children
* Normalize a `node` with a `schema`, but not its children.
*
* @param {Transform} transform
* @param {Schema} schema
* @param {Node} node
* @return {Transform} transform
* @param {Transform} transform
* @param {Schema} schema
* @param {Node} node
* @return {Transform}
*/
function normalizeNodeOnly(transform, schema, node) {
let recursiveCount = 0
let iterations = 0
// Auxiliary function, called recursively, with a maximum calls safety net.
function _recur(_transform, _node) {
// _node.validate should be memoized
const failure = _node.validate(schema)
// Node is valid?
if (!failure) {
return _transform
}
function normalizeRecursively(t, n) {
const failure = n.validate(schema)
if (!failure) return t
const { value, rule } = failure
// Normalize and get the new state
rule.normalize(_transform, _node, value)
// Rule the `normalize` function for the rule with the invalid value.
rule.normalize(t, n, value)
// Search for the updated node in the new state
const newNode = refreshNode(_transform, _node)
// Re-find the node reference, in case it was updated. If the node no longer
// exists, we're done for this branch.
const newNode = refindNode(t, n)
if (!newNode) return t
// Node no longer exist, go back to normalize parents
if (!newNode) {
return _transform
}
// Increment the iterations counter, so that we don't exceed the max.
iterations++
recursiveCount++
if (recursiveCount > MAX_CALLS) {
if (iterations > MAX_ITERATIONS) {
throw new Error('Unexpected number of successive normalizations. Aborting.')
}
return _recur(_transform, newNode)
// Otherwise, recurse to validate again.
return normalizeRecursively(t, newNode)
}
return _recur(transform, node)
return normalizeRecursively(transform, node)
}

View File

@@ -28,8 +28,8 @@ export function collapseToAnchor(transform) {
}
/**
* Move the anchor point to the
* focus point.
* Move the start point to the end point.
*
* @param {Transform} transform
* @return {Transform}
*/
@@ -42,8 +42,8 @@ export function collapseToEnd(transform) {
}
/**
* Move the anchor point to the
* focus point.
* Move the anchor point to the focus point.
*
* @param {Transform} transform
* @return {Transform}
*/
@@ -56,7 +56,7 @@ export function collapseToFocus(transform) {
}
/**
* Move the focus point to the anchor point.
* Move the end point to the start point.
*
* @param {Transform} transform
* @return {Transform}
@@ -378,7 +378,7 @@ export function moveTo(transform, properties) {
export function moveToOffsets(transform, anchor, fokus) {
const { state } = transform
const { document, selection } = state
const { selection } = state
const sel = selection.moveToOffsets(anchor, fokus)
return transform.setSelectionOperation(sel)
}

View File

@@ -68,7 +68,7 @@ export function insertNodeOperation(transform, path, index, node) {
* @param {Array} path
* @param {Number} offset
* @param {String} text
* @param {Set} marks (optional)
* @param {Set<Mark>} marks (optional)
* @return {Transform}
*/
@@ -148,7 +148,6 @@ export function joinNodeOperation(transform, path, withPath) {
*/
export function moveNodeOperation(transform, path, newPath, newIndex) {
const { state } = transform
const parentPath = path.slice(0, -1)
const parentIndex = path[path.length - 1]
const inversePath = newPath.slice().concat([newIndex])
@@ -322,7 +321,7 @@ export function setMarkOperation(transform, path, offset, length, mark, newMark)
*
* @param {Transform} transform
* @param {Array} path
* @param {Object || String} properties
* @param {Object} properties
* @return {Transform}
*/
@@ -386,9 +385,11 @@ export function setSelectionOperation(transform, properties) {
'focusOffset',
].some(p => props.hasOwnProperty(p))
if (selection.marks
&& properties.marks == selection.marks
&& moved) {
if (
selection.marks &&
properties.marks == selection.marks &&
moved
) {
props.marks = null
}

View File

@@ -3,7 +3,7 @@
* Find the DOM node for a `node`.
*
* @param {Node} node
* @return {Element} el
* @return {Element}
*/
function findDOMNode(node) {
@@ -20,6 +20,8 @@ returned from \`renderNode\`.`)
/**
* Export.
*
* @type {Function}
*/
export default findDOMNode

View File

@@ -32,6 +32,8 @@ function setKeyGenerator(func) {
/**
* Export.
*
* @type {Object}
*/
export {

View File

@@ -3,7 +3,7 @@
* Get leaf text for a node
*
* @param {Node} node
* @return {Text} text
* @return {Text}
*/
function getLeafText(node) {

View File

@@ -5,7 +5,7 @@
* @param {Number} index
* @param {Text} text
* @param {Selection} range
* @return {Set} characters
* @return {Boolean}
*/
function isInRange(index, text, range) {

View File

@@ -1,15 +1,22 @@
import Map from 'es6-map'
import IS_DEV from '../constants/is-dev'
/**
* This module serves to memoize methods on immutable instances.
* GLOBAL: True if memoization should is enabled. Only effective in DEV mode.
*
* @type {Boolean}
*/
// Global: True if memoization should is enabled. Only effective in DEV mode
let ENABLED = true
// Global: Changing this cache key will clear all previous cached
// results. Only effective in DEV mode
/**
* GLOBAL: Changing this cache key will clear all previous cached results.
* Only effective in DEV mode.
*
* @type {Number}
*/
let CACHE_KEY = 0
/**
@@ -33,6 +40,8 @@ const UNDEFINED = {}
/**
* Default value for unset keys in native Maps
*
* @type {Undefined}
*/
const UNSET = undefined
@@ -83,9 +92,9 @@ function memoize(object, properties) {
/**
* Set a value at a key path in a tree of Map, creating Maps on the go.
*
* @param{Map} map
* @param{Array} keys
* @param{Any} value
* @param {Map} map
* @param {Array} keys
* @param {Any} value
* @return {Map}
*/
@@ -97,17 +106,16 @@ function setIn(map, keys, value) {
for (const key of keys) {
childMap = parentMap.get(key)
// If the path was not created yet...
if (childMap === UNSET) {
// This path was not created yet
childMap = new Map()
parentMap.set(key, childMap)
}
parentMap = childMap
}
// The whole map path was created
// Set the value to the bottom most map
// The whole path has been created, so set the value to the bottom most map.
childMap.set(LEAF, value)
return map
@@ -115,22 +123,24 @@ function setIn(map, keys, value) {
/**
* Get a value at a key path in a tree of Map.
* If not set, returns UNSET.
* If the set value is undefined, returns UNDEFINED
*
* @param{Map} map
* @param{Array} keys
* @return {Any | UNSET | UNDEFINED}
* If not set, returns UNSET.
* If the set value is undefined, returns UNDEFINED.
*
* @param {Map} map
* @param {Array} keys
* @return {Any|UNSET|UNDEFINED}
*/
function getIn(map, keys) {
let childMap
for (const key of keys) {
childMap = map.get(key)
if (childMap === UNSET) {
// Not found
return UNSET
}
map = childMap
}
@@ -139,6 +149,7 @@ function getIn(map, keys) {
/**
* In DEV mode, clears the previously memoized values, globally.
*
* @return {Void}
*/
@@ -151,6 +162,7 @@ function __clear() {
/**
* In DEV mode, enable or disable the use of memoize values, globally.
*
* @param {Boolean} enabled
* @return {Void}
*/
@@ -161,6 +173,8 @@ function __enable(enabled) {
/**
* Export.
*
* @type {Object}
*/
export {

View File

@@ -2,13 +2,15 @@
/**
* Noop.
*
* @return {Undefined}
* @return {Void}
*/
function noop() {}
/**
* Export.
*
* @type {Function}
*/
export default noop

View File

@@ -12,7 +12,7 @@ import typeOf from 'type-of'
/**
* Normalize a block argument `value`.
*
* @param {Block || String || Object} value
* @param {Block|String|Object} value
* @return {Block}
*/
@@ -32,7 +32,7 @@ function block(value) {
/**
* Normalize an inline argument `value`.
*
* @param {Inline || String || Object} value
* @param {Inline|String|Object} value
* @return {Inline}
*/
@@ -52,7 +52,7 @@ function inline(value) {
/**
* Normalize a key argument `value`.
*
* @param {String || Node} value
* @param {String|Node} value
* @return {String}
*/
@@ -71,7 +71,7 @@ function key(value) {
/**
* Normalize a mark argument `value`.
*
* @param {Mark || String || Object} value
* @param {Mark|String|Object} value
* @return {Mark}
*/
@@ -91,7 +91,7 @@ function mark(value) {
/**
* Normalize a mark properties argument `value`.
*
* @param {String || Object || Mark} value
* @param {String|Object|Mark} value
* @return {Object}
*/
@@ -123,7 +123,7 @@ function markProperties(value = {}) {
/**
* Normalize a node properties argument `value`.
*
* @param {String || Object || Node} value
* @param {String|Object|Node} value
* @return {Object}
*/
@@ -156,7 +156,7 @@ function nodeProperties(value = {}) {
/**
* Normalize a selection argument `value`.
*
* @param {Selection || Object} value
* @param {Selection|Object} value
* @return {Selection}
*/
@@ -175,7 +175,7 @@ function selection(value) {
/**
* Normalize a selection properties argument `value`.
*
* @param {Object || Selection} value
* @param {Object|Selection} value
* @return {Object}
*/

View File

@@ -1,22 +1,33 @@
/**
* Offset key parser regex.
*
* @type {RegExp}
*/
const PARSER = /^(\w+)(?:-(\d+))?$/
/**
* Offset key attribute name.
*
* @type {String}
*/
const ATTRIBUTE = 'data-offset-key'
/**
* Offset key attribute selector.
*
* @type {String}
*/
const SELECTOR = `[${ATTRIBUTE}]`
/**
* Find the start and end bounds from an `offsetKey` and `ranges`.
*
* @param {Number} index
* @param {List} ranges
* @param {List<Range>} ranges
* @return {Object}
*/
@@ -99,7 +110,7 @@ function findKey(element, offset) {
* Find the selection point from an `offsetKey` and `ranges`.
*
* @param {Object} offsetKey
* @param {List} ranges
* @param {List<Range>} ranges
* @return {Object}
*/
@@ -131,7 +142,7 @@ function findPoint(offsetKey, ranges) {
function parse(string) {
const matches = PARSER.exec(string)
if (!matches) throw new Error(`Invalid offset key string "${string}".`)
const [ original, key, index ] = matches
const [ original, key, index ] = matches // eslint-disable-line no-unused-vars
return {
key,
index: parseInt(index, 10)
@@ -153,6 +164,8 @@ function stringify(object) {
/**
* Export.
*
* @type {Object}
*/
export default {

View File

@@ -50,7 +50,7 @@ function isSurrogate(code) {
* Is a character a word character? Needs the `remaining` characters too.
*
* @param {String} char
* @param {String || Void} remaining
* @param {String|Void} remaining
* @return {Boolean}
*/
@@ -121,27 +121,6 @@ function getCharOffsetForward(text, offset) {
return getCharOffset(text)
}
/**
* Get the length of a `string`.
*
* @param {String} string
* @return {Number}
*/
function getLength(string) {
let length = 0
for (
let i = 0, char = string.charAt(i);
i < string.length;
i += getCharLength(char)
) {
length++
}
return length
}
/**
* Get the offset to the end of the first word in `text`.
*
@@ -203,6 +182,8 @@ function getWordOffsetForward(text, offset) {
/**
* Export.
*
* @type {Object}
*/
export default {

View File

@@ -65,7 +65,7 @@ class Transfer {
/**
* Get the Files content of the data transfer.
*
* @return {Array || Void}
* @return {Array|Void}
*/
getFiles() {
@@ -107,7 +107,7 @@ class Transfer {
// attribute, it's actually a Base64-serialized fragment from a cut/copy.
if (!encoded && html && ~html.indexOf('<span data-slate-fragment="')) {
const matches = FRAGMENT_MATCHER.exec(html)
const [ full, attribute ] = matches
const [ full, attribute ] = matches // eslint-disable-line no-unused-vars
encoded = attribute
}
@@ -122,7 +122,7 @@ class Transfer {
/**
* Get the HTML content of the data transfer.
*
* @return {String || Void}
* @return {String|Void}
*/
getHtml() {
@@ -140,7 +140,7 @@ class Transfer {
/**
* Get the Slate node content of the data transfer.
*
* @return {Node || Void}
* @return {Node|Void}
*/
getNode() {
@@ -160,7 +160,7 @@ class Transfer {
/**
* Get the text content of the data transfer.
*
* @return {String || Void}
* @return {String|Void}
*/
getText() {
@@ -244,6 +244,8 @@ class Transfer {
/**
* Export.
*
* @type {Transfer}
*/
export default Transfer

View File

@@ -1,11 +1,13 @@
import IS_DEV from '../constants/is-dev'
/**
* Log a development warning.
*
* @param {String} message
*/
export default function warning(message, ...more) {
function warning(message, ...more) {
if (!IS_DEV) {
return
}
@@ -15,11 +17,17 @@ export default function warning(message, ...more) {
}
try {
// --- Welcome to debugging Slate ---
// --- Welcome to debugging Slate! ---
// This error was thrown as a convenience so that you can use this stack
// to find the callsite that caused this warning to fire.
throw new Error(message)
} catch (x) {
// This error is only for debugging
// This error is only for debugging.
}
}
/**
* Export.
*/
export default warning