FEAT: NEW WORKFLOW ENGINE (#3160)

Co-authored-by: Joel <iamjoel007@gmail.com>
Co-authored-by: Yeuoly <admin@srmxy.cn>
Co-authored-by: JzoNg <jzongcode@gmail.com>
Co-authored-by: StyleZhang <jasonapring2015@outlook.com>
Co-authored-by: jyong <jyong@dify.ai>
Co-authored-by: nite-knite <nkCoding@gmail.com>
Co-authored-by: jyong <718720800@qq.com>
This commit is contained in:
takatost
2024-04-08 18:51:46 +08:00
committed by GitHub
parent 2fb9850af5
commit 7753ba2d37
1161 changed files with 103836 additions and 10327 deletions

View File

@@ -9,10 +9,13 @@ import type {
} from 'lexical'
import {
$createTextNode,
$getSelection,
$isRangeSelection,
$isTextNode,
} from 'lexical'
import type { EntityMatch } from '@lexical/text'
import { CustomTextNode } from './plugins/custom-text/node'
import type { MenuTextMatch } from './types'
export function getSelectedNode(
selection: RangeSelection,
@@ -190,7 +193,7 @@ export function registerLexicalTextEntity<T extends TextNode>(
export const decoratorTransform = (
node: CustomTextNode,
getMatch: (text: string) => null | EntityMatch,
createNode: () => LexicalNode,
createNode: (textNode: TextNode) => LexicalNode,
) => {
if (!node.isSimpleText())
return
@@ -241,7 +244,7 @@ export const decoratorTransform = (
else
[, nodeToReplace, currentNode] = currentNode.splitText(match.start, match.end)
const replacementNode = createNode()
const replacementNode = createNode(nodeToReplace)
nodeToReplace.replace(replacementNode)
if (currentNode == null)
@@ -249,6 +252,49 @@ export const decoratorTransform = (
}
}
function getFullMatchOffset(
documentText: string,
entryText: string,
offset: number,
): number {
let triggerOffset = offset
for (let i = triggerOffset; i <= entryText.length; i++) {
if (documentText.substr(-i) === entryText.substr(0, i))
triggerOffset = i
}
return triggerOffset
}
export function $splitNodeContainingQuery(match: MenuTextMatch): TextNode | null {
const selection = $getSelection()
if (!$isRangeSelection(selection) || !selection.isCollapsed())
return null
const anchor = selection.anchor
if (anchor.type !== 'text')
return null
const anchorNode = anchor.getNode()
if (!anchorNode.isSimpleText())
return null
const selectionOffset = anchor.offset
const textContent = anchorNode.getTextContent().slice(0, selectionOffset)
const characterOffset = match.replaceableString.length
const queryOffset = getFullMatchOffset(
textContent,
match.matchingString,
characterOffset,
)
const startOffset = selectionOffset - queryOffset
if (startOffset < 0)
return null
let newNode
if (startOffset === 0)
[newNode] = anchorNode.splitText(selectionOffset)
else
[, newNode] = anchorNode.splitText(startOffset, selectionOffset)
return newNode
}
export function textToEditorState(text: string) {
const paragraph = text.split('\n')