mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-31 10:51:44 +02:00
working on moving components into the schema
This commit is contained in:
@@ -93,8 +93,8 @@ class Editor extends React.Component {
|
|||||||
super(props)
|
super(props)
|
||||||
this.tmp = {}
|
this.tmp = {}
|
||||||
this.state = {}
|
this.state = {}
|
||||||
this.state.schema = Schema.create(props.schema)
|
|
||||||
this.state.plugins = this.resolvePlugins(props)
|
this.state.plugins = this.resolvePlugins(props)
|
||||||
|
this.state.schema = this.resolveSchema(this.state.plugins)
|
||||||
this.state.state = this.onBeforeChange(props.state)
|
this.state.state = this.onBeforeChange(props.state)
|
||||||
|
|
||||||
// Mix in the event handlers.
|
// Mix in the event handlers.
|
||||||
@@ -112,16 +112,10 @@ class Editor extends React.Component {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
componentWillReceiveProps = (props) => {
|
componentWillReceiveProps = (props) => {
|
||||||
if (props.schema != this.props.schema) {
|
|
||||||
this.setState({
|
|
||||||
schema: Schema.create(props.schema)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
if (props.plugins != this.props.plugins) {
|
if (props.plugins != this.props.plugins) {
|
||||||
this.setState({
|
const plugins = this.resolvePlugins(props)
|
||||||
plugins: this.resolvePlugins(props)
|
const schema = this.resolveSchema(plugins)
|
||||||
})
|
this.setState({ plugins, schema })
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
@@ -269,6 +263,7 @@ class Editor extends React.Component {
|
|||||||
renderDecorations={this.renderDecorations}
|
renderDecorations={this.renderDecorations}
|
||||||
renderMark={this.renderMark}
|
renderMark={this.renderMark}
|
||||||
renderNode={this.renderNode}
|
renderNode={this.renderNode}
|
||||||
|
schema={this.state.schema}
|
||||||
spellCheck={this.props.spellCheck}
|
spellCheck={this.props.spellCheck}
|
||||||
state={this.state.state}
|
state={this.state.state}
|
||||||
style={this.props.style}
|
style={this.props.style}
|
||||||
@@ -361,6 +356,27 @@ class Editor extends React.Component {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolve the editor's schema from a set of `plugins`.
|
||||||
|
*
|
||||||
|
* @param {Array} plugins
|
||||||
|
* @return {Schema}
|
||||||
|
*/
|
||||||
|
|
||||||
|
resolveSchema = (plugins) => {
|
||||||
|
let rules = []
|
||||||
|
|
||||||
|
for (const plugin of plugins) {
|
||||||
|
if (!plugin.schema) continue
|
||||||
|
debugger
|
||||||
|
const schema = Schema.create(plugin.schema)
|
||||||
|
rules = rules.concat(schema.rules)
|
||||||
|
}
|
||||||
|
|
||||||
|
const schema = Schema.create({ rules })
|
||||||
|
return schema
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -53,6 +53,17 @@ class Mark extends new Record(DEFAULTS) {
|
|||||||
return 'mark'
|
return 'mark'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the component for the node from a `schema`.
|
||||||
|
*
|
||||||
|
* @param {Schema} schema
|
||||||
|
* @return {Component || Void}
|
||||||
|
*/
|
||||||
|
|
||||||
|
getComponent(schema) {
|
||||||
|
return schema.__getComponent(this)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -338,6 +338,17 @@ const Node = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the component for the node from a `schema`.
|
||||||
|
*
|
||||||
|
* @param {Schema} schema
|
||||||
|
* @return {Component || Void}
|
||||||
|
*/
|
||||||
|
|
||||||
|
getComponent(schema) {
|
||||||
|
return schema.__getComponent(this)
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a descendant node by `key`.
|
* Get a descendant node by `key`.
|
||||||
*
|
*
|
||||||
@@ -1071,10 +1082,74 @@ const Node = {
|
|||||||
updateDescendant(node) {
|
updateDescendant(node) {
|
||||||
this.assertDescendant(node)
|
this.assertDescendant(node)
|
||||||
return this.mapDescendants(d => d.key == node.key ? node : d)
|
return this.mapDescendants(d => d.key == node.key ? node : d)
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate the node against a `schema`.
|
||||||
|
*
|
||||||
|
* @param {Schema} schema
|
||||||
|
* @return {Object || Void}
|
||||||
|
*/
|
||||||
|
|
||||||
|
validate(schema) {
|
||||||
|
return schema.__validate(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Memoize read methods.
|
||||||
|
*/
|
||||||
|
|
||||||
|
memoize(Node, [
|
||||||
|
'assertChild',
|
||||||
|
'assertDescendant',
|
||||||
|
'findDescendant',
|
||||||
|
'filterDescendants',
|
||||||
|
'getBlocks',
|
||||||
|
'getBlocksAtRange',
|
||||||
|
'getCharactersAtRange',
|
||||||
|
'getChild',
|
||||||
|
'getChildrenAfter',
|
||||||
|
'getChildrenAfterIncluding',
|
||||||
|
'getChildrenBefore',
|
||||||
|
'getChildrenBeforeIncluding',
|
||||||
|
'getChildrenBetween',
|
||||||
|
'getChildrenBetweenIncluding',
|
||||||
|
'getClosest',
|
||||||
|
'getClosestBlock',
|
||||||
|
'getClosestInline',
|
||||||
|
'getComponent',
|
||||||
|
'getDescendant',
|
||||||
|
'getDepth',
|
||||||
|
'getFragmentAtRange',
|
||||||
|
'getFurthest',
|
||||||
|
'getFurthestBlock',
|
||||||
|
'getFurthestInline',
|
||||||
|
'getHighestChild',
|
||||||
|
'getHighestOnlyChildParent',
|
||||||
|
'getInlinesAtRange',
|
||||||
|
'getMarksAtRange',
|
||||||
|
'getNextBlock',
|
||||||
|
'getNextSibling',
|
||||||
|
'getNextText',
|
||||||
|
'getOffset',
|
||||||
|
'getOffsetAtRange',
|
||||||
|
'getParent',
|
||||||
|
'getPreviousSibling',
|
||||||
|
'getPreviousText',
|
||||||
|
'getPreviousBlock',
|
||||||
|
'getTextAtOffset',
|
||||||
|
'getTextDirection',
|
||||||
|
'getTexts',
|
||||||
|
'getTextsAtRange',
|
||||||
|
'hasChild',
|
||||||
|
'hasDescendant',
|
||||||
|
'hasVoidParent',
|
||||||
|
'isInlineSplitAtRange',
|
||||||
|
'validate'
|
||||||
|
])
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Normalize a `key`, from a key string or a node.
|
* Normalize a `key`, from a key string or a node.
|
||||||
*
|
*
|
||||||
@@ -1119,57 +1194,6 @@ for (const key in Transforms) {
|
|||||||
Node[key] = Transforms[key]
|
Node[key] = Transforms[key]
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Memoize read methods.
|
|
||||||
*/
|
|
||||||
|
|
||||||
memoize(Node, [
|
|
||||||
'assertChild',
|
|
||||||
'assertDescendant',
|
|
||||||
'findDescendant',
|
|
||||||
'filterDescendants',
|
|
||||||
'getBlocks',
|
|
||||||
'getBlocksAtRange',
|
|
||||||
'getCharactersAtRange',
|
|
||||||
'getChildrenAfter',
|
|
||||||
'getChildrenAfterIncluding',
|
|
||||||
'getChildrenBefore',
|
|
||||||
'getChildrenBeforeIncluding',
|
|
||||||
'getChildrenBetween',
|
|
||||||
'getChildrenBetweenIncluding',
|
|
||||||
'getClosest',
|
|
||||||
'getClosestBlock',
|
|
||||||
'getClosestInline',
|
|
||||||
'getChild',
|
|
||||||
'getDescendant',
|
|
||||||
'getDepth',
|
|
||||||
'getFragmentAtRange',
|
|
||||||
'getFurthest',
|
|
||||||
'getFurthestBlock',
|
|
||||||
'getFurthestInline',
|
|
||||||
'getHighestChild',
|
|
||||||
'getHighestOnlyChildParent',
|
|
||||||
'getInlinesAtRange',
|
|
||||||
'getMarksAtRange',
|
|
||||||
'getNextBlock',
|
|
||||||
'getNextSibling',
|
|
||||||
'getNextText',
|
|
||||||
'getOffset',
|
|
||||||
'getOffsetAtRange',
|
|
||||||
'getParent',
|
|
||||||
'getPreviousSibling',
|
|
||||||
'getPreviousText',
|
|
||||||
'getPreviousBlock',
|
|
||||||
'getTextAtOffset',
|
|
||||||
'getTextDirection',
|
|
||||||
'getTexts',
|
|
||||||
'getTextsAtRange',
|
|
||||||
'hasChild',
|
|
||||||
'hasDescendant',
|
|
||||||
'hasVoidParent',
|
|
||||||
'isInlineSplitAtRange'
|
|
||||||
])
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Export.
|
* Export.
|
||||||
*/
|
*/
|
||||||
|
@@ -65,7 +65,7 @@ const CHECKS = {
|
|||||||
const { nodes } = object
|
const { nodes } = object
|
||||||
if (!nodes) return
|
if (!nodes) return
|
||||||
const invalids = nodes.filterNot((child) => {
|
const invalids = nodes.filterNot((child) => {
|
||||||
return value.some(fail => !fail(child))
|
return value.some(match => match(child))
|
||||||
})
|
})
|
||||||
|
|
||||||
if (invalids.size) return invalids
|
if (invalids.size) return invalids
|
||||||
@@ -75,7 +75,7 @@ const CHECKS = {
|
|||||||
const { nodes } = object
|
const { nodes } = object
|
||||||
if (!nodes) return
|
if (!nodes) return
|
||||||
const invalids = nodes.filterNot((child) => {
|
const invalids = nodes.filterNot((child) => {
|
||||||
return value.every(fail => fail(child))
|
return value.every(match => !match(child))
|
||||||
})
|
})
|
||||||
|
|
||||||
if (invalids.size) return invalids
|
if (invalids.size) return invalids
|
||||||
@@ -86,10 +86,10 @@ const CHECKS = {
|
|||||||
if (!nodes) return
|
if (!nodes) return
|
||||||
if (nodes.size != value.length) return nodes
|
if (nodes.size != value.length) return nodes
|
||||||
|
|
||||||
const invalids = nodes.filter((child, i) => {
|
const invalids = nodes.filterNot((child, i) => {
|
||||||
const fail = value[i]
|
const match = value[i]
|
||||||
if (!fail) return true
|
if (!match) return false
|
||||||
return fail(child)
|
return match(child)
|
||||||
})
|
})
|
||||||
|
|
||||||
if (invalids.size) return invalids
|
if (invalids.size) return invalids
|
||||||
@@ -138,62 +138,47 @@ class Schema extends new Record(DEFAULTS) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transform a `state` to abide by the schema.
|
* Return the component for an `object`.
|
||||||
*
|
*
|
||||||
* @param {State} state
|
* This method is private, because it should always be called on one of the
|
||||||
* @return {State}
|
* often-changing immutable objects instead, since it will be memoized for
|
||||||
|
* much better performance.
|
||||||
|
*
|
||||||
|
* @param {Mixed} object
|
||||||
|
* @return {Component || Void}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
transform(state) {
|
__getComponent(object) {
|
||||||
const { document } = state
|
const match = this.rules.find(rule => rule.match(object) && rule.component)
|
||||||
let transform = state.transform()
|
if (!match) return
|
||||||
let failure
|
return match.component
|
||||||
|
|
||||||
document.filterDescendantsDeep((node) => {
|
|
||||||
if (failure = this.validateNode(node)) {
|
|
||||||
const { reason, rule } = failure
|
|
||||||
transform = rule.transform(transform, node, reason)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
if (failure = this.validateNode(document)) {
|
|
||||||
const { reason, rule } = failure
|
|
||||||
transform = rule.transform(transform, document, reason)
|
|
||||||
}
|
|
||||||
|
|
||||||
const next = transform.apply({ snapshot: false })
|
|
||||||
return next
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate a `state` against the schema.
|
* Validate an `object` against the schema, returning the failing rule and
|
||||||
|
* reason if the object is invalid, or void if it's valid.
|
||||||
*
|
*
|
||||||
* @param {State} state
|
* This method is private, because it should always be called on one of the
|
||||||
* @return {State}
|
* often-changing immutable objects instead, since it will be memoized for
|
||||||
*/
|
* much better performance.
|
||||||
|
|
||||||
validate(state) {
|
|
||||||
return !!state.document.findDescendant(node => this.validateNode(node))
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validate a `node` against the schema, returning the rule that was not met
|
|
||||||
* if the node is invalid, or null if the rule was valid.
|
|
||||||
*
|
*
|
||||||
* @param {Node} node
|
* @param {Mixed} object
|
||||||
* @return {Object || Void}
|
* @return {Object || Void}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
validateNode(node) {
|
__validate(object) {
|
||||||
let reason
|
let reason
|
||||||
let match = this.rules
|
|
||||||
.filter(rule => !rule.match(node))
|
|
||||||
.find((rule) => {
|
|
||||||
reason = rule.validate(node)
|
|
||||||
if (reason) return true
|
|
||||||
})
|
|
||||||
|
|
||||||
if (!match) return
|
const match = this.rules.find((rule) => {
|
||||||
|
if (!rule.match(object)) return
|
||||||
|
debugger
|
||||||
|
if (!rule.validate) return
|
||||||
|
debugger
|
||||||
|
reason = rule.validate(object)
|
||||||
|
return reason
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!reason) return
|
||||||
|
|
||||||
return {
|
return {
|
||||||
rule: match,
|
rule: match,
|
||||||
@@ -203,16 +188,6 @@ class Schema extends new Record(DEFAULTS) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Memoize read methods.
|
|
||||||
*/
|
|
||||||
|
|
||||||
memoize(Schema.prototype, [
|
|
||||||
'transform',
|
|
||||||
'validate',
|
|
||||||
'validateNode',
|
|
||||||
])
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Normalize the `properties` of a schema.
|
* Normalize the `properties` of a schema.
|
||||||
*
|
*
|
||||||
@@ -267,9 +242,7 @@ function normalizeProperties(properties) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
rules: rules
|
rules: rules.map(normalizeRule)
|
||||||
.concat(RULES)
|
|
||||||
.map(normalizeRule)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -317,10 +290,7 @@ function normalizeValidate(validate) {
|
|||||||
switch (typeOf(validate)) {
|
switch (typeOf(validate)) {
|
||||||
case 'function': return validate
|
case 'function': return validate
|
||||||
case 'boolean': return () => validate
|
case 'boolean': return () => validate
|
||||||
case 'object': return normalizeSpec(validate)
|
case 'object': return normalizeSpec(validate, true)
|
||||||
default: {
|
|
||||||
throw new Error(`Invalid \`validate\` spec: "${validate}".`)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -334,9 +304,6 @@ function normalizeValidate(validate) {
|
|||||||
function normalizeTransform(transform) {
|
function normalizeTransform(transform) {
|
||||||
switch (typeOf(transform)) {
|
switch (typeOf(transform)) {
|
||||||
case 'function': return transform
|
case 'function': return transform
|
||||||
default: {
|
|
||||||
throw new Error(`Invalid \`transform\` spec: "${transform}".`)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -344,10 +311,11 @@ function normalizeTransform(transform) {
|
|||||||
* Normalize a `spec` object.
|
* Normalize a `spec` object.
|
||||||
*
|
*
|
||||||
* @param {Object} obj
|
* @param {Object} obj
|
||||||
|
* @param {Boolean} giveReason
|
||||||
* @return {Boolean}
|
* @return {Boolean}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function normalizeSpec(obj) {
|
function normalizeSpec(obj, giveReason) {
|
||||||
const spec = { ...obj }
|
const spec = { ...obj }
|
||||||
if (spec.exactlyOf) spec.exactlyOf = spec.exactlyOf.map(normalizeSpec)
|
if (spec.exactlyOf) spec.exactlyOf = spec.exactlyOf.map(normalizeSpec)
|
||||||
if (spec.anyOf) spec.anyOf = spec.anyOf.map(normalizeSpec)
|
if (spec.anyOf) spec.anyOf = spec.anyOf.map(normalizeSpec)
|
||||||
@@ -356,11 +324,18 @@ function normalizeSpec(obj) {
|
|||||||
return (node) => {
|
return (node) => {
|
||||||
for (const key in CHECKS) {
|
for (const key in CHECKS) {
|
||||||
const value = spec[key]
|
const value = spec[key]
|
||||||
|
debugger
|
||||||
|
|
||||||
if (value == null) continue
|
if (value == null) continue
|
||||||
|
|
||||||
|
debugger
|
||||||
const fail = CHECKS[key]
|
const fail = CHECKS[key]
|
||||||
const failure = fail(node, value)
|
const failure = fail(node, value)
|
||||||
|
|
||||||
|
if (!giveReason) {
|
||||||
|
return !failure
|
||||||
|
}
|
||||||
|
|
||||||
if (failure != undefined) {
|
if (failure != undefined) {
|
||||||
return {
|
return {
|
||||||
type: key,
|
type: key,
|
||||||
|
@@ -59,7 +59,7 @@ class State extends new Record(DEFAULTS) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is there undoable events?
|
* Are there undoable events?
|
||||||
*
|
*
|
||||||
* @return {Boolean} hasUndos
|
* @return {Boolean} hasUndos
|
||||||
*/
|
*/
|
||||||
@@ -69,7 +69,7 @@ class State extends new Record(DEFAULTS) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is there redoable events?
|
* Are there redoable events?
|
||||||
*
|
*
|
||||||
* @return {Boolean} hasRedos
|
* @return {Boolean} hasRedos
|
||||||
*/
|
*/
|
||||||
@@ -358,6 +358,38 @@ class State extends new Record(DEFAULTS) {
|
|||||||
return this.document.getTextsAtRange(this.selection)
|
return this.document.getTextsAtRange(this.selection)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalize a state against a `schema`.
|
||||||
|
*
|
||||||
|
* @param {Schema} schema
|
||||||
|
* @return {State}
|
||||||
|
*/
|
||||||
|
|
||||||
|
normalize(schema) {
|
||||||
|
const state = this
|
||||||
|
const { document, selection } = this
|
||||||
|
let transform = this.transform()
|
||||||
|
let failure
|
||||||
|
|
||||||
|
document.filterDescendantsDeep((node) => {
|
||||||
|
if (failure = node.validate(schema)) {
|
||||||
|
const { reason, rule } = failure
|
||||||
|
debugger
|
||||||
|
transform = rule.transform(transform, node, reason)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (failure = document.validate(schema)) {
|
||||||
|
const { reason, rule } = failure
|
||||||
|
debugger
|
||||||
|
transform = rule.transform(transform, document, reason)
|
||||||
|
}
|
||||||
|
|
||||||
|
return transform.steps.size
|
||||||
|
? transform.apply({ snapshot: false })
|
||||||
|
: state
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a new `Transform` with the current state as a starting point.
|
* Return a new `Transform` with the current state as a starting point.
|
||||||
*
|
*
|
||||||
|
@@ -228,6 +228,17 @@ class Text extends new Record(DEFAULTS) {
|
|||||||
return this.merge({ characters })
|
return this.merge({ characters })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate the node against a `schema`.
|
||||||
|
*
|
||||||
|
* @param {Schema} schema
|
||||||
|
* @return {Object || Void}
|
||||||
|
*/
|
||||||
|
|
||||||
|
validate(schema) {
|
||||||
|
return schema.__validate(this)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -238,7 +249,8 @@ memoize(Text.prototype, [
|
|||||||
'getDecoratedCharacters',
|
'getDecoratedCharacters',
|
||||||
'getDecoratedRanges',
|
'getDecoratedRanges',
|
||||||
'getRanges',
|
'getRanges',
|
||||||
'getRangesForCharacters'
|
'getRangesForCharacters',
|
||||||
|
'validate'
|
||||||
])
|
])
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -73,66 +73,66 @@ function Plugin(options = {}) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// /**
|
/**
|
||||||
// * The default schema.
|
* The default schema.
|
||||||
// *
|
*
|
||||||
// * @type {Object}
|
* @type {Object}
|
||||||
// */
|
*/
|
||||||
|
|
||||||
// const DEFAULT_SCHEMA = {
|
const DEFAULT_SCHEMA = {
|
||||||
// rules: [
|
rules: [
|
||||||
// {
|
{
|
||||||
// match: {
|
match: {
|
||||||
// kind: 'document'
|
kind: 'document'
|
||||||
// },
|
},
|
||||||
// validate: {
|
validate: {
|
||||||
// anyOf: [
|
anyOf: [
|
||||||
// { kind: 'block' }
|
{ kind: 'block' }
|
||||||
// ]
|
]
|
||||||
// },
|
},
|
||||||
// transform: (transform, match, reason) => {
|
transform: (transform, match, reason) => {
|
||||||
// return reason.value.reduce((tr, node) => {
|
return reason.value.reduce((tr, node) => {
|
||||||
// return tr.removeNodeByKey(node.key)
|
return tr.removeNodeByKey(node.key)
|
||||||
// }, transform)
|
}, transform)
|
||||||
// }
|
}
|
||||||
// },
|
},
|
||||||
// {
|
{
|
||||||
// match: {
|
match: {
|
||||||
// kind: 'block'
|
kind: 'block'
|
||||||
// },
|
},
|
||||||
// validate: {
|
validate: {
|
||||||
// anyOf: [
|
anyOf: [
|
||||||
// { kind: 'block' },
|
{ kind: 'block' },
|
||||||
// { kind: 'inline' },
|
{ kind: 'inline' },
|
||||||
// { kind: 'text' },
|
{ kind: 'text' },
|
||||||
// ]
|
]
|
||||||
// },
|
},
|
||||||
// transform: (transform, match, reason) => {
|
transform: (transform, match, reason) => {
|
||||||
// return reason.value.reduce((tr, node) => {
|
return reason.value.reduce((tr, node) => {
|
||||||
// return tr.removeNodeByKey(node.key)
|
return tr.removeNodeByKey(node.key)
|
||||||
// }, transform)
|
}, transform)
|
||||||
// },
|
},
|
||||||
// component: DEFAULT_BLOCK
|
component: DEFAULT_BLOCK
|
||||||
// },
|
},
|
||||||
// {
|
{
|
||||||
// match: {
|
match: {
|
||||||
// kind: 'inline'
|
kind: 'inline'
|
||||||
// },
|
},
|
||||||
// validate: {
|
validate: {
|
||||||
// anyOf: [
|
anyOf: [
|
||||||
// { kind: 'inline' },
|
{ kind: 'inline' },
|
||||||
// { kind: 'text' },
|
{ kind: 'text' },
|
||||||
// ]
|
]
|
||||||
// },
|
},
|
||||||
// transform: (transform, match, reason) => {
|
transform: (transform, match, reason) => {
|
||||||
// return reason.value.reduce((tr, node) => {
|
return reason.value.reduce((tr, node) => {
|
||||||
// return tr.removeNodeByKey(node.key)
|
return tr.removeNodeByKey(node.key)
|
||||||
// }, transform)
|
}, transform)
|
||||||
// },
|
},
|
||||||
// component: DEFAULT_INLINE
|
component: DEFAULT_INLINE
|
||||||
// },
|
},
|
||||||
// ]
|
]
|
||||||
// }
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* On before change, enforce the editor's schema.
|
* On before change, enforce the editor's schema.
|
||||||
@@ -144,9 +144,8 @@ function Plugin(options = {}) {
|
|||||||
|
|
||||||
function onBeforeChange(state, editor) {
|
function onBeforeChange(state, editor) {
|
||||||
if (state.isNative) return state
|
if (state.isNative) return state
|
||||||
return editor
|
const schema = editor.getSchema()
|
||||||
.getSchema()
|
return state.normalize(schema)
|
||||||
.transform(state)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -700,7 +699,8 @@ function Plugin(options = {}) {
|
|||||||
onKeyDown,
|
onKeyDown,
|
||||||
onPaste,
|
onPaste,
|
||||||
onSelect,
|
onSelect,
|
||||||
renderNode
|
renderNode,
|
||||||
|
schema: DEFAULT_SCHEMA
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -84,8 +84,8 @@
|
|||||||
"open": "open http://localhost:8080/dev.html",
|
"open": "open http://localhost:8080/dev.html",
|
||||||
"prepublish": "npm run dist",
|
"prepublish": "npm run dist",
|
||||||
"start": "http-server ./examples",
|
"start": "http-server ./examples",
|
||||||
"test": "npm-run-all lint dist:npm test:server",
|
"test": "npm-run-all lint dist:npm tests",
|
||||||
"test:server": "mocha --compilers js:babel-core/register --reporter spec ./test/server.js",
|
"tests": "mocha --compilers js:babel-core/register --reporter spec ./test/server.js",
|
||||||
"watch": "npm-run-all --parallel --print-label watch:dist watch:examples start",
|
"watch": "npm-run-all --parallel --print-label watch:dist watch:examples start",
|
||||||
"watch:dist": "babel --watch --out-dir ./dist ./lib",
|
"watch:dist": "babel --watch --out-dir ./dist ./lib",
|
||||||
"watch:examples": "watchify --debug --transform babelify ./examples/index.js -o ./examples/build.dev.js"
|
"watch:examples": "watchify --debug --transform babelify ./examples/index.js -o ./examples/build.dev.js"
|
||||||
|
@@ -1,2 +0,0 @@
|
|||||||
|
|
||||||
export default {}
|
|
@@ -1,8 +0,0 @@
|
|||||||
|
|
||||||
nodes:
|
|
||||||
- kind: block
|
|
||||||
type: default
|
|
||||||
isVoid: true
|
|
||||||
nodes:
|
|
||||||
- kind: text
|
|
||||||
text: one
|
|
@@ -1,5 +0,0 @@
|
|||||||
|
|
||||||
nodes:
|
|
||||||
- kind: block
|
|
||||||
type: default
|
|
||||||
isVoid: true
|
|
@@ -1,2 +0,0 @@
|
|||||||
|
|
||||||
export default {}
|
|
@@ -1,11 +0,0 @@
|
|||||||
|
|
||||||
nodes:
|
|
||||||
- kind: block
|
|
||||||
type: default
|
|
||||||
nodes:
|
|
||||||
- kind: inline
|
|
||||||
type: default
|
|
||||||
isVoid: true
|
|
||||||
nodes:
|
|
||||||
- kind: text
|
|
||||||
text: one
|
|
@@ -1,8 +0,0 @@
|
|||||||
|
|
||||||
nodes:
|
|
||||||
- kind: block
|
|
||||||
type: default
|
|
||||||
nodes:
|
|
||||||
- kind: inline
|
|
||||||
type: default
|
|
||||||
isVoid: true
|
|
@@ -1,8 +1,9 @@
|
|||||||
|
|
||||||
|
import React from 'react'
|
||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
import strip from '../helpers/strip-dynamic'
|
import strip from '../helpers/strip-dynamic'
|
||||||
import readMetadata from 'read-metadata'
|
import readMetadata from 'read-metadata'
|
||||||
import { Raw, Schema } from '../..'
|
import { Raw, Editor, Schema } from '../..'
|
||||||
import { strictEqual } from '../helpers/assert-json'
|
import { strictEqual } from '../helpers/assert-json'
|
||||||
import { resolve } from 'path'
|
import { resolve } from 'path'
|
||||||
|
|
||||||
@@ -22,8 +23,8 @@ describe('schema', () => {
|
|||||||
const expected = readMetadata.sync(resolve(dir, 'output.yaml'))
|
const expected = readMetadata.sync(resolve(dir, 'output.yaml'))
|
||||||
const schema = Schema.create(require(dir))
|
const schema = Schema.create(require(dir))
|
||||||
|
|
||||||
let state = Raw.deserialize(input, { terse: true })
|
const state = Raw.deserialize(input, { terse: true })
|
||||||
state = schema.transform(state)
|
const editor = <Editor state={state} schema={schema} />
|
||||||
const output = Raw.serialize(state, { terse: true })
|
const output = Raw.serialize(state, { terse: true })
|
||||||
strictEqual(strip(output), strip(expected))
|
strictEqual(strip(output), strip(expected))
|
||||||
})
|
})
|
||||||
|
Reference in New Issue
Block a user