wordinweb 0.2.2 → 0.2.4
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/{chunk-JGXXZTQE.js → chunk-QH2L3NPL.js} +163 -75
- package/dist/chunk-QH2L3NPL.js.map +1 -0
- package/dist/collab.d.ts +38 -19
- package/dist/collab.js +281 -53
- package/dist/collab.js.map +1 -1
- package/dist/{index-C2J9egkh.d.ts → index-CGp6gVjn.d.ts} +29 -11
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-JGXXZTQE.js.map +0 -1
|
@@ -3930,7 +3930,7 @@ function parseParaChildren(parent, ctx, out, field, bookmarks) {
|
|
|
3930
3930
|
const style = (r) => {
|
|
3931
3931
|
r.props = {
|
|
3932
3932
|
...r.props,
|
|
3933
|
-
color: isInsert ? "#
|
|
3933
|
+
color: isInsert ? "#188038" : "#D93025",
|
|
3934
3934
|
...isInsert ? { underline: "single" } : { strike: true }
|
|
3935
3935
|
};
|
|
3936
3936
|
};
|
|
@@ -5448,6 +5448,7 @@ function parseVmlPict(pict, ctx) {
|
|
|
5448
5448
|
const strokeColor = el16.attrs["strokecolor"];
|
|
5449
5449
|
const stroked = el16.attrs["stroked"] !== "f" && strokeColor !== void 0;
|
|
5450
5450
|
const ta = style.get("v-text-anchor");
|
|
5451
|
+
const rotation = parseFloat(style.get("rotation") ?? "0") || 0;
|
|
5451
5452
|
const vmlInsets = parseVmlInset(findDescendant(el16, "textbox")?.attrs["inset"]);
|
|
5452
5453
|
out.push({
|
|
5453
5454
|
kind: "anchor",
|
|
@@ -5471,6 +5472,7 @@ function parseVmlPict(pict, ctx) {
|
|
|
5471
5472
|
pctWidthRel: relOf(style.get("mso-width-relative")),
|
|
5472
5473
|
pctHeightRel: relOf(style.get("mso-height-relative")),
|
|
5473
5474
|
textAnchor: ta === "middle" ? "middle" : ta === "bottom" ? "bottom" : void 0,
|
|
5475
|
+
...rotation ? { rotation } : {},
|
|
5474
5476
|
...vmlInsets ? { insets: vmlInsets } : {},
|
|
5475
5477
|
srcDrawing: el16,
|
|
5476
5478
|
...ctx.independentTextboxStories ? { textboxStory: true } : {}
|
|
@@ -22774,6 +22776,12 @@ function insertWordArtAt(doc, caretT, text, preset = "plain") {
|
|
|
22774
22776
|
}[preset];
|
|
22775
22777
|
const docPr = descendant3(drawing, "docPr");
|
|
22776
22778
|
if (docPr) docPr.attrs.name = `WordArt ${docPr.attrs.id}`;
|
|
22779
|
+
const anchor = descendant3(drawing, "anchor");
|
|
22780
|
+
if (anchor) {
|
|
22781
|
+
const wrap = anchor.children.findIndex((child4) => localName(child4.name).startsWith("wrap"));
|
|
22782
|
+
if (wrap !== -1) anchor.children[wrap] = el6("wp:wrapNone");
|
|
22783
|
+
anchor.attrs.behindDoc = "0";
|
|
22784
|
+
}
|
|
22777
22785
|
if (preset === "plain") {
|
|
22778
22786
|
const height = String(Math.round(40 * EMU_PER_PX4));
|
|
22779
22787
|
const extent = descendant3(drawing, "extent");
|
|
@@ -22953,8 +22961,39 @@ var NS_WP4 = "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDra
|
|
|
22953
22961
|
function el7(name, attrs = {}, children2 = [], text = "") {
|
|
22954
22962
|
return { name, attrs, children: children2, text };
|
|
22955
22963
|
}
|
|
22964
|
+
function isVmlShape(el16) {
|
|
22965
|
+
return ["shape", "rect"].includes(localName(el16.name));
|
|
22966
|
+
}
|
|
22967
|
+
function vmlStyle(el16) {
|
|
22968
|
+
const style = /* @__PURE__ */ new Map();
|
|
22969
|
+
for (const declaration of (el16.attrs.style ?? "").split(";")) {
|
|
22970
|
+
const colon = declaration.indexOf(":");
|
|
22971
|
+
if (colon > 0) style.set(declaration.slice(0, colon).trim(), declaration.slice(colon + 1).trim());
|
|
22972
|
+
}
|
|
22973
|
+
return style;
|
|
22974
|
+
}
|
|
22975
|
+
function setVmlStyle(el16, patch) {
|
|
22976
|
+
const style = vmlStyle(el16);
|
|
22977
|
+
for (const [key, value] of Object.entries(patch)) {
|
|
22978
|
+
if (value === null) style.delete(key);
|
|
22979
|
+
else style.set(key, value);
|
|
22980
|
+
}
|
|
22981
|
+
el16.attrs.style = [...style].map(([key, value]) => `${key}:${value}`).join(";");
|
|
22982
|
+
}
|
|
22983
|
+
function vmlLengthPx(raw) {
|
|
22984
|
+
if (!raw) return 0;
|
|
22985
|
+
const match = /^(-?[\d.]+)\s*(pt|in|px)?$/.exec(raw.trim());
|
|
22986
|
+
if (!match) return 0;
|
|
22987
|
+
const value = parseFloat(match[1]);
|
|
22988
|
+
if (match[2] === "pt") return value * 4 / 3;
|
|
22989
|
+
if (match[2] === "in") return value * 96;
|
|
22990
|
+
return value;
|
|
22991
|
+
}
|
|
22992
|
+
function pxToVmlPt(px) {
|
|
22993
|
+
return `${Math.round(px * 75) / 100}pt`;
|
|
22994
|
+
}
|
|
22956
22995
|
function isFloatingDrawing(drawingEl) {
|
|
22957
|
-
return !!child(drawingEl, "anchor");
|
|
22996
|
+
return !!child(drawingEl, "anchor") || isVmlShape(drawingEl) && vmlStyle(drawingEl).get("position") === "absolute";
|
|
22958
22997
|
}
|
|
22959
22998
|
function imageAltText(drawingEl) {
|
|
22960
22999
|
const holder = child(drawingEl, "inline") ?? child(drawingEl, "anchor");
|
|
@@ -23069,7 +23108,20 @@ function setFloatingPosition(doc, drawingEl, xPx, yPx) {
|
|
|
23069
23108
|
}
|
|
23070
23109
|
function setFloatingPagePosition(doc, drawingEl, xPx, yPx) {
|
|
23071
23110
|
const anchor = child(drawingEl, "anchor");
|
|
23072
|
-
if (!anchor)
|
|
23111
|
+
if (!anchor) {
|
|
23112
|
+
if (!isVmlShape(drawingEl)) return false;
|
|
23113
|
+
setVmlStyle(drawingEl, {
|
|
23114
|
+
position: "absolute",
|
|
23115
|
+
"margin-left": pxToVmlPt(xPx),
|
|
23116
|
+
"margin-top": pxToVmlPt(yPx),
|
|
23117
|
+
"mso-position-horizontal": "absolute",
|
|
23118
|
+
"mso-position-horizontal-relative": "page",
|
|
23119
|
+
"mso-position-vertical": "absolute",
|
|
23120
|
+
"mso-position-vertical-relative": "page"
|
|
23121
|
+
});
|
|
23122
|
+
doc.refresh();
|
|
23123
|
+
return true;
|
|
23124
|
+
}
|
|
23073
23125
|
const set = (posName, px) => {
|
|
23074
23126
|
let posEl = child(anchor, posName);
|
|
23075
23127
|
if (!posEl) {
|
|
@@ -23088,7 +23140,16 @@ function setFloatingPagePosition(doc, drawingEl, xPx, yPx) {
|
|
|
23088
23140
|
}
|
|
23089
23141
|
function adjustFloatingPosition(doc, drawingEl, dxPx, dyPx) {
|
|
23090
23142
|
const anchor = child(drawingEl, "anchor");
|
|
23091
|
-
if (!anchor)
|
|
23143
|
+
if (!anchor) {
|
|
23144
|
+
if (!isVmlShape(drawingEl) || !isFloatingDrawing(drawingEl)) return false;
|
|
23145
|
+
const style = vmlStyle(drawingEl);
|
|
23146
|
+
setVmlStyle(drawingEl, {
|
|
23147
|
+
"margin-left": pxToVmlPt(vmlLengthPx(style.get("margin-left")) + dxPx),
|
|
23148
|
+
"margin-top": pxToVmlPt(vmlLengthPx(style.get("margin-top")) + dyPx)
|
|
23149
|
+
});
|
|
23150
|
+
doc.refresh();
|
|
23151
|
+
return true;
|
|
23152
|
+
}
|
|
23092
23153
|
const bump = (posName, deltaPx) => {
|
|
23093
23154
|
const posEl = child(anchor, posName);
|
|
23094
23155
|
if (!posEl) return;
|
|
@@ -23118,13 +23179,19 @@ function drawingTransform(drawingEl) {
|
|
|
23118
23179
|
}
|
|
23119
23180
|
function drawingRotation(drawingEl) {
|
|
23120
23181
|
const xfrm = drawingTransform(drawingEl);
|
|
23121
|
-
if (!xfrm) return 0;
|
|
23182
|
+
if (!xfrm) return isVmlShape(drawingEl) ? parseFloat(vmlStyle(drawingEl).get("rotation") ?? "0") || 0 : 0;
|
|
23122
23183
|
const key = Object.keys(xfrm.attrs).find((k) => localName(k) === "rot");
|
|
23123
23184
|
return key ? (parseInt(xfrm.attrs[key], 10) || 0) / 6e4 : 0;
|
|
23124
23185
|
}
|
|
23125
23186
|
function setDrawingRotation(doc, drawingEl, degrees) {
|
|
23126
23187
|
const xfrm = drawingTransform(drawingEl);
|
|
23127
|
-
if (!xfrm)
|
|
23188
|
+
if (!xfrm) {
|
|
23189
|
+
if (!isVmlShape(drawingEl)) return false;
|
|
23190
|
+
const normalized2 = (degrees % 360 + 360) % 360;
|
|
23191
|
+
setVmlStyle(drawingEl, { rotation: normalized2 === 0 ? null : String(Math.round(normalized2 * 100) / 100) });
|
|
23192
|
+
doc.refresh();
|
|
23193
|
+
return true;
|
|
23194
|
+
}
|
|
23128
23195
|
const key = Object.keys(xfrm.attrs).find((k) => localName(k) === "rot") ?? "rot";
|
|
23129
23196
|
const normalized = (degrees % 360 + 360) % 360;
|
|
23130
23197
|
if (normalized === 0) delete xfrm.attrs[key];
|
|
@@ -24176,6 +24243,26 @@ function insertSuggestedText(doc, t, offset, text, meta) {
|
|
|
24176
24243
|
if (offset < t.text.length) afterChildren.push(textLike(t, t.name, t.text.slice(offset)));
|
|
24177
24244
|
afterChildren.push(...following);
|
|
24178
24245
|
if (afterChildren.length > 0) replacement.push(runLike(rEl, rPr, afterChildren));
|
|
24246
|
+
if (localName(parent.name) === "ins") {
|
|
24247
|
+
const grand = doc.findParentOf(parent);
|
|
24248
|
+
if (!grand) return null;
|
|
24249
|
+
const parentIdx = grand.children.indexOf(parent);
|
|
24250
|
+
if (parentIdx === -1) return null;
|
|
24251
|
+
const insIdx = replacement.indexOf(ins);
|
|
24252
|
+
const before = [...parent.children.slice(0, idx), ...replacement.slice(0, insIdx)];
|
|
24253
|
+
const after = [...replacement.slice(insIdx + 1), ...parent.children.slice(idx + 1)];
|
|
24254
|
+
const outerParts = [];
|
|
24255
|
+
if (before.length > 0) outerParts.push({ ...cloneXml(parent), children: before });
|
|
24256
|
+
outerParts.push(ins);
|
|
24257
|
+
if (after.length > 0) {
|
|
24258
|
+
const afterOuter = { ...cloneXml(parent), children: after };
|
|
24259
|
+
const idKey = Object.keys(afterOuter.attrs).find((key) => localName(key) === "id");
|
|
24260
|
+
if (before.length > 0 && idKey) afterOuter.attrs[idKey] = String(meta.nextId());
|
|
24261
|
+
outerParts.push(afterOuter);
|
|
24262
|
+
}
|
|
24263
|
+
grand.children.splice(parentIdx, 1, ...outerParts);
|
|
24264
|
+
return { t: newT, offset: text.length };
|
|
24265
|
+
}
|
|
24179
24266
|
parent.children.splice(idx, 1, ...replacement);
|
|
24180
24267
|
return { t: newT, offset: text.length };
|
|
24181
24268
|
}
|
|
@@ -25409,7 +25496,7 @@ var _DocxEditor = class _DocxEditor {
|
|
|
25409
25496
|
this.caret = caret;
|
|
25410
25497
|
this.positionCaret();
|
|
25411
25498
|
this.focusText();
|
|
25412
|
-
const ref =
|
|
25499
|
+
const ref = this.revisionAtCaret();
|
|
25413
25500
|
if (ref) this.showSuggestionPopover(ref, e.clientX, e.clientY);
|
|
25414
25501
|
} else {
|
|
25415
25502
|
this.hideCaret();
|
|
@@ -28616,7 +28703,7 @@ var _DocxEditor = class _DocxEditor {
|
|
|
28616
28703
|
showSuggestionPopover(ref, clientX, clientY) {
|
|
28617
28704
|
this.dismissSuggestionPopover();
|
|
28618
28705
|
const isIns = ref.kind === "insertion" || ref.kind === "markInsertion";
|
|
28619
|
-
const ink = isIns ? "#
|
|
28706
|
+
const ink = isIns ? "#188038" : "#D93025";
|
|
28620
28707
|
const attrEndingWith = (suffix) => {
|
|
28621
28708
|
const key = Object.keys(ref.el.attrs).find((k) => k.toLowerCase().endsWith(suffix));
|
|
28622
28709
|
return key ? ref.el.attrs[key] : void 0;
|
|
@@ -28671,17 +28758,9 @@ var _DocxEditor = class _DocxEditor {
|
|
|
28671
28758
|
});
|
|
28672
28759
|
btnRow.appendChild(b);
|
|
28673
28760
|
};
|
|
28674
|
-
|
|
28675
|
-
|
|
28676
|
-
|
|
28677
|
-
note.style.cssText = "font-size:11.5px;color:#5f6368;line-height:1.35;";
|
|
28678
|
-
note.textContent = "Accept and reject are not available in a shared session yet.";
|
|
28679
|
-
box.appendChild(note);
|
|
28680
|
-
} else {
|
|
28681
|
-
box.appendChild(btnRow);
|
|
28682
|
-
mkBtn("\u2713 Accept", "Accept this suggestion", true, () => this.acceptRevisionRef(ref));
|
|
28683
|
-
mkBtn("\u2717 Reject", "Reject this suggestion", false, () => this.rejectRevisionRef(ref));
|
|
28684
|
-
}
|
|
28761
|
+
box.appendChild(btnRow);
|
|
28762
|
+
mkBtn("\u2713 Accept", "Accept this suggestion", true, () => this.acceptRevisionRef(ref));
|
|
28763
|
+
mkBtn("\u2717 Reject", "Reject this suggestion", false, () => this.rejectRevisionRef(ref));
|
|
28685
28764
|
document.body.appendChild(box);
|
|
28686
28765
|
this.suggestionPopover = box;
|
|
28687
28766
|
}
|
|
@@ -29625,27 +29704,16 @@ var _DocxEditor = class _DocxEditor {
|
|
|
29625
29704
|
}
|
|
29626
29705
|
return null;
|
|
29627
29706
|
}
|
|
29628
|
-
/** True in a live session, where accept/reject would fork the room.
|
|
29629
|
-
*
|
|
29630
|
-
* Collab gate (narrow): the four accept/reject entry points below mutate
|
|
29631
|
-
* host.doc DIRECTLY (no emission), so in a live session they would resolve
|
|
29632
|
-
* the suggestion locally with no peer ever seeing it — refused per the
|
|
29633
|
-
* standing audit rule (no mutation branch without an emission). The
|
|
29634
|
-
* acceptRevision/rejectRevision/acceptAllRevisions INTENTS exist and apply
|
|
29635
|
-
* fine (collab/src/apply.ts), but they address a revision by its index in
|
|
29636
|
-
* collectRevisions order, which the editor has no path to produce here.
|
|
29637
|
-
* Wiring that is known follow-on work. Local mode is unaffected. */
|
|
29638
|
-
reviewBlockedByCollab() {
|
|
29639
|
-
return !!this.host.onIntent;
|
|
29640
|
-
}
|
|
29641
29707
|
/** Accept (keep insertion / drop deletion) the given revision, or the one at
|
|
29642
29708
|
* the caret. Re-renders and returns whether anything changed. */
|
|
29643
29709
|
acceptRevisionRef(ref) {
|
|
29644
|
-
if (this.reviewBlockedByCollab()) return false;
|
|
29645
29710
|
const target = ref ?? this.revisionAtCaret();
|
|
29646
29711
|
if (!target) return false;
|
|
29712
|
+
const index = this.host.onIntent ? collectRevisions(this.host.doc).findIndex((item) => item.el === target.el && item.kind === target.kind) : -1;
|
|
29713
|
+
if (this.host.onIntent && index < 0) return false;
|
|
29647
29714
|
this.host.history?.checkpoint();
|
|
29648
29715
|
if (!acceptRevision(this.host.doc, target)) return false;
|
|
29716
|
+
if (this.host.onIntent) this.host.onIntent({ kind: "acceptRevision", index });
|
|
29649
29717
|
this.dismissSuggestionPopover();
|
|
29650
29718
|
this.host.rerender();
|
|
29651
29719
|
this.positionCaret();
|
|
@@ -29655,11 +29723,13 @@ var _DocxEditor = class _DocxEditor {
|
|
|
29655
29723
|
/** Reject (drop insertion / restore deletion) the given revision, or the one
|
|
29656
29724
|
* at the caret. */
|
|
29657
29725
|
rejectRevisionRef(ref) {
|
|
29658
|
-
if (this.reviewBlockedByCollab()) return false;
|
|
29659
29726
|
const target = ref ?? this.revisionAtCaret();
|
|
29660
29727
|
if (!target) return false;
|
|
29728
|
+
const index = this.host.onIntent ? collectRevisions(this.host.doc).findIndex((item) => item.el === target.el && item.kind === target.kind) : -1;
|
|
29729
|
+
if (this.host.onIntent && index < 0) return false;
|
|
29661
29730
|
this.host.history?.checkpoint();
|
|
29662
29731
|
if (!rejectRevision(this.host.doc, target)) return false;
|
|
29732
|
+
if (this.host.onIntent) this.host.onIntent({ kind: "rejectRevision", index });
|
|
29663
29733
|
this.dismissSuggestionPopover();
|
|
29664
29734
|
this.host.rerender();
|
|
29665
29735
|
this.positionCaret();
|
|
@@ -29672,10 +29742,10 @@ var _DocxEditor = class _DocxEditor {
|
|
|
29672
29742
|
}
|
|
29673
29743
|
/** Accept every tracked change (one undo step). Returns how many applied. */
|
|
29674
29744
|
acceptAllRevisions() {
|
|
29675
|
-
if (this.reviewBlockedByCollab()) return 0;
|
|
29676
29745
|
this.host.history?.checkpoint();
|
|
29677
29746
|
const n = acceptAllRevisions(this.host.doc);
|
|
29678
29747
|
if (n === 0) return 0;
|
|
29748
|
+
this.host.onIntent?.({ kind: "acceptAllRevisions" });
|
|
29679
29749
|
this.dismissSuggestionPopover();
|
|
29680
29750
|
this.host.rerender();
|
|
29681
29751
|
this.positionCaret();
|
|
@@ -29684,10 +29754,10 @@ var _DocxEditor = class _DocxEditor {
|
|
|
29684
29754
|
}
|
|
29685
29755
|
/** Reject every tracked change (one undo step). Returns how many applied. */
|
|
29686
29756
|
rejectAllRevisions() {
|
|
29687
|
-
if (this.reviewBlockedByCollab()) return 0;
|
|
29688
29757
|
this.host.history?.checkpoint();
|
|
29689
29758
|
const n = rejectAllRevisions(this.host.doc);
|
|
29690
29759
|
if (n === 0) return 0;
|
|
29760
|
+
this.host.onIntent?.({ kind: "rejectAllRevisions" });
|
|
29691
29761
|
this.dismissSuggestionPopover();
|
|
29692
29762
|
this.host.rerender();
|
|
29693
29763
|
this.positionCaret();
|
|
@@ -30172,14 +30242,21 @@ var _DocxEditor = class _DocxEditor {
|
|
|
30172
30242
|
return;
|
|
30173
30243
|
}
|
|
30174
30244
|
const splitPos = this.host.onIntent ? this.encodeCaretForIntent() : null;
|
|
30175
|
-
const
|
|
30245
|
+
const splitMeta = this.suggesting && this.host.onIntent ? this.frozenRevMeta() : void 0;
|
|
30246
|
+
const split = this.splitParagraphCore(splitMeta);
|
|
30176
30247
|
if (split && splitPos && this.host.doc.stableIds && this.host.onIntent) {
|
|
30177
30248
|
const ids = this.host.doc.stableIds;
|
|
30178
30249
|
const alloc = this.host.allocIds?.(2) ?? [];
|
|
30179
30250
|
const newBlockId = ids.assign(split.after, alloc[0]);
|
|
30180
30251
|
const newRunEl = split.after.children.find((c) => localName(c.name) === "r");
|
|
30181
30252
|
const newRunId = newRunEl ? ids.assign(newRunEl, alloc[1]) : newBlockId;
|
|
30182
|
-
this.host.onIntent({
|
|
30253
|
+
this.host.onIntent({
|
|
30254
|
+
kind: "splitParagraph",
|
|
30255
|
+
at: splitPos,
|
|
30256
|
+
newBlockId,
|
|
30257
|
+
newRunId,
|
|
30258
|
+
suggest: splitMeta ? { author: splitMeta.author, date: splitMeta.date } : void 0
|
|
30259
|
+
});
|
|
30183
30260
|
}
|
|
30184
30261
|
const reparsed = split ? this.host.doc.reparseDirectBodyParagraphSplit(split.before, split.after) : null;
|
|
30185
30262
|
if (reparsed && split && this.caret) {
|
|
@@ -30244,9 +30321,10 @@ var _DocxEditor = class _DocxEditor {
|
|
|
30244
30321
|
}
|
|
30245
30322
|
/** Split the paragraph at the caret without history or commit — shared by
|
|
30246
30323
|
* Enter and multi-line paste. */
|
|
30247
|
-
splitParagraphCore() {
|
|
30324
|
+
splitParagraphCore(meta) {
|
|
30248
30325
|
if (!this.caret) return null;
|
|
30249
|
-
const
|
|
30326
|
+
const ctx = meta ? { suggesting: true, revMeta: () => meta } : this.mutationCtx();
|
|
30327
|
+
const result = applySplitParagraph(this.host.doc, this.caret, ctx);
|
|
30250
30328
|
if (!result) return null;
|
|
30251
30329
|
this.caret = result.caret;
|
|
30252
30330
|
return { before: result.before, after: result.after };
|
|
@@ -35975,7 +36053,7 @@ function DocxToolbar({
|
|
|
35975
36053
|
result === "too-large" ? (() => {
|
|
35976
36054
|
const max = api?.imageMaxBytes() ?? null;
|
|
35977
36055
|
return max === null ? "That image is too large for this document." : `Images must be under ${formatBytes(max)}.`;
|
|
35978
|
-
})() : result === "unsupported-format" ? "Images in a shared document must be PNG, JPEG, GIF, BMP or WebP." : result === "no-relay" ? "This shared document has no image relay, so images can\u2019t be added to it." : result === "upload-failed" ? "Upload failed
|
|
36056
|
+
})() : result === "unsupported-format" ? "Images in a shared document must be PNG, JPEG, GIF, BMP or WebP." : result === "no-relay" ? "This shared document has no image relay, so images can\u2019t be added to it." : result === "upload-failed" ? "Upload failed. The image may be too large, or the connection dropped. Try a smaller image." : result === "no-caret" ? "Click in the document before inserting an image." : "That file could not be read as an image."
|
|
35979
36057
|
);
|
|
35980
36058
|
};
|
|
35981
36059
|
const rootRef = useRef2(null);
|
|
@@ -36851,6 +36929,8 @@ function DocxView({
|
|
|
36851
36929
|
const redrawPresenceRef = useRef3(null);
|
|
36852
36930
|
const presenceRef = useRef3(void 0);
|
|
36853
36931
|
presenceRef.current = collab?.presence;
|
|
36932
|
+
const collabRef = useRef3(collab);
|
|
36933
|
+
collabRef.current = collab;
|
|
36854
36934
|
useEffect3(() => {
|
|
36855
36935
|
redrawPresenceRef.current?.();
|
|
36856
36936
|
}, [collab?.presence]);
|
|
@@ -37017,14 +37097,15 @@ function DocxView({
|
|
|
37017
37097
|
};
|
|
37018
37098
|
const emitBlockIntents = (targets, make) => {
|
|
37019
37099
|
const d = docCacheRef.current?.doc;
|
|
37020
|
-
|
|
37100
|
+
const current = collabRef.current;
|
|
37101
|
+
if (!current || !d?.stableIds) return;
|
|
37021
37102
|
const seen = /* @__PURE__ */ new Set();
|
|
37022
37103
|
for (const t of targets) {
|
|
37023
37104
|
const p = paragraphOf(d, t);
|
|
37024
37105
|
const blockId = p ? d.stableIds.idOf(p) : void 0;
|
|
37025
37106
|
if (blockId !== void 0 && !seen.has(blockId)) {
|
|
37026
37107
|
seen.add(blockId);
|
|
37027
|
-
|
|
37108
|
+
current.submit(make(blockId));
|
|
37028
37109
|
}
|
|
37029
37110
|
}
|
|
37030
37111
|
};
|
|
@@ -37034,7 +37115,7 @@ function DocxView({
|
|
|
37034
37115
|
const presence = presenceRef.current;
|
|
37035
37116
|
if (!handle2 || !d || !presence) return;
|
|
37036
37117
|
drawPresenceSelections(handle2.root, computePresenceSelections(handle2, d, presence));
|
|
37037
|
-
drawPresenceCarets(handle2.root, computePresenceCarets(handle2, d, presence),
|
|
37118
|
+
drawPresenceCarets(handle2.root, computePresenceCarets(handle2, d, presence), collabRef.current?.participantNames);
|
|
37038
37119
|
};
|
|
37039
37120
|
redrawPresenceRef.current = drawCollabPresence;
|
|
37040
37121
|
const rerender = (doc, dirtyBlock, scope = "local", dirtySource) => {
|
|
@@ -37170,7 +37251,8 @@ function DocxView({
|
|
|
37170
37251
|
};
|
|
37171
37252
|
const flushPresence = () => {
|
|
37172
37253
|
presenceQueued = false;
|
|
37173
|
-
|
|
37254
|
+
const current = collabRef.current;
|
|
37255
|
+
if (!current?.setPresence) return;
|
|
37174
37256
|
const ranges = selectionRanges();
|
|
37175
37257
|
const last = ranges?.[ranges.length - 1];
|
|
37176
37258
|
const anchor = presenceCaret ?? (last ? { blockId: last.blockId, runId: last.runId, offset: last.end } : null);
|
|
@@ -37178,7 +37260,7 @@ function DocxView({
|
|
|
37178
37260
|
const key = pos ? JSON.stringify(pos) : "null";
|
|
37179
37261
|
if (key === presenceKey) return;
|
|
37180
37262
|
presenceKey = key;
|
|
37181
|
-
|
|
37263
|
+
current.setPresence(pos);
|
|
37182
37264
|
};
|
|
37183
37265
|
const queuePresence = () => {
|
|
37184
37266
|
if (presenceQueued) return;
|
|
@@ -37217,11 +37299,11 @@ function DocxView({
|
|
|
37217
37299
|
onStyleShortcut: (styleId) => applyStyleShortcut?.(styleId),
|
|
37218
37300
|
// Collaboration: forward each local edit as an intent. The editor
|
|
37219
37301
|
// emits only when doc.stableIds is populated, so enable it here.
|
|
37220
|
-
onIntent: collab ? (intent) =>
|
|
37302
|
+
onIntent: collab ? (intent) => collabRef.current?.submit(intent) : void 0,
|
|
37221
37303
|
// Cmd+Z in a room reverses the last SEQUENCED action over the wire;
|
|
37222
37304
|
// without this hook the editor declines rather than replaying local
|
|
37223
37305
|
// history (which would fork the room silently).
|
|
37224
|
-
onCollabUndo: collab?.undoLast,
|
|
37306
|
+
onCollabUndo: collab?.undoLast ? () => collabRef.current?.undoLast?.() : void 0,
|
|
37225
37307
|
// Presence: broadcast the local caret so remote participants can
|
|
37226
37308
|
// draw this user's cursor (the anchor mirrors the intent addressing).
|
|
37227
37309
|
// The caret is recorded here and sent by flushPresence together with
|
|
@@ -37232,7 +37314,7 @@ function DocxView({
|
|
|
37232
37314
|
} : void 0,
|
|
37233
37315
|
// Disjoint carried-id blocks for the editor's node-creating intents
|
|
37234
37316
|
// (paragraph split); see EditorHost.allocIds.
|
|
37235
|
-
allocIds: collab?.allocIds,
|
|
37317
|
+
allocIds: collab?.allocIds ? (n) => collabRef.current?.allocIds?.(n) ?? [] : void 0,
|
|
37236
37318
|
onTextCommand: (command) => {
|
|
37237
37319
|
const current = apiRef.current;
|
|
37238
37320
|
if (!current) return;
|
|
@@ -37337,27 +37419,30 @@ function DocxView({
|
|
|
37337
37419
|
};
|
|
37338
37420
|
const collabAnchor = (t, offset) => doc.stableIds ? doc.stableIds.encodeCaret(t, offset, (el16) => doc.findParentOf(el16) ?? null) : null;
|
|
37339
37421
|
const collabOp = (make, at) => {
|
|
37340
|
-
|
|
37422
|
+
const current = collabRef.current;
|
|
37423
|
+
if (!current?.submitOp || !doc.stableIds) return false;
|
|
37341
37424
|
const target = at !== void 0 ? at : insertionTarget();
|
|
37342
37425
|
if (!target) return true;
|
|
37343
37426
|
const anchor = collabAnchor(target.t, target.offset);
|
|
37344
37427
|
if (!anchor) return true;
|
|
37345
|
-
const intent = make(anchor, (n) =>
|
|
37428
|
+
const intent = make(anchor, (n) => current.allocIds?.(n) ?? []);
|
|
37346
37429
|
if (!intent) return true;
|
|
37347
37430
|
history.checkpoint();
|
|
37348
|
-
|
|
37431
|
+
current.submitOp(intent);
|
|
37349
37432
|
return true;
|
|
37350
37433
|
};
|
|
37351
37434
|
const collabDocOp = (make) => {
|
|
37352
|
-
|
|
37353
|
-
|
|
37435
|
+
const current = collabRef.current;
|
|
37436
|
+
if (!current?.submitOp || !doc.stableIds) return false;
|
|
37437
|
+
const intent = make((n) => current.allocIds?.(n) ?? []);
|
|
37354
37438
|
if (!intent) return true;
|
|
37355
37439
|
history.checkpoint();
|
|
37356
|
-
|
|
37440
|
+
current.submitOp(intent);
|
|
37357
37441
|
return true;
|
|
37358
37442
|
};
|
|
37359
37443
|
const collabBlockOp = (targets, make) => {
|
|
37360
|
-
|
|
37444
|
+
const current = collabRef.current;
|
|
37445
|
+
if (!current?.submitOp || !doc.stableIds) return false;
|
|
37361
37446
|
const submitted = /* @__PURE__ */ new Set();
|
|
37362
37447
|
let any = false;
|
|
37363
37448
|
for (const t of targets) {
|
|
@@ -37368,18 +37453,19 @@ function DocxView({
|
|
|
37368
37453
|
if (!intent) continue;
|
|
37369
37454
|
if (!any) history.checkpoint();
|
|
37370
37455
|
any = true;
|
|
37371
|
-
|
|
37456
|
+
current.submitOp(intent);
|
|
37372
37457
|
}
|
|
37373
37458
|
return true;
|
|
37374
37459
|
};
|
|
37375
|
-
const captureFormatIds = (segs) =>
|
|
37460
|
+
const captureFormatIds = (segs) => collabRef.current && doc.stableIds ? segs.map((seg) => ({
|
|
37376
37461
|
runId: seg.run.src ? doc.stableIds.idOf(seg.run.src) : void 0,
|
|
37377
37462
|
blockId: seg.run.srcParent ? doc.stableIds.idOf(seg.run.srcParent) : void 0,
|
|
37378
37463
|
runLen: seg.run.src ? runWireLength(seg.run.src) : 0,
|
|
37379
37464
|
cumStart: seg.run.src && seg.t ? wireOffsetOf(seg.run.src, seg.t, seg.start) ?? seg.start : seg.start
|
|
37380
37465
|
})) : [];
|
|
37381
37466
|
const emitFormatIntents = (segs, preIds, formatted, patch) => {
|
|
37382
|
-
|
|
37467
|
+
const current = collabRef.current;
|
|
37468
|
+
if (!current || !doc.stableIds) return;
|
|
37383
37469
|
const spanByRun = /* @__PURE__ */ new Map();
|
|
37384
37470
|
segs.forEach((seg, i) => {
|
|
37385
37471
|
const pre = preIds[i];
|
|
@@ -37402,18 +37488,18 @@ function DocxView({
|
|
|
37402
37488
|
const cumEnd = cumStart + (seg.end - seg.start);
|
|
37403
37489
|
const whole = !seg.t || span.lo <= 0 && span.hi >= runLen || (segCountByRun.get(runId) ?? 1) > 1;
|
|
37404
37490
|
if (whole) {
|
|
37405
|
-
|
|
37491
|
+
current.submit({ kind: "formatRun", blockId, runId, patch });
|
|
37406
37492
|
return;
|
|
37407
37493
|
}
|
|
37408
37494
|
const before = cumStart > 0;
|
|
37409
37495
|
const after = cumEnd < runLen;
|
|
37410
|
-
const alloc =
|
|
37496
|
+
const alloc = current.allocIds?.((before ? 1 : 0) + 1 + (after ? 1 : 0)) ?? [];
|
|
37411
37497
|
let k = 0;
|
|
37412
37498
|
const beforeId = before ? alloc[k++] : void 0;
|
|
37413
37499
|
const middleId = alloc[k++];
|
|
37414
37500
|
const afterId = after ? alloc[k++] : void 0;
|
|
37415
37501
|
if (middleId === void 0) return;
|
|
37416
|
-
|
|
37502
|
+
current.submit({ kind: "formatRange", blockId, runId, start: cumStart, end: cumEnd, patch, beforeId, middleId, afterId });
|
|
37417
37503
|
const middleT = formatted[i]?.t;
|
|
37418
37504
|
const middleRun = middleT ? doc.findParentOf(middleT) : null;
|
|
37419
37505
|
const parent = middleRun ? doc.findParentOf(middleRun) : null;
|
|
@@ -37567,7 +37653,7 @@ function DocxView({
|
|
|
37567
37653
|
return true;
|
|
37568
37654
|
},
|
|
37569
37655
|
updateSelectedChart: (data) => {
|
|
37570
|
-
if (
|
|
37656
|
+
if (collabRef.current?.submitOp) return false;
|
|
37571
37657
|
const source2 = editor?.getSelectedDrawingSource();
|
|
37572
37658
|
if (!source2) return false;
|
|
37573
37659
|
history.checkpoint();
|
|
@@ -37587,7 +37673,7 @@ function DocxView({
|
|
|
37587
37673
|
return true;
|
|
37588
37674
|
},
|
|
37589
37675
|
updateSelectedSmartArt: (data) => {
|
|
37590
|
-
if (
|
|
37676
|
+
if (collabRef.current?.submitOp) return false;
|
|
37591
37677
|
const source2 = editor?.getSelectedDrawingSource();
|
|
37592
37678
|
if (!source2) return false;
|
|
37593
37679
|
history.checkpoint();
|
|
@@ -37598,7 +37684,7 @@ function DocxView({
|
|
|
37598
37684
|
},
|
|
37599
37685
|
getSelectedSmartArt: () => editor?.getSelectedSmartArtData() ?? null,
|
|
37600
37686
|
insertModel3D: async (file, poster) => {
|
|
37601
|
-
if (
|
|
37687
|
+
if (collabRef.current?.submitOp) return false;
|
|
37602
37688
|
const target = insertionTarget();
|
|
37603
37689
|
if (!target) return false;
|
|
37604
37690
|
const preview = poster ?? await objectPoster("3D model", "Double-click in Word to explore", "\u25C7");
|
|
@@ -37610,7 +37696,7 @@ function DocxView({
|
|
|
37610
37696
|
return true;
|
|
37611
37697
|
},
|
|
37612
37698
|
insertOnlineVideo: async (url) => {
|
|
37613
|
-
if (
|
|
37699
|
+
if (collabRef.current?.submitOp) return false;
|
|
37614
37700
|
const target = insertionTarget();
|
|
37615
37701
|
if (!target) return false;
|
|
37616
37702
|
const preview = await objectPoster("Online video", url, "\u25B6");
|
|
@@ -37621,7 +37707,7 @@ function DocxView({
|
|
|
37621
37707
|
return true;
|
|
37622
37708
|
},
|
|
37623
37709
|
insertEmbeddedObject: async (file, filename) => {
|
|
37624
|
-
if (
|
|
37710
|
+
if (collabRef.current?.submitOp) return false;
|
|
37625
37711
|
const target = insertionTarget();
|
|
37626
37712
|
if (!target) return false;
|
|
37627
37713
|
const name = filename ?? (file instanceof File ? file.name : "embedded-file.bin");
|
|
@@ -37642,7 +37728,7 @@ function DocxView({
|
|
|
37642
37728
|
getSelectedSmartArtTextFormat: () => editor?.getSelectedSmartArtTextFormat() ?? null,
|
|
37643
37729
|
setSelectedSmartArtTextFormat: (patch) => editor?.setSelectedSmartArtTextFormat(patch) ?? false,
|
|
37644
37730
|
addComment: (text) => {
|
|
37645
|
-
if (
|
|
37731
|
+
if (collabRef.current?.submitOp) return false;
|
|
37646
37732
|
const segs = editor?.getSelectionSegments() ?? [];
|
|
37647
37733
|
const segments = segs.length > 0 ? segs : handle ? selectionToSegments(handle.bindings) : [];
|
|
37648
37734
|
if (segments.length === 0) return false;
|
|
@@ -37684,12 +37770,12 @@ function DocxView({
|
|
|
37684
37770
|
const caret = editor?.getCaretTarget();
|
|
37685
37771
|
return caret ? cellShadingAt(doc, caret.t) : void 0;
|
|
37686
37772
|
},
|
|
37687
|
-
imageAccept: () =>
|
|
37688
|
-
imageMaxBytes: () =>
|
|
37773
|
+
imageAccept: () => collabRef.current?.submitOp && doc.stableIds ? COLLAB_IMAGE_ACCEPT : LOCAL_IMAGE_ACCEPT,
|
|
37774
|
+
imageMaxBytes: () => collabRef.current?.submitOp && doc.stableIds ? collabRef.current.mediaMaxBlobBytes ?? null : null,
|
|
37689
37775
|
insertImage: async (file) => {
|
|
37690
37776
|
const caret = insertionTarget() ?? documentStart();
|
|
37691
37777
|
if (!caret) return "no-caret";
|
|
37692
|
-
const maxBytes =
|
|
37778
|
+
const maxBytes = collabRef.current?.submitOp && doc.stableIds ? collabRef.current.mediaMaxBlobBytes ?? null : null;
|
|
37693
37779
|
if (typeof maxBytes === "number" && file.size > maxBytes) return "too-large";
|
|
37694
37780
|
const bytes2 = new Uint8Array(await file.arrayBuffer());
|
|
37695
37781
|
const isSvg = file.type === "image/svg+xml";
|
|
@@ -37702,11 +37788,12 @@ function DocxView({
|
|
|
37702
37788
|
const maxW = sp ? sp.pageWidth - sp.marginLeft - sp.marginRight : 624;
|
|
37703
37789
|
const scale = Math.min(1, maxW / naturalWidth);
|
|
37704
37790
|
const ext = file.type === "image/svg+xml" ? "svg" : (file.type.split("/")[1] ?? "png").replace("jpeg", "jpg");
|
|
37705
|
-
|
|
37791
|
+
const current = collabRef.current;
|
|
37792
|
+
if (current?.submitOp && doc.stableIds) {
|
|
37706
37793
|
bmp?.close();
|
|
37707
|
-
if (!
|
|
37794
|
+
if (!current.uploadMedia) return "no-relay";
|
|
37708
37795
|
if (!COLLAB_IMAGE_EXTS.includes(ext)) return "unsupported-format";
|
|
37709
|
-
const media = await
|
|
37796
|
+
const media = await current.uploadMedia(bytes2);
|
|
37710
37797
|
if (!media) return "upload-failed";
|
|
37711
37798
|
const w = naturalWidth * scale;
|
|
37712
37799
|
const h2 = naturalHeight * scale;
|
|
@@ -38287,6 +38374,7 @@ export {
|
|
|
38287
38374
|
acceptRevision,
|
|
38288
38375
|
rejectRevision,
|
|
38289
38376
|
acceptAllRevisions,
|
|
38377
|
+
rejectAllRevisions,
|
|
38290
38378
|
applyInsertText,
|
|
38291
38379
|
applyDeleteRange,
|
|
38292
38380
|
applySplitParagraph,
|
|
@@ -38321,4 +38409,4 @@ export {
|
|
|
38321
38409
|
cfb/cfb.js:
|
|
38322
38410
|
(*! crc32.js (C) 2014-present SheetJS -- http://sheetjs.com *)
|
|
38323
38411
|
*/
|
|
38324
|
-
//# sourceMappingURL=chunk-
|
|
38412
|
+
//# sourceMappingURL=chunk-QH2L3NPL.js.map
|