mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-12 02:03:59 +02:00
change to use lodash.uniqueId, add keygen override, add preserveKeys option to Raw serializer
This commit is contained in:
@@ -41,6 +41,7 @@ import Transforms from './transforms'
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import findDOMNode from './utils/find-dom-node'
|
import findDOMNode from './utils/find-dom-node'
|
||||||
|
import { setKeyGenerator } from './utils/generate-key'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Export.
|
* Export.
|
||||||
@@ -66,7 +67,8 @@ export {
|
|||||||
State,
|
State,
|
||||||
Text,
|
Text,
|
||||||
Transforms,
|
Transforms,
|
||||||
findDOMNode
|
findDOMNode,
|
||||||
|
setKeyGenerator
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@@ -87,5 +89,6 @@ export default {
|
|||||||
State,
|
State,
|
||||||
Text,
|
Text,
|
||||||
Transforms,
|
Transforms,
|
||||||
findDOMNode
|
findDOMNode,
|
||||||
|
setKeyGenerator
|
||||||
}
|
}
|
||||||
|
@@ -14,7 +14,7 @@ import Data from './data'
|
|||||||
import Inline from './inline'
|
import Inline from './inline'
|
||||||
import Node from './node'
|
import Node from './node'
|
||||||
import Text from './text'
|
import Text from './text'
|
||||||
import uid from '../utils/uid'
|
import generateKey from '../utils/generate-key'
|
||||||
import { Map, List, Record } from 'immutable'
|
import { Map, List, Record } from 'immutable'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -48,7 +48,7 @@ class Block extends new Record(DEFAULTS) {
|
|||||||
if (properties instanceof Text) return properties
|
if (properties instanceof Text) return properties
|
||||||
if (!properties.type) throw new Error('You must pass a block `type`.')
|
if (!properties.type) throw new Error('You must pass a block `type`.')
|
||||||
|
|
||||||
properties.key = properties.key || uid(4)
|
properties.key = properties.key || generateKey()
|
||||||
properties.data = Data.create(properties.data)
|
properties.data = Data.create(properties.data)
|
||||||
properties.isVoid = !!properties.isVoid
|
properties.isVoid = !!properties.isVoid
|
||||||
properties.nodes = Block.createList(properties.nodes)
|
properties.nodes = Block.createList(properties.nodes)
|
||||||
|
@@ -12,7 +12,7 @@ import './inline'
|
|||||||
|
|
||||||
import Block from './block'
|
import Block from './block'
|
||||||
import Node from './node'
|
import Node from './node'
|
||||||
import uid from '../utils/uid'
|
import generateKey from '../utils/generate-key'
|
||||||
import { OrderedMap, Record } from 'immutable'
|
import { OrderedMap, Record } from 'immutable'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -40,7 +40,7 @@ class Document extends new Record(DEFAULTS) {
|
|||||||
static create(properties = {}) {
|
static create(properties = {}) {
|
||||||
if (properties instanceof Document) return properties
|
if (properties instanceof Document) return properties
|
||||||
|
|
||||||
properties.key = properties.key || uid(4)
|
properties.key = properties.key || generateKey()
|
||||||
properties.nodes = Block.createList(properties.nodes)
|
properties.nodes = Block.createList(properties.nodes)
|
||||||
|
|
||||||
return new Document(properties)
|
return new Document(properties)
|
||||||
|
@@ -14,7 +14,7 @@ import Block from './block'
|
|||||||
import Data from './data'
|
import Data from './data'
|
||||||
import Node from './node'
|
import Node from './node'
|
||||||
import Text from './text'
|
import Text from './text'
|
||||||
import uid from '../utils/uid'
|
import generateKey from '../utils/generate-key'
|
||||||
import { List, Map, Record } from 'immutable'
|
import { List, Map, Record } from 'immutable'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -48,7 +48,7 @@ class Inline extends new Record(DEFAULTS) {
|
|||||||
if (properties instanceof Text) return properties
|
if (properties instanceof Text) return properties
|
||||||
if (!properties.type) throw new Error('You must pass an inline `type`.')
|
if (!properties.type) throw new Error('You must pass an inline `type`.')
|
||||||
|
|
||||||
properties.key = properties.key || uid(4)
|
properties.key = properties.key || generateKey()
|
||||||
properties.data = Data.create(properties.data)
|
properties.data = Data.create(properties.data)
|
||||||
properties.isVoid = !!properties.isVoid
|
properties.isVoid = !!properties.isVoid
|
||||||
properties.nodes = Inline.createList(properties.nodes)
|
properties.nodes = Inline.createList(properties.nodes)
|
||||||
|
@@ -7,7 +7,7 @@ import Normalize from '../utils/normalize'
|
|||||||
import direction from 'direction'
|
import direction from 'direction'
|
||||||
import isInRange from '../utils/is-in-range'
|
import isInRange from '../utils/is-in-range'
|
||||||
import memoize from '../utils/memoize'
|
import memoize from '../utils/memoize'
|
||||||
import uid from '../utils/uid'
|
import generateKey from '../utils/generate-key'
|
||||||
import { List, Set } from 'immutable'
|
import { List, Set } from 'immutable'
|
||||||
|
|
||||||
|
|
||||||
@@ -1225,7 +1225,7 @@ const Node = {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
regenerateKey() {
|
regenerateKey() {
|
||||||
return this.merge({ key: uid() })
|
return this.merge({ key: generateKey() })
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1296,7 +1296,7 @@ const Node = {
|
|||||||
const oneChars = characters.take(i)
|
const oneChars = characters.take(i)
|
||||||
const twoChars = characters.skip(i)
|
const twoChars = characters.skip(i)
|
||||||
one = child.merge({ characters: oneChars })
|
one = child.merge({ characters: oneChars })
|
||||||
two = child.merge({ characters: twoChars, key: uid() })
|
two = child.merge({ characters: twoChars }).regenerateKey()
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
@@ -1309,7 +1309,7 @@ const Node = {
|
|||||||
|
|
||||||
const twoNodes = nodes.skipUntil(n => n.key == one.key).rest().unshift(two)
|
const twoNodes = nodes.skipUntil(n => n.key == one.key).rest().unshift(two)
|
||||||
one = child.merge({ nodes: oneNodes })
|
one = child.merge({ nodes: oneNodes })
|
||||||
two = child.merge({ nodes: twoNodes, key: uid() })
|
two = child.merge({ nodes: twoNodes }).regenerateKey()
|
||||||
}
|
}
|
||||||
|
|
||||||
child = base.getParent(child.key)
|
child = base.getParent(child.key)
|
||||||
@@ -1344,7 +1344,7 @@ const Node = {
|
|||||||
const twoNodes = nodes.skip(count)
|
const twoNodes = nodes.skip(count)
|
||||||
|
|
||||||
const one = node.merge({ nodes: oneNodes })
|
const one = node.merge({ nodes: oneNodes })
|
||||||
const two = node.merge({ nodes: twoNodes, key: uid() })
|
const two = node.merge({ nodes: twoNodes }).regenerateKey()
|
||||||
|
|
||||||
|
|
||||||
const nodeIndex = parent.nodes.indexOf(node)
|
const nodeIndex = parent.nodes.indexOf(node)
|
||||||
|
@@ -3,7 +3,7 @@ import Character from './character'
|
|||||||
import Mark from './mark'
|
import Mark from './mark'
|
||||||
import Range from './range'
|
import Range from './range'
|
||||||
import memoize from '../utils/memoize'
|
import memoize from '../utils/memoize'
|
||||||
import uid from '../utils/uid'
|
import generateKey from '../utils/generate-key'
|
||||||
import { List, Record, Set } from 'immutable'
|
import { List, Record, Set } from 'immutable'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -30,7 +30,7 @@ class Text extends new Record(DEFAULTS) {
|
|||||||
|
|
||||||
static create(properties = {}) {
|
static create(properties = {}) {
|
||||||
if (properties instanceof Text) return properties
|
if (properties instanceof Text) return properties
|
||||||
properties.key = properties.key || uid(4)
|
properties.key = properties.key || generateKey()
|
||||||
properties.characters = Character.createList(properties.characters)
|
properties.characters = Character.createList(properties.characters)
|
||||||
return new Text(properties)
|
return new Text(properties)
|
||||||
}
|
}
|
||||||
@@ -264,7 +264,7 @@ class Text extends new Record(DEFAULTS) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
regenerateKey() {
|
regenerateKey() {
|
||||||
return this.merge({ key: uid() })
|
return this.merge({ key: generateKey() })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -60,6 +60,7 @@ const Raw = {
|
|||||||
|
|
||||||
deserializeDocument(object, options) {
|
deserializeDocument(object, options) {
|
||||||
return Document.create({
|
return Document.create({
|
||||||
|
key: object.key,
|
||||||
nodes: Block.createList(object.nodes.map((node) => {
|
nodes: Block.createList(object.nodes.map((node) => {
|
||||||
return Raw.deserializeNode(node, options)
|
return Raw.deserializeNode(node, options)
|
||||||
}))
|
}))
|
||||||
@@ -210,6 +211,10 @@ const Raw = {
|
|||||||
.map(node => Raw.serializeNode(node, options))
|
.map(node => Raw.serializeNode(node, options))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!options.preserveKeys) {
|
||||||
|
delete object.key
|
||||||
|
}
|
||||||
|
|
||||||
return options.terse
|
return options.terse
|
||||||
? Raw.tersifyBlock(object)
|
? Raw.tersifyBlock(object)
|
||||||
: object
|
: object
|
||||||
@@ -225,12 +230,17 @@ const Raw = {
|
|||||||
|
|
||||||
serializeDocument(document, options = {}) {
|
serializeDocument(document, options = {}) {
|
||||||
const object = {
|
const object = {
|
||||||
|
key: document.key,
|
||||||
kind: document.kind,
|
kind: document.kind,
|
||||||
nodes: document.nodes
|
nodes: document.nodes
|
||||||
.toArray()
|
.toArray()
|
||||||
.map(node => Raw.serializeNode(node, options))
|
.map(node => Raw.serializeNode(node, options))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!options.preserveKeys) {
|
||||||
|
delete object.key
|
||||||
|
}
|
||||||
|
|
||||||
return options.terse
|
return options.terse
|
||||||
? Raw.tersifyDocument(object)
|
? Raw.tersifyDocument(object)
|
||||||
: object
|
: object
|
||||||
@@ -256,6 +266,10 @@ const Raw = {
|
|||||||
.map(node => Raw.serializeNode(node, options))
|
.map(node => Raw.serializeNode(node, options))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!options.preserveKeys) {
|
||||||
|
delete object.key
|
||||||
|
}
|
||||||
|
|
||||||
return options.terse
|
return options.terse
|
||||||
? Raw.tersifyInline(object)
|
? Raw.tersifyInline(object)
|
||||||
: object
|
: object
|
||||||
@@ -360,6 +374,10 @@ const Raw = {
|
|||||||
.map(range => Raw.serializeRange(range, options))
|
.map(range => Raw.serializeRange(range, options))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!options.preserveKeys) {
|
||||||
|
delete object.key
|
||||||
|
}
|
||||||
|
|
||||||
return options.terse
|
return options.terse
|
||||||
? Raw.tersifyText(object)
|
? Raw.tersifyText(object)
|
||||||
: object
|
: object
|
||||||
@@ -376,6 +394,7 @@ const Raw = {
|
|||||||
const ret = {}
|
const ret = {}
|
||||||
ret.kind = object.kind
|
ret.kind = object.kind
|
||||||
ret.type = object.type
|
ret.type = object.type
|
||||||
|
if (object.key) ret.key = object.key
|
||||||
if (!object.isVoid) ret.nodes = object.nodes
|
if (!object.isVoid) ret.nodes = object.nodes
|
||||||
if (object.isVoid) ret.isVoid = object.isVoid
|
if (object.isVoid) ret.isVoid = object.isVoid
|
||||||
if (!isEmpty(object.data)) ret.data = object.data
|
if (!isEmpty(object.data)) ret.data = object.data
|
||||||
@@ -390,9 +409,10 @@ const Raw = {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
tersifyDocument(object) {
|
tersifyDocument(object) {
|
||||||
return {
|
const ret = {}
|
||||||
nodes: object.nodes
|
ret.nodes = object.nodes
|
||||||
}
|
if (object.key) ret.key = object.key
|
||||||
|
return ret
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -406,6 +426,7 @@ const Raw = {
|
|||||||
const ret = {}
|
const ret = {}
|
||||||
ret.kind = object.kind
|
ret.kind = object.kind
|
||||||
ret.type = object.type
|
ret.type = object.type
|
||||||
|
if (object.key) ret.key = object.key
|
||||||
if (!object.isVoid) ret.nodes = object.nodes
|
if (!object.isVoid) ret.nodes = object.nodes
|
||||||
if (object.isVoid) ret.isVoid = object.isVoid
|
if (object.isVoid) ret.isVoid = object.isVoid
|
||||||
if (!isEmpty(object.data)) ret.data = object.data
|
if (!isEmpty(object.data)) ret.data = object.data
|
||||||
@@ -459,17 +480,17 @@ const Raw = {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
tersifyText(object) {
|
tersifyText(object) {
|
||||||
|
const ret = {}
|
||||||
|
ret.kind = object.kind
|
||||||
|
if (object.key) ret.key = object.key
|
||||||
|
|
||||||
if (object.ranges.length == 1 && object.ranges[0].marks == null) {
|
if (object.ranges.length == 1 && object.ranges[0].marks == null) {
|
||||||
return {
|
ret.text = object.ranges[0].text
|
||||||
kind: object.kind,
|
} else {
|
||||||
text: object.ranges[0].text
|
ret.ranges = object.ranges
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return ret
|
||||||
kind: object.kind,
|
|
||||||
ranges: object.ranges
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -552,6 +573,7 @@ const Raw = {
|
|||||||
return {
|
return {
|
||||||
kind: 'state',
|
kind: 'state',
|
||||||
document: {
|
document: {
|
||||||
|
key: object.key,
|
||||||
kind: 'document',
|
kind: 'document',
|
||||||
nodes: object.nodes
|
nodes: object.nodes
|
||||||
}
|
}
|
||||||
|
40
src/utils/generate-key.js
Normal file
40
src/utils/generate-key.js
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
|
||||||
|
import uniqueId from 'lodash/uniqueId'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default the generator function to Lodash's implementation, which just returns
|
||||||
|
* incrementing numbers as strings.
|
||||||
|
*
|
||||||
|
* @type {Function}
|
||||||
|
*/
|
||||||
|
|
||||||
|
let generate = uniqueId
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a key.
|
||||||
|
*
|
||||||
|
* @return {String}
|
||||||
|
*/
|
||||||
|
|
||||||
|
function generateKey() {
|
||||||
|
return generate()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a different unique ID generating `function`.
|
||||||
|
*
|
||||||
|
* @param {Function} func
|
||||||
|
*/
|
||||||
|
|
||||||
|
function setKeyGenerator(func) {
|
||||||
|
generate = func
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Export.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export {
|
||||||
|
generateKey as default,
|
||||||
|
setKeyGenerator
|
||||||
|
}
|
@@ -1,18 +0,0 @@
|
|||||||
|
|
||||||
import generate from 'uid'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a unique identifier.
|
|
||||||
*
|
|
||||||
* @return {String} uid
|
|
||||||
*/
|
|
||||||
|
|
||||||
function uid() {
|
|
||||||
return generate(10)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Export.
|
|
||||||
*/
|
|
||||||
|
|
||||||
export default uid
|
|
@@ -7,7 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
function stripDynamic(json) {
|
function stripDynamic(json) {
|
||||||
const { key, cache, decorations, ...props } = json
|
const { key, ...props } = json
|
||||||
|
|
||||||
if (props.nodes) {
|
if (props.nodes) {
|
||||||
props.nodes = props.nodes.map(stripDynamic)
|
props.nodes = props.nodes.map(stripDynamic)
|
||||||
|
@@ -60,9 +60,6 @@ describe('serializers', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('json', () => {
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('plain', () => {
|
describe('plain', () => {
|
||||||
describe('deserialize()', () => {
|
describe('deserialize()', () => {
|
||||||
const dir = resolve(__dirname, './fixtures/plain/deserialize')
|
const dir = resolve(__dirname, './fixtures/plain/deserialize')
|
||||||
@@ -165,5 +162,19 @@ describe('serializers', () => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('serialize({ preserveKeys: true })', () => {
|
||||||
|
it('should omit keys by default', () => {
|
||||||
|
const state = Plain.deserialize('string')
|
||||||
|
const serialized = Raw.serialize(state)
|
||||||
|
assert(typeof serialized.document.key === 'undefined')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should preserve keys', () => {
|
||||||
|
const state = Plain.deserialize('string')
|
||||||
|
const serialized = Raw.serialize(state, { preserveKeys: true })
|
||||||
|
assert(typeof serialized.document.key === 'string')
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
Reference in New Issue
Block a user