mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-11 17:53:59 +02:00
fix parent-based schema rules with multiple rules present
This commit is contained in:
@@ -7,6 +7,7 @@ import {
|
|||||||
MarkEntry,
|
MarkEntry,
|
||||||
AncestorEntry,
|
AncestorEntry,
|
||||||
Descendant,
|
Descendant,
|
||||||
|
DescendantEntry,
|
||||||
} from 'slate'
|
} from 'slate'
|
||||||
|
|
||||||
import { MarkError, NodeError } from './errors'
|
import { MarkError, NodeError } from './errors'
|
||||||
@@ -53,10 +54,10 @@ export const checkNode = (
|
|||||||
rule: NodeRule,
|
rule: NodeRule,
|
||||||
rules: NodeRule[]
|
rules: NodeRule[]
|
||||||
): NodeError | undefined => {
|
): NodeError | undefined => {
|
||||||
const { validate: v } = rule
|
const { match: m, validate: v } = rule
|
||||||
const [node, path] = entry
|
const [node, path] = entry
|
||||||
|
|
||||||
if (Editor.isMatch(editor, entry, rule.match)) {
|
if (Editor.isMatch(editor, entry, m)) {
|
||||||
if ('properties' in v) {
|
if ('properties' in v) {
|
||||||
for (const k in v.properties) {
|
for (const k in v.properties) {
|
||||||
const p = v.properties[k]
|
const p = v.properties[k]
|
||||||
@@ -117,7 +118,7 @@ export const checkAncestor = (
|
|||||||
editor: Editor,
|
editor: Editor,
|
||||||
entry: AncestorEntry,
|
entry: AncestorEntry,
|
||||||
rule: NodeRule,
|
rule: NodeRule,
|
||||||
ancestorRules: NodeRule[]
|
parentRules: NodeRule[]
|
||||||
): [NodeRule, NodeError] | undefined => {
|
): [NodeRule, NodeError] | undefined => {
|
||||||
const { validate: v } = rule
|
const { validate: v } = rule
|
||||||
const [parent, parentPath] = entry
|
const [parent, parentPath] = entry
|
||||||
@@ -140,8 +141,8 @@ export const checkAncestor = (
|
|||||||
if (child && !processed.has(child)) {
|
if (child && !processed.has(child)) {
|
||||||
processed.add(child)
|
processed.add(child)
|
||||||
|
|
||||||
for (const r of ancestorRules) {
|
for (const r of parentRules) {
|
||||||
const e = checkParent(editor, entry, index, rule, r)
|
const e = checkParent(editor, entry, [child, childPath], r)
|
||||||
|
|
||||||
if (e) {
|
if (e) {
|
||||||
return [r, e]
|
return [r, e]
|
||||||
@@ -260,20 +261,19 @@ export const checkAncestor = (
|
|||||||
export const checkParent = (
|
export const checkParent = (
|
||||||
editor: Editor,
|
editor: Editor,
|
||||||
entry: AncestorEntry,
|
entry: AncestorEntry,
|
||||||
index: number,
|
childEntry: DescendantEntry,
|
||||||
rule: NodeRule,
|
rule: NodeRule
|
||||||
childRule: NodeRule
|
|
||||||
): NodeError | undefined => {
|
): NodeError | undefined => {
|
||||||
const { validate: cv } = childRule
|
const { match: m, validate: v } = rule
|
||||||
const [parent, parentPath] = entry
|
const [parent, parentPath] = entry
|
||||||
const child = Node.child(parent, index)
|
const [child, childPath] = childEntry
|
||||||
const childPath = parentPath.concat(index)
|
const index = childPath[childPath.length - 1]
|
||||||
|
|
||||||
if (
|
if (
|
||||||
'parent' in cv &&
|
'parent' in v &&
|
||||||
cv.parent != null &&
|
v.parent != null &&
|
||||||
Editor.isMatch(editor, [child, childPath], rule.match) &&
|
Editor.isMatch(editor, [child, childPath], m) &&
|
||||||
!Editor.isMatch(editor, [parent, parentPath], cv.parent)
|
!Editor.isMatch(editor, [parent, parentPath], v.parent)
|
||||||
) {
|
) {
|
||||||
return {
|
return {
|
||||||
code: 'parent_invalid',
|
code: 'parent_invalid',
|
||||||
@@ -284,15 +284,15 @@ export const checkParent = (
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
'previous' in cv &&
|
'previous' in v &&
|
||||||
cv.previous != null &&
|
v.previous != null &&
|
||||||
index > 0 &&
|
index > 0 &&
|
||||||
Editor.isMatch(editor, [child, childPath], rule.match)
|
Editor.isMatch(editor, [child, childPath], m)
|
||||||
) {
|
) {
|
||||||
const prevChild = Node.child(parent, index - 1)
|
const prevChild = Node.child(parent, index - 1)
|
||||||
const prevPath = parentPath.concat(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 {
|
return {
|
||||||
code: 'previous_sibling_invalid',
|
code: 'previous_sibling_invalid',
|
||||||
node: prevChild,
|
node: prevChild,
|
||||||
@@ -302,15 +302,15 @@ export const checkParent = (
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
'next' in cv &&
|
'next' in v &&
|
||||||
cv.next != null &&
|
v.next != null &&
|
||||||
index < parent.children.length - 1 &&
|
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 nextChild = Node.child(parent, index + 1)
|
||||||
const nextPath = parentPath.concat(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 {
|
return {
|
||||||
code: 'next_sibling_invalid',
|
code: 'next_sibling_invalid',
|
||||||
node: nextChild,
|
node: nextChild,
|
||||||
|
@@ -16,7 +16,7 @@ export const withSchema = (
|
|||||||
const { normalizeNode } = editor
|
const { normalizeNode } = editor
|
||||||
const markRules: MarkRule[] = []
|
const markRules: MarkRule[] = []
|
||||||
const nodeRules: NodeRule[] = []
|
const nodeRules: NodeRule[] = []
|
||||||
const ancestorRules: NodeRule[] = []
|
const parentRules: NodeRule[] = []
|
||||||
|
|
||||||
for (const rule of rules) {
|
for (const rule of rules) {
|
||||||
if (rule.for === 'mark') {
|
if (rule.for === 'mark') {
|
||||||
@@ -29,7 +29,7 @@ export const withSchema = (
|
|||||||
'next' in rule.validate ||
|
'next' in rule.validate ||
|
||||||
'previous' in rule.validate
|
'previous' in rule.validate
|
||||||
) {
|
) {
|
||||||
ancestorRules.push(rule)
|
parentRules.push(rule)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -48,7 +48,7 @@ export const withSchema = (
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!Text.isText(n)) {
|
if (!Text.isText(n)) {
|
||||||
const failure = checkAncestor(editor, [n, p], r, ancestorRules)
|
const failure = checkAncestor(editor, [n, p], r, parentRules)
|
||||||
|
|
||||||
if (failure) {
|
if (failure) {
|
||||||
rule = failure[0]
|
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',
|
for: 'node',
|
||||||
match: { c: true },
|
match: { c: true },
|
||||||
validate: {
|
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