Skip to content

Commit c9695f3

Browse files
committed
fix: same id for nodes of same type
1 parent 6ab167f commit c9695f3

11 files changed

Lines changed: 96 additions & 45 deletions

File tree

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1+
let counter = 0;
2+
13
export function generateBlockUniqueId(type) {
4+
counter++;
25
const prefix = (typeof type === 'string' && type.length ? type : 'b').toLowerCase();
36
const ts = Date.now().toString(36);
4-
const rand = Math.floor(Math.random() * 0xffffffff).toString();
5-
return `${prefix}-${ts}-${rand}`;
7+
const rand = Math.floor(Math.random() * 0xffffffff).toString(36);
8+
return `${prefix}-${ts}-${rand}-${counter}`;
69
}

packages/super-editor/src/extensions/block-node/block-node.js

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { Extension } from '@core/Extension.js';
22
import { helpers } from '@core/index.js';
33
const { findChildren } = helpers;
4+
import { Plugin, PluginKey } from 'prosemirror-state';
5+
import { generateBlockUniqueId } from '@core/utilities/index.js';
46

57
export const BlockNode = Extension.create({
68
name: 'BlockNode',
@@ -109,4 +111,57 @@ export const BlockNode = Extension.create({
109111
},
110112
};
111113
},
114+
onCreate() {
115+
const { state, view } = this.editor;
116+
const tr = state.tr;
117+
let changed = false;
118+
119+
state.doc.descendants((node, pos) => {
120+
if (!node.type.spec.group?.split(' ')?.includes('block')) return;
121+
if (node.attrs?.sdBlockId) return;
122+
tr.setNodeMarkup(
123+
pos,
124+
undefined,
125+
{
126+
...node.attrs,
127+
sdBlockId: generateBlockUniqueId(node.type.name),
128+
},
129+
node.marks,
130+
);
131+
changed = true;
132+
return false;
133+
});
134+
135+
if (changed) view.dispatch(tr);
136+
},
137+
addPmPlugins() {
138+
return [
139+
new Plugin({
140+
appendTransaction: (transactions, _oldState, newState) => {
141+
if (!transactions.some((tr) => tr.docChanged)) return null;
142+
143+
let tr = null;
144+
let changed = false;
145+
newState.doc.descendants((node, pos) => {
146+
if (!node.type.spec.group?.split(' ')?.includes('block')) return;
147+
if (node.attrs?.sdBlockId) return;
148+
149+
tr = tr ?? newState.tr;
150+
tr.setNodeMarkup(
151+
pos,
152+
undefined,
153+
{
154+
...node.attrs,
155+
sdBlockId: generateBlockUniqueId(node.type.name),
156+
},
157+
node.marks,
158+
);
159+
changed = true;
160+
});
161+
162+
return changed ? tr : null;
163+
},
164+
}),
165+
];
166+
},
112167
});

packages/super-editor/src/extensions/bullet-list/bullet-list.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { Node, Attribute } from '@core/index.js';
22
import { InputRule } from '@core/InputRule.js';
33
import { ListHelpers } from '@helpers/list-numbering-helpers.js';
44
import { toggleList } from '@core/commands/index.js';
5-
import { generateBlockUniqueId } from '@core/utilities/index.js';
65

