@@ -13,6 +13,88 @@ const BlockAttributes: Record<string, string> = {
1313 depthChange : "data-depth-change" ,
1414} ;
1515
16+ /**
17+ * The main "Block node" documents consist of
18+ */
19+ export const SpecialNode = Node . create < {
20+ domAttributes ?: BlockNoteDOMAttributes ;
21+ editor : BlockNoteEditor < any , any , any > ;
22+ } > ( {
23+ name : "specialNode" ,
24+ group : "blockGroupChild bnBlock bnSpecialNode" ,
25+ // A block always contains content, and optionally a blockGroup which contains nested blocks
26+ content : "blockContent blockGroup?" ,
27+ // Ensures content-specific keyboard handlers trigger first.
28+ priority : 50 ,
29+ defining : true ,
30+ marks : "y-attributed-insert y-attributed-format y-attributed-delete" ,
31+ addAttributes ( ) {
32+ return {
33+ XYZ : {
34+ isRequired : true ,
35+ type : "string" ,
36+ } ,
37+ } ;
38+ } ,
39+ parseHTML ( ) {
40+ return [
41+ // TODO not sure whether this rule is needed or not
42+ // {
43+ // tag: "div[data-node-type=" + this.name + "]",
44+ // getAttrs: (element) => {
45+ // if (typeof element === "string") {
46+ // return false;
47+ // }
48+
49+ // const attrs: Record<string, string> = {};
50+ // for (const [nodeAttr, HTMLAttr] of Object.entries(BlockAttributes)) {
51+ // if (element.getAttribute(HTMLAttr)) {
52+ // attrs[nodeAttr] = element.getAttribute(HTMLAttr)!;
53+ // }
54+ // }
55+
56+ // return attrs;
57+ // },
58+ // },
59+ // Ignore `blockOuter` divs, but parse the `blockContainer` divs inside them.
60+ {
61+ tag : `div[data-node-type="specialNodeOuter"]` ,
62+ skip : true ,
63+ } ,
64+ ] ;
65+ } ,
66+
67+ renderHTML ( { HTMLAttributes } ) {
68+ const specialNodeOuter = document . createElement ( "div" ) ;
69+ specialNodeOuter . className = "bn-block-outer" ;
70+ specialNodeOuter . setAttribute ( "data-node-type" , "specialNodeOuter" ) ;
71+ for ( const [ attribute , value ] of Object . entries ( HTMLAttributes ) ) {
72+ if ( attribute !== "class" ) {
73+ specialNodeOuter . setAttribute ( attribute , value ) ;
74+ }
75+ }
76+
77+ const blockHTMLAttributes = {
78+ ...( this . options . domAttributes ?. block || { } ) ,
79+ ...HTMLAttributes ,
80+ } ;
81+ const block = document . createElement ( "div" ) ;
82+ block . className = mergeCSSClasses ( "bn-block" , blockHTMLAttributes . class ) ;
83+ block . setAttribute ( "data-node-type" , this . name ) ;
84+ for ( const [ attribute , value ] of Object . entries ( blockHTMLAttributes ) ) {
85+ if ( attribute !== "class" ) {
86+ block . setAttribute ( attribute , value ) ;
87+ }
88+ }
89+
90+ specialNodeOuter . appendChild ( block ) ;
91+
92+ return {
93+ dom : specialNodeOuter ,
94+ contentDOM : block ,
95+ } ;
96+ } ,
97+ } ) ;
1698/**
1799 * The main "Block node" documents consist of
18100 */
@@ -23,7 +105,7 @@ export const BlockContainer = Node.create<{
23105 name : "blockContainer" ,
24106 group : "blockGroupChild bnBlock" ,
25107 // A block always contains content, and optionally a blockGroup which contains nested blocks
26- content : "blockContent blockGroup?" ,
108+ content : "bnSpecialNode? blockContent bnSpecialNode? blockGroup?" ,
27109 // Ensures content-specific keyboard handlers trigger first.
28110 priority : 50 ,
29111 defining : true ,
0 commit comments