docxodus 9.4.0 → 9.5.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 +501 -93
- package/dist/editor.d.ts +61 -11
- package/dist/editor.d.ts.map +1 -1
- package/dist/editor.js +207 -69
- package/dist/editor.js.map +1 -1
- package/dist/embed.bundle.js +510 -94
- package/dist/embed.iife.js +510 -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 +1 -1
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
|
*
|
|
@@ -5282,7 +5607,7 @@ var DocxodusEditor = (() => {
|
|
|
5282
5607
|
handle.style.display = "flex";
|
|
5283
5608
|
handle.style.left = `${Math.max(4, rect.left - 32)}px`;
|
|
5284
5609
|
handle.style.top = `${Math.max(4, rect.top + (unit.tagName === "TABLE" ? 6 : Math.max(0, (rect.height - 28) / 2)))}px`;
|
|
5285
|
-
const preview = (unit
|
|
5610
|
+
const preview = blockPreviewText(unit);
|
|
5286
5611
|
handle.setAttribute("aria-label", preview ? `Move block: ${preview}` : "Move block");
|
|
5287
5612
|
}
|
|
5288
5613
|
hideBlockHandle() {
|
|
@@ -5293,14 +5618,33 @@ var DocxodusEditor = (() => {
|
|
|
5293
5618
|
const source = this.currentBlockDragSource();
|
|
5294
5619
|
if (source && this.blockDragHandle?.style.display !== "none") this.showBlockHandle(source);
|
|
5295
5620
|
}
|
|
5296
|
-
|
|
5621
|
+
/** Draw the drop line on `zone`'s requested edge, or take it away when there is no target. */
|
|
5622
|
+
paintDropIndicator(data) {
|
|
5297
5623
|
const indicator = this.blockDropIndicator;
|
|
5624
|
+
const zone = data.zone;
|
|
5298
5625
|
if (!indicator) return;
|
|
5299
|
-
|
|
5626
|
+
if (!zone) {
|
|
5627
|
+
this.hideDropIndicator();
|
|
5628
|
+
return;
|
|
5629
|
+
}
|
|
5630
|
+
const y = Math.round(this.dropEdgeY(zone, data.position === "after" ? "after" : "before") + this.dropZoneShift()) - 1;
|
|
5631
|
+
indicator.style.transform = `translate3d(${Math.round(zone.left)}px, ${y}px, 0)`;
|
|
5632
|
+
indicator.style.width = `${Math.max(24, Math.round(zone.width))}px`;
|
|
5300
5633
|
indicator.style.display = "block";
|
|
5301
|
-
|
|
5302
|
-
|
|
5303
|
-
|
|
5634
|
+
}
|
|
5635
|
+
/**
|
|
5636
|
+
* Where to draw the line for an insertion on `position` of `zone` — the MIDDLE of the gap to
|
|
5637
|
+
* the neighbour on that side, not the zone's own border-box edge. A paragraph's `w:spacing`
|
|
5638
|
+
* becomes a CSS margin, which sits outside the box, so drawing on the edge underlines the
|
|
5639
|
+
* block's last line instead of reading as a gap between two blocks. Falls back to the raw edge
|
|
5640
|
+
* at the ends of the flow, and degrades to the same value when blocks are contiguous.
|
|
5641
|
+
*/
|
|
5642
|
+
dropEdgeY(zone, position) {
|
|
5643
|
+
const neighbour = this.dropZones[zone.index + (position === "after" ? 1 : -1)];
|
|
5644
|
+
if (!neighbour) {
|
|
5645
|
+
return position === "after" ? zone.bottom + zone.marginAfter / 2 : zone.top - zone.marginBefore / 2;
|
|
5646
|
+
}
|
|
5647
|
+
return position === "after" ? (zone.bottom + neighbour.top) / 2 : (neighbour.bottom + zone.top) / 2;
|
|
5304
5648
|
}
|
|
5305
5649
|
hideDropIndicator() {
|
|
5306
5650
|
if (this.blockDropIndicator) this.blockDropIndicator.style.display = "none";
|
|
@@ -5380,45 +5724,75 @@ var DocxodusEditor = (() => {
|
|
|
5380
5724
|
if (!sides) return false;
|
|
5381
5725
|
return position ? sides[position] : sides.before || sides.after;
|
|
5382
5726
|
}
|
|
5727
|
+
/** Measure every movable block once, at drag start. See `BlockDropZone`. */
|
|
5728
|
+
captureDropZones() {
|
|
5729
|
+
const view = this.container.ownerDocument.defaultView;
|
|
5730
|
+
this.dropZoneScroller = this.scrollContainer();
|
|
5731
|
+
this.dropZoneOrigin = this.scrollOffsetSum();
|
|
5732
|
+
this.dropZones = [];
|
|
5733
|
+
const boxes = [];
|
|
5734
|
+
for (const unit of this.bodyUnitNodes()) {
|
|
5735
|
+
const anchorId = this.isMovableBlockUnit(unit) ? this.anchorIdOf(unit) : null;
|
|
5736
|
+
if (!anchorId) continue;
|
|
5737
|
+
const box = this.unitWrapperOf(unit);
|
|
5738
|
+
const rect = box.getBoundingClientRect();
|
|
5739
|
+
boxes.push(box);
|
|
5740
|
+
this.dropZones.push({
|
|
5741
|
+
unit,
|
|
5742
|
+
anchorId,
|
|
5743
|
+
index: this.dropZones.length,
|
|
5744
|
+
top: rect.top,
|
|
5745
|
+
bottom: rect.bottom,
|
|
5746
|
+
left: rect.left,
|
|
5747
|
+
width: rect.width,
|
|
5748
|
+
marginBefore: 0,
|
|
5749
|
+
marginAfter: 0
|
|
5750
|
+
});
|
|
5751
|
+
}
|
|
5752
|
+
const ends = new Set([0, this.dropZones.length - 1].filter((i) => i >= 0 && i < boxes.length));
|
|
5753
|
+
for (const i of ends) {
|
|
5754
|
+
const style = view?.getComputedStyle(boxes[i]);
|
|
5755
|
+
this.dropZones[i].marginBefore = parseFloat(style?.marginTop ?? "0") || 0;
|
|
5756
|
+
this.dropZones[i].marginAfter = parseFloat(style?.marginBottom ?? "0") || 0;
|
|
5757
|
+
}
|
|
5758
|
+
}
|
|
5759
|
+
scrollOffsetSum() {
|
|
5760
|
+
const view = this.container.ownerDocument.defaultView;
|
|
5761
|
+
return (view?.scrollY ?? 0) + (this.dropZoneScroller?.scrollTop ?? 0);
|
|
5762
|
+
}
|
|
5763
|
+
/** How far the measured boxes have travelled since capture, from scrolling (drag autoscroll). */
|
|
5764
|
+
dropZoneShift() {
|
|
5765
|
+
return this.dropZoneOrigin - this.scrollOffsetSum();
|
|
5766
|
+
}
|
|
5383
5767
|
/**
|
|
5384
|
-
*
|
|
5385
|
-
*
|
|
5386
|
-
*
|
|
5387
|
-
*
|
|
5768
|
+
* Where a drop at `clientY` lands, or null when nothing there is legal.
|
|
5769
|
+
*
|
|
5770
|
+
* Resolution is by VERTICAL GEOMETRY over the measured blocks, not by which element the pointer
|
|
5771
|
+
* is over: the drag handle floats in the page margin, so a drag straight down the gutter — the
|
|
5772
|
+
* natural gesture — never crosses a paragraph box, and element hit testing gave those drags no
|
|
5773
|
+
* indicator and no drop at all. The nearest block by vertical distance is the target; the half
|
|
5774
|
+
* the pointer is in picks the side, snapped to the other side when only that one is legal
|
|
5775
|
+
* (a section break or a cross-block range usually makes exactly one side illegal). When neither
|
|
5776
|
+
* side is legal — the pointer is in a region this block cannot reach — there is no drop, and
|
|
5777
|
+
* nothing is drawn.
|
|
5388
5778
|
*/
|
|
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
|
-
}));
|
|
5779
|
+
resolveDropAt(clientY) {
|
|
5780
|
+
const y = clientY - this.dropZoneShift();
|
|
5781
|
+
let best = null;
|
|
5782
|
+
let bestGap = Infinity;
|
|
5783
|
+
for (const zone of this.dropZones) {
|
|
5784
|
+
const gap = y < zone.top ? zone.top - y : y > zone.bottom ? y - zone.bottom : 0;
|
|
5785
|
+
if (gap < bestGap) {
|
|
5786
|
+
best = zone;
|
|
5787
|
+
bestGap = gap;
|
|
5788
|
+
}
|
|
5789
|
+
if (gap === 0) break;
|
|
5421
5790
|
}
|
|
5791
|
+
if (!best || best.unit === this.blockDragSource) return null;
|
|
5792
|
+
const preferred = y < (best.top + best.bottom) / 2 ? "before" : "after";
|
|
5793
|
+
if (this.isValidMoveTarget(best.unit, preferred)) return { zone: best, position: preferred };
|
|
5794
|
+
const other = preferred === "before" ? "after" : "before";
|
|
5795
|
+
return this.isValidMoveTarget(best.unit, other) ? { zone: best, position: other } : null;
|
|
5422
5796
|
}
|
|
5423
5797
|
closeBlockMoveMenu(restoreFocus = false) {
|
|
5424
5798
|
if (!this.blockMoveMenu || !this.blockDragHandle) return;
|
|
@@ -5593,20 +5967,50 @@ var DocxodusEditor = (() => {
|
|
|
5593
5967
|
const source = this.currentBlockDragSource();
|
|
5594
5968
|
return { type: BLOCK_DRAG_TYPE, sourceAnchorId: source ? this.anchorIdOf(source) : void 0 };
|
|
5595
5969
|
},
|
|
5970
|
+
// The browser would otherwise ghost the 26px grip, which says nothing about what is moving.
|
|
5971
|
+
onGenerateDragPreview: ({ nativeSetDragImage }) => {
|
|
5972
|
+
const source = this.currentBlockDragSource();
|
|
5973
|
+
setCustomNativeDragPreview({
|
|
5974
|
+
nativeSetDragImage,
|
|
5975
|
+
getOffset: pointerOutsideOfPreview({ x: "14px", y: "10px" }),
|
|
5976
|
+
render: ({ container }) => {
|
|
5977
|
+
const chip = doc.createElement("div");
|
|
5978
|
+
chip.className = "docx-block-drag-preview";
|
|
5979
|
+
chip.textContent = source && blockPreviewText(source) || "Move block";
|
|
5980
|
+
container.appendChild(chip);
|
|
5981
|
+
return () => chip.remove();
|
|
5982
|
+
}
|
|
5983
|
+
});
|
|
5984
|
+
},
|
|
5596
5985
|
onDragStart: () => {
|
|
5986
|
+
const source = this.currentBlockDragSource();
|
|
5597
5987
|
this.blockDragging = true;
|
|
5598
5988
|
handle.classList.add("docx-block-dragging");
|
|
5989
|
+
source?.classList.add("docx-block-drag-source");
|
|
5599
5990
|
this.closeBlockMoveMenu();
|
|
5600
|
-
this.refreshBlockMoveTargets(
|
|
5601
|
-
this.
|
|
5991
|
+
this.refreshBlockMoveTargets(source);
|
|
5992
|
+
this.captureDropZones();
|
|
5602
5993
|
},
|
|
5603
5994
|
onDrop: () => {
|
|
5604
5995
|
this.blockDragging = false;
|
|
5605
5996
|
this.blockDragPointerDown = false;
|
|
5997
|
+
this.dropZones = [];
|
|
5606
5998
|
handle.classList.remove("docx-block-dragging");
|
|
5999
|
+
doc.querySelectorAll(".docx-block-drag-source").forEach((el) => el.classList.remove("docx-block-drag-source"));
|
|
5607
6000
|
this.hideDropIndicator();
|
|
5608
6001
|
}
|
|
5609
6002
|
}));
|
|
6003
|
+
this.blockDragCleanup.push(dropTargetForElements({
|
|
6004
|
+
element: this.editRoot,
|
|
6005
|
+
canDrop: ({ source }) => source.data.type === BLOCK_DRAG_TYPE,
|
|
6006
|
+
getData: ({ input }) => {
|
|
6007
|
+
const hit = this.resolveDropAt(input.clientY);
|
|
6008
|
+
return hit ? { type: BLOCK_DRAG_TYPE, targetAnchorId: hit.zone.anchorId, position: hit.position, zone: hit.zone } : { type: BLOCK_DRAG_TYPE };
|
|
6009
|
+
},
|
|
6010
|
+
onDragEnter: ({ self }) => this.paintDropIndicator(self.data),
|
|
6011
|
+
onDrag: ({ self }) => this.paintDropIndicator(self.data),
|
|
6012
|
+
onDragLeave: () => this.hideDropIndicator()
|
|
6013
|
+
}));
|
|
5610
6014
|
this.blockDragCleanup.push(monitorForElements({
|
|
5611
6015
|
canMonitor: ({ source }) => source.data.type === BLOCK_DRAG_TYPE,
|
|
5612
6016
|
onDrop: ({ source, location: location2 }) => {
|
|
@@ -5633,13 +6037,13 @@ var DocxodusEditor = (() => {
|
|
|
5633
6037
|
canScroll: ({ source }) => source.data.type === BLOCK_DRAG_TYPE,
|
|
5634
6038
|
getAllowedAxis: () => "vertical"
|
|
5635
6039
|
}));
|
|
5636
|
-
this.refreshBlockDropTargets();
|
|
5637
6040
|
}
|
|
5638
6041
|
teardownBlockDrag() {
|
|
5639
6042
|
this.blockMoveTargetPrefetch?.();
|
|
5640
6043
|
this.blockMoveTargetPrefetch = null;
|
|
5641
6044
|
this.blockMoveTargetCache.clear();
|
|
5642
|
-
|
|
6045
|
+
this.dropZones = [];
|
|
6046
|
+
this.dropZoneScroller = null;
|
|
5643
6047
|
for (const cleanup of this.blockDragCleanup.splice(0)) cleanup();
|
|
5644
6048
|
this.blockDragHandle?.remove();
|
|
5645
6049
|
this.blockDropIndicator?.remove();
|
|
@@ -5728,17 +6132,17 @@ var DocxodusEditor = (() => {
|
|
|
5728
6132
|
bodyRoot.after(this.region.footerBand);
|
|
5729
6133
|
this.region.refreshAll();
|
|
5730
6134
|
}
|
|
5731
|
-
/**
|
|
6135
|
+
/**
|
|
6136
|
+
* Continuous (non-paginated) mount: inject the converter's styles + body, wire blocks.
|
|
6137
|
+
*
|
|
6138
|
+
* The body always gets its own `.docx-body-flow` wrapper — not only when bands are docked.
|
|
6139
|
+
* It is the sheet: the element the viewport gives page geometry to and zooms, and the one
|
|
6140
|
+
* the bands dock around. Without it the container would have to be both the scrolling host
|
|
6141
|
+
* and the scaled page, which are different boxes.
|
|
6142
|
+
*/
|
|
5732
6143
|
mountHtml(fullHtml) {
|
|
5733
6144
|
const parsed = new DOMParser().parseFromString(fullHtml, "text/html");
|
|
5734
6145
|
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
6146
|
this.container.innerHTML = styles;
|
|
5743
6147
|
const flow = document.createElement("div");
|
|
5744
6148
|
flow.className = "docx-body-flow";
|
|
@@ -5747,7 +6151,8 @@ var DocxodusEditor = (() => {
|
|
|
5747
6151
|
this.editRoot = flow;
|
|
5748
6152
|
if (this.options.editable) this.wireBlocks(flow);
|
|
5749
6153
|
this.stampPlanState();
|
|
5750
|
-
this.dockBands(flow);
|
|
6154
|
+
if (this.region) this.dockBands(flow);
|
|
6155
|
+
this.viewport.attach(flow, true);
|
|
5751
6156
|
}
|
|
5752
6157
|
/** Paginated mount: flow blocks into page boxes via pagination.ts, wire the page clones. */
|
|
5753
6158
|
mountPaginated(fullHtml) {
|
|
@@ -5768,6 +6173,7 @@ var DocxodusEditor = (() => {
|
|
|
5768
6173
|
this.editRoot = pageRoot;
|
|
5769
6174
|
if (this.options.editable) this.wireBlocks(pageRoot);
|
|
5770
6175
|
if (this.region) this.dockBands(target);
|
|
6176
|
+
this.viewport.attach(pageRoot, false);
|
|
5771
6177
|
}
|
|
5772
6178
|
wireBlocks(root) {
|
|
5773
6179
|
root.querySelectorAll("[data-anchor]").forEach((el) => this.wireBlock(el));
|
|
@@ -7576,14 +7982,7 @@ var DocxodusEditor = (() => {
|
|
|
7576
7982
|
SHOULD win.
|
|
7577
7983
|
(No backticks in this file's comments: the stylesheet is a template literal.) */
|
|
7578
7984
|
.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
|
-
}
|
|
7985
|
+
.dxr[data-chrome] .dxr-surface { margin: 26px auto; padding: 0 16px 96px; }
|
|
7587
7986
|
.dxr-surface [contenteditable="true"]:focus {
|
|
7588
7987
|
outline: 2px solid var(--dxr-accent);
|
|
7589
7988
|
outline-offset: 2px;
|
|
@@ -7595,7 +7994,10 @@ var DocxodusEditor = (() => {
|
|
|
7595
7994
|
so they dock as their own regions. Styled from the same tokens as the ribbon
|
|
7596
7995
|
so the surface reads as one instrument rather than two apps. */
|
|
7597
7996
|
.dxr-surface .docx-hf-band {
|
|
7598
|
-
|
|
7997
|
+
/* Docked outside the zoomed sheet, so it takes the page's on-screen width from the
|
|
7998
|
+
custom property the viewport publishes rather than stretching to the whole surface. */
|
|
7999
|
+
width: min(100%, var(--docx-sheet-width, 100%));
|
|
8000
|
+
margin: 0 auto 14px;
|
|
7599
8001
|
padding: 9px 72px 13px;
|
|
7600
8002
|
border: 1px solid var(--dxr-rule);
|
|
7601
8003
|
border-left: 2px solid #c2ccd9;
|
|
@@ -7603,7 +8005,7 @@ var DocxodusEditor = (() => {
|
|
|
7603
8005
|
background: var(--dxr-sheet);
|
|
7604
8006
|
}
|
|
7605
8007
|
.dxr-surface .docx-hf-band + .docx-body-flow { margin-top: 0; }
|
|
7606
|
-
.dxr-surface .docx-hf-band[data-hf-band="footer"] { margin: 14px
|
|
8008
|
+
.dxr-surface .docx-hf-band[data-hf-band="footer"] { margin: 14px auto 0; }
|
|
7607
8009
|
.dxr-surface .docx-hf-chrome {
|
|
7608
8010
|
display: flex;
|
|
7609
8011
|
gap: 8px;
|
|
@@ -7658,13 +8060,15 @@ var DocxodusEditor = (() => {
|
|
|
7658
8060
|
text-transform: none;
|
|
7659
8061
|
}
|
|
7660
8062
|
.dxr-surface .docx-hf-band[data-hf-inherited] { border-style: dashed; }
|
|
7661
|
-
.
|
|
7662
|
-
|
|
7663
|
-
|
|
7664
|
-
|
|
7665
|
-
|
|
8063
|
+
/* The sheet IS the page. The editor's viewport sizes .docx-body-flow to the section's page
|
|
8064
|
+
width and its section wrappers to the authored text column, so the horizontal gutters here
|
|
8065
|
+
are the document's own w:sectPr margins, not a padding this chrome invents; only the
|
|
8066
|
+
vertical breathing room is ours. Centering is left to margin:auto so a page the viewport
|
|
8067
|
+
has zoomed to fit stays centered at its scaled width. */
|
|
7666
8068
|
.dxr[data-chrome] .dxr-surface[data-view="continuous"] .docx-body-flow {
|
|
7667
|
-
|
|
8069
|
+
max-width: 100%;
|
|
8070
|
+
margin: 0 auto;
|
|
8071
|
+
padding: 56px 0;
|
|
7668
8072
|
border-radius: 3px;
|
|
7669
8073
|
background: var(--dxr-sheet);
|
|
7670
8074
|
box-shadow: 0 1px 3px rgba(16, 20, 24, .14), 0 8px 24px rgba(16, 20, 24, .05);
|
|
@@ -7743,9 +8147,11 @@ var DocxodusEditor = (() => {
|
|
|
7743
8147
|
.dxr[data-chrome="compact"] .dxr-note { display: none; }
|
|
7744
8148
|
.dxr[data-chrome="compact"] .dxr-rail { display: none; }
|
|
7745
8149
|
.dxr[data-chrome="compact"] .dxr-hint { display: none; }
|
|
8150
|
+
/* Compact trims the chrome around the page, never the page: the document's own column width
|
|
8151
|
+
is what the viewport's fit-to-width zoom scales, so a phone shows a whole smaller page
|
|
8152
|
+
instead of a narrower one that breaks its lines somewhere Word never would. */
|
|
7746
8153
|
.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; }
|
|
8154
|
+
.dxr[data-chrome="compact"] .dxr-surface[data-view="continuous"] .docx-body-flow { padding: 22px 0; }
|
|
7749
8155
|
.dxr[data-chrome="compact"] .dxr-surface .docx-hf-band { padding: 9px 18px 13px; }
|
|
7750
8156
|
.dxr[data-chrome="compact"] .dxr-surface .docx-hf-chrome,
|
|
7751
8157
|
.dxr[data-chrome="compact"] .dxr-surface .docx-hf-warning { margin-left: 0; }
|
|
@@ -8495,6 +8901,8 @@ var DocxodusEditor = (() => {
|
|
|
8495
8901
|
fabricateClasses: this.options.fabricateClasses,
|
|
8496
8902
|
editable: this.options.editable,
|
|
8497
8903
|
scale: this.options.scale,
|
|
8904
|
+
columnWidth: this.options.columnWidth,
|
|
8905
|
+
fitToWidth: this.options.fitToWidth,
|
|
8498
8906
|
onEdit: this.options.onEdit,
|
|
8499
8907
|
onMove: this.options.onMove,
|
|
8500
8908
|
paginated,
|