feat(insights): fix DBSCAN, Persian embeddings crash, D3 physics layouts, and D3 node not found runtime error
This commit is contained in:
72
memento-note/lib/editor/apply-clip-rtl-direction.ts
Normal file
72
memento-note/lib/editor/apply-clip-rtl-direction.ts
Normal file
@@ -0,0 +1,72 @@
|
||||
import type { Editor } from '@tiptap/core'
|
||||
import { detectTextDirection, inferLangFromUrl } from '@/lib/clip/rtl-content'
|
||||
|
||||
const RTL_BLOCK_TYPES = new Set([
|
||||
'clipArticle',
|
||||
'bulletList',
|
||||
'orderedList',
|
||||
'listItem',
|
||||
'heading',
|
||||
'paragraph',
|
||||
'blockquote',
|
||||
])
|
||||
|
||||
function nodeShouldBeRtl(
|
||||
node: { type: { name: string }; textContent: string; attrs: { dir?: string | null } },
|
||||
urlIsRtl: boolean,
|
||||
): boolean {
|
||||
if (node.attrs.dir === 'rtl') return false
|
||||
if (urlIsRtl) return true
|
||||
const text = node.textContent || ''
|
||||
if (!text.trim()) return false
|
||||
return detectTextDirection(text) === 'rtl'
|
||||
}
|
||||
|
||||
/**
|
||||
* Applique dir="rtl" explicitement sur les nœuds TipTap (titres, listes, paragraphes).
|
||||
* Basé sur la doc TipTap setTextDirection — évite textDirection:'auto' (bug listes #7338).
|
||||
* @see https://tiptap.dev/docs/editor/api/commands/nodes-and-marks/set-text-direction
|
||||
* @see https://github.com/ueberdosis/tiptap/issues/7338
|
||||
*/
|
||||
export function applyClipRtlDirection(
|
||||
editor: Editor,
|
||||
options?: { sourceUrl?: string | null },
|
||||
): boolean {
|
||||
if (!editor || editor.isDestroyed) return false
|
||||
|
||||
const urlIsRtl = Boolean(options?.sourceUrl && inferLangFromUrl(options.sourceUrl))
|
||||
const ranges: Array<{ from: number; to: number }> = []
|
||||
|
||||
editor.state.doc.descendants((node, pos) => {
|
||||
if (node.type.name === 'clipArticle') {
|
||||
ranges.push({ from: pos, to: pos + node.nodeSize })
|
||||
}
|
||||
})
|
||||
|
||||
if (ranges.length === 0) {
|
||||
editor.state.doc.descendants((node, pos) => {
|
||||
if (node.isText || !RTL_BLOCK_TYPES.has(node.type.name)) return
|
||||
if (!nodeShouldBeRtl(node, urlIsRtl)) return
|
||||
ranges.push({ from: pos, to: pos + node.nodeSize })
|
||||
})
|
||||
}
|
||||
|
||||
if (ranges.length === 0) return false
|
||||
|
||||
return editor
|
||||
.chain()
|
||||
.command(({ tr, state, dispatch }) => {
|
||||
let changed = false
|
||||
for (const { from, to } of ranges) {
|
||||
state.doc.nodesBetween(from, to, (node, pos) => {
|
||||
if (node.isText || node.attrs.dir === 'rtl') return
|
||||
if (!RTL_BLOCK_TYPES.has(node.type.name)) return
|
||||
tr.setNodeMarkup(pos, undefined, { ...node.attrs, dir: 'rtl' })
|
||||
changed = true
|
||||
})
|
||||
}
|
||||
if (dispatch && changed) dispatch(tr)
|
||||
return changed
|
||||
})
|
||||
.run()
|
||||
}
|
||||
Reference in New Issue
Block a user