@shadow-garden/bapbong-model 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -43,7 +43,8 @@ function pastedParagraphAttrs(el, heading) {
43
43
  return {
44
44
  heading,
45
45
  align: m ? m[1].toLowerCase() : null,
46
- borders: dataJson(el, "data-borders")
46
+ borders: dataJson(el, "data-borders"),
47
+ carry: dataJson(el, "data-carry")
47
48
  };
48
49
  }
49
50
  function pastedImageAttrs(el) {
@@ -80,7 +81,8 @@ function pastedCellAttrs(el) {
80
81
  background: bg ? bg[1].trim() : null,
81
82
  vAlign: e.getAttribute("data-valign"),
82
83
  borders: dataJson(el, "data-borders"),
83
- padding: dataJson(el, "data-padding")
84
+ padding: dataJson(el, "data-padding"),
85
+ carry: dataJson(el, "data-carry")
84
86
  };
85
87
  }
86
88
  var schema = new import_prosemirror_model.Schema({
@@ -136,7 +138,13 @@ var schema = new import_prosemirror_model.Schema({
136
138
  pageBreakBefore: { default: false },
137
139
  // w:pBdr — { top?, bottom?, left?, right? } of BorderSide, or null.
138
140
  // Importer-set; painted as a box around the paragraph's lines.
139
- borders: { default: null }
141
+ borders: { default: null },
142
+ // Carry-through fidelity (docx round-trip): OOXML paragraph
143
+ // properties the model does NOT represent, preserved verbatim so a
144
+ // customer's save never drops them. { pPr?: string, markRPr?: string }
145
+ // — raw XML fragments (pPr extras / the paragraph-mark w:rPr), or
146
+ // null. Importer-set; the exporter splices them back into w:pPr.
147
+ carry: { default: null }
140
148
  },
141
149
  // HTML paste path: recover heading level from h1–h6 and alignment from
142
150
  // inline style. Other attrs (list/indent/tabs/spacing) stay importer-only
@@ -156,6 +164,8 @@ var schema = new import_prosemirror_model.Schema({
156
164
  if (attrs.styleId) dom["data-style"] = attrs.styleId;
157
165
  if (node.attrs["borders"])
158
166
  dom["data-borders"] = JSON.stringify(node.attrs["borders"]);
167
+ if (node.attrs["carry"])
168
+ dom["data-carry"] = JSON.stringify(node.attrs["carry"]);
159
169
  return [tag, dom, 0];
160
170
  }
161
171
  },
@@ -237,7 +247,12 @@ var schema = new import_prosemirror_model.Schema({
237
247
  // insideV }, or null — OOXML tables are borderless unless declared.
238
248
  borders: { default: null },
239
249
  // w:tblPr/w:jc — 'center' | 'right' table alignment, or null (left).
240
- align: { default: null }
250
+ align: { default: null },
251
+ // Carry-through fidelity: unmodelled w:tblPr children (tblStyle,
252
+ // tblLayout, tblLook, tblInd, floating tblpPr, …) as one raw XML
253
+ // string ({ tblPr: string }), or null. Importer-set; the exporter
254
+ // splices it back so a save never drops them.
255
+ carry: { default: null }
241
256
  },
242
257
  // Complex attrs round-trip as data-* JSON — ProseMirror's clipboard is
243
258
  // a toDOM → parseDOM pass, so without this an internal copy/paste
@@ -248,7 +263,8 @@ var schema = new import_prosemirror_model.Schema({
248
263
  getAttrs: (el) => ({
249
264
  borders: dataJson(el, "data-borders"),
250
265
  cellPadding: dataJson(el, "data-cell-padding"),
251
- align: el.getAttribute("data-align")
266
+ align: el.getAttribute("data-align"),
267
+ carry: dataJson(el, "data-carry")
252
268
  })
253
269
  }
254
270
  ],
@@ -259,6 +275,7 @@ var schema = new import_prosemirror_model.Schema({
259
275
  if (a["cellPadding"])
260
276
  dom["data-cell-padding"] = JSON.stringify(a["cellPadding"]);
261
277
  if (a["align"]) dom["data-align"] = String(a["align"]);
278
+ if (a["carry"]) dom["data-carry"] = JSON.stringify(a["carry"]);
262
279
  return ["table", dom, ["tbody", 0]];
263
280
  }
264
281
  },
@@ -271,7 +288,10 @@ var schema = new import_prosemirror_model.Schema({
271
288
  // (Word's default) means the paginator may split the row mid-content.
272
289
  cantSplit: { default: false },
273
290
  // w:trHeight — { value: px, exact: boolean } or null (auto).
274
- height: { default: null }
291
+ height: { default: null },
292
+ // Carry-through fidelity: unmodelled w:trPr children ({ trPr: string
293
+ // } — gridBefore/wBefore, cnfStyle, …), or null. Importer-set.
294
+ carry: { default: null }
275
295
  },
276
296
  parseDOM: [
277
297
  {
@@ -279,7 +299,8 @@ var schema = new import_prosemirror_model.Schema({
279
299
  getAttrs: (el) => ({
280
300
  header: el.getAttribute("data-header") === "true",
281
301
  cantSplit: el.getAttribute("data-cant-split") === "true",
282
- height: dataJson(el, "data-height")
302
+ height: dataJson(el, "data-height"),
303
+ carry: dataJson(el, "data-carry")
283
304
  })
284
305
  }
285
306
  ],
@@ -289,6 +310,8 @@ var schema = new import_prosemirror_model.Schema({
289
310
  if (node.attrs["cantSplit"]) dom["data-cant-split"] = "true";
290
311
  if (node.attrs["height"])
291
312
  dom["data-height"] = JSON.stringify(node.attrs["height"]);
313
+ if (node.attrs["carry"])
314
+ dom["data-carry"] = JSON.stringify(node.attrs["carry"]);
292
315
  return ["tr", dom, 0];
293
316
  }
294
317
  },
@@ -306,8 +329,11 @@ var schema = new import_prosemirror_model.Schema({
306
329
  // w:vAlign — 'center' | 'bottom' (top default)
307
330
  borders: { default: null },
308
331
  // w:tcBorders per-side visibility override
309
- padding: { default: null }
332
+ padding: { default: null },
310
333
  // w:tcMar per-side margin override (px)
334
+ // Carry-through fidelity: unmodelled w:tcPr children ({ tcPr: string
335
+ // } — textDirection, noWrap, tcFitText, …), or null. Importer-set.
336
+ carry: { default: null }
311
337
  },
312
338
  parseDOM: [
313
339
  { tag: "td", getAttrs: pastedCellAttrs },
@@ -329,6 +355,8 @@ var schema = new import_prosemirror_model.Schema({
329
355
  attrs["data-borders"] = JSON.stringify(node.attrs["borders"]);
330
356
  if (node.attrs["padding"])
331
357
  attrs["data-padding"] = JSON.stringify(node.attrs["padding"]);
358
+ if (node.attrs["carry"])
359
+ attrs["data-carry"] = JSON.stringify(node.attrs["carry"]);
332
360
  return ["td", attrs, 0];
333
361
  }
334
362
  }
@@ -475,6 +503,28 @@ var schema = new import_prosemirror_model.Schema({
475
503
  0
476
504
  ];
477
505
  }
506
+ },
507
+ // Carry-through fidelity (docx round-trip): run properties the model does
508
+ // NOT represent (w:rtl, w:kern, w:szCs, …), preserved verbatim as one raw
509
+ // XML fragment so saving a customer's file never drops them. Invisible —
510
+ // no rendering; the docx exporter splices `xml` back into the run's rPr.
511
+ // Typing inside/at the edge of a carried run extends the mark (inclusive
512
+ // default), which is the faithful behavior for properties like w:rtl.
513
+ carryRPr: {
514
+ attrs: { xml: {} },
515
+ toDOM(mark) {
516
+ return ["span", { "data-carry-rpr": String(mark.attrs["xml"]) }, 0];
517
+ },
518
+ parseDOM: [
519
+ {
520
+ tag: "span[data-carry-rpr]",
521
+ getAttrs: (el) => ({
522
+ xml: el.getAttribute(
523
+ "data-carry-rpr"
524
+ ) ?? ""
525
+ })
526
+ }
527
+ ]
478
528
  }
479
529
  // The `comment` mark (w:commentRangeStart/End) is contributed by the comment
480
530
  // plugin (@shadow-garden/bapbong-comments) via the editor's schema
package/dist/index.js CHANGED
@@ -15,7 +15,8 @@ function pastedParagraphAttrs(el, heading) {
15
15
  return {
16
16
  heading,
17
17
  align: m ? m[1].toLowerCase() : null,
18
- borders: dataJson(el, "data-borders")
18
+ borders: dataJson(el, "data-borders"),
19
+ carry: dataJson(el, "data-carry")
19
20
  };
20
21
  }
21
22
  function pastedImageAttrs(el) {
@@ -52,7 +53,8 @@ function pastedCellAttrs(el) {
52
53
  background: bg ? bg[1].trim() : null,
53
54
  vAlign: e.getAttribute("data-valign"),
54
55
  borders: dataJson(el, "data-borders"),
55
- padding: dataJson(el, "data-padding")
56
+ padding: dataJson(el, "data-padding"),
57
+ carry: dataJson(el, "data-carry")
56
58
  };
57
59
  }
58
60
  var schema = new Schema({
@@ -108,7 +110,13 @@ var schema = new Schema({
108
110
  pageBreakBefore: { default: false },
109
111
  // w:pBdr — { top?, bottom?, left?, right? } of BorderSide, or null.
110
112
  // Importer-set; painted as a box around the paragraph's lines.
111
- borders: { default: null }
113
+ borders: { default: null },
114
+ // Carry-through fidelity (docx round-trip): OOXML paragraph
115
+ // properties the model does NOT represent, preserved verbatim so a
116
+ // customer's save never drops them. { pPr?: string, markRPr?: string }
117
+ // — raw XML fragments (pPr extras / the paragraph-mark w:rPr), or
118
+ // null. Importer-set; the exporter splices them back into w:pPr.
119
+ carry: { default: null }
112
120
  },
113
121
  // HTML paste path: recover heading level from h1–h6 and alignment from
114
122
  // inline style. Other attrs (list/indent/tabs/spacing) stay importer-only
@@ -128,6 +136,8 @@ var schema = new Schema({
128
136
  if (attrs.styleId) dom["data-style"] = attrs.styleId;
129
137
  if (node.attrs["borders"])
130
138
  dom["data-borders"] = JSON.stringify(node.attrs["borders"]);
139
+ if (node.attrs["carry"])
140
+ dom["data-carry"] = JSON.stringify(node.attrs["carry"]);
131
141
  return [tag, dom, 0];
132
142
  }
133
143
  },
@@ -209,7 +219,12 @@ var schema = new Schema({
209
219
  // insideV }, or null — OOXML tables are borderless unless declared.
210
220
  borders: { default: null },
211
221
  // w:tblPr/w:jc — 'center' | 'right' table alignment, or null (left).
212
- align: { default: null }
222
+ align: { default: null },
223
+ // Carry-through fidelity: unmodelled w:tblPr children (tblStyle,
224
+ // tblLayout, tblLook, tblInd, floating tblpPr, …) as one raw XML
225
+ // string ({ tblPr: string }), or null. Importer-set; the exporter
226
+ // splices it back so a save never drops them.
227
+ carry: { default: null }
213
228
  },
214
229
  // Complex attrs round-trip as data-* JSON — ProseMirror's clipboard is
215
230
  // a toDOM → parseDOM pass, so without this an internal copy/paste
@@ -220,7 +235,8 @@ var schema = new Schema({
220
235
  getAttrs: (el) => ({
221
236
  borders: dataJson(el, "data-borders"),
222
237
  cellPadding: dataJson(el, "data-cell-padding"),
223
- align: el.getAttribute("data-align")
238
+ align: el.getAttribute("data-align"),
239
+ carry: dataJson(el, "data-carry")
224
240
  })
225
241
  }
226
242
  ],
@@ -231,6 +247,7 @@ var schema = new Schema({
231
247
  if (a["cellPadding"])
232
248
  dom["data-cell-padding"] = JSON.stringify(a["cellPadding"]);
233
249
  if (a["align"]) dom["data-align"] = String(a["align"]);
250
+ if (a["carry"]) dom["data-carry"] = JSON.stringify(a["carry"]);
234
251
  return ["table", dom, ["tbody", 0]];
235
252
  }
236
253
  },
@@ -243,7 +260,10 @@ var schema = new Schema({
243
260
  // (Word's default) means the paginator may split the row mid-content.
244
261
  cantSplit: { default: false },
245
262
  // w:trHeight — { value: px, exact: boolean } or null (auto).
246
- height: { default: null }
263
+ height: { default: null },
264
+ // Carry-through fidelity: unmodelled w:trPr children ({ trPr: string
265
+ // } — gridBefore/wBefore, cnfStyle, …), or null. Importer-set.
266
+ carry: { default: null }
247
267
  },
248
268
  parseDOM: [
249
269
  {
@@ -251,7 +271,8 @@ var schema = new Schema({
251
271
  getAttrs: (el) => ({
252
272
  header: el.getAttribute("data-header") === "true",
253
273
  cantSplit: el.getAttribute("data-cant-split") === "true",
254
- height: dataJson(el, "data-height")
274
+ height: dataJson(el, "data-height"),
275
+ carry: dataJson(el, "data-carry")
255
276
  })
256
277
  }
257
278
  ],
@@ -261,6 +282,8 @@ var schema = new Schema({
261
282
  if (node.attrs["cantSplit"]) dom["data-cant-split"] = "true";
262
283
  if (node.attrs["height"])
263
284
  dom["data-height"] = JSON.stringify(node.attrs["height"]);
285
+ if (node.attrs["carry"])
286
+ dom["data-carry"] = JSON.stringify(node.attrs["carry"]);
264
287
  return ["tr", dom, 0];
265
288
  }
266
289
  },
@@ -278,8 +301,11 @@ var schema = new Schema({
278
301
  // w:vAlign — 'center' | 'bottom' (top default)
279
302
  borders: { default: null },
280
303
  // w:tcBorders per-side visibility override
281
- padding: { default: null }
304
+ padding: { default: null },
282
305
  // w:tcMar per-side margin override (px)
306
+ // Carry-through fidelity: unmodelled w:tcPr children ({ tcPr: string
307
+ // } — textDirection, noWrap, tcFitText, …), or null. Importer-set.
308
+ carry: { default: null }
283
309
  },
284
310
  parseDOM: [
285
311
  { tag: "td", getAttrs: pastedCellAttrs },
@@ -301,6 +327,8 @@ var schema = new Schema({
301
327
  attrs["data-borders"] = JSON.stringify(node.attrs["borders"]);
302
328
  if (node.attrs["padding"])
303
329
  attrs["data-padding"] = JSON.stringify(node.attrs["padding"]);
330
+ if (node.attrs["carry"])
331
+ attrs["data-carry"] = JSON.stringify(node.attrs["carry"]);
304
332
  return ["td", attrs, 0];
305
333
  }
306
334
  }
@@ -447,6 +475,28 @@ var schema = new Schema({
447
475
  0
448
476
  ];
449
477
  }
478
+ },
479
+ // Carry-through fidelity (docx round-trip): run properties the model does
480
+ // NOT represent (w:rtl, w:kern, w:szCs, …), preserved verbatim as one raw
481
+ // XML fragment so saving a customer's file never drops them. Invisible —
482
+ // no rendering; the docx exporter splices `xml` back into the run's rPr.
483
+ // Typing inside/at the edge of a carried run extends the mark (inclusive
484
+ // default), which is the faithful behavior for properties like w:rtl.
485
+ carryRPr: {
486
+ attrs: { xml: {} },
487
+ toDOM(mark) {
488
+ return ["span", { "data-carry-rpr": String(mark.attrs["xml"]) }, 0];
489
+ },
490
+ parseDOM: [
491
+ {
492
+ tag: "span[data-carry-rpr]",
493
+ getAttrs: (el) => ({
494
+ xml: el.getAttribute(
495
+ "data-carry-rpr"
496
+ ) ?? ""
497
+ })
498
+ }
499
+ ]
450
500
  }
451
501
  // The `comment` mark (w:commentRangeStart/End) is contributed by the comment
452
502
  // plugin (@shadow-garden/bapbong-comments) via the editor's schema
@@ -8,7 +8,7 @@ import { Schema } from 'prosemirror-model';
8
8
  * extend THIS schema so the importer, layout engine, and (canvas) painter all
9
9
  * agree on one document model.
10
10
  */
11
- export declare const schema: Schema<"doc" | "paragraph" | "text" | "hard_break" | "image" | "page_field" | "table" | "table_row" | "table_cell", "strong" | "em" | "underline" | "strike" | "textColor" | "fontSize" | "vertAlign" | "highlight" | "fontFamily" | "link" | "footnote">;
11
+ export declare const schema: Schema<"doc" | "paragraph" | "text" | "hard_break" | "image" | "page_field" | "table" | "table_row" | "table_cell", "strong" | "em" | "underline" | "strike" | "textColor" | "fontSize" | "vertAlign" | "highlight" | "fontFamily" | "link" | "footnote" | "carryRPr">;
12
12
  /** Concrete schema type, handy for typing Node/Mark across packages. */
13
13
  export type BapbongSchema = typeof schema;
14
14
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/lib/model.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAgF3C;;;;;;;;GAQG;AACH,eAAO,MAAM,MAAM,2PAiZjB,CAAC;AAEH,wEAAwE;AACxE,MAAM,MAAM,aAAa,GAAG,OAAO,MAAM,CAAC;AAE1C;;;;;GAKG;AACH,eAAO,MAAM,aAAa,yDA0CxB,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,OAAO,aAAa,CAAC;AAEjD,qDAAqD;AACrD,MAAM,MAAM,KAAK,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;AAE5D;+EAC+E;AAC/E,MAAM,WAAW,MAAM;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,2EAA2E;AAC3E,MAAM,WAAW,OAAO;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;CACzC;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,QAAQ,GAAG,IAAI,CAAC;IACtB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,CAAC,EAAE,OAAO,GAAG,UAAU,GAAG,IAAI,CAAC;CACvC;AA0BD;;;4EAG4E;AAC5E,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB"}
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/lib/model.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAkF3C;;;;;;;;GAQG;AACH,eAAO,MAAM,MAAM,wQAscjB,CAAC;AAEH,wEAAwE;AACxE,MAAM,MAAM,aAAa,GAAG,OAAO,MAAM,CAAC;AAE1C;;;;;GAKG;AACH,eAAO,MAAM,aAAa,yDA0CxB,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,OAAO,aAAa,CAAC;AAEjD,qDAAqD;AACrD,MAAM,MAAM,KAAK,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;AAE5D;+EAC+E;AAC/E,MAAM,WAAW,MAAM;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,2EAA2E;AAC3E,MAAM,WAAW,OAAO;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;CACzC;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,QAAQ,GAAG,IAAI,CAAC;IACtB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,CAAC,EAAE,OAAO,GAAG,UAAU,GAAG,IAAI,CAAC;CACvC;AA0BD;;;4EAG4E;AAC5E,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shadow-garden/bapbong-model",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "bapbong — ProseMirror document model / schema",
5
5
  "license": "MIT",
6
6
  "repository": {