76
/**
87
* Matches a bullet list to a dash or asterisk.
@@ -52,10 +51,10 @@ export const BulletList = Node.create({
5251
},
5352

5453
sdBlockId: {
55-
default: () => generateBlockUniqueId(this.name),
56-
parseHTML: (elem) => elem.getAttribute('sd-block-id'),
57-
renderHTML: (attrs) => {
58-
return attrs.sdBlockId ? { 'sd-block-id': attrs.sdBlockId } : {};
54+
default: () => null,
55+
parseDOM: (elem) => elem.getAttribute('data-sd-block-id'),
56+
renderDOM: (attrs) => {
57+
return attrs.sdBlockId ? { 'data-sd-block-id': attrs.sdBlockId } : {};
5958
},
6059
},
6160

packages/super-editor/src/extensions/heading/heading.js

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { Node, Attribute } from '@core/index.js';
2-
import { generateBlockUniqueId } from '@core/utilities/sdBlockUniqueId.js';
32

43
export const Heading = Node.create({
54
name: 'heading',
@@ -27,13 +26,10 @@ export const Heading = Node.create({
2726
},
2827
tabStops: { rendered: false },
2928
sdBlockId: {
30-
default: generateBlockUniqueId(this.name),
31-
parseHTML: (elem) => elem.getAttribute('sd-block-id'),
32-
renderHTML: (attrs) => {
33-
if (!attrs.sdBlockId) return { 'sd-block-id': generateBlockUniqueId(this.name) };
34-
return {
35-
'sd-block-id': attrs.sdBlockId,
36-
};
29+
default: () => null,
30+
parseDOM: (elem) => elem.getAttribute('data-sd-block-id'),
31+
renderDOM: (attrs) => {
32+
return attrs.sdBlockId ? { 'data-sd-block-id': attrs.sdBlockId } : {};
3733
},
3834
},
3935
};

packages/super-editor/src/extensions/ordered-list/ordered-list.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { findParentNode } from '@helpers/index.js';
33
import { toggleList } from '@core/commands/index.js';
44
import { InputRule } from '@core/InputRule.js';
55
import { ListHelpers } from '@helpers/list-numbering-helpers.js';
6-
import { generateBlockUniqueId } from '@core/utilities/index.js';
6+
77
const inputRegex = /^(\d+)\.\s$/;
88

99
export const OrderedList = Node.create({
@@ -44,10 +44,10 @@ export const OrderedList = Node.create({
4444
},
4545

4646
sdBlockId: {
47-
default: () => generateBlockUniqueId(this.name),
48-
parseHTML: (elem) => elem.getAttribute('sd-block-id'),
49-
renderHTML: (attrs) => {
50-
return attrs.sdBlockId ? { 'sd-block-id': attrs.sdBlockId } : {};
47+
default: () => null,
48+
parseDOM: (elem) => elem.getAttribute('data-sd-block-id'),
49+
renderDOM: (attrs) => {
50+
return attrs.sdBlockId ? { 'data-sd-block-id': attrs.sdBlockId } : {};
5151
},
5252
},
5353

packages/super-editor/src/extensions/paragraph/paragraph.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { Decoration, DecorationSet } from 'prosemirror-view';
33
import { Node, Attribute } from '@core/index.js';
44
import { getSpacingStyleString, getMarksStyle } from '@extensions/linked-styles/index.js';
55
import { getDefaultSpacing } from './helpers/getDefaultSpacing.js';
6-
import { generateBlockUniqueId } from '@core/utilities/index.js';
76

87
export const Paragraph = Node.create({
98
name: 'paragraph',
@@ -88,10 +87,11 @@ export const Paragraph = Node.create({
8887
},
8988
styleId: {},
9089
sdBlockId: {
91-
default: () => generateBlockUniqueId(this.name),
92-
parseHTML: (elem) => elem.getAttribute('sd-block-id'),
93-
renderHTML: (attrs) => {
94-
return attrs.sdBlockId ? { 'sd-block-id': attrs.sdBlockId } : {};
90+
default: null,
91+
keepOnSplit: false,
92+
parseDOM: (elem) => elem.getAttribute('data-sd-block-id'),
93+
renderDOM: (attrs) => {
94+
return attrs.sdBlockId ? { 'data-sd-block-id': attrs.sdBlockId } : {};
9595
},
9696
},
9797
attributes: {

packages/super-editor/src/extensions/shape-container/shape-container.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { Node, Attribute } from '@core/index.js';
2-
import { generateBlockUniqueId } from '@core/utilities/sdBlockUniqueId.js';
32

43
export const ShapeContainer = Node.create({
54
name: 'shapeContainer',
@@ -30,10 +29,10 @@ export const ShapeContainer = Node.create({
3029
},
3130
},
3231
sdBlockId: {
33-
default: () => generateBlockUniqueId(this.name),
34-
parseHTML: (elem) => elem.getAttribute('sd-block-id'),
35-
renderHTML: (attrs) => {
36-
return attrs.sdBlockId ? { 'sd-block-id': attrs.sdBlockId } : {};
32+
default: () => null,
33+
parseDOM: (elem) => elem.getAttribute('data-sd-block-id'),
34+
renderDOM: (attrs) => {
35+
return attrs.sdBlockId ? { 'data-sd-block-id': attrs.sdBlockId } : {};
3736
},
3837
},
3938
style: {

packages/super-editor/src/extensions/shape-textbox/shape-textbox.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { Node, Attribute } from '@core/index.js';
2-
import { generateBlockUniqueId } from '@core/utilities/sdBlockUniqueId.js';
32

43
export const ShapeTextbox = Node.create({
54
name: 'shapeTextbox',
@@ -22,10 +21,10 @@ export const ShapeTextbox = Node.create({
2221
addAttributes() {
2322
return {
2423
sdBlockId: {
25-
default: () => generateBlockUniqueId(this.name),
26-
parseHTML: (elem) => elem.getAttribute('sd-block-id'),
27-
renderHTML: (attrs) => {
28-
return attrs.sdBlockId ? { 'sd-block-id': attrs.sdBlockId } : {};
24+
default: () => null,
25+
parseDOM: (elem) => elem.getAttribute('data-sd-block-id'),
26+
renderDOM: (attrs) => {
27+
return attrs.sdBlockId ? { 'data-sd-block-id': attrs.sdBlockId } : {};
2928
},
3029
},
3130
attributes: {

packages/super-editor/src/extensions/structured-content/document-section.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { htmlHandler } from '@core/InputRule.js';
44
import { Selection } from 'prosemirror-state';
55
import { DOMParser as PMDOMParser } from 'prosemirror-model';
66
import { findParentNode, SectionHelpers } from '@helpers/index.js';
7-
import { generateBlockUniqueId } from '@core/utilities/sdBlockUniqueId.js';
87

98
export const DocumentSection = Node.create({
109
name: 'documentSection',
@@ -39,10 +38,10 @@ export const DocumentSection = Node.create({
3938
return {
4039
id: {},
4140
sdBlockId: {
42-
default: () => generateBlockUniqueId(this.name),
43-
parseHTML: (elem) => elem.getAttribute('sd-block-id'),
44-
renderHTML: (attrs) => {
45-
return attrs.sdBlockId ? { 'sd-block-id': attrs.sdBlockId } : {};
41+
default: () => null,
42+
parseDOM: (elem) => elem.getAttribute('data-sd-block-id'),
43+
renderDOM: (attrs) => {
44+
return attrs.sdBlockId ? { 'data-sd-block-id': attrs.sdBlockId } : {};
4645
},
4746
},
4847
title: {},

packages/super-editor/src/extensions/table/table.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { Node, Attribute } from '@core/index.js';
22
import { callOrGet } from '@core/utilities/callOrGet.js';
3-
import { generateBlockUniqueId } from '@core/utilities/sdBlockUniqueId.js';
43
import { getExtensionConfigField } from '@core/helpers/getExtensionConfigField.js';
54
import { /* TableView */ createTableView } from './TableView.js';
65
import { createTable } from './tableHelpers/createTable.js';
@@ -74,10 +73,10 @@ export const Table = Node.create({
7473
},
7574
}, */
7675
sdBlockId: {
77-
default: () => generateBlockUniqueId(this.name),
78-
parseHTML: (elem) => elem.getAttribute('sd-block-id'),
79-
renderHTML: (attrs) => {
80-
return attrs.sdBlockId ? { 'sd-block-id': attrs.sdBlockId } : {};
76+
default: () => null,
77+
parseDOM: (elem) => elem.getAttribute('data-sd-block-id'),
78+
renderDOM: (attrs) => {
79+
return attrs.sdBlockId ? { 'data-sd-block-id': attrs.sdBlockId } : {};
8180
},
8281
},
8382

0 commit comments

Comments
 (0)