Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"author": "yousefed",
"tags": ["Advanced", "Development", "Collaboration"],
"dependencies": {
"@blocknote/diagram-block": "latest",
"@blocknote/xl-multi-column": "latest",
"@y/protocols": "^1.0.6-rc.1",
"@y/y": "^14.0.0-rc.26"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"@mantine/hooks": "^9.0.2",
"react": "^19.2.3",
"react-dom": "^19.2.3",
"@blocknote/diagram-block": "latest",
"@blocknote/xl-multi-column": "latest",
"@y/protocols": "^1.0.6-rc.1",
"@y/y": "^14.0.0-rc.26"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,22 @@ import {
PartialBlock,
withPageBreak,
} from "@blocknote/core";
import { createReactDiagramBlockSpec } from "@blocknote/diagram-block";
import { withMultiColumn } from "@blocknote/xl-multi-column";

/**
* The gallery's editor schema: the default blocks plus `pageBreak` and
* multi-column (`columnList` / `column`) so scenarios can exercise those block
* types and load the shared `testDocument`. It's a superset of the default
* schema, so every existing scenario keeps working. The gallery editors AND the
* The gallery's editor schema: the default blocks plus `pageBreak`,
* multi-column (`columnList` / `column`) and a Mermaid `diagram` so scenarios
* can exercise those block types and load the shared `testDocument`. It's a
* superset of the default schema, so every existing scenario keeps working. The gallery editors AND the
* shared test fixtures both build on this so the two never drift.
*/
export const gallerySchema = withMultiColumn(
withPageBreak(BlockNoteSchema.create()),
withPageBreak(
BlockNoteSchema.create().extend({
blockSpecs: { diagram: createReactDiagramBlockSpec() },
}),
),
);

type GallerySchema = typeof gallerySchema;
Expand Down
21 changes: 21 additions & 0 deletions examples/07-collaboration/14-suggestion-gallery/src/scenarios.ts
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,27 @@ export const scenarios: SuggestionScenario[] = [
});
},
},
{
kind: "single",
id: "text-edit-diagram",
title: "Edit a diagram",
category: "Basic text",
description:
"Rename a node in a Mermaid diagram. The source shows the struck-through " +
"and inserted text; the preview renders the suggested diagram.",
initial: [
{
id: "diagram",
type: "diagram",
content: "graph TD\n A[Draft] --> B[Review]",
},
],
apply: (editor) => {
editor.updateBlock("diagram", {
content: "graph TD\n A[Draft] --> B[Publish]",
});
},
},
{
kind: "single",
id: "text-add-bold",
Expand Down
37 changes: 35 additions & 2 deletions packages/core/src/api/nodeConversions/nodeToBlock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { UnreachableCaseError } from "../../util/typescript.js";
import {
getBlockInfoWithManualOffset,
getNodeId,
isSuggestedDeletionNode,
} from "../getBlockInfoFromPos.js";
import {
getBlockCache,
Expand All @@ -29,6 +30,32 @@ import {
getStyleSchema,
} from "../pmUtil.js";

/**
* The text of a plain content node. Plain content can't carry marks, so text
* marked as deleted (in a version diff or a suggestion) would merge with its
* replacement (e.g. `x^2` → `y^3` reads `xy^23`) - keep only the result.
*
* Styled text (`contentNodeToInlineContent`) still includes deleted text; see
* the note there.
*
* TODO(suggestion mode): Do NOT keep this behavior when we implement suggestion
* mode. Converting nodes to blocks must preserve pending suggestions, not
* silently read deletions as accepted in `editor.document`, `onChange` or exports.
* We only accept filtering here because plain text content has no good
* representation of inline formatting, including insertion/deletion marks, and
* merging both versions produces invalid preview source. Suggestion mode needs
* to preserve that information and resolve the preview source separately.
*/
function plainContentText(node: Node): string {
let text = "";
node.forEach((child) => {
if (!isSuggestedDeletionNode(child)) {
text += child.textContent;
}
});
return text;
}

/**
* Converts an internal (prosemirror) table node contentto a BlockNote Tablecontent
*/
Expand Down Expand Up @@ -147,6 +174,12 @@ export function contentNodeToInlineContent<
const content: InlineContent<any, S>[] = [];
let currentContent: InlineContent<any, S> | undefined = undefined;

// NOTE: unlike plain content (`plainContentText`), text marked as deleted in
// a version diff or suggestion is kept here, merged with its replacement. We
// might want to filter it too, but that changes what `editor.document`,
// `onChange` and exports report while suggestions show, and makes a block
// whose text is all deleted read as empty.

// Most of the logic below is for handling links because in ProseMirror links are marks
// while in BlockNote links are a type of inline content
contentNode.content.forEach((node) => {
Expand Down Expand Up @@ -375,7 +408,7 @@ export function nodeToCustomInlineContent<
) as any; // TODO: is this safe? could we have Links here that are undesired?
} else if (icConfig.content === "plain") {
// Plain inline content is a single unstyled string.
content = node.textContent as any;
content = plainContentText(node) as any;
} else {
content = undefined;
}
Expand Down Expand Up @@ -475,7 +508,7 @@ export function nodeToBlock<
}
// Plain content is a single unstyled text item; an empty block is an
// empty array, matching inline content.
const text = blockInfo.blockContent.node.textContent;
const text = plainContentText(blockInfo.blockContent.node);
content = text.length > 0 ? [{ type: "text", text, styles: {} }] : [];
} else if (blockConfig.content === "none") {
content = undefined;
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/i18n/locales/ar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,8 @@ export const ar: Dictionary = {
inserted: "مُدرج",
inserted_by: (users: string) => `أُدرج بواسطة: ${users}`,
deleted_by: (users: string) => `حُذف بواسطة: ${users}`,
changed: "مُعدَّل",
changed_by: (users: string) => `عُدّل بواسطة: ${users}`,
formatting_change_by: (formats: string, users: string) =>
`تغيير التنسيق (${formats}) بواسطة: ${users}`,
},
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/i18n/locales/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,8 @@ export const de: Dictionary = {
inserted: "Eingefügt",
inserted_by: (users: string) => `Eingefügt von: ${users}`,
deleted_by: (users: string) => `Gelöscht von: ${users}`,
changed: "Geändert",
changed_by: (users: string) => `Geändert von: ${users}`,
formatting_change_by: (formats: string, users: string) =>
`Formatierungsänderung (${formats}) von: ${users}`,
},
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/i18n/locales/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,8 @@ export const en = {
inserted: "Inserted",
inserted_by: (users: string) => `Inserted by: ${users}`,
deleted_by: (users: string) => `Deleted by: ${users}`,
changed: "Changed",
changed_by: (users: string) => `Changed by: ${users}`,
formatting_change_by: (formats: string, users: string) =>
`Formatting change (${formats}) by: ${users}`,
},
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/i18n/locales/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,8 @@ export const es: Dictionary = {
inserted: "Insertado",
inserted_by: (users: string) => `Insertado por: ${users}`,
deleted_by: (users: string) => `Eliminado por: ${users}`,
changed: "Modificado",
changed_by: (users: string) => `Modificado por: ${users}`,
formatting_change_by: (formats: string, users: string) =>
`Cambio de formato (${formats}) por: ${users}`,
},
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/i18n/locales/fa.ts
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,8 @@ export const fa = {
inserted: "درج\u200cشده",
inserted_by: (users: string) => `درج‌شده توسط: ${users}`,
deleted_by: (users: string) => `حذف‌شده توسط: ${users}`,
changed: "تغییر\u200cیافته",
changed_by: (users: string) => `تغییر\u200cیافته توسط: ${users}`,
formatting_change_by: (formats: string, users: string) =>
`تغییر قالب‌بندی (${formats}) توسط: ${users}`,
},
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/i18n/locales/fr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,8 @@ export const fr: Dictionary = {
inserted: "Inséré",
inserted_by: (users: string) => `Inséré par : ${users}`,
deleted_by: (users: string) => `Supprimé par : ${users}`,
changed: "Modifié",
changed_by: (users: string) => `Modifié par : ${users}`,
formatting_change_by: (formats: string, users: string) =>
`Modification de mise en forme (${formats}) par : ${users}`,
},
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/i18n/locales/he.ts
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,8 @@ export const he: Dictionary = {
inserted: "נוסף",
inserted_by: (users: string) => `נוסף על ידי: ${users}`,
deleted_by: (users: string) => `נמחק על ידי: ${users}`,
changed: "שונה",
changed_by: (users: string) => `שונה על ידי: ${users}`,
formatting_change_by: (formats: string, users: string) =>
`שינוי עיצוב (${formats}) על ידי: ${users}`,
},
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/i18n/locales/hr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,8 @@ export const hr: Dictionary = {
inserted: "Umetnuto",
inserted_by: (users: string) => `Umetnuo/la: ${users}`,
deleted_by: (users: string) => `Izbrisao/la: ${users}`,
changed: "Promijenjeno",
changed_by: (users: string) => `Promijenio/la: ${users}`,
formatting_change_by: (formats: string, users: string) =>
`Promjena oblikovanja (${formats}) od: ${users}`,
},
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/i18n/locales/is.ts
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,8 @@ export const is: Dictionary = {
inserted: "Sett inn",
inserted_by: (users: string) => `Sett inn af: ${users}`,
deleted_by: (users: string) => `Eytt af: ${users}`,
changed: "Breytt",
changed_by: (users: string) => `Breytt af: ${users}`,
formatting_change_by: (formats: string, users: string) =>
`Sniðbreyting (${formats}) af: ${users}`,
},
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/i18n/locales/it.ts
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,8 @@ export const it: Dictionary = {
inserted: "Inserito",
inserted_by: (users: string) => `Inserito da: ${users}`,
deleted_by: (users: string) => `Eliminato da: ${users}`,
changed: "Modificato",
changed_by: (users: string) => `Modificato da: ${users}`,
formatting_change_by: (formats: string, users: string) =>
`Modifica formattazione (${formats}) da: ${users}`,
},
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/i18n/locales/ja.ts
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,8 @@ export const ja: Dictionary = {
inserted: "挿入済み",
inserted_by: (users: string) => `挿入者: ${users}`,
deleted_by: (users: string) => `削除者: ${users}`,
changed: "変更済み",
changed_by: (users: string) => `変更者: ${users}`,
formatting_change_by: (formats: string, users: string) =>
`書式の変更 (${formats}) 変更者: ${users}`,
},
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/i18n/locales/ko.ts
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,8 @@ export const ko: Dictionary = {
inserted: "삽입됨",
inserted_by: (users: string) => `삽입한 사람: ${users}`,
deleted_by: (users: string) => `삭제한 사람: ${users}`,
changed: "변경됨",
changed_by: (users: string) => `변경한 사람: ${users}`,
formatting_change_by: (formats: string, users: string) =>
`서식 변경 (${formats}) 변경한 사람: ${users}`,
},
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/i18n/locales/nl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,8 @@ export const nl: Dictionary = {
inserted: "Ingevoegd",
inserted_by: (users: string) => `Ingevoegd door: ${users}`,
deleted_by: (users: string) => `Verwijderd door: ${users}`,
changed: "Gewijzigd",
changed_by: (users: string) => `Gewijzigd door: ${users}`,
formatting_change_by: (formats: string, users: string) =>
`Opmaakwijziging (${formats}) door: ${users}`,
},
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/i18n/locales/no.ts
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,8 @@ export const no: Dictionary = {
inserted: "Satt inn",
inserted_by: (users: string) => `Satt inn av: ${users}`,
deleted_by: (users: string) => `Slettet av: ${users}`,
changed: "Endret",
changed_by: (users: string) => `Endret av: ${users}`,
formatting_change_by: (formats: string, users: string) =>
`Formateringsendring (${formats}) av: ${users}`,
},
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/i18n/locales/pl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,8 @@ export const pl: Dictionary = {
inserted: "Wstawiono",
inserted_by: (users: string) => `Wstawione przez: ${users}`,
deleted_by: (users: string) => `Usunięte przez: ${users}`,
changed: "Zmieniono",
changed_by: (users: string) => `Zmienione przez: ${users}`,
formatting_change_by: (formats: string, users: string) =>
`Zmiana formatowania (${formats}) przez: ${users}`,
},
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/i18n/locales/pt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,8 @@ export const pt: Dictionary = {
inserted: "Inserido",
inserted_by: (users: string) => `Inserido por: ${users}`,
deleted_by: (users: string) => `Excluído por: ${users}`,
changed: "Alterado",
changed_by: (users: string) => `Alterado por: ${users}`,
formatting_change_by: (formats: string, users: string) =>
`Alteração de formatação (${formats}) por: ${users}`,
},
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/i18n/locales/ru.ts
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,8 @@ export const ru: Dictionary = {
inserted: "Вставлено",
inserted_by: (users: string) => `Вставлено: ${users}`,
deleted_by: (users: string) => `Удалено: ${users}`,
changed: "Изменено",
changed_by: (users: string) => `Изменено: ${users}`,
formatting_change_by: (formats: string, users: string) =>
`Изменение форматирования (${formats}): ${users}`,
},
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/i18n/locales/sk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,8 @@ export const sk = {
inserted: "Vložené",
inserted_by: (users: string) => `Vložil: ${users}`,
deleted_by: (users: string) => `Odstránil: ${users}`,
changed: "Zmenené",
changed_by: (users: string) => `Zmenil: ${users}`,
formatting_change_by: (formats: string, users: string) =>
`Zmena formátovania (${formats}) od: ${users}`,
},
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/i18n/locales/uk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,8 @@ export const uk: Dictionary = {
inserted: "Вставлено",
inserted_by: (users: string) => `Вставлено користувачем: ${users}`,
deleted_by: (users: string) => `Видалено користувачем: ${users}`,
changed: "Змінено",
changed_by: (users: string) => `Змінено користувачем: ${users}`,
formatting_change_by: (formats: string, users: string) =>
`Зміна форматування (${formats}) користувачем: ${users}`,
},
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/i18n/locales/uz.ts
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,8 @@ export const uz: Dictionary = {
inserted: "Qo'shildi",
inserted_by: (users: string) => `Qo'shgan: ${users}`,
deleted_by: (users: string) => `O'chirgan: ${users}`,
changed: "O'zgartirildi",
changed_by: (users: string) => `O'zgartirgan: ${users}`,
formatting_change_by: (formats: string, users: string) =>
`Formatlash o'zgarishi (${formats}), o'zgartirgan: ${users}`,
},
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/i18n/locales/vi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,8 @@ export const vi: Dictionary = {
inserted: "Đã chèn",
inserted_by: (users: string) => `Được chèn bởi: ${users}`,
deleted_by: (users: string) => `Được xóa bởi: ${users}`,
changed: "Đã thay đổi",
changed_by: (users: string) => `Được thay đổi bởi: ${users}`,
formatting_change_by: (formats: string, users: string) =>
`Thay đổi định dạng (${formats}) bởi: ${users}`,
},
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/i18n/locales/zh-tw.ts
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,8 @@ export const zhTW: Dictionary = {
inserted: "已插入",
inserted_by: (users: string) => `插入者:${users}`,
deleted_by: (users: string) => `刪除者:${users}`,
changed: "已變更",
changed_by: (users: string) => `變更者:${users}`,
formatting_change_by: (formats: string, users: string) =>
`格式變更(${formats}),變更者:${users}`,
},
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/i18n/locales/zh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,8 @@ export const zh: Dictionary = {
inserted: "已插入",
inserted_by: (users: string) => `插入者:${users}`,
deleted_by: (users: string) => `删除者:${users}`,
changed: "已更改",
changed_by: (users: string) => `更改者:${users}`,
formatting_change_by: (formats: string, users: string) =>
`格式更改(${formats}),更改者:${users}`,
},
Expand Down
Loading
Loading