mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-07-31 20:40:19 +02:00
fix parent-based schema rules with multiple rules present
This commit is contained in:
@@ -7,6 +7,7 @@ import {
|
||||
MarkEntry,
|
||||
AncestorEntry,
|
||||
Descendant,
|
||||
DescendantEntry,
|
||||
} from 'slate'
|
||||
|
||||
import { MarkError, NodeError } from './errors'
|
||||
@@ -53,10 +54,10 @@ export const checkNode = (
|
||||
rule: NodeRule,
|
||||
rules: NodeRule[]
|
||||
): NodeError | undefined => {
|
||||
const { validate: v } = rule
|
||||
const { match: m, validate: v } = rule
|
||||
const [node, path] = entry
|
||||
|
||||
if (Editor.isMatch(editor, entry, rule.match)) {
|
||||
if (Editor.isMatch(editor, entry, m)) {
|
||||
if ('properties' in v) {
|
||||
for (const k in v.properties) {
|
||||
const p = v.properties[k]
|
||||
@@ -117,7 +118,7 @@ export const checkAncestor = (
|
||||
editor: Editor,
|
||||
entry: AncestorEntry,
|
||||
rule: NodeRule,
|
||||
ancestorRules: NodeRule[]
|
||||
parentRules: NodeRule[]
|
||||
): [NodeRule, NodeError] | undefined => {
|
||||
const { validate: v } = rule
|
||||
const [parent, parentPath] = entry
|
||||
@@ -140,8 +141,8 @@ export const checkAncestor = (
|
||||
if (child && !processed.has(child)) {
|
||||
processed.add(child)
|
||||
|
||||
for (const r of ancestorRules) {
|
||||
const e = checkParent(editor, entry, index, rule, r)
|
||||
for (const r of parentRules) {
|
||||
const e = checkParent(editor, entry, [child, childPath], r)
|
||||
|
||||
if (e) {
|
||||
return [r, e]
|
||||
@@ -260,20 +261,19 @@ export const checkAncestor = (
|
||||
export const checkParent = (
|
||||
editor: Editor,
|
||||
entry: AncestorEntry,
|
||||
index: number,
|
||||
rule: NodeRule,
|
||||
childRule: NodeRule
|
||||
childEntry: DescendantEntry,
|
||||
rule: NodeRule
|
||||
): NodeError | undefined => {
|
||||
const { validate: cv } = childRule
|
||||
const { match: m, validate: v } = rule
|
||||
const [parent, parentPath] = entry
|
||||
const child = Node.child(parent, index)
|
||||
const childPath = parentPath.concat(index)
|
||||
const [child, childPath] = childEntry
|
||||
const index = childPath[childPath.length - 1]
|
||||
|
||||
if (
|
||||
'parent' in cv &&
|
||||
cv.parent != null &&
|
||||
Editor.isMatch(editor, [child, childPath], rule.match) &&
|
||||
!Editor.isMatch(editor, [parent, parentPath], cv.parent)
|
||||
'parent' in v &&
|
||||
v.parent != null &&
|
||||
Editor.isMatch(editor, [child, childPath], m) &&
|
||||
!Editor.isMatch(editor, [parent, parentPath], v.parent)
|
||||
) {
|
||||
return {
|
||||
code: 'parent_invalid',
|
||||
@@ -284,15 +284,15 @@ export const checkParent = (
|
||||
}
|
||||
|
||||
if (
|
||||
'previous' in cv &&
|
||||
cv.previous != null &&
|
||||
'previous' in v &&
|
||||
v.previous != null &&
|
||||
index > 0 &&
|
||||
Editor.isMatch(editor, [child, childPath], rule.match)
|
||||
Editor.isMatch(editor, [child, childPath], m)
|
||||
) {
|
||||
const prevChild = Node.child(parent, index - 1)
|
||||
const prevPath = parentPath.concat(index - 1)
|
||||
|
||||
if (!Editor.isMatch(editor, [prevChild, prevPath], cv.previous)) {
|
||||
if (!Editor.isMatch(editor, [prevChild, prevPath], v.previous)) {
|
||||
return {
|
||||
code: 'previous_sibling_invalid',
|
||||
node: prevChild,
|
||||
@@ -302,15 +302,15 @@ export const checkParent = (
|
||||
}
|
||||
|
||||
if (
|
||||
'next' in cv &&
|
||||
cv.next != null &&
|
||||
'next' in v &&
|
||||
v.next != null &&
|
||||
index < parent.children.length - 1 &&
|
||||
Editor.isMatch(editor, [child, childPath], rule.match)
|
||||
Editor.isMatch(editor, [child, childPath], m)
|
||||
) {
|
||||
const nextChild = Node.child(parent, index + 1)
|
||||
const nextPath = parentPath.concat(index + 1)
|
||||
|
||||
if (!Editor.isMatch(editor, [nextChild, nextPath], cv.next)) {
|
||||
if (!Editor.isMatch(editor, [nextChild, nextPath], v.next)) {
|
||||
return {
|
||||
code: 'next_sibling_invalid',
|
||||
node: nextChild,
|
||||
|
@@ -16,7 +16,7 @@ export const withSchema = (
|
||||
const { normalizeNode } = editor
|
||||
const markRules: MarkRule[] = []
|
||||
const nodeRules: NodeRule[] = []
|
||||
const ancestorRules: NodeRule[] = []
|
||||
const parentRules: NodeRule[] = []
|
||||
|
||||
for (const rule of rules) {
|
||||
if (rule.for === 'mark') {
|
||||
@@ -29,7 +29,7 @@ export const withSchema = (
|
||||
'next' in rule.validate ||
|
||||
'previous' in rule.validate
|
||||
) {
|
||||
ancestorRules.push(rule)
|
||||
parentRules.push(rule)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -48,7 +48,7 @@ export const withSchema = (
|
||||
}
|
||||
|
||||
if (!Text.isText(n)) {
|
||||
const failure = checkAncestor(editor, [n, p], r, ancestorRules)
|
||||
const failure = checkAncestor(editor, [n, p], r, parentRules)
|
||||
|
||||
if (failure) {
|
||||
rule = failure[0]
|
||||
|
33
packages/slate-schema/test/validations/next/invalid-extra.js
Normal file
33
packages/slate-schema/test/validations/next/invalid-extra.js
Normal file
@@ -0,0 +1,33 @@
|
||||
/** @jsx jsx */
|
||||
|
||||
import { jsx } from 'slate-hyperscript'
|
||||
|
||||
export const schema = [
|
||||
{
|
||||
for: 'node',
|
||||
match: { a: true },
|
||||
validate: {
|
||||
next: [{ b: true }],
|
||||
},
|
||||
},
|
||||
{
|
||||
for: 'node',
|
||||
match: { a: true },
|
||||
validate: {},
|
||||
},
|
||||
]
|
||||
|
||||
export const input = (
|
||||
<editor>
|
||||
<element a>one</element>
|
||||
<element c>two</element>
|
||||
<element b>three</element>
|
||||
</editor>
|
||||
)
|
||||
|
||||
export const output = (
|
||||
<editor>
|
||||
<element a>one</element>
|
||||
<element b>three</element>
|
||||
</editor>
|
||||
)
|
@@ -0,0 +1,37 @@
|
||||
/** @jsx jsx */
|
||||
|
||||
import { jsx } from 'slate-hyperscript'
|
||||
|
||||
export const schema = [
|
||||
{
|
||||
for: 'node',
|
||||
match: { c: true },
|
||||
validate: {
|
||||
parent: { b: true },
|
||||
},
|
||||
},
|
||||
{
|
||||
for: 'node',
|
||||
match: { a: true },
|
||||
validate: {},
|
||||
},
|
||||
]
|
||||
|
||||
export const input = (
|
||||
<editor>
|
||||
<element a>
|
||||
<element a>one</element>
|
||||
<element a>two</element>
|
||||
<element c>three</element>
|
||||
</element>
|
||||
</editor>
|
||||
)
|
||||
|
||||
export const output = (
|
||||
<editor>
|
||||
<element a>
|
||||
<element a>one</element>
|
||||
<element a>two</element>
|
||||
</element>
|
||||
</editor>
|
||||
)
|
@@ -7,7 +7,7 @@ export const schema = [
|
||||
for: 'node',
|
||||
match: { c: true },
|
||||
validate: {
|
||||
parent: [{ b: true }],
|
||||
parent: { b: true },
|
||||
},
|
||||
},
|
||||
]
|
33
packages/slate-schema/test/validations/parent/valid.js
Normal file
33
packages/slate-schema/test/validations/parent/valid.js
Normal file
@@ -0,0 +1,33 @@
|
||||
/** @jsx jsx */
|
||||
|
||||
import { jsx } from 'slate-hyperscript'
|
||||
|
||||
export const schema = [
|
||||
{
|
||||
for: 'node',
|
||||
match: { c: true },
|
||||
validate: {
|
||||
parent: { b: true },
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
export const input = (
|
||||
<editor>
|
||||
<element b>
|
||||
<element a>one</element>
|
||||
<element a>two</element>
|
||||
<element c>three</element>
|
||||
</element>
|
||||
</editor>
|
||||
)
|
||||
|
||||
export const output = (
|
||||
<editor>
|
||||
<element b>
|
||||
<element a>one</element>
|
||||
<element a>two</element>
|
||||
<element c>three</element>
|
||||
</element>
|
||||
</editor>
|
||||
)
|
@@ -0,0 +1,33 @@
|
||||
/** @jsx jsx */
|
||||
|
||||
import { jsx } from 'slate-hyperscript'
|
||||
|
||||
export const schema = [
|
||||
{
|
||||
for: 'node',
|
||||
match: { a: true },
|
||||
validate: {
|
||||
next: [{ b: true }],
|
||||
},
|
||||
},
|
||||
{
|
||||
for: 'node',
|
||||
match: { c: true },
|
||||
validate: {},
|
||||
},
|
||||
]
|
||||
|
||||
export const input = (
|
||||
<editor>
|
||||
<element a>one</element>
|
||||
<element c>two</element>
|
||||
<element b>three</element>
|
||||
</editor>
|
||||
)
|
||||
|
||||
export const output = (
|
||||
<editor>
|
||||
<element a>one</element>
|
||||
<element b>three</element>
|
||||
</editor>
|
||||
)
|
Reference in New Issue
Block a user