mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-28 09:29:49 +02:00
* refactor to eliminate ./utils/normalize, fixes #372 * fix mark default value
This commit is contained in:
@@ -14,6 +14,7 @@
|
||||
"immutable": "^3.8.1",
|
||||
"is-empty": "^1.0.0",
|
||||
"is-in-browser": "^1.1.3",
|
||||
"is-plain-object": "^2.0.4",
|
||||
"is-window": "^1.0.2",
|
||||
"keycode": "^2.1.2",
|
||||
"lodash": "^4.17.4",
|
||||
|
@@ -1,5 +1,7 @@
|
||||
|
||||
import Normalize from '../utils/normalize'
|
||||
import Block from '../models/block'
|
||||
import Inline from '../models/inline'
|
||||
import Mark from '../models/mark'
|
||||
|
||||
/**
|
||||
* Changes.
|
||||
@@ -49,7 +51,7 @@ PROXY_TRANSFORMS.forEach((method) => {
|
||||
*/
|
||||
|
||||
Changes.addMark = (change, mark) => {
|
||||
mark = Normalize.mark(mark)
|
||||
mark = Mark.create(mark)
|
||||
const { state } = change
|
||||
const { document, selection } = state
|
||||
|
||||
@@ -95,7 +97,7 @@ Changes.delete = (change) => {
|
||||
*/
|
||||
|
||||
Changes.insertBlock = (change, block) => {
|
||||
block = Normalize.block(block)
|
||||
block = Block.create(block)
|
||||
const { state } = change
|
||||
const { selection } = state
|
||||
change.insertBlockAtRange(selection, block)
|
||||
@@ -155,7 +157,7 @@ Changes.insertFragment = (change, fragment) => {
|
||||
*/
|
||||
|
||||
Changes.insertInline = (change, inline) => {
|
||||
inline = Normalize.inline(inline)
|
||||
inline = Inline.create(inline)
|
||||
const { state } = change
|
||||
const { selection } = state
|
||||
change.insertInlineAtRange(selection, inline)
|
||||
@@ -209,7 +211,7 @@ Changes.splitBlock = (change, depth = 1) => {
|
||||
*/
|
||||
|
||||
Changes.removeMark = (change, mark) => {
|
||||
mark = Normalize.mark(mark)
|
||||
mark = Mark.create(mark)
|
||||
const { state } = change
|
||||
const { document, selection } = state
|
||||
|
||||
@@ -239,7 +241,7 @@ Changes.removeMark = (change, mark) => {
|
||||
*/
|
||||
|
||||
Changes.toggleMark = (change, mark) => {
|
||||
mark = Normalize.mark(mark)
|
||||
mark = Mark.create(mark)
|
||||
const { state } = change
|
||||
const exists = state.activeMarks.has(mark)
|
||||
|
||||
|
@@ -1,5 +1,8 @@
|
||||
|
||||
import Normalize from '../utils/normalize'
|
||||
import Block from '../models/block'
|
||||
import Inline from '../models/inline'
|
||||
import Mark from '../models/mark'
|
||||
import Node from '../models/node'
|
||||
import String from '../utils/string'
|
||||
import SCHEMA from '../schemas/core'
|
||||
import { List } from 'immutable'
|
||||
@@ -597,7 +600,7 @@ Changes.deleteForwardAtRange = (change, range, n = 1, options = {}) => {
|
||||
*/
|
||||
|
||||
Changes.insertBlockAtRange = (change, range, block, options = {}) => {
|
||||
block = Normalize.block(block)
|
||||
block = Block.create(block)
|
||||
const { normalize = true } = options
|
||||
|
||||
if (range.isExpanded) {
|
||||
@@ -766,7 +769,7 @@ Changes.insertFragmentAtRange = (change, range, fragment, options = {}) => {
|
||||
|
||||
Changes.insertInlineAtRange = (change, range, inline, options = {}) => {
|
||||
const { normalize = true } = options
|
||||
inline = Normalize.inline(inline)
|
||||
inline = Inline.create(inline)
|
||||
|
||||
if (range.isExpanded) {
|
||||
change.deleteAtRange(range, OPTS)
|
||||
@@ -978,7 +981,7 @@ Changes.splitInlineAtRange = (change, range, height = Infinity, options = {}) =>
|
||||
Changes.toggleMarkAtRange = (change, range, mark, options = {}) => {
|
||||
if (range.isCollapsed) return
|
||||
|
||||
mark = Normalize.mark(mark)
|
||||
mark = Mark.create(mark)
|
||||
|
||||
const { normalize = true } = options
|
||||
const { state } = change
|
||||
@@ -1004,7 +1007,7 @@ Changes.toggleMarkAtRange = (change, range, mark, options = {}) => {
|
||||
*/
|
||||
|
||||
Changes.unwrapBlockAtRange = (change, range, properties, options = {}) => {
|
||||
properties = Normalize.nodeProperties(properties)
|
||||
properties = Node.createProperties(properties)
|
||||
|
||||
const { normalize = true } = options
|
||||
let { state } = change
|
||||
@@ -1097,7 +1100,7 @@ Changes.unwrapBlockAtRange = (change, range, properties, options = {}) => {
|
||||
*/
|
||||
|
||||
Changes.unwrapInlineAtRange = (change, range, properties, options = {}) => {
|
||||
properties = Normalize.nodeProperties(properties)
|
||||
properties = Node.createProperties(properties)
|
||||
|
||||
const { normalize = true } = options
|
||||
const { state } = change
|
||||
@@ -1143,7 +1146,7 @@ Changes.unwrapInlineAtRange = (change, range, properties, options = {}) => {
|
||||
*/
|
||||
|
||||
Changes.wrapBlockAtRange = (change, range, block, options = {}) => {
|
||||
block = Normalize.block(block)
|
||||
block = Block.create(block)
|
||||
block = block.set('nodes', block.nodes.clear())
|
||||
|
||||
const { normalize = true } = options
|
||||
@@ -1229,7 +1232,7 @@ Changes.wrapInlineAtRange = (change, range, inline, options = {}) => {
|
||||
return change.wrapInlineByKey(inlineParent.key, inline, options)
|
||||
}
|
||||
|
||||
inline = Normalize.inline(inline)
|
||||
inline = Inline.create(inline)
|
||||
inline = inline.set('nodes', inline.nodes.clear())
|
||||
|
||||
const blocks = document.getBlocksAtRange(range)
|
||||
|
@@ -1,5 +1,8 @@
|
||||
|
||||
import Normalize from '../utils/normalize'
|
||||
import Block from '../models/block'
|
||||
import Inline from '../models/inline'
|
||||
import Mark from '../models/mark'
|
||||
import Node from '../models/node'
|
||||
import SCHEMA from '../schemas/core'
|
||||
|
||||
/**
|
||||
@@ -23,7 +26,7 @@ const Changes = {}
|
||||
*/
|
||||
|
||||
Changes.addMarkByKey = (change, key, offset, length, mark, options = {}) => {
|
||||
mark = Normalize.mark(mark)
|
||||
mark = Mark.create(mark)
|
||||
const { normalize = true } = options
|
||||
const { state } = change
|
||||
const { document } = state
|
||||
@@ -232,7 +235,7 @@ Changes.moveNodeByKey = (change, key, newKey, newIndex, options = {}) => {
|
||||
*/
|
||||
|
||||
Changes.removeMarkByKey = (change, key, offset, length, mark, options = {}) => {
|
||||
mark = Normalize.mark(mark)
|
||||
mark = Mark.create(mark)
|
||||
const { normalize = true } = options
|
||||
const { state } = change
|
||||
const { document } = state
|
||||
@@ -376,8 +379,8 @@ Changes.removeTextByKey = (change, key, offset, length, options = {}) => {
|
||||
*/
|
||||
|
||||
Changes.setMarkByKey = (change, key, offset, length, mark, properties, options = {}) => {
|
||||
mark = Normalize.mark(mark)
|
||||
properties = Normalize.markProperties(properties)
|
||||
mark = Mark.create(mark)
|
||||
properties = Mark.createProperties(properties)
|
||||
const { normalize = true } = options
|
||||
const { state } = change
|
||||
const { document } = state
|
||||
@@ -409,7 +412,7 @@ Changes.setMarkByKey = (change, key, offset, length, mark, properties, options =
|
||||
*/
|
||||
|
||||
Changes.setNodeByKey = (change, key, properties, options = {}) => {
|
||||
properties = Normalize.nodeProperties(properties)
|
||||
properties = Node.createProperties(properties)
|
||||
const { normalize = true } = options
|
||||
const { state } = change
|
||||
const { document } = state
|
||||
@@ -599,7 +602,7 @@ Changes.unwrapNodeByKey = (change, key, options = {}) => {
|
||||
*/
|
||||
|
||||
Changes.wrapInlineByKey = (change, key, inline, options) => {
|
||||
inline = Normalize.inline(inline)
|
||||
inline = Inline.create(inline)
|
||||
inline = inline.set('nodes', inline.nodes.clear())
|
||||
|
||||
const { document } = change.state
|
||||
@@ -622,7 +625,7 @@ Changes.wrapInlineByKey = (change, key, inline, options) => {
|
||||
*/
|
||||
|
||||
Changes.wrapBlockByKey = (change, key, block, options) => {
|
||||
block = Normalize.block(block)
|
||||
block = Block.create(block)
|
||||
block = block.set('nodes', block.nodes.clear())
|
||||
|
||||
const { document } = change.state
|
||||
|
@@ -1,5 +1,4 @@
|
||||
|
||||
import Normalize from '../utils/normalize'
|
||||
import Schema from '../models/schema'
|
||||
import { Set } from 'immutable'
|
||||
|
||||
@@ -49,11 +48,9 @@ Changes.normalizeNodeByKey = (change, key, schema) => {
|
||||
// If the schema has no validation rules, there's nothing to normalize.
|
||||
if (!schema.hasValidators) return
|
||||
|
||||
key = Normalize.key(key)
|
||||
const { state } = change
|
||||
const { document } = state
|
||||
const node = document.assertNode(key)
|
||||
|
||||
normalizeNodeAndChildren(change, node, schema)
|
||||
}
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
|
||||
import Normalize from '../utils/normalize'
|
||||
import Selection from '../models/selection'
|
||||
import isEmpty from 'is-empty'
|
||||
import logger from '../utils/logger'
|
||||
import pick from 'lodash/pick'
|
||||
@@ -20,7 +20,7 @@ const Changes = {}
|
||||
*/
|
||||
|
||||
Changes.select = (change, properties, options = {}) => {
|
||||
properties = Normalize.selectionProperties(properties)
|
||||
properties = Selection.createProperties(properties)
|
||||
|
||||
const { snapshot = false } = options
|
||||
const { state } = change
|
||||
|
@@ -11,11 +11,11 @@ import './document'
|
||||
|
||||
import Data from './data'
|
||||
import Node from './node'
|
||||
import Inline from './inline'
|
||||
import Text from './text'
|
||||
import MODEL_TYPES from '../constants/model-types'
|
||||
import generateKey from '../utils/generate-key'
|
||||
import { Map, List, Record } from 'immutable'
|
||||
import isPlainObject from 'is-plain-object'
|
||||
import { List, Map, Record } from 'immutable'
|
||||
|
||||
/**
|
||||
* Default properties.
|
||||
@@ -26,9 +26,9 @@ import { Map, List, Record } from 'immutable'
|
||||
const DEFAULTS = {
|
||||
data: new Map(),
|
||||
isVoid: false,
|
||||
key: null,
|
||||
key: undefined,
|
||||
nodes: new List(),
|
||||
type: null
|
||||
type: undefined,
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -37,55 +37,64 @@ const DEFAULTS = {
|
||||
* @type {Block}
|
||||
*/
|
||||
|
||||
class Block extends new Record(DEFAULTS) {
|
||||
class Block extends Record(DEFAULTS) {
|
||||
|
||||
/**
|
||||
* Create a new `Block` with `attrs`.
|
||||
*
|
||||
* @param {Object|Block} attrs
|
||||
* @param {Object|String|Block} attrs
|
||||
* @return {Block}
|
||||
*/
|
||||
|
||||
static create(attrs = {}) {
|
||||
if (Block.isBlock(attrs)) return attrs
|
||||
if (Inline.isInline(attrs)) return attrs
|
||||
if (Text.isText(attrs)) return attrs
|
||||
|
||||
if (!attrs.type) {
|
||||
throw new Error('You must pass a block `type`.')
|
||||
if (Block.isBlock(attrs)) {
|
||||
return attrs
|
||||
}
|
||||
|
||||
const { nodes } = attrs
|
||||
const empty = !nodes || nodes.size == 0 || nodes.length == 0
|
||||
const block = new Block({
|
||||
type: attrs.type,
|
||||
key: attrs.key || generateKey(),
|
||||
data: Data.create(attrs.data),
|
||||
isVoid: !!attrs.isVoid,
|
||||
nodes: Node.createList(empty ? [Text.create()] : nodes),
|
||||
})
|
||||
if (typeof attrs == 'string') {
|
||||
attrs = { type: attrs }
|
||||
}
|
||||
|
||||
return block
|
||||
if (isPlainObject(attrs)) {
|
||||
const { data, isVoid, key, type } = attrs
|
||||
let { nodes } = attrs
|
||||
|
||||
if (typeof type != 'string') {
|
||||
throw new Error('`Block.create` requires a block `type` string.')
|
||||
}
|
||||
|
||||
if (nodes == null || nodes.length == 0) {
|
||||
nodes = [Text.create()]
|
||||
}
|
||||
|
||||
const block = new Block({
|
||||
data: Data.create(data),
|
||||
isVoid: !!isVoid,
|
||||
key: key || generateKey(),
|
||||
nodes: Node.createList(nodes),
|
||||
type,
|
||||
})
|
||||
|
||||
return block
|
||||
}
|
||||
|
||||
throw new Error(`\`Block.create\` only accepts objects, strings or blocks, but you passed it: ${attrs}`)
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a list of `Blocks` from `elements`.
|
||||
*
|
||||
* @param {Array<Object|Block>|List<Block>} elements
|
||||
* @param {Array<Block|Object>|List<Block|Object>} elements
|
||||
* @return {List<Block>}
|
||||
*/
|
||||
|
||||
static createList(elements = []) {
|
||||
if (List.isList(elements)) {
|
||||
return elements
|
||||
}
|
||||
|
||||
if (Array.isArray(elements)) {
|
||||
if (List.isList(elements) || Array.isArray(elements)) {
|
||||
const list = new List(elements.map(Block.create))
|
||||
return list
|
||||
}
|
||||
|
||||
throw new Error(`Block.createList() must be passed an \`Array\` or a \`List\`. You passed: ${elements}`)
|
||||
throw new Error(`\`Block.createList\` only accepts arrays or lists, but you passed it: ${elements}`)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -110,7 +119,7 @@ class Block extends new Record(DEFAULTS) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the node empty?
|
||||
* Check if the block is empty.
|
||||
*
|
||||
* @return {Boolean}
|
||||
*/
|
||||
@@ -120,7 +129,7 @@ class Block extends new Record(DEFAULTS) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the concatenated text `string` of all child nodes.
|
||||
* Get the concatenated text of all the block's children.
|
||||
*
|
||||
* @return {String}
|
||||
*/
|
||||
|
@@ -1,6 +1,8 @@
|
||||
|
||||
import Mark from './mark'
|
||||
import MODEL_TYPES from '../constants/model-types'
|
||||
import Mark from './mark'
|
||||
import isPlainObject from 'is-plain-object'
|
||||
import logger from '../utils/logger'
|
||||
import { List, Record, Set } from 'immutable'
|
||||
|
||||
/**
|
||||
@@ -11,7 +13,7 @@ import { List, Record, Set } from 'immutable'
|
||||
|
||||
const DEFAULTS = {
|
||||
marks: new Set(),
|
||||
text: ''
|
||||
text: '',
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -20,58 +22,56 @@ const DEFAULTS = {
|
||||
* @type {Character}
|
||||
*/
|
||||
|
||||
class Character extends new Record(DEFAULTS) {
|
||||
class Character extends Record(DEFAULTS) {
|
||||
|
||||
/**
|
||||
* Create a `Character` with `attrs`.
|
||||
*
|
||||
* @param {Object|Character} attrs
|
||||
* @param {Object|String|Character} attrs
|
||||
* @return {Character}
|
||||
*/
|
||||
|
||||
static create(attrs = {}) {
|
||||
if (Character.isCharacter(attrs)) return attrs
|
||||
if (Character.isCharacter(attrs)) {
|
||||
return attrs
|
||||
}
|
||||
|
||||
const character = new Character({
|
||||
text: attrs.text,
|
||||
marks: Mark.createSet(attrs.marks),
|
||||
})
|
||||
if (typeof attrs == 'string') {
|
||||
attrs = { text: attrs }
|
||||
}
|
||||
|
||||
return character
|
||||
if (isPlainObject(attrs)) {
|
||||
const { marks, text } = attrs
|
||||
|
||||
const character = new Character({
|
||||
text,
|
||||
marks: Mark.createSet(marks),
|
||||
})
|
||||
|
||||
return character
|
||||
}
|
||||
|
||||
throw new Error(`\`Character.create\` only accepts objects, strings or characters, but you passed it: ${attrs}`)
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a list of `Characters` from `elements`.
|
||||
*
|
||||
* @param {Array<Object|Character>|List<Character>} elements
|
||||
* @param {String|Array<Object|Character|String>|List<Object|Character|String>} elements
|
||||
* @return {List<Character>}
|
||||
*/
|
||||
|
||||
static createList(elements = []) {
|
||||
if (List.isList(elements)) {
|
||||
return elements
|
||||
if (typeof elements == 'string') {
|
||||
elements = elements.split('')
|
||||
}
|
||||
|
||||
if (Array.isArray(elements)) {
|
||||
if (List.isList(elements) || Array.isArray(elements)) {
|
||||
const list = new List(elements.map(Character.create))
|
||||
return list
|
||||
}
|
||||
|
||||
throw new Error(`Character.createList() must be passed an \`Array\` or a \`List\`. You passed: ${elements}`)
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a characters list from a `string` and optional `marks`.
|
||||
*
|
||||
* @param {String} string
|
||||
* @param {Set<Mark>} marks (optional)
|
||||
* @return {List<Character>}
|
||||
*/
|
||||
|
||||
static createListFromText(string, marks) {
|
||||
const chars = string.split('').map(text => ({ text, marks }))
|
||||
const list = Character.createList(chars)
|
||||
return list
|
||||
throw new Error(`\`Block.createList\` only accepts strings, arrays or lists, but you passed it: ${elements}`)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -85,6 +85,15 @@ class Character extends new Record(DEFAULTS) {
|
||||
return !!(value && value[MODEL_TYPES.CHARACTER])
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated.
|
||||
*/
|
||||
|
||||
static createListFromText(string) {
|
||||
logger.deprecate('0.22.0', 'The `Character.createListFromText(string)` method is deprecated, use `Character.createList(string)` instead.')
|
||||
return this.createList(string)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the kind.
|
||||
*
|
||||
|
@@ -1,4 +1,5 @@
|
||||
|
||||
import isPlainObject from 'is-plain-object'
|
||||
import { Map } from 'immutable'
|
||||
|
||||
/**
|
||||
@@ -15,14 +16,20 @@ const Data = {
|
||||
/**
|
||||
* Create a new `Data` with `attrs`.
|
||||
*
|
||||
* @param {Object} attrs
|
||||
* @param {Object|Data|Map} attrs
|
||||
* @return {Data} data
|
||||
*/
|
||||
|
||||
create(attrs = {}) {
|
||||
return Map.isMap(attrs)
|
||||
? attrs
|
||||
: new Map(attrs)
|
||||
if (Map.isMap(attrs)) {
|
||||
return attrs
|
||||
}
|
||||
|
||||
if (isPlainObject(attrs)) {
|
||||
return new Map(attrs)
|
||||
}
|
||||
|
||||
throw new Error(`\`Data.create\` only accepts objects or maps, but you passed it: ${attrs}`)
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -14,6 +14,7 @@ import Data from './data'
|
||||
import Node from './node'
|
||||
import MODEL_TYPES from '../constants/model-types'
|
||||
import generateKey from '../utils/generate-key'
|
||||
import isPlainObject from 'is-plain-object'
|
||||
import { List, Map, Record } from 'immutable'
|
||||
|
||||
/**
|
||||
@@ -24,7 +25,7 @@ import { List, Map, Record } from 'immutable'
|
||||
|
||||
const DEFAULTS = {
|
||||
data: new Map(),
|
||||
key: null,
|
||||
key: undefined,
|
||||
nodes: new List(),
|
||||
}
|
||||
|
||||
@@ -34,25 +35,36 @@ const DEFAULTS = {
|
||||
* @type {Document}
|
||||
*/
|
||||
|
||||
class Document extends new Record(DEFAULTS) {
|
||||
class Document extends Record(DEFAULTS) {
|
||||
|
||||
/**
|
||||
* Create a new `Document` with `attrs`.
|
||||
*
|
||||
* @param {Object|Document} attrs
|
||||
* @param {Object|Array|List|Text} attrs
|
||||
* @return {Document}
|
||||
*/
|
||||
|
||||
static create(attrs = {}) {
|
||||
if (Document.isDocument(attrs)) return attrs
|
||||
if (Document.isDocument(attrs)) {
|
||||
return attrs
|
||||
}
|
||||
|
||||
const document = new Document({
|
||||
key: attrs.key || generateKey(),
|
||||
data: Data.create(attrs.data),
|
||||
nodes: Node.createList(attrs.nodes),
|
||||
})
|
||||
if (List.isList(attrs) || Array.isArray(attrs)) {
|
||||
attrs = { nodes: attrs }
|
||||
}
|
||||
|
||||
return document
|
||||
if (isPlainObject(attrs)) {
|
||||
const { data, key, nodes } = attrs
|
||||
const document = new Document({
|
||||
key: key || generateKey(),
|
||||
data: Data.create(data),
|
||||
nodes: Node.createList(nodes),
|
||||
})
|
||||
|
||||
return document
|
||||
}
|
||||
|
||||
throw new Error(`\`Document.create\` only accepts objects, arrays, lists or documents, but you passed it: ${attrs}`)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -77,7 +89,7 @@ class Document extends new Record(DEFAULTS) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the document empty?
|
||||
* Check if the document is empty.
|
||||
*
|
||||
* @return {Boolean}
|
||||
*/
|
||||
@@ -87,7 +99,7 @@ class Document extends new Record(DEFAULTS) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the concatenated text `string` of all child nodes.
|
||||
* Get the concatenated text of all the document's children.
|
||||
*
|
||||
* @return {String}
|
||||
*/
|
||||
|
@@ -2,6 +2,7 @@
|
||||
import MODEL_TYPES from '../constants/model-types'
|
||||
import Debug from 'debug'
|
||||
import isEqual from 'lodash/isEqual'
|
||||
import isPlainObject from 'is-plain-object'
|
||||
import { Record, Stack } from 'immutable'
|
||||
|
||||
/**
|
||||
@@ -29,24 +30,30 @@ const DEFAULTS = {
|
||||
* @type {History}
|
||||
*/
|
||||
|
||||
class History extends new Record(DEFAULTS) {
|
||||
class History extends Record(DEFAULTS) {
|
||||
|
||||
/**
|
||||
* Create a new `History` with `attrs`.
|
||||
*
|
||||
* @param {Object} attrs
|
||||
* @param {Object|History} attrs
|
||||
* @return {History}
|
||||
*/
|
||||
|
||||
static create(attrs = {}) {
|
||||
if (History.isHistory(attrs)) return attrs
|
||||
if (History.isHistory(attrs)) {
|
||||
return attrs
|
||||
}
|
||||
|
||||
const history = new History({
|
||||
undos: attrs.undos || new Stack(),
|
||||
redos: attrs.redos || new Stack(),
|
||||
})
|
||||
if (isPlainObject(attrs)) {
|
||||
const history = new History({
|
||||
undos: attrs.undos || new Stack(),
|
||||
redos: attrs.redos || new Stack(),
|
||||
})
|
||||
|
||||
return history
|
||||
return history
|
||||
}
|
||||
|
||||
throw new Error(`\`History.create\` only accepts objects or histories, but you passed it: ${attrs}`)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -9,12 +9,12 @@ import './document'
|
||||
* Dependencies.
|
||||
*/
|
||||
|
||||
import Block from './block'
|
||||
import Data from './data'
|
||||
import Node from './node'
|
||||
import Text from './text'
|
||||
import MODEL_TYPES from '../constants/model-types'
|
||||
import generateKey from '../utils/generate-key'
|
||||
import isPlainObject from 'is-plain-object'
|
||||
import { List, Map, Record } from 'immutable'
|
||||
|
||||
/**
|
||||
@@ -26,9 +26,9 @@ import { List, Map, Record } from 'immutable'
|
||||
const DEFAULTS = {
|
||||
data: new Map(),
|
||||
isVoid: false,
|
||||
key: null,
|
||||
key: undefined,
|
||||
nodes: new List(),
|
||||
type: null
|
||||
type: undefined,
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -37,47 +37,64 @@ const DEFAULTS = {
|
||||
* @type {Inline}
|
||||
*/
|
||||
|
||||
class Inline extends new Record(DEFAULTS) {
|
||||
class Inline extends Record(DEFAULTS) {
|
||||
|
||||
/**
|
||||
* Create a new `Inline` with `attrs`.
|
||||
*
|
||||
* @param {Object|Inline} attrs
|
||||
* @param {Object|String|Inline} attrs
|
||||
* @return {Inline}
|
||||
*/
|
||||
|
||||
static create(attrs = {}) {
|
||||
if (Block.isBlock(attrs)) return attrs
|
||||
if (Inline.isInline(attrs)) return attrs
|
||||
if (Text.isText(attrs)) return attrs
|
||||
|
||||
if (!attrs.type) {
|
||||
throw new Error('You must pass an inline `type`.')
|
||||
if (Inline.isInline(attrs)) {
|
||||
return attrs
|
||||
}
|
||||
|
||||
const { nodes } = attrs
|
||||
const empty = !nodes || nodes.size == 0 || nodes.length == 0
|
||||
const inline = new Inline({
|
||||
type: attrs.type,
|
||||
key: attrs.key || generateKey(),
|
||||
data: Data.create(attrs.data),
|
||||
isVoid: !!attrs.isVoid,
|
||||
nodes: Node.createList(empty ? [Text.create()] : nodes),
|
||||
})
|
||||
if (typeof attrs == 'string') {
|
||||
attrs = { type: attrs }
|
||||
}
|
||||
|
||||
return inline
|
||||
if (isPlainObject(attrs)) {
|
||||
const { data, isVoid, key, type } = attrs
|
||||
let { nodes } = attrs
|
||||
|
||||
if (typeof type != 'string') {
|
||||
throw new Error('`Inline.create` requires a block `type` string.')
|
||||
}
|
||||
|
||||
if (nodes == null || nodes.length == 0) {
|
||||
nodes = [Text.create()]
|
||||
}
|
||||
|
||||
const inline = new Inline({
|
||||
data: Data.create(data),
|
||||
isVoid: !!isVoid,
|
||||
key: key || generateKey(),
|
||||
nodes: Node.createList(nodes),
|
||||
type,
|
||||
})
|
||||
|
||||
return inline
|
||||
}
|
||||
|
||||
throw new Error(`\`Inline.create\` only accepts objects, strings or inlines, but you passed it: ${attrs}`)
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a list of `Inlines` from an array.
|
||||
*
|
||||
* @param {Array<Object|Inline>} elements
|
||||
* @param {Array<Inline|Object>|List<Inline|Object>} elements
|
||||
* @return {List<Inline>}
|
||||
*/
|
||||
|
||||
static createList(elements = []) {
|
||||
if (List.isList(elements)) return elements
|
||||
return new List(elements.map(Inline.create))
|
||||
if (List.isList(elements) || Array.isArray(elements)) {
|
||||
const list = new List(elements.map(Inline.create))
|
||||
return list
|
||||
}
|
||||
|
||||
throw new Error(`\`Inline.createList\` only accepts arrays or lists, but you passed it: ${elements}`)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -102,7 +119,7 @@ class Inline extends new Record(DEFAULTS) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the node empty?
|
||||
* Check if the inline is empty.
|
||||
*
|
||||
* @return {Boolean}
|
||||
*/
|
||||
@@ -112,7 +129,7 @@ class Inline extends new Record(DEFAULTS) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the concatenated text `string` of all child nodes.
|
||||
* Get the concatenated text of all the inline's children.
|
||||
*
|
||||
* @return {String}
|
||||
*/
|
||||
|
@@ -1,7 +1,8 @@
|
||||
|
||||
import Data from './data'
|
||||
import memoize from '../utils/memoize'
|
||||
import MODEL_TYPES from '../constants/model-types'
|
||||
import Data from './data'
|
||||
import isPlainObject from 'is-plain-object'
|
||||
import memoize from '../utils/memoize'
|
||||
import { Map, Record, Set } from 'immutable'
|
||||
|
||||
/**
|
||||
@@ -12,7 +13,7 @@ import { Map, Record, Set } from 'immutable'
|
||||
|
||||
const DEFAULTS = {
|
||||
data: new Map(),
|
||||
type: null
|
||||
type: undefined,
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -21,7 +22,7 @@ const DEFAULTS = {
|
||||
* @type {Mark}
|
||||
*/
|
||||
|
||||
class Mark extends new Record(DEFAULTS) {
|
||||
class Mark extends Record(DEFAULTS) {
|
||||
|
||||
/**
|
||||
* Create a new `Mark` with `attrs`.
|
||||
@@ -31,18 +32,30 @@ class Mark extends new Record(DEFAULTS) {
|
||||
*/
|
||||
|
||||
static create(attrs = {}) {
|
||||
if (Mark.isMark(attrs)) return attrs
|
||||
|
||||
if (!attrs.type) {
|
||||
throw new Error(`You must provide \`attrs.type\` to \`Mark.create(attrs)\`.`)
|
||||
if (Mark.isMark(attrs)) {
|
||||
return attrs
|
||||
}
|
||||
|
||||
const mark = new Mark({
|
||||
type: attrs.type,
|
||||
data: Data.create(attrs.data),
|
||||
})
|
||||
if (typeof attrs == 'string') {
|
||||
attrs = { type: attrs }
|
||||
}
|
||||
|
||||
return mark
|
||||
if (isPlainObject(attrs)) {
|
||||
const { data, type } = attrs
|
||||
|
||||
if (typeof type != 'string') {
|
||||
throw new Error('`Mark.create` requires a mark `type` string.')
|
||||
}
|
||||
|
||||
const mark = new Mark({
|
||||
type,
|
||||
data: Data.create(data),
|
||||
})
|
||||
|
||||
return mark
|
||||
}
|
||||
|
||||
throw new Error(`\`Mark.create\` only accepts objects, strings or marks, but you passed it: ${attrs}`)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -53,11 +66,7 @@ class Mark extends new Record(DEFAULTS) {
|
||||
*/
|
||||
|
||||
static createSet(elements) {
|
||||
if (Set.isSet(elements)) {
|
||||
return elements
|
||||
}
|
||||
|
||||
if (Array.isArray(elements)) {
|
||||
if (Set.isSet(elements) || Array.isArray(elements)) {
|
||||
const marks = new Set(elements.map(Mark.create))
|
||||
return marks
|
||||
}
|
||||
@@ -66,7 +75,36 @@ class Mark extends new Record(DEFAULTS) {
|
||||
return new Set()
|
||||
}
|
||||
|
||||
throw new Error(`Mark.createSet() must be passed an \`Array\`, a \`List\` or \`null\`. You passed: ${elements}`)
|
||||
throw new Error(`\`Mark.createSet\` only accepts sets, arrays or null, but you passed it: ${elements}`)
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a dictionary of settable mark properties from `attrs`.
|
||||
*
|
||||
* @param {Object|String|Mark} attrs
|
||||
* @return {Object}
|
||||
*/
|
||||
|
||||
static createProperties(attrs = {}) {
|
||||
if (Mark.isMark(attrs)) {
|
||||
return {
|
||||
data: attrs.data,
|
||||
type: attrs.type,
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof attrs == 'string') {
|
||||
return { type: attrs }
|
||||
}
|
||||
|
||||
if (isPlainObject(attrs)) {
|
||||
const props = {}
|
||||
if ('type' in attrs) props.type = attrs.type
|
||||
if ('data' in attrs) props.data = Data.create(attrs.data)
|
||||
return props
|
||||
}
|
||||
|
||||
throw new Error(`\`Mark.createProperties\` only accepts objects, strings or marks, but you passed it: ${attrs}`)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -1,12 +1,13 @@
|
||||
|
||||
import Block from './block'
|
||||
import Data from './data'
|
||||
import Document from './document'
|
||||
import Inline from './inline'
|
||||
import Normalize from '../utils/normalize'
|
||||
import Text from './text'
|
||||
import direction from 'direction'
|
||||
import generateKey from '../utils/generate-key'
|
||||
import isInRange from '../utils/is-in-range'
|
||||
import isPlainObject from 'is-plain-object'
|
||||
import logger from '../utils/logger'
|
||||
import memoize from '../utils/memoize'
|
||||
import { List, OrderedSet, Set } from 'immutable'
|
||||
@@ -30,20 +31,23 @@ class Node {
|
||||
*/
|
||||
|
||||
static create(attrs = {}) {
|
||||
if (Block.isBlock(attrs)) return attrs
|
||||
if (Document.isDocument(attrs)) return attrs
|
||||
if (Inline.isInline(attrs)) return attrs
|
||||
if (Text.isText(attrs)) return attrs
|
||||
if (Node.isNode(attrs)) {
|
||||
return attrs
|
||||
}
|
||||
|
||||
switch (attrs.kind) {
|
||||
case 'block': return Block.create(attrs)
|
||||
case 'document': return Document.create(attrs)
|
||||
case 'inline': return Inline.create(attrs)
|
||||
case 'text': return Text.create(attrs)
|
||||
default: {
|
||||
throw new Error(`You must pass a \`kind\` attribute to create a \`Node\`.`)
|
||||
if (isPlainObject(attrs)) {
|
||||
switch (attrs.kind) {
|
||||
case 'block': return Block.create(attrs)
|
||||
case 'document': return Document.create(attrs)
|
||||
case 'inline': return Inline.create(attrs)
|
||||
case 'text': return Text.create(attrs)
|
||||
default: {
|
||||
throw new Error('`Node.create` requires a `kind` string.')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error(`\`Node.create\` only accepts objects or nodes but you passed it: ${attrs}`)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -54,16 +58,43 @@ class Node {
|
||||
*/
|
||||
|
||||
static createList(elements = []) {
|
||||
if (List.isList(elements)) {
|
||||
return elements
|
||||
}
|
||||
|
||||
if (Array.isArray(elements)) {
|
||||
if (List.isList(elements) || Array.isArray(elements)) {
|
||||
const list = new List(elements.map(Node.create))
|
||||
return list
|
||||
}
|
||||
|
||||
throw new Error(`Node.createList() must be passed an \`Array\` or a \`List\`. You passed: ${elements}`)
|
||||
throw new Error(`\`Node.createList\` only accepts lists or arrays, but you passed it: ${elements}`)
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a dictionary of settable node properties from `attrs`.
|
||||
*
|
||||
* @param {Object|String|Node} attrs
|
||||
* @return {Object}
|
||||
*/
|
||||
|
||||
static createProperties(attrs = {}) {
|
||||
if (Block.isBlock(attrs) || Inline.isInline(attrs)) {
|
||||
return {
|
||||
data: attrs.data,
|
||||
isVoid: attrs.isVoid,
|
||||
type: attrs.type,
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof attrs == 'string') {
|
||||
return { type: attrs }
|
||||
}
|
||||
|
||||
if (isPlainObject(attrs)) {
|
||||
const props = {}
|
||||
if ('type' in attrs) props.type = attrs.type
|
||||
if ('data' in attrs) props.data = Data.create(attrs.data)
|
||||
if ('isVoid' in attrs) props.isVoid = attrs.isVoid
|
||||
return props
|
||||
}
|
||||
|
||||
throw new Error(`\`Node.createProperties\` only accepts objects, strings, blocks or inlines, but you passed it: ${attrs}`)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -92,8 +123,8 @@ class Node {
|
||||
*/
|
||||
|
||||
areDescendantsSorted(first, second) {
|
||||
first = Normalize.key(first)
|
||||
second = Normalize.key(second)
|
||||
first = normalizeKey(first)
|
||||
second = normalizeKey(second)
|
||||
|
||||
let sorted
|
||||
|
||||
@@ -121,7 +152,7 @@ class Node {
|
||||
const child = this.getChild(key)
|
||||
|
||||
if (!child) {
|
||||
key = Normalize.key(key)
|
||||
key = normalizeKey(key)
|
||||
throw new Error(`Could not find a child node with key "${key}".`)
|
||||
}
|
||||
|
||||
@@ -139,7 +170,7 @@ class Node {
|
||||
const descendant = this.getDescendant(key)
|
||||
|
||||
if (!descendant) {
|
||||
key = Normalize.key(key)
|
||||
key = normalizeKey(key)
|
||||
throw new Error(`Could not find a descendant node with key "${key}".`)
|
||||
}
|
||||
|
||||
@@ -157,7 +188,7 @@ class Node {
|
||||
const node = this.getNode(key)
|
||||
|
||||
if (!node) {
|
||||
key = Normalize.key(key)
|
||||
key = normalizeKey(key)
|
||||
throw new Error(`Could not find a node with key "${key}".`)
|
||||
}
|
||||
|
||||
@@ -251,7 +282,7 @@ class Node {
|
||||
*/
|
||||
|
||||
getAncestors(key) {
|
||||
key = Normalize.key(key)
|
||||
key = normalizeKey(key)
|
||||
|
||||
if (key == this.key) return List()
|
||||
if (this.hasChild(key)) return List([this])
|
||||
@@ -428,7 +459,7 @@ class Node {
|
||||
*/
|
||||
|
||||
getChild(key) {
|
||||
key = Normalize.key(key)
|
||||
key = normalizeKey(key)
|
||||
return this.nodes.find(node => node.key == key)
|
||||
}
|
||||
|
||||
@@ -441,7 +472,7 @@ class Node {
|
||||
*/
|
||||
|
||||
getClosest(key, iterator) {
|
||||
key = Normalize.key(key)
|
||||
key = normalizeKey(key)
|
||||
const ancestors = this.getAncestors(key)
|
||||
if (!ancestors) {
|
||||
throw new Error(`Could not find a descendant node with key "${key}".`)
|
||||
@@ -493,8 +524,8 @@ class Node {
|
||||
*/
|
||||
|
||||
getCommonAncestor(one, two) {
|
||||
one = Normalize.key(one)
|
||||
two = Normalize.key(two)
|
||||
one = normalizeKey(one)
|
||||
two = normalizeKey(two)
|
||||
|
||||
if (one == this.key) return this
|
||||
if (two == this.key) return this
|
||||
@@ -562,7 +593,7 @@ class Node {
|
||||
*/
|
||||
|
||||
getDescendant(key) {
|
||||
key = Normalize.key(key)
|
||||
key = normalizeKey(key)
|
||||
let descendantFound = null
|
||||
|
||||
const found = this.nodes.find((node) => {
|
||||
@@ -710,7 +741,7 @@ class Node {
|
||||
getFurthest(key, iterator) {
|
||||
const ancestors = this.getAncestors(key)
|
||||
if (!ancestors) {
|
||||
key = Normalize.key(key)
|
||||
key = normalizeKey(key)
|
||||
throw new Error(`Could not find a descendant node with key "${key}".`)
|
||||
}
|
||||
|
||||
@@ -748,7 +779,7 @@ class Node {
|
||||
*/
|
||||
|
||||
getFurthestAncestor(key) {
|
||||
key = Normalize.key(key)
|
||||
key = normalizeKey(key)
|
||||
return this.nodes.find((node) => {
|
||||
if (node.key == key) return true
|
||||
if (node.kind == 'text') return false
|
||||
@@ -767,7 +798,7 @@ class Node {
|
||||
const ancestors = this.getAncestors(key)
|
||||
|
||||
if (!ancestors) {
|
||||
key = Normalize.key(key)
|
||||
key = normalizeKey(key)
|
||||
throw new Error(`Could not find a descendant node with key "${key}".`)
|
||||
}
|
||||
|
||||
@@ -1111,7 +1142,7 @@ class Node {
|
||||
*/
|
||||
|
||||
getNextSibling(key) {
|
||||
key = Normalize.key(key)
|
||||
key = normalizeKey(key)
|
||||
|
||||
const parent = this.getParent(key)
|
||||
const after = parent.nodes
|
||||
@@ -1131,7 +1162,7 @@ class Node {
|
||||
*/
|
||||
|
||||
getNextText(key) {
|
||||
key = Normalize.key(key)
|
||||
key = normalizeKey(key)
|
||||
return this.getTexts()
|
||||
.skipUntil(text => text.key == key)
|
||||
.get(1)
|
||||
@@ -1145,7 +1176,7 @@ class Node {
|
||||
*/
|
||||
|
||||
getNode(key) {
|
||||
key = Normalize.key(key)
|
||||
key = normalizeKey(key)
|
||||
return this.key == key ? this : this.getDescendant(key)
|
||||
}
|
||||
|
||||
@@ -1277,7 +1308,7 @@ class Node {
|
||||
*/
|
||||
|
||||
getPreviousSibling(key) {
|
||||
key = Normalize.key(key)
|
||||
key = normalizeKey(key)
|
||||
const parent = this.getParent(key)
|
||||
const before = parent.nodes
|
||||
.takeUntil(child => child.key == key)
|
||||
@@ -1297,7 +1328,7 @@ class Node {
|
||||
*/
|
||||
|
||||
getPreviousText(key) {
|
||||
key = Normalize.key(key)
|
||||
key = normalizeKey(key)
|
||||
return this.getTexts()
|
||||
.takeUntil(text => text.key == key)
|
||||
.last()
|
||||
@@ -1611,7 +1642,7 @@ class Node {
|
||||
*/
|
||||
|
||||
removeDescendant(key) {
|
||||
key = Normalize.key(key)
|
||||
key = normalizeKey(key)
|
||||
|
||||
let node = this
|
||||
let parent = node.getParent(key)
|
||||
@@ -1872,6 +1903,25 @@ class Node {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize a key argument `value`.
|
||||
*
|
||||
* @param {String|Node} value
|
||||
* @return {String}
|
||||
*/
|
||||
|
||||
function normalizeKey(value) {
|
||||
if (typeof value == 'string') return value
|
||||
|
||||
logger.deprecate('0.14.0', 'An object was passed to a Node method instead of a `key` string. This was previously supported, but is being deprecated because it can have a negative impact on performance. The object in question was:', value)
|
||||
|
||||
if (Node.isNode(value)) {
|
||||
return value.key
|
||||
}
|
||||
|
||||
throw new Error(`Invalid \`key\` argument! It must be either a block, an inline, a text, or a string. You passed: ${value}`)
|
||||
}
|
||||
|
||||
/**
|
||||
* Memoize read methods.
|
||||
*/
|
||||
|
@@ -1,7 +1,8 @@
|
||||
|
||||
import MODEL_TYPES from '../constants/model-types'
|
||||
import Character from './character'
|
||||
import Mark from './mark'
|
||||
import MODEL_TYPES from '../constants/model-types'
|
||||
import isPlainObject from 'is-plain-object'
|
||||
import { Record, Set } from 'immutable'
|
||||
|
||||
/**
|
||||
@@ -21,7 +22,7 @@ const DEFAULTS = {
|
||||
* @type {Range}
|
||||
*/
|
||||
|
||||
class Range extends new Record(DEFAULTS) {
|
||||
class Range extends Record(DEFAULTS) {
|
||||
|
||||
/**
|
||||
* Create a new `Range` with `attrs`.
|
||||
@@ -31,14 +32,25 @@ class Range extends new Record(DEFAULTS) {
|
||||
*/
|
||||
|
||||
static create(attrs = {}) {
|
||||
if (Range.isRange(attrs)) return attrs
|
||||
if (Range.isRange(attrs)) {
|
||||
return attrs
|
||||
}
|
||||
|
||||
const range = new Range({
|
||||
text: attrs.text,
|
||||
marks: Mark.createSet(attrs.marks),
|
||||
})
|
||||
if (typeof attrs == 'string') {
|
||||
attrs = { text: attrs }
|
||||
}
|
||||
|
||||
return range
|
||||
if (isPlainObject(attrs)) {
|
||||
const { marks, text } = attrs
|
||||
const range = new Range({
|
||||
text,
|
||||
marks: Mark.createSet(marks),
|
||||
})
|
||||
|
||||
return range
|
||||
}
|
||||
|
||||
throw new Error(`\`Range.create\` only accepts objects, strings or ranges, but you passed it: ${attrs}`)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -2,6 +2,7 @@
|
||||
import MODEL_TYPES from '../constants/model-types'
|
||||
import React from 'react'
|
||||
import find from 'lodash/find'
|
||||
import isPlainObject from 'is-plain-object'
|
||||
import isReactComponent from '../utils/is-react-component'
|
||||
import logger from '../utils/logger'
|
||||
import typeOf from 'type-of'
|
||||
@@ -23,7 +24,7 @@ const DEFAULTS = {
|
||||
* @type {Schema}
|
||||
*/
|
||||
|
||||
class Schema extends new Record(DEFAULTS) {
|
||||
class Schema extends Record(DEFAULTS) {
|
||||
|
||||
/**
|
||||
* Create a new `Schema` with `attrs`.
|
||||
@@ -33,9 +34,16 @@ class Schema extends new Record(DEFAULTS) {
|
||||
*/
|
||||
|
||||
static create(attrs = {}) {
|
||||
if (Schema.isSchema(attrs)) return attrs
|
||||
const schema = new Schema(normalizeProperties(attrs))
|
||||
return schema
|
||||
if (Schema.isSchema(attrs)) {
|
||||
return attrs
|
||||
}
|
||||
|
||||
if (isPlainObject(attrs)) {
|
||||
const schema = new Schema(normalizeProperties(attrs))
|
||||
return schema
|
||||
}
|
||||
|
||||
throw new Error(`\`Schema.create\` only accepts objects or schemas, but you passed it: ${attrs}`)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -1,6 +1,7 @@
|
||||
|
||||
import logger from '../utils/logger'
|
||||
import MODEL_TYPES from '../constants/model-types'
|
||||
import isPlainObject from 'is-plain-object'
|
||||
import logger from '../utils/logger'
|
||||
import { Record } from 'immutable'
|
||||
|
||||
/**
|
||||
@@ -25,7 +26,7 @@ const DEFAULTS = {
|
||||
* @type {Selection}
|
||||
*/
|
||||
|
||||
class Selection extends new Record(DEFAULTS) {
|
||||
class Selection extends Record(DEFAULTS) {
|
||||
|
||||
/**
|
||||
* Create a new `Selection` with `attrs`.
|
||||
@@ -35,9 +36,51 @@ class Selection extends new Record(DEFAULTS) {
|
||||
*/
|
||||
|
||||
static create(attrs = {}) {
|
||||
if (Selection.isSelection(attrs)) return attrs
|
||||
const selection = new Selection(attrs)
|
||||
return selection
|
||||
if (Selection.isSelection(attrs)) {
|
||||
return attrs
|
||||
}
|
||||
|
||||
if (isPlainObject(attrs)) {
|
||||
const selection = new Selection(attrs)
|
||||
return selection
|
||||
}
|
||||
|
||||
throw new Error(`\`Selection.create\` only accepts objects or selections, but you passed it: ${attrs}`)
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a dictionary of settable selection properties from `attrs`.
|
||||
*
|
||||
* @param {Object|String|Selection} attrs
|
||||
* @return {Object}
|
||||
*/
|
||||
|
||||
static createProperties(attrs = {}) {
|
||||
if (Selection.isSelection(attrs)) {
|
||||
return {
|
||||
anchorKey: attrs.anchorKey,
|
||||
anchorOffset: attrs.anchorOffset,
|
||||
focusKey: attrs.focusKey,
|
||||
focusOffset: attrs.focusOffset,
|
||||
isBackward: attrs.isBackward,
|
||||
isFocused: attrs.isFocused,
|
||||
marks: attrs.marks,
|
||||
}
|
||||
}
|
||||
|
||||
if (isPlainObject(attrs)) {
|
||||
const props = {}
|
||||
if ('anchorKey' in attrs) props.anchorKey = attrs.anchorKey
|
||||
if ('anchorOffset' in attrs) props.anchorOffset = attrs.anchorOffset
|
||||
if ('focusKey' in attrs) props.focusKey = attrs.focusKey
|
||||
if ('focusOffset' in attrs) props.focusOffset = attrs.focusOffset
|
||||
if ('isBackward' in attrs) props.isBackward = attrs.isBackward
|
||||
if ('isFocused' in attrs) props.isFocused = attrs.isFocused
|
||||
if ('marks' in attrs) props.marks = attrs.marks
|
||||
return props
|
||||
}
|
||||
|
||||
throw new Error(`\`Selection.createProperties\` only accepts objects or selections, but you passed it: ${attrs}`)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -51,7 +51,7 @@ const DEFAULTS = {
|
||||
* @type {Stack}
|
||||
*/
|
||||
|
||||
class Stack extends new Record(DEFAULTS) {
|
||||
class Stack extends Record(DEFAULTS) {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
|
@@ -5,6 +5,7 @@ import Change from './change'
|
||||
import Document from './document'
|
||||
import History from './history'
|
||||
import Selection from './selection'
|
||||
import isPlainObject from 'is-plain-object'
|
||||
import logger from '../utils/logger'
|
||||
import { Record, Set, List, Map } from 'immutable'
|
||||
|
||||
@@ -15,11 +16,11 @@ import { Record, Set, List, Map } from 'immutable'
|
||||
*/
|
||||
|
||||
const DEFAULTS = {
|
||||
document: new Document(),
|
||||
selection: new Selection(),
|
||||
history: new History(),
|
||||
document: Document.create(),
|
||||
selection: Selection.create(),
|
||||
history: History.create(),
|
||||
data: new Map(),
|
||||
isNative: false
|
||||
isNative: false,
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -28,7 +29,7 @@ const DEFAULTS = {
|
||||
* @type {State}
|
||||
*/
|
||||
|
||||
class State extends new Record(DEFAULTS) {
|
||||
class State extends Record(DEFAULTS) {
|
||||
|
||||
/**
|
||||
* Create a new `State` with `attrs`.
|
||||
@@ -40,37 +41,43 @@ class State extends new Record(DEFAULTS) {
|
||||
*/
|
||||
|
||||
static create(attrs = {}, options = {}) {
|
||||
if (State.isState(attrs)) return attrs
|
||||
|
||||
const document = Document.create(attrs.document)
|
||||
let selection = Selection.create(attrs.selection)
|
||||
let data = new Map()
|
||||
|
||||
if (selection.isUnset) {
|
||||
const text = document.getFirstText()
|
||||
if (text) selection = selection.collapseToStartOf(text)
|
||||
if (State.isState(attrs)) {
|
||||
return attrs
|
||||
}
|
||||
|
||||
// Set default value for `data`.
|
||||
if (options.plugins) {
|
||||
for (const plugin of options.plugins) {
|
||||
if (plugin.data) data = data.merge(plugin.data)
|
||||
if (isPlainObject(attrs)) {
|
||||
const document = Document.create(attrs.document)
|
||||
let selection = Selection.create(attrs.selection)
|
||||
let data = new Map()
|
||||
|
||||
if (selection.isUnset) {
|
||||
const text = document.getFirstText()
|
||||
if (text) selection = selection.collapseToStartOf(text)
|
||||
}
|
||||
|
||||
// Set default value for `data`.
|
||||
if (options.plugins) {
|
||||
for (const plugin of options.plugins) {
|
||||
if (plugin.data) data = data.merge(plugin.data)
|
||||
}
|
||||
}
|
||||
|
||||
// Then add data provided in `attrs`.
|
||||
if (attrs.data) data = data.merge(attrs.data)
|
||||
|
||||
let state = new State({ document, selection, data })
|
||||
|
||||
if (options.normalize !== false) {
|
||||
state = state
|
||||
.change({ save: false })
|
||||
.normalize(SCHEMA)
|
||||
.state
|
||||
}
|
||||
|
||||
return state
|
||||
}
|
||||
|
||||
// Then add data provided in `attrs`.
|
||||
if (attrs.data) data = data.merge(attrs.data)
|
||||
|
||||
let state = new State({ document, selection, data })
|
||||
|
||||
if (options.normalize !== false) {
|
||||
state = state
|
||||
.change({ save: false })
|
||||
.normalize(SCHEMA)
|
||||
.state
|
||||
}
|
||||
|
||||
return state
|
||||
throw new Error(`\`State.create\` only accepts objects or states, but you passed it: ${attrs}`)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -3,9 +3,11 @@ import Character from './character'
|
||||
import Mark from './mark'
|
||||
import Range from './range'
|
||||
import MODEL_TYPES from '../constants/model-types'
|
||||
import memoize from '../utils/memoize'
|
||||
import generateKey from '../utils/generate-key'
|
||||
import { List, Record, OrderedSet, Set, is } from 'immutable'
|
||||
import isPlainObject from 'is-plain-object'
|
||||
import logger from '../utils/logger'
|
||||
import memoize from '../utils/memoize'
|
||||
import { List, Record, OrderedSet, is } from 'immutable'
|
||||
|
||||
/**
|
||||
* Default properties.
|
||||
@@ -15,7 +17,7 @@ import { List, Record, OrderedSet, Set, is } from 'immutable'
|
||||
|
||||
const DEFAULTS = {
|
||||
characters: new List(),
|
||||
key: null
|
||||
key: undefined,
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -24,57 +26,45 @@ const DEFAULTS = {
|
||||
* @type {Text}
|
||||
*/
|
||||
|
||||
class Text extends new Record(DEFAULTS) {
|
||||
class Text extends Record(DEFAULTS) {
|
||||
|
||||
/**
|
||||
* Create a new `Text` with `attrs`.
|
||||
*
|
||||
* @param {Object|Text} attrs
|
||||
* @param {Object|Array|List|String|Text} attrs
|
||||
* @return {Text}
|
||||
*/
|
||||
|
||||
static create(attrs = {}) {
|
||||
if (Text.isText(attrs)) return attrs
|
||||
if (attrs.ranges) return Text.createFromRanges(attrs.ranges)
|
||||
if (Text.isText(attrs)) {
|
||||
return attrs
|
||||
}
|
||||
|
||||
const text = new Text({
|
||||
characters: Character.createList(attrs.characters),
|
||||
key: attrs.key || generateKey(),
|
||||
})
|
||||
if (List.isList(attrs) || Array.isArray(attrs)) {
|
||||
attrs = { ranges: attrs }
|
||||
}
|
||||
|
||||
return text
|
||||
}
|
||||
if (typeof attrs == 'string') {
|
||||
attrs = { ranges: [{ text: attrs }] }
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new `Text` from a string
|
||||
*
|
||||
* @param {String} text
|
||||
* @param {Set<Mark>} marks (optional)
|
||||
* @return {Text}
|
||||
*/
|
||||
if (isPlainObject(attrs)) {
|
||||
const { characters, ranges, key } = attrs
|
||||
const chars = ranges
|
||||
? ranges
|
||||
.map(Range.create)
|
||||
.reduce((l, r) => l.concat(r.getCharacters()), Character.createList())
|
||||
: Character.createList(characters)
|
||||
|
||||
static createFromString(string, marks = Set()) {
|
||||
const range = Range.create({ text: string, marks })
|
||||
const text = Text.createFromRanges([range])
|
||||
return text
|
||||
}
|
||||
const text = new Text({
|
||||
characters: chars,
|
||||
key: key || generateKey(),
|
||||
})
|
||||
|
||||
/**
|
||||
* Create a new `Text` from a list of ranges
|
||||
*
|
||||
* @param {List<Range>|Array<Range>} ranges
|
||||
* @return {Text}
|
||||
*/
|
||||
return text
|
||||
}
|
||||
|
||||
static createFromRanges(ranges) {
|
||||
const characters = ranges
|
||||
.map(Range.create)
|
||||
.reduce((list, range) => {
|
||||
return list.concat(range.getCharacters())
|
||||
}, Character.createList())
|
||||
|
||||
const text = Text.create({ characters })
|
||||
return text
|
||||
throw new Error(`\`Text.create\` only accepts objects, arrays, strings or texts, but you passed it: ${attrs}`)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -104,6 +94,24 @@ class Text extends new Record(DEFAULTS) {
|
||||
return !!(value && value[MODEL_TYPES.TEXT])
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated.
|
||||
*/
|
||||
|
||||
static createFromString(string) {
|
||||
logger.deprecate('0.22.0', 'The `Text.createFromString(string)` method is deprecated, use `Text.create(string)` instead.')
|
||||
return Text.create(string)
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated.
|
||||
*/
|
||||
|
||||
static createFromRanges(ranges) {
|
||||
logger.deprecate('0.22.0', 'The `Text.createFromRanges(ranges)` method is deprecated, use `Text.create(ranges)` instead.')
|
||||
return Text.create(ranges)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the node's kind.
|
||||
*
|
||||
@@ -319,7 +327,7 @@ class Text extends new Record(DEFAULTS) {
|
||||
|
||||
insertText(index, text, marks) {
|
||||
let { characters } = this
|
||||
const chars = Character.createListFromText(text, marks)
|
||||
const chars = Character.createList(text.split('').map(char => ({ text: char, marks })))
|
||||
|
||||
characters = characters.slice(0, index)
|
||||
.concat(chars)
|
||||
|
@@ -1,6 +1,7 @@
|
||||
|
||||
import Debug from 'debug'
|
||||
import Normalize from '../utils/normalize'
|
||||
import Node from '../models/node'
|
||||
import Mark from '../models/mark'
|
||||
import logger from '../utils/logger'
|
||||
|
||||
/**
|
||||
@@ -29,7 +30,7 @@ const APPLIERS = {
|
||||
|
||||
add_mark(state, operation) {
|
||||
const { path, offset, length } = operation
|
||||
const mark = Normalize.mark(operation.mark)
|
||||
const mark = Mark.create(operation.mark)
|
||||
let { document } = state
|
||||
let node = document.assertPath(path)
|
||||
node = node.addMark(offset, length, mark)
|
||||
@@ -48,7 +49,7 @@ const APPLIERS = {
|
||||
|
||||
insert_node(state, operation) {
|
||||
const { path } = operation
|
||||
const node = Normalize.node(operation.node)
|
||||
const node = Node.create(operation.node)
|
||||
const index = path[path.length - 1]
|
||||
const rest = path.slice(0, -1)
|
||||
let { document } = state
|
||||
@@ -71,7 +72,7 @@ const APPLIERS = {
|
||||
const { path, offset, text } = operation
|
||||
|
||||
let { marks } = operation
|
||||
if (Array.isArray(marks)) marks = Normalize.marks(marks)
|
||||
if (Array.isArray(marks)) marks = Mark.createSet(marks)
|
||||
|
||||
let { document, selection } = state
|
||||
const { anchorKey, focusKey, anchorOffset, focusOffset } = selection
|
||||
@@ -207,7 +208,7 @@ const APPLIERS = {
|
||||
|
||||
remove_mark(state, operation) {
|
||||
const { path, offset, length } = operation
|
||||
const mark = Normalize.mark(operation.mark)
|
||||
const mark = Mark.create(operation.mark)
|
||||
let { document } = state
|
||||
let node = document.assertPath(path)
|
||||
node = node.removeMark(offset, length, mark)
|
||||
@@ -341,7 +342,7 @@ const APPLIERS = {
|
||||
|
||||
set_mark(state, operation) {
|
||||
const { path, offset, length, properties } = operation
|
||||
const mark = Normalize.mark(operation.mark)
|
||||
const mark = Mark.create(operation.mark)
|
||||
let { document } = state
|
||||
let node = document.assertPath(path)
|
||||
node = node.updateMark(offset, length, mark, properties)
|
||||
@@ -393,8 +394,8 @@ const APPLIERS = {
|
||||
const properties = { ...operation.properties }
|
||||
let { document, selection } = state
|
||||
|
||||
if (properties.marks !== undefined) {
|
||||
properties.marks = Normalize.marks(properties.marks)
|
||||
if (properties.marks != null) {
|
||||
properties.marks = Mark.createSet(properties.marks)
|
||||
}
|
||||
|
||||
if (properties.anchorPath !== undefined) {
|
||||
|
@@ -125,7 +125,7 @@ const rules = [
|
||||
return node.text !== ' ' || node.nodes.size !== 1
|
||||
},
|
||||
normalize: (change, node, result) => {
|
||||
const text = Text.createFromString(' ')
|
||||
const text = Text.create(' ')
|
||||
const index = node.nodes.size
|
||||
|
||||
change.insertNodeByKey(node.key, index, text, OPTS)
|
||||
|
@@ -1,351 +0,0 @@
|
||||
|
||||
import Block from '../models/block'
|
||||
import Document from '../models/document'
|
||||
import Inline from '../models/inline'
|
||||
import Data from '../models/data'
|
||||
import Mark from '../models/mark'
|
||||
import Selection from '../models/selection'
|
||||
import Text from '../models/text'
|
||||
import logger from './logger'
|
||||
import typeOf from 'type-of'
|
||||
import { Set } from 'immutable'
|
||||
|
||||
/**
|
||||
* Normalize a block argument `value`.
|
||||
*
|
||||
* @param {Block|String|Object} value
|
||||
* @return {Block}
|
||||
*/
|
||||
|
||||
function block(value) {
|
||||
if (Block.isBlock(value)) return value
|
||||
|
||||
if (
|
||||
Inline.isInline(value) ||
|
||||
Mark.isMark(value) ||
|
||||
Text.isText(value) ||
|
||||
Selection.isSelection(value)
|
||||
) {
|
||||
throw new Error(`Invalid \`block\` argument! It must be a block, an object, or a string. You passed: ${value}`)
|
||||
}
|
||||
|
||||
|
||||
switch (typeOf(value)) {
|
||||
case 'string':
|
||||
case 'object': {
|
||||
return Block.create(nodeProperties(value))
|
||||
}
|
||||
default: {
|
||||
throw new Error(`Invalid \`block\` argument! It must be a block, an object, or a string. You passed: ${value}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize an inline argument `value`.
|
||||
*
|
||||
* @param {Inline|String|Object} value
|
||||
* @return {Inline}
|
||||
*/
|
||||
|
||||
function inline(value) {
|
||||
if (Inline.isInline(value)) return value
|
||||
|
||||
if (
|
||||
Block.isBlock(value) ||
|
||||
Mark.isMark(value) ||
|
||||
Text.isText(value) ||
|
||||
Selection.isSelection(value)
|
||||
) {
|
||||
throw new Error(`Invalid \`inline\` argument! It must be an inline, an object, or a string. You passed: ${value}`)
|
||||
}
|
||||
|
||||
switch (typeOf(value)) {
|
||||
case 'string':
|
||||
case 'object': {
|
||||
return Inline.create(nodeProperties(value))
|
||||
}
|
||||
default: {
|
||||
throw new Error(`Invalid \`inline\` argument! It must be an inline, an object, or a string. You passed: ${value}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize an text argument `value`.
|
||||
*
|
||||
* @param {Text|String|Object} value
|
||||
* @return {Text}
|
||||
*/
|
||||
|
||||
function text(value) {
|
||||
if (Text.isText(value)) return value
|
||||
|
||||
if (
|
||||
Block.isBlock(value) ||
|
||||
Inline.isInline(value) ||
|
||||
Mark.isMark(value) ||
|
||||
Selection.isSelection(value)
|
||||
) {
|
||||
throw new Error(`Invalid \`text\` argument! It must be a text, an object, or a string. You passed: ${value}`)
|
||||
}
|
||||
|
||||
switch (typeOf(value)) {
|
||||
case 'object': {
|
||||
return Text.create(value)
|
||||
}
|
||||
default: {
|
||||
throw new Error(`Invalid \`text\` argument! It must be an text, an object, or a string. You passed: ${value}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize a node `value`.
|
||||
*
|
||||
* @param {Node|Object} value
|
||||
* @return {Node}
|
||||
*/
|
||||
|
||||
function node(value) {
|
||||
if (Block.isBlock(value)) return value
|
||||
if (Document.isDocument(value)) return value
|
||||
if (Inline.isInline(value)) return value
|
||||
if (Text.isText(value)) return value
|
||||
|
||||
switch (typeOf(value)) {
|
||||
case 'object': {
|
||||
switch (value.kind) {
|
||||
case 'block': return block(value)
|
||||
case 'inline': return inline(value)
|
||||
case 'text': return text(value)
|
||||
default: {
|
||||
throw new Error(`Invalid \`node.kind\` property. It must be either "block" or "inline". You passed: ${value}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
default: {
|
||||
throw new Error(`Invalid \`node\` argument! It must be a block, an inline, a text, or an object. You passed: ${value}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize a key argument `value`.
|
||||
*
|
||||
* @param {String|Node} value
|
||||
* @return {String}
|
||||
*/
|
||||
|
||||
function key(value) {
|
||||
if (typeOf(value) == 'string') return value
|
||||
|
||||
logger.warn('An object was passed to a Node method instead of a `key` string. This was previously supported, but is being deprecated because it can have a negative impact on performance. The object in question was:', value)
|
||||
|
||||
if (
|
||||
Block.isBlock(value) ||
|
||||
Document.isDocument(value) ||
|
||||
Inline.isInline(value) ||
|
||||
Text.isText(value)
|
||||
) {
|
||||
return value.key
|
||||
}
|
||||
|
||||
throw new Error(`Invalid \`key\` argument! It must be either a block, an inline, a text, or a string. You passed: ${value}`)
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize a mark argument `value`.
|
||||
*
|
||||
* @param {Mark|String|Object} value
|
||||
* @return {Mark}
|
||||
*/
|
||||
|
||||
function mark(value) {
|
||||
if (Mark.isMark(value)) return value
|
||||
if (
|
||||
Block.isBlock(value) ||
|
||||
Inline.isInline(value) ||
|
||||
Text.isText(value) ||
|
||||
Selection.isSelection(value)
|
||||
) {
|
||||
throw new Error(`Invalid \`mark\` argument! It must be a mark, an object, or a string. You passed: ${value}`)
|
||||
}
|
||||
|
||||
switch (typeOf(value)) {
|
||||
case 'string':
|
||||
case 'object': {
|
||||
return Mark.create(markProperties(value))
|
||||
}
|
||||
default: {
|
||||
throw new Error(`Invalid \`mark\` argument! It must be a mark, an object, or a string. You passed: ${value}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize a set of marks argument `values`.
|
||||
*
|
||||
* @param {Set<Marks>|Array} values
|
||||
* @return {Set<Marks>}
|
||||
*/
|
||||
|
||||
function marks(values) {
|
||||
if (Set.isSet(values)) return values
|
||||
|
||||
switch (typeOf(values)) {
|
||||
case 'array': {
|
||||
return Mark.createSet(values)
|
||||
}
|
||||
case 'null': {
|
||||
return null
|
||||
}
|
||||
default: {
|
||||
throw new Error(`Invalid \`marks\` argument! It must be a set of marks or an array. You passed: ${values}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize a mark properties argument `value`.
|
||||
*
|
||||
* @param {String|Object|Mark} value
|
||||
* @return {Object}
|
||||
*/
|
||||
|
||||
function markProperties(value = {}) {
|
||||
const ret = {}
|
||||
|
||||
switch (typeOf(value)) {
|
||||
case 'string': {
|
||||
ret.type = value
|
||||
break
|
||||
}
|
||||
case 'object': {
|
||||
for (const k in value) {
|
||||
if (k == 'data') {
|
||||
if (value[k] !== undefined) ret[k] = Data.create(value[k])
|
||||
} else if (!k.startsWith('@@__SLATE')) {
|
||||
ret[k] = value[k]
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
default: {
|
||||
throw new Error(`Invalid mark \`properties\` argument! It must be an object, a string or a mark. You passed: ${value}`)
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize a node properties argument `value`.
|
||||
*
|
||||
* @param {String|Object|Node} value
|
||||
* @return {Object}
|
||||
*/
|
||||
|
||||
function nodeProperties(value = {}) {
|
||||
const ret = {}
|
||||
|
||||
switch (typeOf(value)) {
|
||||
case 'string': {
|
||||
ret.type = value
|
||||
break
|
||||
}
|
||||
case 'object': {
|
||||
if (value.isVoid !== undefined) ret.isVoid = !!value.isVoid
|
||||
for (const k in value) {
|
||||
if (k == 'data') {
|
||||
if (value[k] !== undefined) ret[k] = Data.create(value[k])
|
||||
} else if (!k.startsWith('@@__SLATE')) {
|
||||
ret[k] = value[k]
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
default: {
|
||||
throw new Error(`Invalid node \`properties\` argument! It must be an object, a string or a node. You passed: ${value}`)
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize a selection argument `value`.
|
||||
*
|
||||
* @param {Selection|Object} value
|
||||
* @return {Selection}
|
||||
*/
|
||||
|
||||
function selection(value) {
|
||||
if (Selection.isSelection(value)) return value
|
||||
if (
|
||||
Mark.isMark(value) ||
|
||||
Block.isBlock(value) ||
|
||||
Inline.isInline(value) ||
|
||||
Text.isText(value)
|
||||
) {
|
||||
throw new Error(`Invalid \`selection\` argument! It must be a selection or an object. You passed: ${value}`)``
|
||||
}
|
||||
|
||||
switch (typeOf(value)) {
|
||||
case 'object': {
|
||||
return Selection.create(value)
|
||||
}
|
||||
default: {
|
||||
throw new Error(`Invalid \`selection\` argument! It must be a selection or an object. You passed: ${value}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize a selection properties argument `value`.
|
||||
*
|
||||
* @param {Object|Selection} value
|
||||
* @return {Object}
|
||||
*/
|
||||
|
||||
function selectionProperties(value = {}) {
|
||||
const ret = {}
|
||||
|
||||
switch (typeOf(value)) {
|
||||
case 'object': {
|
||||
if (value.anchorKey !== undefined) ret.anchorKey = value.anchorKey
|
||||
if (value.anchorOffset !== undefined) ret.anchorOffset = value.anchorOffset
|
||||
if (value.focusKey !== undefined) ret.focusKey = value.focusKey
|
||||
if (value.focusOffset !== undefined) ret.focusOffset = value.focusOffset
|
||||
if (value.isBackward !== undefined) ret.isBackward = !!value.isBackward
|
||||
if (value.isFocused !== undefined) ret.isFocused = !!value.isFocused
|
||||
if (value.marks !== undefined) ret.marks = value.marks
|
||||
break
|
||||
}
|
||||
default: {
|
||||
throw new Error(`Invalid selection \`properties\` argument! It must be an object or a selection. You passed: ${value}`)
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
/**
|
||||
* Export.
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
|
||||
export default {
|
||||
block,
|
||||
inline,
|
||||
node,
|
||||
key,
|
||||
mark,
|
||||
marks,
|
||||
markProperties,
|
||||
nodeProperties,
|
||||
selection,
|
||||
selectionProperties,
|
||||
text,
|
||||
}
|
10
yarn.lock
10
yarn.lock
@@ -3251,6 +3251,12 @@ is-path-inside@^1.0.0:
|
||||
dependencies:
|
||||
path-is-inside "^1.0.1"
|
||||
|
||||
is-plain-object@^2.0.4:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677"
|
||||
dependencies:
|
||||
isobject "^3.0.1"
|
||||
|
||||
is-posix-bracket@^0.1.0:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4"
|
||||
@@ -3329,6 +3335,10 @@ isobject@^2.0.0:
|
||||
dependencies:
|
||||
isarray "1.0.0"
|
||||
|
||||
isobject@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df"
|
||||
|
||||
isomorphic-fetch@^2.1.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9"
|
||||
|
Reference in New Issue
Block a user