1
0
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:
Ian Storm Taylor
2019-12-02 23:23:30 -05:00
parent 6fc935a4b8
commit ed2b84ca7a
7 changed files with 163 additions and 27 deletions

View File

@@ -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,

View File

@@ -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]

View 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>
)

View File

@@ -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>
)

View File

@@ -7,7 +7,7 @@ export const schema = [
for: 'node',
match: { c: true },
validate: {
parent: [{ b: true }],
parent: { b: true },
},
},
]

View 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>
)

View 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: { 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>
)