docxodus 9.4.0 → 9.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/editor.bundle.js +514 -93
- package/dist/editor.d.ts +71 -11
- package/dist/editor.d.ts.map +1 -1
- package/dist/editor.js +220 -69
- package/dist/editor.js.map +1 -1
- package/dist/embed.bundle.js +523 -94
- package/dist/embed.iife.js +523 -94
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/page-geometry.d.ts +74 -0
- package/dist/page-geometry.d.ts.map +1 -0
- package/dist/page-geometry.js +105 -0
- package/dist/page-geometry.js.map +1 -0
- package/dist/pagination.bundle.js +8 -6
- package/dist/pagination.d.ts +2 -25
- package/dist/pagination.d.ts.map +1 -1
- package/dist/pagination.js +2 -45
- package/dist/pagination.js.map +1 -1
- package/dist/ribbon-chrome.d.ts +1 -1
- package/dist/ribbon-chrome.d.ts.map +1 -1
- package/dist/ribbon-chrome.js +18 -18
- package/dist/ribbon.js +2 -0
- package/dist/ribbon.js.map +1 -1
- package/dist/viewport.d.ts +80 -0
- package/dist/viewport.d.ts.map +1 -0
- package/dist/viewport.js +139 -0
- package/dist/viewport.js.map +1 -0
- package/dist/wasm/_framework/Docxodus.wasm +0 -0
- package/dist/wasm/_framework/Docxodus.wasm.br +0 -0
- package/dist/wasm/_framework/DocxodusWasm.wasm +0 -0
- package/dist/wasm/_framework/DocxodusWasm.wasm.br +0 -0
- package/dist/wasm/_framework/dotnet.boot.js +3 -3
- package/dist/wasm/_framework/dotnet.boot.js.br +0 -0
- package/package.json +2 -2
package/dist/editor.bundle.js
CHANGED
|
@@ -161,20 +161,18 @@ var DocxodusEditor = (() => {
|
|
|
161
161
|
return (renderer ?? RENDERERS.decimal)(value);
|
|
162
162
|
}
|
|
163
163
|
|
|
164
|
-
// src/
|
|
164
|
+
// src/page-geometry.ts
|
|
165
165
|
var DEFAULT_PAGE_WIDTH = 612;
|
|
166
166
|
var DEFAULT_PAGE_HEIGHT = 792;
|
|
167
167
|
var DEFAULT_MARGIN = 72;
|
|
168
|
-
var
|
|
169
|
-
var MIN_BODY_CONTENT_HEIGHT = 72;
|
|
168
|
+
var DEFAULT_HEADER_FOOTER_HEIGHT = 36;
|
|
170
169
|
function pxToPt(px) {
|
|
171
170
|
return px * 0.75;
|
|
172
171
|
}
|
|
173
172
|
function ptToPx(pt) {
|
|
174
173
|
return pt / 0.75;
|
|
175
174
|
}
|
|
176
|
-
|
|
177
|
-
function parseDimensions(section) {
|
|
175
|
+
function parseSectionDimensions(section) {
|
|
178
176
|
const pageWidth = parseFloat(section.dataset.pageWidth || "") || DEFAULT_PAGE_WIDTH;
|
|
179
177
|
const pageHeight = parseFloat(section.dataset.pageHeight || "") || DEFAULT_PAGE_HEIGHT;
|
|
180
178
|
const contentWidth = parseFloat(section.dataset.contentWidth || "") || pageWidth - 2 * DEFAULT_MARGIN;
|
|
@@ -198,6 +196,42 @@ var DocxodusEditor = (() => {
|
|
|
198
196
|
footerHeight
|
|
199
197
|
};
|
|
200
198
|
}
|
|
199
|
+
function sectionWrappers(root) {
|
|
200
|
+
const sections = Array.from(root.querySelectorAll("[data-section-index]"));
|
|
201
|
+
return sections.length > 0 ? sections : [root];
|
|
202
|
+
}
|
|
203
|
+
var MIN_FIT_SCALE = 0.25;
|
|
204
|
+
function fitScale(availablePx, naturalPt, max = 1) {
|
|
205
|
+
if (!(availablePx > 0) || !(naturalPt > 0)) return max;
|
|
206
|
+
const naturalPx = ptToPx(naturalPt);
|
|
207
|
+
if (naturalPx <= availablePx) return max;
|
|
208
|
+
return Math.max(MIN_FIT_SCALE, Math.min(max, availablePx / naturalPx));
|
|
209
|
+
}
|
|
210
|
+
function applyZoom(el, scale, naturalPt) {
|
|
211
|
+
if (scale === 1) {
|
|
212
|
+
el.style.removeProperty("zoom");
|
|
213
|
+
el.style.removeProperty("transform");
|
|
214
|
+
el.style.removeProperty("transform-origin");
|
|
215
|
+
el.style.removeProperty("margin-right");
|
|
216
|
+
el.style.removeProperty("margin-bottom");
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
const zoomSupported = typeof CSS !== "undefined" && typeof CSS.supports === "function" && CSS.supports("zoom", "0.5");
|
|
220
|
+
if (zoomSupported) {
|
|
221
|
+
el.style.zoom = String(scale);
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
el.style.transform = `scale(${scale})`;
|
|
225
|
+
el.style.transformOrigin = "top left";
|
|
226
|
+
if (naturalPt) {
|
|
227
|
+
el.style.marginRight = `-${ptToPx(naturalPt.width * (1 - scale))}px`;
|
|
228
|
+
el.style.marginBottom = `-${ptToPx(naturalPt.height * (1 - scale))}px`;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// src/pagination.ts
|
|
233
|
+
var MAX_FOOTNOTE_AREA_RATIO = 0.6;
|
|
234
|
+
var MIN_BODY_CONTENT_HEIGHT = 72;
|
|
201
235
|
var PaginationEngine = class {
|
|
202
236
|
/**
|
|
203
237
|
* Creates a new pagination engine.
|
|
@@ -243,7 +277,7 @@ var DocxodusEditor = (() => {
|
|
|
243
277
|
const sectionsToProcess = sections.length > 0 ? Array.from(sections) : [this.stagingElement];
|
|
244
278
|
for (const section of sectionsToProcess) {
|
|
245
279
|
const sectionIndex = parseInt(section.dataset.sectionIndex || "0", 10);
|
|
246
|
-
const dims =
|
|
280
|
+
const dims = parseSectionDimensions(section);
|
|
247
281
|
this.stagingElement.style.visibility = "hidden";
|
|
248
282
|
this.stagingElement.style.position = "absolute";
|
|
249
283
|
this.stagingElement.style.left = "-9999px";
|
|
@@ -1541,6 +1575,114 @@ var DocxodusEditor = (() => {
|
|
|
1541
1575
|
return engine.paginate();
|
|
1542
1576
|
}
|
|
1543
1577
|
|
|
1578
|
+
// src/viewport.ts
|
|
1579
|
+
var DocumentViewport = class {
|
|
1580
|
+
constructor(host, options = {}) {
|
|
1581
|
+
this.root = null;
|
|
1582
|
+
/** Natural page size in points — the widest section's PAGE box, which is what must fit. */
|
|
1583
|
+
this.natural = { width: 0, height: 0 };
|
|
1584
|
+
this.observer = null;
|
|
1585
|
+
this.host = host;
|
|
1586
|
+
this.options = {
|
|
1587
|
+
columnWidth: options.columnWidth ?? "section",
|
|
1588
|
+
fitToWidth: options.fitToWidth ?? true,
|
|
1589
|
+
scale: options.scale ?? 1
|
|
1590
|
+
};
|
|
1591
|
+
}
|
|
1592
|
+
/**
|
|
1593
|
+
* Adopt a freshly mounted document root (a continuous flow, or the paginated page stack).
|
|
1594
|
+
* Safe to call on every remount; the previous root is released first.
|
|
1595
|
+
*
|
|
1596
|
+
* `applySectionGeometry` is false for the paginated view, which already builds real page
|
|
1597
|
+
* boxes at the section's dimensions — there the viewport contributes only the fit zoom.
|
|
1598
|
+
*/
|
|
1599
|
+
attach(root, applySectionGeometry) {
|
|
1600
|
+
this.release();
|
|
1601
|
+
this.root = root;
|
|
1602
|
+
this.natural = applySectionGeometry ? this.stampSections(root) : this.measurePages(root);
|
|
1603
|
+
this.refresh();
|
|
1604
|
+
if (typeof ResizeObserver !== "undefined") {
|
|
1605
|
+
this.observer = new ResizeObserver(() => this.refresh());
|
|
1606
|
+
this.observer.observe(this.host);
|
|
1607
|
+
}
|
|
1608
|
+
}
|
|
1609
|
+
/** Recompute the fit zoom against the host's current width. */
|
|
1610
|
+
refresh() {
|
|
1611
|
+
if (!this.root) return;
|
|
1612
|
+
const scale = this.scale;
|
|
1613
|
+
applyZoom(this.root, scale, this.natural);
|
|
1614
|
+
this.host.style.setProperty(
|
|
1615
|
+
"--docx-sheet-width",
|
|
1616
|
+
this.natural.width > 0 ? `${ptToPx(this.natural.width) * scale}px` : "100%"
|
|
1617
|
+
);
|
|
1618
|
+
}
|
|
1619
|
+
/** The zoom currently applied (1 = 100%). Reported by the ribbon's anchor rail. */
|
|
1620
|
+
get scale() {
|
|
1621
|
+
if (!this.root) return this.options.scale;
|
|
1622
|
+
return this.options.fitToWidth ? fitScale(this.availableWidthPx(), this.natural.width, this.options.scale) : this.options.scale;
|
|
1623
|
+
}
|
|
1624
|
+
dispose() {
|
|
1625
|
+
this.release();
|
|
1626
|
+
this.root = null;
|
|
1627
|
+
}
|
|
1628
|
+
release() {
|
|
1629
|
+
this.observer?.disconnect();
|
|
1630
|
+
this.observer = null;
|
|
1631
|
+
if (this.root) applyZoom(this.root, 1);
|
|
1632
|
+
this.host.style.removeProperty("--docx-sheet-width");
|
|
1633
|
+
}
|
|
1634
|
+
/** The host's content box, which is the space a page has to fit into. */
|
|
1635
|
+
availableWidthPx() {
|
|
1636
|
+
const style = typeof getComputedStyle === "function" ? getComputedStyle(this.host) : null;
|
|
1637
|
+
const padding = style ? (parseFloat(style.paddingLeft) || 0) + (parseFloat(style.paddingRight) || 0) : 0;
|
|
1638
|
+
return Math.max(0, this.host.clientWidth - padding);
|
|
1639
|
+
}
|
|
1640
|
+
/**
|
|
1641
|
+
* Give each section wrapper its `w:sectPr` geometry: the authored text column, guttered by
|
|
1642
|
+
* the authored margins. The wrapper then measures exactly one page wide, which is what the
|
|
1643
|
+
* sheet chrome paints and what the fit zoom scales.
|
|
1644
|
+
*/
|
|
1645
|
+
stampSections(root) {
|
|
1646
|
+
const sections = sectionWrappers(root);
|
|
1647
|
+
if (this.options.columnWidth === "fluid") {
|
|
1648
|
+
root.style.removeProperty("width");
|
|
1649
|
+
for (const section of sections) {
|
|
1650
|
+
section.style.removeProperty("width");
|
|
1651
|
+
section.style.removeProperty("padding-left");
|
|
1652
|
+
section.style.removeProperty("padding-right");
|
|
1653
|
+
}
|
|
1654
|
+
return { width: 0, height: 0 };
|
|
1655
|
+
}
|
|
1656
|
+
let widest = 0;
|
|
1657
|
+
for (const section of sections) {
|
|
1658
|
+
const dims = parseSectionDimensions(section);
|
|
1659
|
+
section.style.width = `${dims.contentWidth}pt`;
|
|
1660
|
+
section.style.paddingLeft = `${dims.marginLeft}pt`;
|
|
1661
|
+
section.style.paddingRight = `${dims.marginRight}pt`;
|
|
1662
|
+
section.style.boxSizing = "content-box";
|
|
1663
|
+
section.style.marginLeft = "auto";
|
|
1664
|
+
section.style.marginRight = "auto";
|
|
1665
|
+
widest = Math.max(widest, dims.pageWidth);
|
|
1666
|
+
}
|
|
1667
|
+
if (widest > 0 && sections[0] !== root) root.style.width = `${widest}pt`;
|
|
1668
|
+
return { width: widest, height: 0 };
|
|
1669
|
+
}
|
|
1670
|
+
/**
|
|
1671
|
+
* The paginated view's page boxes are already page-sized — `pagination.ts` writes each
|
|
1672
|
+
* box's `width` in points — so the widest of those is the natural width. Reading the
|
|
1673
|
+
* inline width rather than the laid-out box keeps this independent of the per-box zoom
|
|
1674
|
+
* pagination may itself have applied.
|
|
1675
|
+
*/
|
|
1676
|
+
measurePages(root) {
|
|
1677
|
+
let widest = 0;
|
|
1678
|
+
for (const box of Array.from(root.children)) {
|
|
1679
|
+
const declared = /^([\d.]+)pt$/.exec(box.style.width || "");
|
|
1680
|
+
widest = Math.max(widest, declared ? parseFloat(declared[1]) : pxToPt(box.offsetWidth));
|
|
1681
|
+
}
|
|
1682
|
+
return { width: widest, height: 0 };
|
|
1683
|
+
}
|
|
1684
|
+
};
|
|
1685
|
+
|
|
1544
1686
|
// src/editor-headerfooter.ts
|
|
1545
1687
|
var PAGE_FORMAT_LABELS = [
|
|
1546
1688
|
{ value: "", label: "Format\u2026" },
|
|
@@ -3629,6 +3771,146 @@ var DocxodusEditor = (() => {
|
|
|
3629
3771
|
return once(cleanup);
|
|
3630
3772
|
}
|
|
3631
3773
|
|
|
3774
|
+
// node_modules/@atlaskit/pragmatic-drag-and-drop/dist/esm/public-utils/element/custom-native-drag-preview/set-custom-native-drag-preview.js
|
|
3775
|
+
function ownKeys4(e, r) {
|
|
3776
|
+
var t = Object.keys(e);
|
|
3777
|
+
if (Object.getOwnPropertySymbols) {
|
|
3778
|
+
var o = Object.getOwnPropertySymbols(e);
|
|
3779
|
+
r && (o = o.filter(function(r2) {
|
|
3780
|
+
return Object.getOwnPropertyDescriptor(e, r2).enumerable;
|
|
3781
|
+
})), t.push.apply(t, o);
|
|
3782
|
+
}
|
|
3783
|
+
return t;
|
|
3784
|
+
}
|
|
3785
|
+
function _objectSpread4(e) {
|
|
3786
|
+
for (var r = 1; r < arguments.length; r++) {
|
|
3787
|
+
var t = null != arguments[r] ? arguments[r] : {};
|
|
3788
|
+
r % 2 ? ownKeys4(Object(t), true).forEach(function(r2) {
|
|
3789
|
+
_defineProperty(e, r2, t[r2]);
|
|
3790
|
+
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys4(Object(t)).forEach(function(r2) {
|
|
3791
|
+
Object.defineProperty(e, r2, Object.getOwnPropertyDescriptor(t, r2));
|
|
3792
|
+
});
|
|
3793
|
+
}
|
|
3794
|
+
return e;
|
|
3795
|
+
}
|
|
3796
|
+
function defaultOffset() {
|
|
3797
|
+
return {
|
|
3798
|
+
x: 0,
|
|
3799
|
+
y: 0
|
|
3800
|
+
};
|
|
3801
|
+
}
|
|
3802
|
+
function setCustomNativeDragPreview(_ref) {
|
|
3803
|
+
var render = _ref.render, nativeSetDragImage = _ref.nativeSetDragImage, _ref$getOffset = _ref.getOffset, getOffset = _ref$getOffset === void 0 ? defaultOffset : _ref$getOffset;
|
|
3804
|
+
var container = document.createElement("div");
|
|
3805
|
+
if (supportsPopover()) {
|
|
3806
|
+
container.setAttribute("popover", "manual");
|
|
3807
|
+
}
|
|
3808
|
+
Object.assign(container.style, _objectSpread4(_objectSpread4({
|
|
3809
|
+
// Ensuring we don't cause reflow when adding the element to the page
|
|
3810
|
+
// Using `position:fixed` rather than `position:absolute` so we are
|
|
3811
|
+
// positioned on the current viewport.
|
|
3812
|
+
// `position:fixed` also creates a new stacking context, so we don't need to do that here
|
|
3813
|
+
position: "fixed"
|
|
3814
|
+
}, supportsPopover() ? (
|
|
3815
|
+
// needs to come first as it has 'inset: unset' which
|
|
3816
|
+
// needs to be overridden by our top / left values
|
|
3817
|
+
popoverResetUserAgentStyles
|
|
3818
|
+
) : {
|
|
3819
|
+
// Fallback: using maximum possible z-index so that this element
|
|
3820
|
+
// will always be on top of other positioned content.
|
|
3821
|
+
zIndex: maxZIndex
|
|
3822
|
+
}), {}, {
|
|
3823
|
+
// According to `mdn`, the element can be offscreen:
|
|
3824
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/setDragImage#imgelement
|
|
3825
|
+
//
|
|
3826
|
+
// However, that information does not appear in the specs:
|
|
3827
|
+
// https://html.spec.whatwg.org/multipage/dnd.html#dom-datatransfer-setdragimage-dev
|
|
3828
|
+
//
|
|
3829
|
+
// If the element is _completely_ offscreen, Safari@17.1 will cancel the drag
|
|
3830
|
+
top: 0,
|
|
3831
|
+
left: 0,
|
|
3832
|
+
// Avoiding any additional events caused by the new element (being super safe)
|
|
3833
|
+
pointerEvents: "none"
|
|
3834
|
+
}));
|
|
3835
|
+
document.body.append(container);
|
|
3836
|
+
if (supportsPopover()) {
|
|
3837
|
+
container.showPopover();
|
|
3838
|
+
}
|
|
3839
|
+
var unmount = render({
|
|
3840
|
+
container
|
|
3841
|
+
});
|
|
3842
|
+
queueMicrotask(function() {
|
|
3843
|
+
var previewOffset = getOffset({
|
|
3844
|
+
container
|
|
3845
|
+
});
|
|
3846
|
+
if (isSafari()) {
|
|
3847
|
+
var rect = container.getBoundingClientRect();
|
|
3848
|
+
if (rect.width === 0) {
|
|
3849
|
+
return;
|
|
3850
|
+
}
|
|
3851
|
+
container.style.left = "-".concat(rect.width - 1e-4, "px");
|
|
3852
|
+
}
|
|
3853
|
+
nativeSetDragImage === null || nativeSetDragImage === void 0 || nativeSetDragImage(container, previewOffset.x, previewOffset.y);
|
|
3854
|
+
});
|
|
3855
|
+
function cleanup() {
|
|
3856
|
+
unbindMonitor();
|
|
3857
|
+
unmount === null || unmount === void 0 || unmount();
|
|
3858
|
+
document.body.removeChild(container);
|
|
3859
|
+
}
|
|
3860
|
+
var unbindMonitor = monitorForElements({
|
|
3861
|
+
// Remove portal in the dragstart event so that the user will never see it
|
|
3862
|
+
onDragStart: cleanup,
|
|
3863
|
+
// Backup: remove portal when the drop finishes (this would be an error case)
|
|
3864
|
+
onDrop: cleanup
|
|
3865
|
+
});
|
|
3866
|
+
}
|
|
3867
|
+
|
|
3868
|
+
// node_modules/@atlaskit/pragmatic-drag-and-drop/dist/esm/util/is-safari-on-ios.js
|
|
3869
|
+
var isSafariOnIOS = once(function isSafariOnIOS2() {
|
|
3870
|
+
if (false) {
|
|
3871
|
+
return false;
|
|
3872
|
+
}
|
|
3873
|
+
return isSafari() && "ontouchend" in document;
|
|
3874
|
+
});
|
|
3875
|
+
|
|
3876
|
+
// node_modules/@atlaskit/pragmatic-drag-and-drop/dist/esm/public-utils/element/custom-native-drag-preview/center-under-pointer.js
|
|
3877
|
+
var centerUnderPointer = function centerUnderPointer2(_ref) {
|
|
3878
|
+
var container = _ref.container;
|
|
3879
|
+
var rect = container.getBoundingClientRect();
|
|
3880
|
+
return {
|
|
3881
|
+
x: rect.width / 2,
|
|
3882
|
+
y: rect.height / 2
|
|
3883
|
+
};
|
|
3884
|
+
};
|
|
3885
|
+
|
|
3886
|
+
// node_modules/@atlaskit/pragmatic-drag-and-drop/dist/esm/public-utils/element/custom-native-drag-preview/pointer-outside-of-preview.js
|
|
3887
|
+
function pointerOutsideOfPreview(point) {
|
|
3888
|
+
return function getOffset(_ref) {
|
|
3889
|
+
var container = _ref.container;
|
|
3890
|
+
if (isSafariOnIOS() || isAndroid()) {
|
|
3891
|
+
return centerUnderPointer({
|
|
3892
|
+
container
|
|
3893
|
+
});
|
|
3894
|
+
}
|
|
3895
|
+
Object.assign(container.style, {
|
|
3896
|
+
borderInlineStart: "".concat(point.x, " solid transparent"),
|
|
3897
|
+
borderTop: "".concat(point.y, " solid transparent")
|
|
3898
|
+
});
|
|
3899
|
+
var computed = window.getComputedStyle(container);
|
|
3900
|
+
if (computed.direction === "rtl") {
|
|
3901
|
+
var box = container.getBoundingClientRect();
|
|
3902
|
+
return {
|
|
3903
|
+
x: box.width,
|
|
3904
|
+
y: 0
|
|
3905
|
+
};
|
|
3906
|
+
}
|
|
3907
|
+
return {
|
|
3908
|
+
x: 0,
|
|
3909
|
+
y: 0
|
|
3910
|
+
};
|
|
3911
|
+
};
|
|
3912
|
+
}
|
|
3913
|
+
|
|
3632
3914
|
// node_modules/@atlaskit/pragmatic-drag-and-drop-auto-scroll/dist/esm/shared/engagement-history.js
|
|
3633
3915
|
var ledger2 = /* @__PURE__ */ new Map();
|
|
3634
3916
|
var requested = /* @__PURE__ */ new Set();
|
|
@@ -3762,7 +4044,7 @@ var DocxodusEditor = (() => {
|
|
|
3762
4044
|
}
|
|
3763
4045
|
|
|
3764
4046
|
// node_modules/@atlaskit/pragmatic-drag-and-drop-auto-scroll/dist/esm/shared/configuration.js
|
|
3765
|
-
function
|
|
4047
|
+
function ownKeys5(e, r) {
|
|
3766
4048
|
var t = Object.keys(e);
|
|
3767
4049
|
if (Object.getOwnPropertySymbols) {
|
|
3768
4050
|
var o = Object.getOwnPropertySymbols(e);
|
|
@@ -3772,12 +4054,12 @@ var DocxodusEditor = (() => {
|
|
|
3772
4054
|
}
|
|
3773
4055
|
return t;
|
|
3774
4056
|
}
|
|
3775
|
-
function
|
|
4057
|
+
function _objectSpread5(e) {
|
|
3776
4058
|
for (var r = 1; r < arguments.length; r++) {
|
|
3777
4059
|
var t = null != arguments[r] ? arguments[r] : {};
|
|
3778
|
-
r % 2 ?
|
|
4060
|
+
r % 2 ? ownKeys5(Object(t), true).forEach(function(r2) {
|
|
3779
4061
|
_defineProperty(e, r2, t[r2]);
|
|
3780
|
-
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) :
|
|
4062
|
+
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys5(Object(t)).forEach(function(r2) {
|
|
3781
4063
|
Object.defineProperty(e, r2, Object.getOwnPropertyDescriptor(t, r2));
|
|
3782
4064
|
});
|
|
3783
4065
|
}
|
|
@@ -3812,7 +4094,7 @@ var DocxodusEditor = (() => {
|
|
|
3812
4094
|
};
|
|
3813
4095
|
function getInternalConfig(provided) {
|
|
3814
4096
|
var _provided$maxScrollSp;
|
|
3815
|
-
return
|
|
4097
|
+
return _objectSpread5(_objectSpread5({}, baseConfig), {}, {
|
|
3816
4098
|
// only allowing limited control over the config at this stage
|
|
3817
4099
|
maxPixelScrollPerSecond: maxPixelScrollPerSecond[(_provided$maxScrollSp = provided === null || provided === void 0 ? void 0 : provided.maxScrollSpeed) !== null && _provided$maxScrollSp !== void 0 ? _provided$maxScrollSp : "standard"]
|
|
3818
4100
|
});
|
|
@@ -4296,7 +4578,7 @@ var DocxodusEditor = (() => {
|
|
|
4296
4578
|
}
|
|
4297
4579
|
|
|
4298
4580
|
// node_modules/@atlaskit/pragmatic-drag-and-drop-auto-scroll/dist/esm/over-element/make-api.js
|
|
4299
|
-
function
|
|
4581
|
+
function ownKeys6(e, r) {
|
|
4300
4582
|
var t = Object.keys(e);
|
|
4301
4583
|
if (Object.getOwnPropertySymbols) {
|
|
4302
4584
|
var o = Object.getOwnPropertySymbols(e);
|
|
@@ -4306,12 +4588,12 @@ var DocxodusEditor = (() => {
|
|
|
4306
4588
|
}
|
|
4307
4589
|
return t;
|
|
4308
4590
|
}
|
|
4309
|
-
function
|
|
4591
|
+
function _objectSpread6(e) {
|
|
4310
4592
|
for (var r = 1; r < arguments.length; r++) {
|
|
4311
4593
|
var t = null != arguments[r] ? arguments[r] : {};
|
|
4312
|
-
r % 2 ?
|
|
4594
|
+
r % 2 ? ownKeys6(Object(t), true).forEach(function(r2) {
|
|
4313
4595
|
_defineProperty(e, r2, t[r2]);
|
|
4314
|
-
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) :
|
|
4596
|
+
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys6(Object(t)).forEach(function(r2) {
|
|
4315
4597
|
Object.defineProperty(e, r2, Object.getOwnPropertyDescriptor(t, r2));
|
|
4316
4598
|
});
|
|
4317
4599
|
}
|
|
@@ -4350,7 +4632,7 @@ var DocxodusEditor = (() => {
|
|
|
4350
4632
|
}
|
|
4351
4633
|
function autoScrollWindow() {
|
|
4352
4634
|
var args = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
|
|
4353
|
-
var unique =
|
|
4635
|
+
var unique = _objectSpread6({}, args);
|
|
4354
4636
|
windowRegistry.add(unique);
|
|
4355
4637
|
function cleanup() {
|
|
4356
4638
|
windowRegistry.delete(unique);
|
|
@@ -4503,6 +4785,11 @@ var DocxodusEditor = (() => {
|
|
|
4503
4785
|
var EDITABLE_TAGS = /* @__PURE__ */ new Set(["P", "H1", "H2", "H3", "H4", "H5", "H6"]);
|
|
4504
4786
|
var BLOCK_DRAG_TYPE = "docxodus-block";
|
|
4505
4787
|
var blockDragStyledDocuments = /* @__PURE__ */ new WeakSet();
|
|
4788
|
+
function blockPreviewText(unit) {
|
|
4789
|
+
if (unit.tagName === "TABLE") return "Table";
|
|
4790
|
+
const text = (unit.textContent ?? "").trim().replace(/\s+/g, " ");
|
|
4791
|
+
return text.length > 48 ? `${text.slice(0, 48)}\u2026` : text;
|
|
4792
|
+
}
|
|
4506
4793
|
function ensureBlockDragStyles(doc) {
|
|
4507
4794
|
if (blockDragStyledDocuments.has(doc)) return;
|
|
4508
4795
|
blockDragStyledDocuments.add(doc);
|
|
@@ -4517,10 +4804,28 @@ var DocxodusEditor = (() => {
|
|
|
4517
4804
|
}
|
|
4518
4805
|
.docx-block-handle:hover, .docx-block-handle:focus-visible { color: #344054; border-color: #98a2b3; outline: none; }
|
|
4519
4806
|
.docx-block-handle[aria-pressed="true"] { color: #175cd3; border-color: #84adff; background: #eff8ff; }
|
|
4520
|
-
.docx-block-handle.docx-block-dragging { cursor: grabbing; opacity: .
|
|
4807
|
+
.docx-block-handle.docx-block-dragging { cursor: grabbing; opacity: .35; }
|
|
4808
|
+
/* The block being carried. Dimming it is the "a drag is happening" signal that survives the
|
|
4809
|
+
pointer being anywhere on screen \u2014 the drop line only says where, not what. */
|
|
4810
|
+
.docx-block-drag-source { opacity: .38; transition: opacity 120ms ease-out; }
|
|
4811
|
+
/* Positioned by transform so tracking the pointer costs no layout. Flipping display none\u2192block
|
|
4812
|
+
restarts the fade \u2014 one cheap entry animation per appearance, none while it tracks. */
|
|
4521
4813
|
.docx-block-drop-indicator {
|
|
4522
|
-
position: fixed; z-index: 2147482999; display: none; height:
|
|
4523
|
-
|
|
4814
|
+
position: fixed; top: 0; left: 0; z-index: 2147482999; display: none; height: 0;
|
|
4815
|
+
pointer-events: none; border-top: 2px solid #2e90fa;
|
|
4816
|
+
filter: drop-shadow(0 1px 2px rgba(46,144,250,.5));
|
|
4817
|
+
animation: docx-block-drop-in 110ms ease-out;
|
|
4818
|
+
}
|
|
4819
|
+
.docx-block-drop-indicator::before {
|
|
4820
|
+
content: ""; position: absolute; top: -5px; left: -2px; width: 8px; height: 8px;
|
|
4821
|
+
border-radius: 50%; background: #2e90fa;
|
|
4822
|
+
}
|
|
4823
|
+
@keyframes docx-block-drop-in { from { opacity: 0; } to { opacity: 1; } }
|
|
4824
|
+
.docx-block-drag-preview {
|
|
4825
|
+
max-width: 320px; padding: 6px 10px; border: 1px solid #b2ddff; border-radius: 6px;
|
|
4826
|
+
background: #eff8ff; color: #175cd3; box-shadow: 0 6px 16px rgba(16,24,40,.18);
|
|
4827
|
+
font: 500 13px/1.35 system-ui, sans-serif; white-space: nowrap; overflow: hidden;
|
|
4828
|
+
text-overflow: ellipsis;
|
|
4524
4829
|
}
|
|
4525
4830
|
.docx-block-move-menu {
|
|
4526
4831
|
position: fixed; z-index: 2147483001; display: none; min-width: 150px; padding: 5px;
|
|
@@ -4908,7 +5213,11 @@ var DocxodusEditor = (() => {
|
|
|
4908
5213
|
this.blockMoveLive = null;
|
|
4909
5214
|
this.blockDragSource = null;
|
|
4910
5215
|
this.blockDragCleanup = [];
|
|
4911
|
-
|
|
5216
|
+
/** Block boxes measured at drag start — see `BlockDropZone`. Empty when no drag is in flight. */
|
|
5217
|
+
this.dropZones = [];
|
|
5218
|
+
/** Combined scroll offset when `dropZones` was measured, and the scroller measured against. */
|
|
5219
|
+
this.dropZoneOrigin = 0;
|
|
5220
|
+
this.dropZoneScroller = null;
|
|
4912
5221
|
this.blockDragging = false;
|
|
4913
5222
|
this.blockDragPointerDown = false;
|
|
4914
5223
|
/** Anchors the current drag source may legally move next to, per the engine's own rules.
|
|
@@ -5037,6 +5346,11 @@ var DocxodusEditor = (() => {
|
|
|
5037
5346
|
this.handle = handle;
|
|
5038
5347
|
this.options = options;
|
|
5039
5348
|
this.editRoot = container;
|
|
5349
|
+
this.viewport = new DocumentViewport(container, {
|
|
5350
|
+
columnWidth: options.columnWidth,
|
|
5351
|
+
fitToWidth: options.fitToWidth,
|
|
5352
|
+
scale: options.scale
|
|
5353
|
+
});
|
|
5040
5354
|
if (typeof document !== "undefined") {
|
|
5041
5355
|
document.addEventListener("selectionchange", this.onSelectionChange);
|
|
5042
5356
|
document.addEventListener("mousedown", this.onMouseDown, true);
|
|
@@ -5119,6 +5433,8 @@ var DocxodusEditor = (() => {
|
|
|
5119
5433
|
editable: options.editable ?? true,
|
|
5120
5434
|
paginated: options.paginated ?? false,
|
|
5121
5435
|
scale: options.scale ?? 1,
|
|
5436
|
+
columnWidth: options.columnWidth ?? "section",
|
|
5437
|
+
fitToWidth: options.fitToWidth ?? true,
|
|
5122
5438
|
headerFooter: options.headerFooter ?? false,
|
|
5123
5439
|
blockDrag: options.blockDrag ?? false,
|
|
5124
5440
|
trackedChanges: options.trackedChanges ?? 0 /* Accept */,
|
|
@@ -5175,6 +5491,7 @@ var DocxodusEditor = (() => {
|
|
|
5175
5491
|
}
|
|
5176
5492
|
this.clearDragSelection();
|
|
5177
5493
|
this.teardownBlockDrag();
|
|
5494
|
+
this.viewport.dispose();
|
|
5178
5495
|
this.exports.DocxSessionBridge.CloseSession(this.handle);
|
|
5179
5496
|
}
|
|
5180
5497
|
/**
|
|
@@ -5192,6 +5509,14 @@ var DocxodusEditor = (() => {
|
|
|
5192
5509
|
get root() {
|
|
5193
5510
|
return this.container;
|
|
5194
5511
|
}
|
|
5512
|
+
/**
|
|
5513
|
+
* The zoom the viewport is currently applying (1 = 100%). Below 1 the page is wider than the
|
|
5514
|
+
* host and has been scaled to fit rather than reflowed — the honest thing to show a user who
|
|
5515
|
+
* is wondering why a phone shows the whole page.
|
|
5516
|
+
*/
|
|
5517
|
+
get zoom() {
|
|
5518
|
+
return this.viewport.scale;
|
|
5519
|
+
}
|
|
5195
5520
|
/**
|
|
5196
5521
|
* The live `DocxSession` handle backing this editor — the model of record.
|
|
5197
5522
|
*
|
|
@@ -5202,6 +5527,19 @@ var DocxodusEditor = (() => {
|
|
|
5202
5527
|
get sessionHandle() {
|
|
5203
5528
|
return this.handle;
|
|
5204
5529
|
}
|
|
5530
|
+
/**
|
|
5531
|
+
* Repaint from the live session after it was mutated OUTSIDE the editor's own
|
|
5532
|
+
* commands — a host driving {@link sessionHandle} directly (an agent pipeline,
|
|
5533
|
+
* `raw.replaceXml`, a batch import). Continuous mode patches incrementally from
|
|
5534
|
+
* the render plan (a Unid-preserving single-block mutation repaints just that
|
|
5535
|
+
* block); paginated mode — or anything the reconciler cannot prove — remounts.
|
|
5536
|
+
* The editor cannot observe external mutations, so the host owns calling this
|
|
5537
|
+
* once per mutation batch.
|
|
5538
|
+
*/
|
|
5539
|
+
refresh() {
|
|
5540
|
+
this.assertOpen();
|
|
5541
|
+
this.reconcile();
|
|
5542
|
+
}
|
|
5205
5543
|
/** Move one top-level body block relative to another and repaint from the live session. */
|
|
5206
5544
|
moveBlock(sourceAnchorId, targetAnchorId, position) {
|
|
5207
5545
|
this.assertOpen();
|
|
@@ -5282,7 +5620,7 @@ var DocxodusEditor = (() => {
|
|
|
5282
5620
|
handle.style.display = "flex";
|
|
5283
5621
|
handle.style.left = `${Math.max(4, rect.left - 32)}px`;
|
|
5284
5622
|
handle.style.top = `${Math.max(4, rect.top + (unit.tagName === "TABLE" ? 6 : Math.max(0, (rect.height - 28) / 2)))}px`;
|
|
5285
|
-
const preview = (unit
|
|
5623
|
+
const preview = blockPreviewText(unit);
|
|
5286
5624
|
handle.setAttribute("aria-label", preview ? `Move block: ${preview}` : "Move block");
|
|
5287
5625
|
}
|
|
5288
5626
|
hideBlockHandle() {
|
|
@@ -5293,14 +5631,33 @@ var DocxodusEditor = (() => {
|
|
|
5293
5631
|
const source = this.currentBlockDragSource();
|
|
5294
5632
|
if (source && this.blockDragHandle?.style.display !== "none") this.showBlockHandle(source);
|
|
5295
5633
|
}
|
|
5296
|
-
|
|
5634
|
+
/** Draw the drop line on `zone`'s requested edge, or take it away when there is no target. */
|
|
5635
|
+
paintDropIndicator(data) {
|
|
5297
5636
|
const indicator = this.blockDropIndicator;
|
|
5637
|
+
const zone = data.zone;
|
|
5298
5638
|
if (!indicator) return;
|
|
5299
|
-
|
|
5639
|
+
if (!zone) {
|
|
5640
|
+
this.hideDropIndicator();
|
|
5641
|
+
return;
|
|
5642
|
+
}
|
|
5643
|
+
const y = Math.round(this.dropEdgeY(zone, data.position === "after" ? "after" : "before") + this.dropZoneShift()) - 1;
|
|
5644
|
+
indicator.style.transform = `translate3d(${Math.round(zone.left)}px, ${y}px, 0)`;
|
|
5645
|
+
indicator.style.width = `${Math.max(24, Math.round(zone.width))}px`;
|
|
5300
5646
|
indicator.style.display = "block";
|
|
5301
|
-
|
|
5302
|
-
|
|
5303
|
-
|
|
5647
|
+
}
|
|
5648
|
+
/**
|
|
5649
|
+
* Where to draw the line for an insertion on `position` of `zone` — the MIDDLE of the gap to
|
|
5650
|
+
* the neighbour on that side, not the zone's own border-box edge. A paragraph's `w:spacing`
|
|
5651
|
+
* becomes a CSS margin, which sits outside the box, so drawing on the edge underlines the
|
|
5652
|
+
* block's last line instead of reading as a gap between two blocks. Falls back to the raw edge
|
|
5653
|
+
* at the ends of the flow, and degrades to the same value when blocks are contiguous.
|
|
5654
|
+
*/
|
|
5655
|
+
dropEdgeY(zone, position) {
|
|
5656
|
+
const neighbour = this.dropZones[zone.index + (position === "after" ? 1 : -1)];
|
|
5657
|
+
if (!neighbour) {
|
|
5658
|
+
return position === "after" ? zone.bottom + zone.marginAfter / 2 : zone.top - zone.marginBefore / 2;
|
|
5659
|
+
}
|
|
5660
|
+
return position === "after" ? (zone.bottom + neighbour.top) / 2 : (neighbour.bottom + zone.top) / 2;
|
|
5304
5661
|
}
|
|
5305
5662
|
hideDropIndicator() {
|
|
5306
5663
|
if (this.blockDropIndicator) this.blockDropIndicator.style.display = "none";
|
|
@@ -5380,45 +5737,75 @@ var DocxodusEditor = (() => {
|
|
|
5380
5737
|
if (!sides) return false;
|
|
5381
5738
|
return position ? sides[position] : sides.before || sides.after;
|
|
5382
5739
|
}
|
|
5740
|
+
/** Measure every movable block once, at drag start. See `BlockDropZone`. */
|
|
5741
|
+
captureDropZones() {
|
|
5742
|
+
const view = this.container.ownerDocument.defaultView;
|
|
5743
|
+
this.dropZoneScroller = this.scrollContainer();
|
|
5744
|
+
this.dropZoneOrigin = this.scrollOffsetSum();
|
|
5745
|
+
this.dropZones = [];
|
|
5746
|
+
const boxes = [];
|
|
5747
|
+
for (const unit of this.bodyUnitNodes()) {
|
|
5748
|
+
const anchorId = this.isMovableBlockUnit(unit) ? this.anchorIdOf(unit) : null;
|
|
5749
|
+
if (!anchorId) continue;
|
|
5750
|
+
const box = this.unitWrapperOf(unit);
|
|
5751
|
+
const rect = box.getBoundingClientRect();
|
|
5752
|
+
boxes.push(box);
|
|
5753
|
+
this.dropZones.push({
|
|
5754
|
+
unit,
|
|
5755
|
+
anchorId,
|
|
5756
|
+
index: this.dropZones.length,
|
|
5757
|
+
top: rect.top,
|
|
5758
|
+
bottom: rect.bottom,
|
|
5759
|
+
left: rect.left,
|
|
5760
|
+
width: rect.width,
|
|
5761
|
+
marginBefore: 0,
|
|
5762
|
+
marginAfter: 0
|
|
5763
|
+
});
|
|
5764
|
+
}
|
|
5765
|
+
const ends = new Set([0, this.dropZones.length - 1].filter((i) => i >= 0 && i < boxes.length));
|
|
5766
|
+
for (const i of ends) {
|
|
5767
|
+
const style = view?.getComputedStyle(boxes[i]);
|
|
5768
|
+
this.dropZones[i].marginBefore = parseFloat(style?.marginTop ?? "0") || 0;
|
|
5769
|
+
this.dropZones[i].marginAfter = parseFloat(style?.marginBottom ?? "0") || 0;
|
|
5770
|
+
}
|
|
5771
|
+
}
|
|
5772
|
+
scrollOffsetSum() {
|
|
5773
|
+
const view = this.container.ownerDocument.defaultView;
|
|
5774
|
+
return (view?.scrollY ?? 0) + (this.dropZoneScroller?.scrollTop ?? 0);
|
|
5775
|
+
}
|
|
5776
|
+
/** How far the measured boxes have travelled since capture, from scrolling (drag autoscroll). */
|
|
5777
|
+
dropZoneShift() {
|
|
5778
|
+
return this.dropZoneOrigin - this.scrollOffsetSum();
|
|
5779
|
+
}
|
|
5383
5780
|
/**
|
|
5384
|
-
*
|
|
5385
|
-
*
|
|
5386
|
-
*
|
|
5387
|
-
*
|
|
5781
|
+
* Where a drop at `clientY` lands, or null when nothing there is legal.
|
|
5782
|
+
*
|
|
5783
|
+
* Resolution is by VERTICAL GEOMETRY over the measured blocks, not by which element the pointer
|
|
5784
|
+
* is over: the drag handle floats in the page margin, so a drag straight down the gutter — the
|
|
5785
|
+
* natural gesture — never crosses a paragraph box, and element hit testing gave those drags no
|
|
5786
|
+
* indicator and no drop at all. The nearest block by vertical distance is the target; the half
|
|
5787
|
+
* the pointer is in picks the side, snapped to the other side when only that one is legal
|
|
5788
|
+
* (a section break or a cross-block range usually makes exactly one side illegal). When neither
|
|
5789
|
+
* side is legal — the pointer is in a region this block cannot reach — there is no drop, and
|
|
5790
|
+
* nothing is drawn.
|
|
5388
5791
|
*/
|
|
5389
|
-
|
|
5390
|
-
const
|
|
5391
|
-
|
|
5392
|
-
|
|
5393
|
-
const
|
|
5394
|
-
|
|
5395
|
-
|
|
5396
|
-
|
|
5397
|
-
|
|
5398
|
-
|
|
5399
|
-
|
|
5400
|
-
this.blockDragTargetCleanup.push(dropTargetForElements({
|
|
5401
|
-
element: unit,
|
|
5402
|
-
// A target the engine would refuse is not a drop target at all, so Pragmatic never
|
|
5403
|
-
// fires onDragEnter for it and no indicator is drawn over it.
|
|
5404
|
-
canDrop: ({ source }) => source.data.type === BLOCK_DRAG_TYPE && source.data.sourceAnchorId !== this.anchorIdOf(unit) && this.isValidMoveTarget(unit),
|
|
5405
|
-
getData: ({ input }) => ({
|
|
5406
|
-
type: BLOCK_DRAG_TYPE,
|
|
5407
|
-
targetAnchorId: this.anchorIdOf(unit),
|
|
5408
|
-
position: this.dropPositionFor(unit, input.clientY),
|
|
5409
|
-
targetElement: unit
|
|
5410
|
-
}),
|
|
5411
|
-
onDragEnter: ({ self }) => {
|
|
5412
|
-
const pos = self.data.position === "after" ? "after" : "before";
|
|
5413
|
-
this.showDropIndicator(unit, pos);
|
|
5414
|
-
},
|
|
5415
|
-
onDrag: ({ self }) => {
|
|
5416
|
-
const pos = self.data.position === "after" ? "after" : "before";
|
|
5417
|
-
this.showDropIndicator(unit, pos);
|
|
5418
|
-
},
|
|
5419
|
-
onDragLeave: () => this.hideDropIndicator()
|
|
5420
|
-
}));
|
|
5792
|
+
resolveDropAt(clientY) {
|
|
5793
|
+
const y = clientY - this.dropZoneShift();
|
|
5794
|
+
let best = null;
|
|
5795
|
+
let bestGap = Infinity;
|
|
5796
|
+
for (const zone of this.dropZones) {
|
|
5797
|
+
const gap = y < zone.top ? zone.top - y : y > zone.bottom ? y - zone.bottom : 0;
|
|
5798
|
+
if (gap < bestGap) {
|
|
5799
|
+
best = zone;
|
|
5800
|
+
bestGap = gap;
|
|
5801
|
+
}
|
|
5802
|
+
if (gap === 0) break;
|
|
5421
5803
|
}
|
|
5804
|
+
if (!best || best.unit === this.blockDragSource) return null;
|
|
5805
|
+
const preferred = y < (best.top + best.bottom) / 2 ? "before" : "after";
|
|
5806
|
+
if (this.isValidMoveTarget(best.unit, preferred)) return { zone: best, position: preferred };
|
|
5807
|
+
const other = preferred === "before" ? "after" : "before";
|
|
5808
|
+
return this.isValidMoveTarget(best.unit, other) ? { zone: best, position: other } : null;
|
|
5422
5809
|
}
|
|
5423
5810
|
closeBlockMoveMenu(restoreFocus = false) {
|
|
5424
5811
|
if (!this.blockMoveMenu || !this.blockDragHandle) return;
|
|
@@ -5593,20 +5980,50 @@ var DocxodusEditor = (() => {
|
|
|
5593
5980
|
const source = this.currentBlockDragSource();
|
|
5594
5981
|
return { type: BLOCK_DRAG_TYPE, sourceAnchorId: source ? this.anchorIdOf(source) : void 0 };
|
|
5595
5982
|
},
|
|
5983
|
+
// The browser would otherwise ghost the 26px grip, which says nothing about what is moving.
|
|
5984
|
+
onGenerateDragPreview: ({ nativeSetDragImage }) => {
|
|
5985
|
+
const source = this.currentBlockDragSource();
|
|
5986
|
+
setCustomNativeDragPreview({
|
|
5987
|
+
nativeSetDragImage,
|
|
5988
|
+
getOffset: pointerOutsideOfPreview({ x: "14px", y: "10px" }),
|
|
5989
|
+
render: ({ container }) => {
|
|
5990
|
+
const chip = doc.createElement("div");
|
|
5991
|
+
chip.className = "docx-block-drag-preview";
|
|
5992
|
+
chip.textContent = source && blockPreviewText(source) || "Move block";
|
|
5993
|
+
container.appendChild(chip);
|
|
5994
|
+
return () => chip.remove();
|
|
5995
|
+
}
|
|
5996
|
+
});
|
|
5997
|
+
},
|
|
5596
5998
|
onDragStart: () => {
|
|
5999
|
+
const source = this.currentBlockDragSource();
|
|
5597
6000
|
this.blockDragging = true;
|
|
5598
6001
|
handle.classList.add("docx-block-dragging");
|
|
6002
|
+
source?.classList.add("docx-block-drag-source");
|
|
5599
6003
|
this.closeBlockMoveMenu();
|
|
5600
|
-
this.refreshBlockMoveTargets(
|
|
5601
|
-
this.
|
|
6004
|
+
this.refreshBlockMoveTargets(source);
|
|
6005
|
+
this.captureDropZones();
|
|
5602
6006
|
},
|
|
5603
6007
|
onDrop: () => {
|
|
5604
6008
|
this.blockDragging = false;
|
|
5605
6009
|
this.blockDragPointerDown = false;
|
|
6010
|
+
this.dropZones = [];
|
|
5606
6011
|
handle.classList.remove("docx-block-dragging");
|
|
6012
|
+
doc.querySelectorAll(".docx-block-drag-source").forEach((el) => el.classList.remove("docx-block-drag-source"));
|
|
5607
6013
|
this.hideDropIndicator();
|
|
5608
6014
|
}
|
|
5609
6015
|
}));
|
|
6016
|
+
this.blockDragCleanup.push(dropTargetForElements({
|
|
6017
|
+
element: this.editRoot,
|
|
6018
|
+
canDrop: ({ source }) => source.data.type === BLOCK_DRAG_TYPE,
|
|
6019
|
+
getData: ({ input }) => {
|
|
6020
|
+
const hit = this.resolveDropAt(input.clientY);
|
|
6021
|
+
return hit ? { type: BLOCK_DRAG_TYPE, targetAnchorId: hit.zone.anchorId, position: hit.position, zone: hit.zone } : { type: BLOCK_DRAG_TYPE };
|
|
6022
|
+
},
|
|
6023
|
+
onDragEnter: ({ self }) => this.paintDropIndicator(self.data),
|
|
6024
|
+
onDrag: ({ self }) => this.paintDropIndicator(self.data),
|
|
6025
|
+
onDragLeave: () => this.hideDropIndicator()
|
|
6026
|
+
}));
|
|
5610
6027
|
this.blockDragCleanup.push(monitorForElements({
|
|
5611
6028
|
canMonitor: ({ source }) => source.data.type === BLOCK_DRAG_TYPE,
|
|
5612
6029
|
onDrop: ({ source, location: location2 }) => {
|
|
@@ -5633,13 +6050,13 @@ var DocxodusEditor = (() => {
|
|
|
5633
6050
|
canScroll: ({ source }) => source.data.type === BLOCK_DRAG_TYPE,
|
|
5634
6051
|
getAllowedAxis: () => "vertical"
|
|
5635
6052
|
}));
|
|
5636
|
-
this.refreshBlockDropTargets();
|
|
5637
6053
|
}
|
|
5638
6054
|
teardownBlockDrag() {
|
|
5639
6055
|
this.blockMoveTargetPrefetch?.();
|
|
5640
6056
|
this.blockMoveTargetPrefetch = null;
|
|
5641
6057
|
this.blockMoveTargetCache.clear();
|
|
5642
|
-
|
|
6058
|
+
this.dropZones = [];
|
|
6059
|
+
this.dropZoneScroller = null;
|
|
5643
6060
|
for (const cleanup of this.blockDragCleanup.splice(0)) cleanup();
|
|
5644
6061
|
this.blockDragHandle?.remove();
|
|
5645
6062
|
this.blockDropIndicator?.remove();
|
|
@@ -5728,17 +6145,17 @@ var DocxodusEditor = (() => {
|
|
|
5728
6145
|
bodyRoot.after(this.region.footerBand);
|
|
5729
6146
|
this.region.refreshAll();
|
|
5730
6147
|
}
|
|
5731
|
-
/**
|
|
6148
|
+
/**
|
|
6149
|
+
* Continuous (non-paginated) mount: inject the converter's styles + body, wire blocks.
|
|
6150
|
+
*
|
|
6151
|
+
* The body always gets its own `.docx-body-flow` wrapper — not only when bands are docked.
|
|
6152
|
+
* It is the sheet: the element the viewport gives page geometry to and zooms, and the one
|
|
6153
|
+
* the bands dock around. Without it the container would have to be both the scrolling host
|
|
6154
|
+
* and the scaled page, which are different boxes.
|
|
6155
|
+
*/
|
|
5732
6156
|
mountHtml(fullHtml) {
|
|
5733
6157
|
const parsed = new DOMParser().parseFromString(fullHtml, "text/html");
|
|
5734
6158
|
const styles = Array.from(parsed.querySelectorAll("style")).map((s) => s.outerHTML).join("");
|
|
5735
|
-
if (!this.region) {
|
|
5736
|
-
this.container.innerHTML = styles + parsed.body.innerHTML;
|
|
5737
|
-
this.editRoot = this.container;
|
|
5738
|
-
if (this.options.editable) this.wireBlocks(this.container);
|
|
5739
|
-
this.stampPlanState();
|
|
5740
|
-
return;
|
|
5741
|
-
}
|
|
5742
6159
|
this.container.innerHTML = styles;
|
|
5743
6160
|
const flow = document.createElement("div");
|
|
5744
6161
|
flow.className = "docx-body-flow";
|
|
@@ -5747,7 +6164,8 @@ var DocxodusEditor = (() => {
|
|
|
5747
6164
|
this.editRoot = flow;
|
|
5748
6165
|
if (this.options.editable) this.wireBlocks(flow);
|
|
5749
6166
|
this.stampPlanState();
|
|
5750
|
-
this.dockBands(flow);
|
|
6167
|
+
if (this.region) this.dockBands(flow);
|
|
6168
|
+
this.viewport.attach(flow, true);
|
|
5751
6169
|
}
|
|
5752
6170
|
/** Paginated mount: flow blocks into page boxes via pagination.ts, wire the page clones. */
|
|
5753
6171
|
mountPaginated(fullHtml) {
|
|
@@ -5768,6 +6186,7 @@ var DocxodusEditor = (() => {
|
|
|
5768
6186
|
this.editRoot = pageRoot;
|
|
5769
6187
|
if (this.options.editable) this.wireBlocks(pageRoot);
|
|
5770
6188
|
if (this.region) this.dockBands(target);
|
|
6189
|
+
this.viewport.attach(pageRoot, false);
|
|
5771
6190
|
}
|
|
5772
6191
|
wireBlocks(root) {
|
|
5773
6192
|
root.querySelectorAll("[data-anchor]").forEach((el) => this.wireBlock(el));
|
|
@@ -7576,14 +7995,7 @@ var DocxodusEditor = (() => {
|
|
|
7576
7995
|
SHOULD win.
|
|
7577
7996
|
(No backticks in this file's comments: the stylesheet is a template literal.) */
|
|
7578
7997
|
.dxr-scroll { flex: 1 1 auto; min-height: 0; overflow: auto; -webkit-overflow-scrolling: touch; }
|
|
7579
|
-
.dxr[data-chrome] .dxr-surface {
|
|
7580
|
-
.dxr-surface[data-view="continuous"] > * { background: var(--dxr-sheet); }
|
|
7581
|
-
.dxr[data-chrome] .dxr-surface[data-view="continuous"] {
|
|
7582
|
-
padding: 56px 72px;
|
|
7583
|
-
border-radius: 3px;
|
|
7584
|
-
background: var(--dxr-sheet);
|
|
7585
|
-
box-shadow: 0 1px 3px rgba(16, 20, 24, .14), 0 8px 24px rgba(16, 20, 24, .05);
|
|
7586
|
-
}
|
|
7998
|
+
.dxr[data-chrome] .dxr-surface { margin: 26px auto; padding: 0 16px 96px; }
|
|
7587
7999
|
.dxr-surface [contenteditable="true"]:focus {
|
|
7588
8000
|
outline: 2px solid var(--dxr-accent);
|
|
7589
8001
|
outline-offset: 2px;
|
|
@@ -7595,7 +8007,10 @@ var DocxodusEditor = (() => {
|
|
|
7595
8007
|
so they dock as their own regions. Styled from the same tokens as the ribbon
|
|
7596
8008
|
so the surface reads as one instrument rather than two apps. */
|
|
7597
8009
|
.dxr-surface .docx-hf-band {
|
|
7598
|
-
|
|
8010
|
+
/* Docked outside the zoomed sheet, so it takes the page's on-screen width from the
|
|
8011
|
+
custom property the viewport publishes rather than stretching to the whole surface. */
|
|
8012
|
+
width: min(100%, var(--docx-sheet-width, 100%));
|
|
8013
|
+
margin: 0 auto 14px;
|
|
7599
8014
|
padding: 9px 72px 13px;
|
|
7600
8015
|
border: 1px solid var(--dxr-rule);
|
|
7601
8016
|
border-left: 2px solid #c2ccd9;
|
|
@@ -7603,7 +8018,7 @@ var DocxodusEditor = (() => {
|
|
|
7603
8018
|
background: var(--dxr-sheet);
|
|
7604
8019
|
}
|
|
7605
8020
|
.dxr-surface .docx-hf-band + .docx-body-flow { margin-top: 0; }
|
|
7606
|
-
.dxr-surface .docx-hf-band[data-hf-band="footer"] { margin: 14px
|
|
8021
|
+
.dxr-surface .docx-hf-band[data-hf-band="footer"] { margin: 14px auto 0; }
|
|
7607
8022
|
.dxr-surface .docx-hf-chrome {
|
|
7608
8023
|
display: flex;
|
|
7609
8024
|
gap: 8px;
|
|
@@ -7658,13 +8073,15 @@ var DocxodusEditor = (() => {
|
|
|
7658
8073
|
text-transform: none;
|
|
7659
8074
|
}
|
|
7660
8075
|
.dxr-surface .docx-hf-band[data-hf-inherited] { border-style: dashed; }
|
|
7661
|
-
.
|
|
7662
|
-
|
|
7663
|
-
|
|
7664
|
-
|
|
7665
|
-
|
|
8076
|
+
/* The sheet IS the page. The editor's viewport sizes .docx-body-flow to the section's page
|
|
8077
|
+
width and its section wrappers to the authored text column, so the horizontal gutters here
|
|
8078
|
+
are the document's own w:sectPr margins, not a padding this chrome invents; only the
|
|
8079
|
+
vertical breathing room is ours. Centering is left to margin:auto so a page the viewport
|
|
8080
|
+
has zoomed to fit stays centered at its scaled width. */
|
|
7666
8081
|
.dxr[data-chrome] .dxr-surface[data-view="continuous"] .docx-body-flow {
|
|
7667
|
-
|
|
8082
|
+
max-width: 100%;
|
|
8083
|
+
margin: 0 auto;
|
|
8084
|
+
padding: 56px 0;
|
|
7668
8085
|
border-radius: 3px;
|
|
7669
8086
|
background: var(--dxr-sheet);
|
|
7670
8087
|
box-shadow: 0 1px 3px rgba(16, 20, 24, .14), 0 8px 24px rgba(16, 20, 24, .05);
|
|
@@ -7743,9 +8160,11 @@ var DocxodusEditor = (() => {
|
|
|
7743
8160
|
.dxr[data-chrome="compact"] .dxr-note { display: none; }
|
|
7744
8161
|
.dxr[data-chrome="compact"] .dxr-rail { display: none; }
|
|
7745
8162
|
.dxr[data-chrome="compact"] .dxr-hint { display: none; }
|
|
8163
|
+
/* Compact trims the chrome around the page, never the page: the document's own column width
|
|
8164
|
+
is what the viewport's fit-to-width zoom scales, so a phone shows a whole smaller page
|
|
8165
|
+
instead of a narrower one that breaks its lines somewhere Word never would. */
|
|
7746
8166
|
.dxr[data-chrome="compact"] .dxr-surface { margin: 12px auto; padding: 0 10px 64px; }
|
|
7747
|
-
.dxr[data-chrome="compact"] .dxr-surface[data-view="continuous"] { padding: 22px
|
|
7748
|
-
.dxr[data-chrome="compact"] .dxr-surface[data-view="continuous"] .docx-body-flow { padding: 22px 18px; }
|
|
8167
|
+
.dxr[data-chrome="compact"] .dxr-surface[data-view="continuous"] .docx-body-flow { padding: 22px 0; }
|
|
7749
8168
|
.dxr[data-chrome="compact"] .dxr-surface .docx-hf-band { padding: 9px 18px 13px; }
|
|
7750
8169
|
.dxr[data-chrome="compact"] .dxr-surface .docx-hf-chrome,
|
|
7751
8170
|
.dxr[data-chrome="compact"] .dxr-surface .docx-hf-warning { margin-left: 0; }
|
|
@@ -8495,6 +8914,8 @@ var DocxodusEditor = (() => {
|
|
|
8495
8914
|
fabricateClasses: this.options.fabricateClasses,
|
|
8496
8915
|
editable: this.options.editable,
|
|
8497
8916
|
scale: this.options.scale,
|
|
8917
|
+
columnWidth: this.options.columnWidth,
|
|
8918
|
+
fitToWidth: this.options.fitToWidth,
|
|
8498
8919
|
onEdit: this.options.onEdit,
|
|
8499
8920
|
onMove: this.options.onMove,
|
|
8500
8921
|
paginated,
|