1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-08-20 06:01:24 +02:00

refactor normalizing function

This commit is contained in:
Ian Storm Taylor
2016-08-16 12:50:35 -07:00
parent fb29bdbd4e
commit ff1f25585e
9 changed files with 207 additions and 192 deletions

View File

@@ -5,6 +5,7 @@ import Data from './data'
import Document from './document'
import Inline from './inline'
import Mark from './mark'
import Normalize from '../utils/normalize'
import Selection from './selection'
import Text from './text'
import direction from 'direction'
@@ -34,7 +35,7 @@ const Node = {
const child = this.getChild(key)
if (!child) {
key = normalizeKey(key)
key = Normalize.key(key)
throw new Error(`Could not find a child node with key "${key}".`)
}
@@ -52,7 +53,7 @@ const Node = {
const descendant = this.getDescendant(key)
if (!descendant) {
key = normalizeKey(key)
key = Normalize.key(key)
throw new Error(`Could not find a descendant node with key "${key}".`)
}
@@ -308,7 +309,7 @@ const Node = {
*/
getChild(key) {
key = normalizeKey(key)
key = Normalize.key(key)
return this.nodes.find(node => node.key == key)
},
@@ -390,7 +391,7 @@ const Node = {
*/
getDescendant(key) {
key = normalizeKey(key)
key = Normalize.key(key)
let child = this.getChild(key)
if (child) return child
@@ -511,7 +512,7 @@ const Node = {
*/
getHighestChild(key) {
key = normalizeKey(key)
key = Normalize.key(key)
return this.nodes.find(node => {
if (node.key == key) return true
if (node.kind == 'text') return false
@@ -653,7 +654,7 @@ const Node = {
*/
getNextText(key) {
key = normalizeKey(key)
key = Normalize.key(key)
return this.getTexts()
.skipUntil(text => text.key == key)
.get(1)
@@ -744,7 +745,7 @@ const Node = {
*/
getPreviousText(key) {
key = normalizeKey(key)
key = Normalize.key(key)
return this.getTexts()
.takeUntil(text => text.key == key)
.last()
@@ -1186,18 +1187,6 @@ memoize(Node, [
'validate'
])
/**
* Normalize a `key`, from a key string or a node.
*
* @param {String or Node} key
* @return {String} key
*/
function normalizeKey(key) {
if (typeof key == 'string') return key
return key.key
}
/**
* Export.
*/

View File

@@ -1,5 +1,6 @@
import normalizeMark from '../utils/normalize-mark'
import Normalize from '../utils/normalize'
import {
addMarkAtRange,
deleteAtRange,
@@ -32,7 +33,7 @@ import {
*/
export function addMark(state, mark) {
mark = normalizeMark(mark)
mark = Normalize.mark(mark)
let { cursorMarks, document, selection } = state
// If the selection is collapsed, add the mark to the cursor instead.
@@ -463,7 +464,7 @@ export function splitInline(state, depth = Infinity) {
*/
export function removeMark(state, mark) {
mark = normalizeMark(mark)
mark = Normalize.mark(mark)
let { cursorMarks, document, selection } = state
// If the selection is collapsed, remove the mark from the cursor instead.
@@ -486,7 +487,7 @@ export function removeMark(state, mark) {
*/
export function toggleMark(state, mark) {
mark = normalizeMark(mark)
mark = Normalize.mark(mark)
const exists = state.marks.some(m => m.equals(mark))
return exists
? removeMark(state, mark)

View File

@@ -1,13 +1,10 @@
import Block from '../models/block'
import Inline from '../models/inline'
import Normalize from '../utils/normalize'
import Selection from '../models/selection'
import Text from '../models/text'
import isInRange from '../utils/is-in-range'
import normalizeBlock from '../utils/normalize-block'
import normalizeInline from '../utils/normalize-inline'
import normalizeMark from '../utils/normalize-mark'
import normalizeProperties from '../utils/normalize-node-or-mark-properties'
import uid from '../utils/uid'
import { Set } from 'immutable'
@@ -24,7 +21,7 @@ export function addMarkAtRange(state, range, mark) {
let { document } = state
// Normalize the mark.
mark = normalizeMark(mark)
mark = Normalize.mark(mark)
// When the range is collapsed, do nothing.
if (range.isCollapsed) return state
@@ -276,7 +273,7 @@ export function insertBlockAtRange(state, range, block) {
let { document } = state
// Normalize the block argument.
block = normalizeBlock(block)
block = Normalize.block(block)
// If expanded, delete the range first.
if (range.isExpanded) {
@@ -460,7 +457,7 @@ export function insertInlineAtRange(state, range, inline) {
let { document } = state
// Normalize the inline argument.
inline = normalizeInline(inline)
inline = Normalize.inline(inline)
// If expanded, delete the range first.
if (range.isExpanded) {
@@ -542,7 +539,7 @@ export function insertTextAtRange(state, range, string, marks) {
*/
export function removeMarkAtRange(state, range, mark) {
mark = normalizeMark(mark)
mark = Normalize.mark(mark)
let { document } = state
// When the range is collapsed, do nothing.
@@ -584,7 +581,7 @@ export function removeMarkAtRange(state, range, mark) {
*/
export function setBlockAtRange(state, range, properties = {}) {
properties = normalizeProperties(properties)
properties = Normalize.nodeProperties(properties)
let { document } = state
const blocks = document.getBlocksAtRange(range)
@@ -608,7 +605,7 @@ export function setBlockAtRange(state, range, properties = {}) {
*/
export function setInlineAtRange(state, range, properties = {}) {
properties = normalizeProperties(properties)
properties = Normalize.nodeProperties(properties)
let { document } = state
const inlines = document.getInlinesAtRange(range)
@@ -801,7 +798,7 @@ export function splitTextAtRange(state, range) {
*/
export function toggleMarkAtRange(state, range, mark) {
mark = normalizeMark(mark)
mark = Normalize.mark(mark)
let { document } = state
// When the range is collapsed, do nothing.
@@ -826,7 +823,7 @@ export function toggleMarkAtRange(state, range, mark) {
*/
export function unwrapBlockAtRange(state, range, properties) {
properties = normalizeProperties(properties)
properties = Normalize.nodeProperties(properties)
let { document } = state
// Get the deepest blocks in the range.
@@ -921,7 +918,7 @@ export function unwrapBlockAtRange(state, range, properties) {
*/
export function unwrapInlineAtRange(state, range, properties) {
properties = normalizeProperties(properties)
properties = Normalize.nodeProperties(properties)
let { document } = state
let blocks = document.getInlinesAtRange(range)
@@ -969,7 +966,7 @@ export function unwrapInlineAtRange(state, range, properties) {
*/
export function wrapBlockAtRange(state, range, properties) {
properties = normalizeProperties(properties)
properties = Normalize.nodeProperties(properties)
let { document } = state
// Get the block nodes, sorted by depth.
@@ -1028,7 +1025,7 @@ export function wrapBlockAtRange(state, range, properties) {
*/
export function wrapInlineAtRange(state, range, properties) {
properties = normalizeProperties(properties)
properties = Normalize.nodeProperties(properties)
let { document } = state
// If collapsed, there's nothing to wrap.

View File

@@ -1,5 +1,5 @@
import normalizeProperties from '../utils/normalize-node-or-mark-properties'
import Normalize from '../utils/normalize'
/**
* Remove a node by `key`.
@@ -27,7 +27,7 @@ export function removeNodeByKey(state, key) {
*/
export function setNodeByKey(state, key, properties) {
properties = normalizeProperties(properties)
properties = Normalize.nodeProperties(properties)
let { document } = state
let descendant = document.assertDescendant(key)
descendant = descendant.merge(properties)

View File

@@ -1,35 +0,0 @@
import Block from '../models/block'
import normalizeProperties from './normalize-node-or-mark-properties'
import typeOf from 'type-of'
/**
* Normalize a `block` argument, which can be a string or plain object too.
*
* @param {Block or String or Object} block
* @return {Block}
*/
function normalizeBlock(block) {
if (block instanceof Block) return block
const type = typeOf(block)
switch (type) {
case 'string':
case 'object': {
return Block.create(normalizeProperties(block))
}
default: {
throw new Error(`A \`block\` argument must be a block, an object or a string, but you passed: "${type}".`)
}
}
}
/**
* Export.
*
* @type {Function}
*/
export default normalizeBlock

View File

@@ -1,35 +0,0 @@
import Inline from '../models/inline'
import normalizeProperties from './normalize-node-or-mark-properties'
import typeOf from 'type-of'
/**
* Normalize an `inline` argument, which can be a string or plain object too.
*
* @param {Inline or String or Object} inline
* @return {Inline}
*/
function normalizeInline(inline) {
if (inline instanceof Inline) return inline
const type = typeOf(inline)
switch (type) {
case 'string':
case 'object': {
return Inline.create(normalizeProperties(inline))
}
default: {
throw new Error(`An \`inline\` argument must be an inline, an object or a string, but you passed: "${type}".`)
}
}
}
/**
* Export.
*
* @type {Function}
*/
export default normalizeInline

View File

@@ -1,35 +0,0 @@
import Mark from '../models/mark'
import typeOf from 'type-of'
import normalizeProperties from './normalize-node-or-mark-properties'
/**
* Normalize a `mark` argument, which can be a string or plain object too.
*
* @param {Mark or String or Object} mark
* @return {Mark}
*/
function normalizeMark(mark) {
if (mark instanceof Mark) return mark
const type = typeOf(mark)
switch (type) {
case 'string':
case 'object': {
return Mark.create(normalizeProperties(mark))
}
default: {
throw new Error(`A \`mark\` argument must be a mark, an object or a string, but you passed: "${type}".`)
}
}
}
/**
* Export.
*
* @type {Function}
*/
export default normalizeMark

View File

@@ -1,47 +0,0 @@
import Data from '../models/data'
import typeOf from 'type-of'
/**
* Normalize the `properties` of a node or mark, which can be either a type
* string or a dictionary of properties. If it's a dictionary, `data` is
* optional and shouldn't be set if null or undefined.
*
* @param {String or Object} properties
* @return {Object}
*/
function normalizeNodeOrMarkProperties(properties = {}) {
const ret = {}
const type = typeOf(properties)
switch (type) {
case 'string': {
ret.type = properties
break
}
case 'object': {
for (const key in properties) {
if (key == 'data') {
if (properties[key] != null) ret[key] = Data.create(properties[key])
} else {
ret[key] = properties[key]
}
}
break
}
default: {
throw new Error(`A \`properties\` argument must be an object or a string, but you passed: "${type}".`)
}
}
return ret
}
/**
* Export.
*
* @type {Function}
*/
export default normalizeNodeOrMarkProperties

180
lib/utils/normalize.js Normal file
View File

@@ -0,0 +1,180 @@
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 Text from '../models/text'
import typeOf from 'type-of'
/**
* Normalize a block argument `value`.
*
* @param {Block || String || Object} value
* @return {Block}
*/
function block(value) {
if (value instanceof Block) return value
const type = typeOf(value)
switch (type) {
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 (value instanceof Inline) return value
const type = typeOf(value)
switch (type) {
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 a key argument `value`.
*
* @param {String || Node} value
* @return {String}
*/
function key(value) {
if (value instanceof Block) return value.key
if (value instanceof Inline) return value.key
if (value instanceof Text) return value.key
// Special-case document for now.
if (value instanceof Document) return
const type = typeOf(value)
if (type == 'string') return value
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} mark
* @return {Mark}
*/
function mark(value) {
if (value instanceof Mark) return value
const type = typeOf(value)
switch (type) {
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 mark properties argument `value`.
*
* @param {String || Object} value
* @return {Object}
*/
function markProperties(value = {}) {
const ret = {}
const type = typeOf(value)
switch (type) {
case 'string': {
ret.type = value
break
}
case 'object': {
for (const k in value) {
if (k == 'data') {
if (value[k] != null) ret[k] = Data.create(value[k])
} else {
ret[k] = value[k]
}
}
break
}
default: {
throw new Error(`Invalid mark \`properties\` argument! It must be an object or a string. You passed: "${value}".`)
}
}
return ret
}
/**
* Normalize a node properties argument `value`.
*
* @param {String || Object} value
* @return {Object}
*/
function nodeProperties(value = {}) {
const ret = {}
const type = typeOf(value)
switch (type) {
case 'string': {
ret.type = value
break
}
case 'object': {
if (value.isVoid != null) ret.isVoid = !!value.isVoid
for (const k in value) {
if (k == 'data') {
if (value[k] != null) ret[k] = Data.create(value[k])
} else {
ret[k] = value[k]
}
}
break
}
default: {
throw new Error(`Invalid node \`properties\` argument! It must be an object or a string. You passed: "${value}".`)
}
}
return ret
}
/**
* Export.
*
* @type {Object}
*/
export default {
block,
inline,
key,
mark,
markProperties,
nodeProperties,
}