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/embed.bundle.js
CHANGED
|
@@ -1328,20 +1328,18 @@ function formatPageNumber(value, format) {
|
|
|
1328
1328
|
return (renderer ?? RENDERERS.decimal)(value);
|
|
1329
1329
|
}
|
|
1330
1330
|
|
|
1331
|
-
// src/
|
|
1331
|
+
// src/page-geometry.ts
|
|
1332
1332
|
var DEFAULT_PAGE_WIDTH = 612;
|
|
1333
1333
|
var DEFAULT_PAGE_HEIGHT = 792;
|
|
1334
1334
|
var DEFAULT_MARGIN = 72;
|
|
1335
|
-
var
|
|
1336
|
-
var MIN_BODY_CONTENT_HEIGHT = 72;
|
|
1335
|
+
var DEFAULT_HEADER_FOOTER_HEIGHT = 36;
|
|
1337
1336
|
function pxToPt(px) {
|
|
1338
1337
|
return px * 0.75;
|
|
1339
1338
|
}
|
|
1340
1339
|
function ptToPx(pt) {
|
|
1341
1340
|
return pt / 0.75;
|
|
1342
1341
|
}
|
|
1343
|
-
|
|
1344
|
-
function parseDimensions(section) {
|
|
1342
|
+
function parseSectionDimensions(section) {
|
|
1345
1343
|
const pageWidth = parseFloat(section.dataset.pageWidth || "") || DEFAULT_PAGE_WIDTH;
|
|
1346
1344
|
const pageHeight = parseFloat(section.dataset.pageHeight || "") || DEFAULT_PAGE_HEIGHT;
|
|
1347
1345
|
const contentWidth = parseFloat(section.dataset.contentWidth || "") || pageWidth - 2 * DEFAULT_MARGIN;
|
|
@@ -1365,6 +1363,42 @@ function parseDimensions(section) {
|
|
|
1365
1363
|
footerHeight
|
|
1366
1364
|
};
|
|
1367
1365
|
}
|
|
1366
|
+
function sectionWrappers(root) {
|
|
1367
|
+
const sections = Array.from(root.querySelectorAll("[data-section-index]"));
|
|
1368
|
+
return sections.length > 0 ? sections : [root];
|
|
1369
|
+
}
|
|
1370
|
+
var MIN_FIT_SCALE = 0.25;
|
|
1371
|
+
function fitScale(availablePx, naturalPt, max = 1) {
|
|
1372
|
+
if (!(availablePx > 0) || !(naturalPt > 0)) return max;
|
|
1373
|
+
const naturalPx = ptToPx(naturalPt);
|
|
1374
|
+
if (naturalPx <= availablePx) return max;
|
|
1375
|
+
return Math.max(MIN_FIT_SCALE, Math.min(max, availablePx / naturalPx));
|
|
1376
|
+
}
|
|
1377
|
+
function applyZoom(el, scale, naturalPt) {
|
|
1378
|
+
if (scale === 1) {
|
|
1379
|
+
el.style.removeProperty("zoom");
|
|
1380
|
+
el.style.removeProperty("transform");
|
|
1381
|
+
el.style.removeProperty("transform-origin");
|
|
1382
|
+
el.style.removeProperty("margin-right");
|
|
1383
|
+
el.style.removeProperty("margin-bottom");
|
|
1384
|
+
return;
|
|
1385
|
+
}
|
|
1386
|
+
const zoomSupported = typeof CSS !== "undefined" && typeof CSS.supports === "function" && CSS.supports("zoom", "0.5");
|
|
1387
|
+
if (zoomSupported) {
|
|
1388
|
+
el.style.zoom = String(scale);
|
|
1389
|
+
return;
|
|
1390
|
+
}
|
|
1391
|
+
el.style.transform = `scale(${scale})`;
|
|
1392
|
+
el.style.transformOrigin = "top left";
|
|
1393
|
+
if (naturalPt) {
|
|
1394
|
+
el.style.marginRight = `-${ptToPx(naturalPt.width * (1 - scale))}px`;
|
|
1395
|
+
el.style.marginBottom = `-${ptToPx(naturalPt.height * (1 - scale))}px`;
|
|
1396
|
+
}
|
|
1397
|
+
}
|
|
1398
|
+
|
|
1399
|
+
// src/pagination.ts
|
|
1400
|
+
var MAX_FOOTNOTE_AREA_RATIO = 0.6;
|
|
1401
|
+
var MIN_BODY_CONTENT_HEIGHT = 72;
|
|
1368
1402
|
var PaginationEngine = class {
|
|
1369
1403
|
/**
|
|
1370
1404
|
* Creates a new pagination engine.
|
|
@@ -1410,7 +1444,7 @@ var PaginationEngine = class {
|
|
|
1410
1444
|
const sectionsToProcess = sections.length > 0 ? Array.from(sections) : [this.stagingElement];
|
|
1411
1445
|
for (const section of sectionsToProcess) {
|
|
1412
1446
|
const sectionIndex = parseInt(section.dataset.sectionIndex || "0", 10);
|
|
1413
|
-
const dims =
|
|
1447
|
+
const dims = parseSectionDimensions(section);
|
|
1414
1448
|
this.stagingElement.style.visibility = "hidden";
|
|
1415
1449
|
this.stagingElement.style.position = "absolute";
|
|
1416
1450
|
this.stagingElement.style.left = "-9999px";
|
|
@@ -2708,6 +2742,114 @@ function paginateHtml(html, container, options = {}) {
|
|
|
2708
2742
|
return engine.paginate();
|
|
2709
2743
|
}
|
|
2710
2744
|
|
|
2745
|
+
// src/viewport.ts
|
|
2746
|
+
var DocumentViewport = class {
|
|
2747
|
+
constructor(host, options = {}) {
|
|
2748
|
+
this.root = null;
|
|
2749
|
+
/** Natural page size in points — the widest section's PAGE box, which is what must fit. */
|
|
2750
|
+
this.natural = { width: 0, height: 0 };
|
|
2751
|
+
this.observer = null;
|
|
2752
|
+
this.host = host;
|
|
2753
|
+
this.options = {
|
|
2754
|
+
columnWidth: options.columnWidth ?? "section",
|
|
2755
|
+
fitToWidth: options.fitToWidth ?? true,
|
|
2756
|
+
scale: options.scale ?? 1
|
|
2757
|
+
};
|
|
2758
|
+
}
|
|
2759
|
+
/**
|
|
2760
|
+
* Adopt a freshly mounted document root (a continuous flow, or the paginated page stack).
|
|
2761
|
+
* Safe to call on every remount; the previous root is released first.
|
|
2762
|
+
*
|
|
2763
|
+
* `applySectionGeometry` is false for the paginated view, which already builds real page
|
|
2764
|
+
* boxes at the section's dimensions — there the viewport contributes only the fit zoom.
|
|
2765
|
+
*/
|
|
2766
|
+
attach(root, applySectionGeometry) {
|
|
2767
|
+
this.release();
|
|
2768
|
+
this.root = root;
|
|
2769
|
+
this.natural = applySectionGeometry ? this.stampSections(root) : this.measurePages(root);
|
|
2770
|
+
this.refresh();
|
|
2771
|
+
if (typeof ResizeObserver !== "undefined") {
|
|
2772
|
+
this.observer = new ResizeObserver(() => this.refresh());
|
|
2773
|
+
this.observer.observe(this.host);
|
|
2774
|
+
}
|
|
2775
|
+
}
|
|
2776
|
+
/** Recompute the fit zoom against the host's current width. */
|
|
2777
|
+
refresh() {
|
|
2778
|
+
if (!this.root) return;
|
|
2779
|
+
const scale = this.scale;
|
|
2780
|
+
applyZoom(this.root, scale, this.natural);
|
|
2781
|
+
this.host.style.setProperty(
|
|
2782
|
+
"--docx-sheet-width",
|
|
2783
|
+
this.natural.width > 0 ? `${ptToPx(this.natural.width) * scale}px` : "100%"
|
|
2784
|
+
);
|
|
2785
|
+
}
|
|
2786
|
+
/** The zoom currently applied (1 = 100%). Reported by the ribbon's anchor rail. */
|
|
2787
|
+
get scale() {
|
|
2788
|
+
if (!this.root) return this.options.scale;
|
|
2789
|
+
return this.options.fitToWidth ? fitScale(this.availableWidthPx(), this.natural.width, this.options.scale) : this.options.scale;
|
|
2790
|
+
}
|
|
2791
|
+
dispose() {
|
|
2792
|
+
this.release();
|
|
2793
|
+
this.root = null;
|
|
2794
|
+
}
|
|
2795
|
+
release() {
|
|
2796
|
+
this.observer?.disconnect();
|
|
2797
|
+
this.observer = null;
|
|
2798
|
+
if (this.root) applyZoom(this.root, 1);
|
|
2799
|
+
this.host.style.removeProperty("--docx-sheet-width");
|
|
2800
|
+
}
|
|
2801
|
+
/** The host's content box, which is the space a page has to fit into. */
|
|
2802
|
+
availableWidthPx() {
|
|
2803
|
+
const style = typeof getComputedStyle === "function" ? getComputedStyle(this.host) : null;
|
|
2804
|
+
const padding = style ? (parseFloat(style.paddingLeft) || 0) + (parseFloat(style.paddingRight) || 0) : 0;
|
|
2805
|
+
return Math.max(0, this.host.clientWidth - padding);
|
|
2806
|
+
}
|
|
2807
|
+
/**
|
|
2808
|
+
* Give each section wrapper its `w:sectPr` geometry: the authored text column, guttered by
|
|
2809
|
+
* the authored margins. The wrapper then measures exactly one page wide, which is what the
|
|
2810
|
+
* sheet chrome paints and what the fit zoom scales.
|
|
2811
|
+
*/
|
|
2812
|
+
stampSections(root) {
|
|
2813
|
+
const sections = sectionWrappers(root);
|
|
2814
|
+
if (this.options.columnWidth === "fluid") {
|
|
2815
|
+
root.style.removeProperty("width");
|
|
2816
|
+
for (const section of sections) {
|
|
2817
|
+
section.style.removeProperty("width");
|
|
2818
|
+
section.style.removeProperty("padding-left");
|
|
2819
|
+
section.style.removeProperty("padding-right");
|
|
2820
|
+
}
|
|
2821
|
+
return { width: 0, height: 0 };
|
|
2822
|
+
}
|
|
2823
|
+
let widest = 0;
|
|
2824
|
+
for (const section of sections) {
|
|
2825
|
+
const dims = parseSectionDimensions(section);
|
|
2826
|
+
section.style.width = `${dims.contentWidth}pt`;
|
|
2827
|
+
section.style.paddingLeft = `${dims.marginLeft}pt`;
|
|
2828
|
+
section.style.paddingRight = `${dims.marginRight}pt`;
|
|
2829
|
+
section.style.boxSizing = "content-box";
|
|
2830
|
+
section.style.marginLeft = "auto";
|
|
2831
|
+
section.style.marginRight = "auto";
|
|
2832
|
+
widest = Math.max(widest, dims.pageWidth);
|
|
2833
|
+
}
|
|
2834
|
+
if (widest > 0 && sections[0] !== root) root.style.width = `${widest}pt`;
|
|
2835
|
+
return { width: widest, height: 0 };
|
|
2836
|
+
}
|
|
2837
|
+
/**
|
|
2838
|
+
* The paginated view's page boxes are already page-sized — `pagination.ts` writes each
|
|
2839
|
+
* box's `width` in points — so the widest of those is the natural width. Reading the
|
|
2840
|
+
* inline width rather than the laid-out box keeps this independent of the per-box zoom
|
|
2841
|
+
* pagination may itself have applied.
|
|
2842
|
+
*/
|
|
2843
|
+
measurePages(root) {
|
|
2844
|
+
let widest = 0;
|
|
2845
|
+
for (const box of Array.from(root.children)) {
|
|
2846
|
+
const declared = /^([\d.]+)pt$/.exec(box.style.width || "");
|
|
2847
|
+
widest = Math.max(widest, declared ? parseFloat(declared[1]) : pxToPt(box.offsetWidth));
|
|
2848
|
+
}
|
|
2849
|
+
return { width: widest, height: 0 };
|
|
2850
|
+
}
|
|
2851
|
+
};
|
|
2852
|
+
|
|
2711
2853
|
// src/editor-headerfooter.ts
|
|
2712
2854
|
var PAGE_FORMAT_LABELS = [
|
|
2713
2855
|
{ value: "", label: "Format\u2026" },
|
|
@@ -4796,6 +4938,146 @@ function draggable(args) {
|
|
|
4796
4938
|
return once(cleanup);
|
|
4797
4939
|
}
|
|
4798
4940
|
|
|
4941
|
+
// node_modules/@atlaskit/pragmatic-drag-and-drop/dist/esm/public-utils/element/custom-native-drag-preview/set-custom-native-drag-preview.js
|
|
4942
|
+
function ownKeys4(e, r) {
|
|
4943
|
+
var t = Object.keys(e);
|
|
4944
|
+
if (Object.getOwnPropertySymbols) {
|
|
4945
|
+
var o = Object.getOwnPropertySymbols(e);
|
|
4946
|
+
r && (o = o.filter(function(r2) {
|
|
4947
|
+
return Object.getOwnPropertyDescriptor(e, r2).enumerable;
|
|
4948
|
+
})), t.push.apply(t, o);
|
|
4949
|
+
}
|
|
4950
|
+
return t;
|
|
4951
|
+
}
|
|
4952
|
+
function _objectSpread4(e) {
|
|
4953
|
+
for (var r = 1; r < arguments.length; r++) {
|
|
4954
|
+
var t = null != arguments[r] ? arguments[r] : {};
|
|
4955
|
+
r % 2 ? ownKeys4(Object(t), true).forEach(function(r2) {
|
|
4956
|
+
_defineProperty(e, r2, t[r2]);
|
|
4957
|
+
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys4(Object(t)).forEach(function(r2) {
|
|
4958
|
+
Object.defineProperty(e, r2, Object.getOwnPropertyDescriptor(t, r2));
|
|
4959
|
+
});
|
|
4960
|
+
}
|
|
4961
|
+
return e;
|
|
4962
|
+
}
|
|
4963
|
+
function defaultOffset() {
|
|
4964
|
+
return {
|
|
4965
|
+
x: 0,
|
|
4966
|
+
y: 0
|
|
4967
|
+
};
|
|
4968
|
+
}
|
|
4969
|
+
function setCustomNativeDragPreview(_ref) {
|
|
4970
|
+
var render = _ref.render, nativeSetDragImage = _ref.nativeSetDragImage, _ref$getOffset = _ref.getOffset, getOffset = _ref$getOffset === void 0 ? defaultOffset : _ref$getOffset;
|
|
4971
|
+
var container = document.createElement("div");
|
|
4972
|
+
if (supportsPopover()) {
|
|
4973
|
+
container.setAttribute("popover", "manual");
|
|
4974
|
+
}
|
|
4975
|
+
Object.assign(container.style, _objectSpread4(_objectSpread4({
|
|
4976
|
+
// Ensuring we don't cause reflow when adding the element to the page
|
|
4977
|
+
// Using `position:fixed` rather than `position:absolute` so we are
|
|
4978
|
+
// positioned on the current viewport.
|
|
4979
|
+
// `position:fixed` also creates a new stacking context, so we don't need to do that here
|
|
4980
|
+
position: "fixed"
|
|
4981
|
+
}, supportsPopover() ? (
|
|
4982
|
+
// needs to come first as it has 'inset: unset' which
|
|
4983
|
+
// needs to be overridden by our top / left values
|
|
4984
|
+
popoverResetUserAgentStyles
|
|
4985
|
+
) : {
|
|
4986
|
+
// Fallback: using maximum possible z-index so that this element
|
|
4987
|
+
// will always be on top of other positioned content.
|
|
4988
|
+
zIndex: maxZIndex
|
|
4989
|
+
}), {}, {
|
|
4990
|
+
// According to `mdn`, the element can be offscreen:
|
|
4991
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/setDragImage#imgelement
|
|
4992
|
+
//
|
|
4993
|
+
// However, that information does not appear in the specs:
|
|
4994
|
+
// https://html.spec.whatwg.org/multipage/dnd.html#dom-datatransfer-setdragimage-dev
|
|
4995
|
+
//
|
|
4996
|
+
// If the element is _completely_ offscreen, Safari@17.1 will cancel the drag
|
|
4997
|
+
top: 0,
|
|
4998
|
+
left: 0,
|
|
4999
|
+
// Avoiding any additional events caused by the new element (being super safe)
|
|
5000
|
+
pointerEvents: "none"
|
|
5001
|
+
}));
|
|
5002
|
+
document.body.append(container);
|
|
5003
|
+
if (supportsPopover()) {
|
|
5004
|
+
container.showPopover();
|
|
5005
|
+
}
|
|
5006
|
+
var unmount = render({
|
|
5007
|
+
container
|
|
5008
|
+
});
|
|
5009
|
+
queueMicrotask(function() {
|
|
5010
|
+
var previewOffset = getOffset({
|
|
5011
|
+
container
|
|
5012
|
+
});
|
|
5013
|
+
if (isSafari()) {
|
|
5014
|
+
var rect = container.getBoundingClientRect();
|
|
5015
|
+
if (rect.width === 0) {
|
|
5016
|
+
return;
|
|
5017
|
+
}
|
|
5018
|
+
container.style.left = "-".concat(rect.width - 1e-4, "px");
|
|
5019
|
+
}
|
|
5020
|
+
nativeSetDragImage === null || nativeSetDragImage === void 0 || nativeSetDragImage(container, previewOffset.x, previewOffset.y);
|
|
5021
|
+
});
|
|
5022
|
+
function cleanup() {
|
|
5023
|
+
unbindMonitor();
|
|
5024
|
+
unmount === null || unmount === void 0 || unmount();
|
|
5025
|
+
document.body.removeChild(container);
|
|
5026
|
+
}
|
|
5027
|
+
var unbindMonitor = monitorForElements({
|
|
5028
|
+
// Remove portal in the dragstart event so that the user will never see it
|
|
5029
|
+
onDragStart: cleanup,
|
|
5030
|
+
// Backup: remove portal when the drop finishes (this would be an error case)
|
|
5031
|
+
onDrop: cleanup
|
|
5032
|
+
});
|
|
5033
|
+
}
|
|
5034
|
+
|
|
5035
|
+
// node_modules/@atlaskit/pragmatic-drag-and-drop/dist/esm/util/is-safari-on-ios.js
|
|
5036
|
+
var isSafariOnIOS = once(function isSafariOnIOS2() {
|
|
5037
|
+
if (false) {
|
|
5038
|
+
return false;
|
|
5039
|
+
}
|
|
5040
|
+
return isSafari() && "ontouchend" in document;
|
|
5041
|
+
});
|
|
5042
|
+
|
|
5043
|
+
// node_modules/@atlaskit/pragmatic-drag-and-drop/dist/esm/public-utils/element/custom-native-drag-preview/center-under-pointer.js
|
|
5044
|
+
var centerUnderPointer = function centerUnderPointer2(_ref) {
|
|
5045
|
+
var container = _ref.container;
|
|
5046
|
+
var rect = container.getBoundingClientRect();
|
|
5047
|
+
return {
|
|
5048
|
+
x: rect.width / 2,
|
|
5049
|
+
y: rect.height / 2
|
|
5050
|
+
};
|
|
5051
|
+
};
|
|
5052
|
+
|
|
5053
|
+
// node_modules/@atlaskit/pragmatic-drag-and-drop/dist/esm/public-utils/element/custom-native-drag-preview/pointer-outside-of-preview.js
|
|
5054
|
+
function pointerOutsideOfPreview(point) {
|
|
5055
|
+
return function getOffset(_ref) {
|
|
5056
|
+
var container = _ref.container;
|
|
5057
|
+
if (isSafariOnIOS() || isAndroid()) {
|
|
5058
|
+
return centerUnderPointer({
|
|
5059
|
+
container
|
|
5060
|
+
});
|
|
5061
|
+
}
|
|
5062
|
+
Object.assign(container.style, {
|
|
5063
|
+
borderInlineStart: "".concat(point.x, " solid transparent"),
|
|
5064
|
+
borderTop: "".concat(point.y, " solid transparent")
|
|
5065
|
+
});
|
|
5066
|
+
var computed = window.getComputedStyle(container);
|
|
5067
|
+
if (computed.direction === "rtl") {
|
|
5068
|
+
var box = container.getBoundingClientRect();
|
|
5069
|
+
return {
|
|
5070
|
+
x: box.width,
|
|
5071
|
+
y: 0
|
|
5072
|
+
};
|
|
5073
|
+
}
|
|
5074
|
+
return {
|
|
5075
|
+
x: 0,
|
|
5076
|
+
y: 0
|
|
5077
|
+
};
|
|
5078
|
+
};
|
|
5079
|
+
}
|
|
5080
|
+
|
|
4799
5081
|
// node_modules/@atlaskit/pragmatic-drag-and-drop-auto-scroll/dist/esm/shared/engagement-history.js
|
|
4800
5082
|
var ledger2 = /* @__PURE__ */ new Map();
|
|
4801
5083
|
var requested = /* @__PURE__ */ new Set();
|
|
@@ -4929,7 +5211,7 @@ function addScrollableAttribute(element) {
|
|
|
4929
5211
|
}
|
|
4930
5212
|
|
|
4931
5213
|
// node_modules/@atlaskit/pragmatic-drag-and-drop-auto-scroll/dist/esm/shared/configuration.js
|
|
4932
|
-
function
|
|
5214
|
+
function ownKeys5(e, r) {
|
|
4933
5215
|
var t = Object.keys(e);
|
|
4934
5216
|
if (Object.getOwnPropertySymbols) {
|
|
4935
5217
|
var o = Object.getOwnPropertySymbols(e);
|
|
@@ -4939,12 +5221,12 @@ function ownKeys4(e, r) {
|
|
|
4939
5221
|
}
|
|
4940
5222
|
return t;
|
|
4941
5223
|
}
|
|
4942
|
-
function
|
|
5224
|
+
function _objectSpread5(e) {
|
|
4943
5225
|
for (var r = 1; r < arguments.length; r++) {
|
|
4944
5226
|
var t = null != arguments[r] ? arguments[r] : {};
|
|
4945
|
-
r % 2 ?
|
|
5227
|
+
r % 2 ? ownKeys5(Object(t), true).forEach(function(r2) {
|
|
4946
5228
|
_defineProperty(e, r2, t[r2]);
|
|
4947
|
-
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) :
|
|
5229
|
+
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys5(Object(t)).forEach(function(r2) {
|
|
4948
5230
|
Object.defineProperty(e, r2, Object.getOwnPropertyDescriptor(t, r2));
|
|
4949
5231
|
});
|
|
4950
5232
|
}
|
|
@@ -4979,7 +5261,7 @@ var maxPixelScrollPerSecond = {
|
|
|
4979
5261
|
};
|
|
4980
5262
|
function getInternalConfig(provided) {
|
|
4981
5263
|
var _provided$maxScrollSp;
|
|
4982
|
-
return
|
|
5264
|
+
return _objectSpread5(_objectSpread5({}, baseConfig), {}, {
|
|
4983
5265
|
// only allowing limited control over the config at this stage
|
|
4984
5266
|
maxPixelScrollPerSecond: maxPixelScrollPerSecond[(_provided$maxScrollSp = provided === null || provided === void 0 ? void 0 : provided.maxScrollSpeed) !== null && _provided$maxScrollSp !== void 0 ? _provided$maxScrollSp : "standard"]
|
|
4985
5267
|
});
|
|
@@ -5463,7 +5745,7 @@ function tryScroll(_ref3) {
|
|
|
5463
5745
|
}
|
|
5464
5746
|
|
|
5465
5747
|
// node_modules/@atlaskit/pragmatic-drag-and-drop-auto-scroll/dist/esm/over-element/make-api.js
|
|
5466
|
-
function
|
|
5748
|
+
function ownKeys6(e, r) {
|
|
5467
5749
|
var t = Object.keys(e);
|
|
5468
5750
|
if (Object.getOwnPropertySymbols) {
|
|
5469
5751
|
var o = Object.getOwnPropertySymbols(e);
|
|
@@ -5473,12 +5755,12 @@ function ownKeys5(e, r) {
|
|
|
5473
5755
|
}
|
|
5474
5756
|
return t;
|
|
5475
5757
|
}
|
|
5476
|
-
function
|
|
5758
|
+
function _objectSpread6(e) {
|
|
5477
5759
|
for (var r = 1; r < arguments.length; r++) {
|
|
5478
5760
|
var t = null != arguments[r] ? arguments[r] : {};
|
|
5479
|
-
r % 2 ?
|
|
5761
|
+
r % 2 ? ownKeys6(Object(t), true).forEach(function(r2) {
|
|
5480
5762
|
_defineProperty(e, r2, t[r2]);
|
|
5481
|
-
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) :
|
|
5763
|
+
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys6(Object(t)).forEach(function(r2) {
|
|
5482
5764
|
Object.defineProperty(e, r2, Object.getOwnPropertyDescriptor(t, r2));
|
|
5483
5765
|
});
|
|
5484
5766
|
}
|
|
@@ -5517,7 +5799,7 @@ function makeApi(_ref) {
|
|
|
5517
5799
|
}
|
|
5518
5800
|
function autoScrollWindow() {
|
|
5519
5801
|
var args = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
|
|
5520
|
-
var unique =
|
|
5802
|
+
var unique = _objectSpread6({}, args);
|
|
5521
5803
|
windowRegistry.add(unique);
|
|
5522
5804
|
function cleanup() {
|
|
5523
5805
|
windowRegistry.delete(unique);
|
|
@@ -5670,6 +5952,11 @@ function needsRemount(diff, newUnits, oldKinds, threshold = 40) {
|
|
|
5670
5952
|
var EDITABLE_TAGS = /* @__PURE__ */ new Set(["P", "H1", "H2", "H3", "H4", "H5", "H6"]);
|
|
5671
5953
|
var BLOCK_DRAG_TYPE = "docxodus-block";
|
|
5672
5954
|
var blockDragStyledDocuments = /* @__PURE__ */ new WeakSet();
|
|
5955
|
+
function blockPreviewText(unit) {
|
|
5956
|
+
if (unit.tagName === "TABLE") return "Table";
|
|
5957
|
+
const text = (unit.textContent ?? "").trim().replace(/\s+/g, " ");
|
|
5958
|
+
return text.length > 48 ? `${text.slice(0, 48)}\u2026` : text;
|
|
5959
|
+
}
|
|
5673
5960
|
function ensureBlockDragStyles(doc) {
|
|
5674
5961
|
if (blockDragStyledDocuments.has(doc)) return;
|
|
5675
5962
|
blockDragStyledDocuments.add(doc);
|
|
@@ -5684,10 +5971,28 @@ function ensureBlockDragStyles(doc) {
|
|
|
5684
5971
|
}
|
|
5685
5972
|
.docx-block-handle:hover, .docx-block-handle:focus-visible { color: #344054; border-color: #98a2b3; outline: none; }
|
|
5686
5973
|
.docx-block-handle[aria-pressed="true"] { color: #175cd3; border-color: #84adff; background: #eff8ff; }
|
|
5687
|
-
.docx-block-handle.docx-block-dragging { cursor: grabbing; opacity: .
|
|
5974
|
+
.docx-block-handle.docx-block-dragging { cursor: grabbing; opacity: .35; }
|
|
5975
|
+
/* The block being carried. Dimming it is the "a drag is happening" signal that survives the
|
|
5976
|
+
pointer being anywhere on screen \u2014 the drop line only says where, not what. */
|
|
5977
|
+
.docx-block-drag-source { opacity: .38; transition: opacity 120ms ease-out; }
|
|
5978
|
+
/* Positioned by transform so tracking the pointer costs no layout. Flipping display none\u2192block
|
|
5979
|
+
restarts the fade \u2014 one cheap entry animation per appearance, none while it tracks. */
|
|
5688
5980
|
.docx-block-drop-indicator {
|
|
5689
|
-
position: fixed; z-index: 2147482999; display: none; height:
|
|
5690
|
-
|
|
5981
|
+
position: fixed; top: 0; left: 0; z-index: 2147482999; display: none; height: 0;
|
|
5982
|
+
pointer-events: none; border-top: 2px solid #2e90fa;
|
|
5983
|
+
filter: drop-shadow(0 1px 2px rgba(46,144,250,.5));
|
|
5984
|
+
animation: docx-block-drop-in 110ms ease-out;
|
|
5985
|
+
}
|
|
5986
|
+
.docx-block-drop-indicator::before {
|
|
5987
|
+
content: ""; position: absolute; top: -5px; left: -2px; width: 8px; height: 8px;
|
|
5988
|
+
border-radius: 50%; background: #2e90fa;
|
|
5989
|
+
}
|
|
5990
|
+
@keyframes docx-block-drop-in { from { opacity: 0; } to { opacity: 1; } }
|
|
5991
|
+
.docx-block-drag-preview {
|
|
5992
|
+
max-width: 320px; padding: 6px 10px; border: 1px solid #b2ddff; border-radius: 6px;
|
|
5993
|
+
background: #eff8ff; color: #175cd3; box-shadow: 0 6px 16px rgba(16,24,40,.18);
|
|
5994
|
+
font: 500 13px/1.35 system-ui, sans-serif; white-space: nowrap; overflow: hidden;
|
|
5995
|
+
text-overflow: ellipsis;
|
|
5691
5996
|
}
|
|
5692
5997
|
.docx-block-move-menu {
|
|
5693
5998
|
position: fixed; z-index: 2147483001; display: none; min-width: 150px; padding: 5px;
|
|
@@ -6075,7 +6380,11 @@ var DocxEditor = class _DocxEditor {
|
|
|
6075
6380
|
this.blockMoveLive = null;
|
|
6076
6381
|
this.blockDragSource = null;
|
|
6077
6382
|
this.blockDragCleanup = [];
|
|
6078
|
-
|
|
6383
|
+
/** Block boxes measured at drag start — see `BlockDropZone`. Empty when no drag is in flight. */
|
|
6384
|
+
this.dropZones = [];
|
|
6385
|
+
/** Combined scroll offset when `dropZones` was measured, and the scroller measured against. */
|
|
6386
|
+
this.dropZoneOrigin = 0;
|
|
6387
|
+
this.dropZoneScroller = null;
|
|
6079
6388
|
this.blockDragging = false;
|
|
6080
6389
|
this.blockDragPointerDown = false;
|
|
6081
6390
|
/** Anchors the current drag source may legally move next to, per the engine's own rules.
|
|
@@ -6204,6 +6513,11 @@ var DocxEditor = class _DocxEditor {
|
|
|
6204
6513
|
this.handle = handle;
|
|
6205
6514
|
this.options = options;
|
|
6206
6515
|
this.editRoot = container;
|
|
6516
|
+
this.viewport = new DocumentViewport(container, {
|
|
6517
|
+
columnWidth: options.columnWidth,
|
|
6518
|
+
fitToWidth: options.fitToWidth,
|
|
6519
|
+
scale: options.scale
|
|
6520
|
+
});
|
|
6207
6521
|
if (typeof document !== "undefined") {
|
|
6208
6522
|
document.addEventListener("selectionchange", this.onSelectionChange);
|
|
6209
6523
|
document.addEventListener("mousedown", this.onMouseDown, true);
|
|
@@ -6286,6 +6600,8 @@ var DocxEditor = class _DocxEditor {
|
|
|
6286
6600
|
editable: options.editable ?? true,
|
|
6287
6601
|
paginated: options.paginated ?? false,
|
|
6288
6602
|
scale: options.scale ?? 1,
|
|
6603
|
+
columnWidth: options.columnWidth ?? "section",
|
|
6604
|
+
fitToWidth: options.fitToWidth ?? true,
|
|
6289
6605
|
headerFooter: options.headerFooter ?? false,
|
|
6290
6606
|
blockDrag: options.blockDrag ?? false,
|
|
6291
6607
|
trackedChanges: options.trackedChanges ?? 0 /* Accept */,
|
|
@@ -6342,6 +6658,7 @@ var DocxEditor = class _DocxEditor {
|
|
|
6342
6658
|
}
|
|
6343
6659
|
this.clearDragSelection();
|
|
6344
6660
|
this.teardownBlockDrag();
|
|
6661
|
+
this.viewport.dispose();
|
|
6345
6662
|
this.exports.DocxSessionBridge.CloseSession(this.handle);
|
|
6346
6663
|
}
|
|
6347
6664
|
/**
|
|
@@ -6359,6 +6676,14 @@ var DocxEditor = class _DocxEditor {
|
|
|
6359
6676
|
get root() {
|
|
6360
6677
|
return this.container;
|
|
6361
6678
|
}
|
|
6679
|
+
/**
|
|
6680
|
+
* The zoom the viewport is currently applying (1 = 100%). Below 1 the page is wider than the
|
|
6681
|
+
* host and has been scaled to fit rather than reflowed — the honest thing to show a user who
|
|
6682
|
+
* is wondering why a phone shows the whole page.
|
|
6683
|
+
*/
|
|
6684
|
+
get zoom() {
|
|
6685
|
+
return this.viewport.scale;
|
|
6686
|
+
}
|
|
6362
6687
|
/**
|
|
6363
6688
|
* The live `DocxSession` handle backing this editor — the model of record.
|
|
6364
6689
|
*
|
|
@@ -6369,6 +6694,19 @@ var DocxEditor = class _DocxEditor {
|
|
|
6369
6694
|
get sessionHandle() {
|
|
6370
6695
|
return this.handle;
|
|
6371
6696
|
}
|
|
6697
|
+
/**
|
|
6698
|
+
* Repaint from the live session after it was mutated OUTSIDE the editor's own
|
|
6699
|
+
* commands — a host driving {@link sessionHandle} directly (an agent pipeline,
|
|
6700
|
+
* `raw.replaceXml`, a batch import). Continuous mode patches incrementally from
|
|
6701
|
+
* the render plan (a Unid-preserving single-block mutation repaints just that
|
|
6702
|
+
* block); paginated mode — or anything the reconciler cannot prove — remounts.
|
|
6703
|
+
* The editor cannot observe external mutations, so the host owns calling this
|
|
6704
|
+
* once per mutation batch.
|
|
6705
|
+
*/
|
|
6706
|
+
refresh() {
|
|
6707
|
+
this.assertOpen();
|
|
6708
|
+
this.reconcile();
|
|
6709
|
+
}
|
|
6372
6710
|
/** Move one top-level body block relative to another and repaint from the live session. */
|
|
6373
6711
|
moveBlock(sourceAnchorId, targetAnchorId, position) {
|
|
6374
6712
|
this.assertOpen();
|
|
@@ -6449,7 +6787,7 @@ var DocxEditor = class _DocxEditor {
|
|
|
6449
6787
|
handle.style.display = "flex";
|
|
6450
6788
|
handle.style.left = `${Math.max(4, rect.left - 32)}px`;
|
|
6451
6789
|
handle.style.top = `${Math.max(4, rect.top + (unit.tagName === "TABLE" ? 6 : Math.max(0, (rect.height - 28) / 2)))}px`;
|
|
6452
|
-
const preview = (unit
|
|
6790
|
+
const preview = blockPreviewText(unit);
|
|
6453
6791
|
handle.setAttribute("aria-label", preview ? `Move block: ${preview}` : "Move block");
|
|
6454
6792
|
}
|
|
6455
6793
|
hideBlockHandle() {
|
|
@@ -6460,14 +6798,33 @@ var DocxEditor = class _DocxEditor {
|
|
|
6460
6798
|
const source = this.currentBlockDragSource();
|
|
6461
6799
|
if (source && this.blockDragHandle?.style.display !== "none") this.showBlockHandle(source);
|
|
6462
6800
|
}
|
|
6463
|
-
|
|
6801
|
+
/** Draw the drop line on `zone`'s requested edge, or take it away when there is no target. */
|
|
6802
|
+
paintDropIndicator(data) {
|
|
6464
6803
|
const indicator = this.blockDropIndicator;
|
|
6804
|
+
const zone = data.zone;
|
|
6465
6805
|
if (!indicator) return;
|
|
6466
|
-
|
|
6806
|
+
if (!zone) {
|
|
6807
|
+
this.hideDropIndicator();
|
|
6808
|
+
return;
|
|
6809
|
+
}
|
|
6810
|
+
const y = Math.round(this.dropEdgeY(zone, data.position === "after" ? "after" : "before") + this.dropZoneShift()) - 1;
|
|
6811
|
+
indicator.style.transform = `translate3d(${Math.round(zone.left)}px, ${y}px, 0)`;
|
|
6812
|
+
indicator.style.width = `${Math.max(24, Math.round(zone.width))}px`;
|
|
6467
6813
|
indicator.style.display = "block";
|
|
6468
|
-
|
|
6469
|
-
|
|
6470
|
-
|
|
6814
|
+
}
|
|
6815
|
+
/**
|
|
6816
|
+
* Where to draw the line for an insertion on `position` of `zone` — the MIDDLE of the gap to
|
|
6817
|
+
* the neighbour on that side, not the zone's own border-box edge. A paragraph's `w:spacing`
|
|
6818
|
+
* becomes a CSS margin, which sits outside the box, so drawing on the edge underlines the
|
|
6819
|
+
* block's last line instead of reading as a gap between two blocks. Falls back to the raw edge
|
|
6820
|
+
* at the ends of the flow, and degrades to the same value when blocks are contiguous.
|
|
6821
|
+
*/
|
|
6822
|
+
dropEdgeY(zone, position) {
|
|
6823
|
+
const neighbour = this.dropZones[zone.index + (position === "after" ? 1 : -1)];
|
|
6824
|
+
if (!neighbour) {
|
|
6825
|
+
return position === "after" ? zone.bottom + zone.marginAfter / 2 : zone.top - zone.marginBefore / 2;
|
|
6826
|
+
}
|
|
6827
|
+
return position === "after" ? (zone.bottom + neighbour.top) / 2 : (neighbour.bottom + zone.top) / 2;
|
|
6471
6828
|
}
|
|
6472
6829
|
hideDropIndicator() {
|
|
6473
6830
|
if (this.blockDropIndicator) this.blockDropIndicator.style.display = "none";
|
|
@@ -6547,45 +6904,75 @@ var DocxEditor = class _DocxEditor {
|
|
|
6547
6904
|
if (!sides) return false;
|
|
6548
6905
|
return position ? sides[position] : sides.before || sides.after;
|
|
6549
6906
|
}
|
|
6907
|
+
/** Measure every movable block once, at drag start. See `BlockDropZone`. */
|
|
6908
|
+
captureDropZones() {
|
|
6909
|
+
const view = this.container.ownerDocument.defaultView;
|
|
6910
|
+
this.dropZoneScroller = this.scrollContainer();
|
|
6911
|
+
this.dropZoneOrigin = this.scrollOffsetSum();
|
|
6912
|
+
this.dropZones = [];
|
|
6913
|
+
const boxes = [];
|
|
6914
|
+
for (const unit of this.bodyUnitNodes()) {
|
|
6915
|
+
const anchorId = this.isMovableBlockUnit(unit) ? this.anchorIdOf(unit) : null;
|
|
6916
|
+
if (!anchorId) continue;
|
|
6917
|
+
const box = this.unitWrapperOf(unit);
|
|
6918
|
+
const rect = box.getBoundingClientRect();
|
|
6919
|
+
boxes.push(box);
|
|
6920
|
+
this.dropZones.push({
|
|
6921
|
+
unit,
|
|
6922
|
+
anchorId,
|
|
6923
|
+
index: this.dropZones.length,
|
|
6924
|
+
top: rect.top,
|
|
6925
|
+
bottom: rect.bottom,
|
|
6926
|
+
left: rect.left,
|
|
6927
|
+
width: rect.width,
|
|
6928
|
+
marginBefore: 0,
|
|
6929
|
+
marginAfter: 0
|
|
6930
|
+
});
|
|
6931
|
+
}
|
|
6932
|
+
const ends = new Set([0, this.dropZones.length - 1].filter((i) => i >= 0 && i < boxes.length));
|
|
6933
|
+
for (const i of ends) {
|
|
6934
|
+
const style = view?.getComputedStyle(boxes[i]);
|
|
6935
|
+
this.dropZones[i].marginBefore = parseFloat(style?.marginTop ?? "0") || 0;
|
|
6936
|
+
this.dropZones[i].marginAfter = parseFloat(style?.marginBottom ?? "0") || 0;
|
|
6937
|
+
}
|
|
6938
|
+
}
|
|
6939
|
+
scrollOffsetSum() {
|
|
6940
|
+
const view = this.container.ownerDocument.defaultView;
|
|
6941
|
+
return (view?.scrollY ?? 0) + (this.dropZoneScroller?.scrollTop ?? 0);
|
|
6942
|
+
}
|
|
6943
|
+
/** How far the measured boxes have travelled since capture, from scrolling (drag autoscroll). */
|
|
6944
|
+
dropZoneShift() {
|
|
6945
|
+
return this.dropZoneOrigin - this.scrollOffsetSum();
|
|
6946
|
+
}
|
|
6550
6947
|
/**
|
|
6551
|
-
*
|
|
6552
|
-
*
|
|
6553
|
-
*
|
|
6554
|
-
*
|
|
6555
|
-
|
|
6556
|
-
|
|
6557
|
-
|
|
6558
|
-
|
|
6559
|
-
|
|
6560
|
-
|
|
6561
|
-
|
|
6562
|
-
|
|
6563
|
-
|
|
6564
|
-
|
|
6565
|
-
|
|
6566
|
-
for (const
|
|
6567
|
-
|
|
6568
|
-
|
|
6569
|
-
|
|
6570
|
-
|
|
6571
|
-
|
|
6572
|
-
|
|
6573
|
-
type: BLOCK_DRAG_TYPE,
|
|
6574
|
-
targetAnchorId: this.anchorIdOf(unit),
|
|
6575
|
-
position: this.dropPositionFor(unit, input.clientY),
|
|
6576
|
-
targetElement: unit
|
|
6577
|
-
}),
|
|
6578
|
-
onDragEnter: ({ self }) => {
|
|
6579
|
-
const pos = self.data.position === "after" ? "after" : "before";
|
|
6580
|
-
this.showDropIndicator(unit, pos);
|
|
6581
|
-
},
|
|
6582
|
-
onDrag: ({ self }) => {
|
|
6583
|
-
const pos = self.data.position === "after" ? "after" : "before";
|
|
6584
|
-
this.showDropIndicator(unit, pos);
|
|
6585
|
-
},
|
|
6586
|
-
onDragLeave: () => this.hideDropIndicator()
|
|
6587
|
-
}));
|
|
6948
|
+
* Where a drop at `clientY` lands, or null when nothing there is legal.
|
|
6949
|
+
*
|
|
6950
|
+
* Resolution is by VERTICAL GEOMETRY over the measured blocks, not by which element the pointer
|
|
6951
|
+
* is over: the drag handle floats in the page margin, so a drag straight down the gutter — the
|
|
6952
|
+
* natural gesture — never crosses a paragraph box, and element hit testing gave those drags no
|
|
6953
|
+
* indicator and no drop at all. The nearest block by vertical distance is the target; the half
|
|
6954
|
+
* the pointer is in picks the side, snapped to the other side when only that one is legal
|
|
6955
|
+
* (a section break or a cross-block range usually makes exactly one side illegal). When neither
|
|
6956
|
+
* side is legal — the pointer is in a region this block cannot reach — there is no drop, and
|
|
6957
|
+
* nothing is drawn.
|
|
6958
|
+
*/
|
|
6959
|
+
resolveDropAt(clientY) {
|
|
6960
|
+
const y = clientY - this.dropZoneShift();
|
|
6961
|
+
let best = null;
|
|
6962
|
+
let bestGap = Infinity;
|
|
6963
|
+
for (const zone of this.dropZones) {
|
|
6964
|
+
const gap = y < zone.top ? zone.top - y : y > zone.bottom ? y - zone.bottom : 0;
|
|
6965
|
+
if (gap < bestGap) {
|
|
6966
|
+
best = zone;
|
|
6967
|
+
bestGap = gap;
|
|
6968
|
+
}
|
|
6969
|
+
if (gap === 0) break;
|
|
6588
6970
|
}
|
|
6971
|
+
if (!best || best.unit === this.blockDragSource) return null;
|
|
6972
|
+
const preferred = y < (best.top + best.bottom) / 2 ? "before" : "after";
|
|
6973
|
+
if (this.isValidMoveTarget(best.unit, preferred)) return { zone: best, position: preferred };
|
|
6974
|
+
const other = preferred === "before" ? "after" : "before";
|
|
6975
|
+
return this.isValidMoveTarget(best.unit, other) ? { zone: best, position: other } : null;
|
|
6589
6976
|
}
|
|
6590
6977
|
closeBlockMoveMenu(restoreFocus = false) {
|
|
6591
6978
|
if (!this.blockMoveMenu || !this.blockDragHandle) return;
|
|
@@ -6760,20 +7147,50 @@ var DocxEditor = class _DocxEditor {
|
|
|
6760
7147
|
const source = this.currentBlockDragSource();
|
|
6761
7148
|
return { type: BLOCK_DRAG_TYPE, sourceAnchorId: source ? this.anchorIdOf(source) : void 0 };
|
|
6762
7149
|
},
|
|
7150
|
+
// The browser would otherwise ghost the 26px grip, which says nothing about what is moving.
|
|
7151
|
+
onGenerateDragPreview: ({ nativeSetDragImage }) => {
|
|
7152
|
+
const source = this.currentBlockDragSource();
|
|
7153
|
+
setCustomNativeDragPreview({
|
|
7154
|
+
nativeSetDragImage,
|
|
7155
|
+
getOffset: pointerOutsideOfPreview({ x: "14px", y: "10px" }),
|
|
7156
|
+
render: ({ container }) => {
|
|
7157
|
+
const chip = doc.createElement("div");
|
|
7158
|
+
chip.className = "docx-block-drag-preview";
|
|
7159
|
+
chip.textContent = source && blockPreviewText(source) || "Move block";
|
|
7160
|
+
container.appendChild(chip);
|
|
7161
|
+
return () => chip.remove();
|
|
7162
|
+
}
|
|
7163
|
+
});
|
|
7164
|
+
},
|
|
6763
7165
|
onDragStart: () => {
|
|
7166
|
+
const source = this.currentBlockDragSource();
|
|
6764
7167
|
this.blockDragging = true;
|
|
6765
7168
|
handle.classList.add("docx-block-dragging");
|
|
7169
|
+
source?.classList.add("docx-block-drag-source");
|
|
6766
7170
|
this.closeBlockMoveMenu();
|
|
6767
|
-
this.refreshBlockMoveTargets(
|
|
6768
|
-
this.
|
|
7171
|
+
this.refreshBlockMoveTargets(source);
|
|
7172
|
+
this.captureDropZones();
|
|
6769
7173
|
},
|
|
6770
7174
|
onDrop: () => {
|
|
6771
7175
|
this.blockDragging = false;
|
|
6772
7176
|
this.blockDragPointerDown = false;
|
|
7177
|
+
this.dropZones = [];
|
|
6773
7178
|
handle.classList.remove("docx-block-dragging");
|
|
7179
|
+
doc.querySelectorAll(".docx-block-drag-source").forEach((el) => el.classList.remove("docx-block-drag-source"));
|
|
6774
7180
|
this.hideDropIndicator();
|
|
6775
7181
|
}
|
|
6776
7182
|
}));
|
|
7183
|
+
this.blockDragCleanup.push(dropTargetForElements({
|
|
7184
|
+
element: this.editRoot,
|
|
7185
|
+
canDrop: ({ source }) => source.data.type === BLOCK_DRAG_TYPE,
|
|
7186
|
+
getData: ({ input }) => {
|
|
7187
|
+
const hit = this.resolveDropAt(input.clientY);
|
|
7188
|
+
return hit ? { type: BLOCK_DRAG_TYPE, targetAnchorId: hit.zone.anchorId, position: hit.position, zone: hit.zone } : { type: BLOCK_DRAG_TYPE };
|
|
7189
|
+
},
|
|
7190
|
+
onDragEnter: ({ self }) => this.paintDropIndicator(self.data),
|
|
7191
|
+
onDrag: ({ self }) => this.paintDropIndicator(self.data),
|
|
7192
|
+
onDragLeave: () => this.hideDropIndicator()
|
|
7193
|
+
}));
|
|
6777
7194
|
this.blockDragCleanup.push(monitorForElements({
|
|
6778
7195
|
canMonitor: ({ source }) => source.data.type === BLOCK_DRAG_TYPE,
|
|
6779
7196
|
onDrop: ({ source, location: location2 }) => {
|
|
@@ -6800,13 +7217,13 @@ var DocxEditor = class _DocxEditor {
|
|
|
6800
7217
|
canScroll: ({ source }) => source.data.type === BLOCK_DRAG_TYPE,
|
|
6801
7218
|
getAllowedAxis: () => "vertical"
|
|
6802
7219
|
}));
|
|
6803
|
-
this.refreshBlockDropTargets();
|
|
6804
7220
|
}
|
|
6805
7221
|
teardownBlockDrag() {
|
|
6806
7222
|
this.blockMoveTargetPrefetch?.();
|
|
6807
7223
|
this.blockMoveTargetPrefetch = null;
|
|
6808
7224
|
this.blockMoveTargetCache.clear();
|
|
6809
|
-
|
|
7225
|
+
this.dropZones = [];
|
|
7226
|
+
this.dropZoneScroller = null;
|
|
6810
7227
|
for (const cleanup of this.blockDragCleanup.splice(0)) cleanup();
|
|
6811
7228
|
this.blockDragHandle?.remove();
|
|
6812
7229
|
this.blockDropIndicator?.remove();
|
|
@@ -6895,17 +7312,17 @@ var DocxEditor = class _DocxEditor {
|
|
|
6895
7312
|
bodyRoot.after(this.region.footerBand);
|
|
6896
7313
|
this.region.refreshAll();
|
|
6897
7314
|
}
|
|
6898
|
-
/**
|
|
7315
|
+
/**
|
|
7316
|
+
* Continuous (non-paginated) mount: inject the converter's styles + body, wire blocks.
|
|
7317
|
+
*
|
|
7318
|
+
* The body always gets its own `.docx-body-flow` wrapper — not only when bands are docked.
|
|
7319
|
+
* It is the sheet: the element the viewport gives page geometry to and zooms, and the one
|
|
7320
|
+
* the bands dock around. Without it the container would have to be both the scrolling host
|
|
7321
|
+
* and the scaled page, which are different boxes.
|
|
7322
|
+
*/
|
|
6899
7323
|
mountHtml(fullHtml) {
|
|
6900
7324
|
const parsed = new DOMParser().parseFromString(fullHtml, "text/html");
|
|
6901
7325
|
const styles = Array.from(parsed.querySelectorAll("style")).map((s) => s.outerHTML).join("");
|
|
6902
|
-
if (!this.region) {
|
|
6903
|
-
this.container.innerHTML = styles + parsed.body.innerHTML;
|
|
6904
|
-
this.editRoot = this.container;
|
|
6905
|
-
if (this.options.editable) this.wireBlocks(this.container);
|
|
6906
|
-
this.stampPlanState();
|
|
6907
|
-
return;
|
|
6908
|
-
}
|
|
6909
7326
|
this.container.innerHTML = styles;
|
|
6910
7327
|
const flow = document.createElement("div");
|
|
6911
7328
|
flow.className = "docx-body-flow";
|
|
@@ -6914,7 +7331,8 @@ var DocxEditor = class _DocxEditor {
|
|
|
6914
7331
|
this.editRoot = flow;
|
|
6915
7332
|
if (this.options.editable) this.wireBlocks(flow);
|
|
6916
7333
|
this.stampPlanState();
|
|
6917
|
-
this.dockBands(flow);
|
|
7334
|
+
if (this.region) this.dockBands(flow);
|
|
7335
|
+
this.viewport.attach(flow, true);
|
|
6918
7336
|
}
|
|
6919
7337
|
/** Paginated mount: flow blocks into page boxes via pagination.ts, wire the page clones. */
|
|
6920
7338
|
mountPaginated(fullHtml) {
|
|
@@ -6935,6 +7353,7 @@ var DocxEditor = class _DocxEditor {
|
|
|
6935
7353
|
this.editRoot = pageRoot;
|
|
6936
7354
|
if (this.options.editable) this.wireBlocks(pageRoot);
|
|
6937
7355
|
if (this.region) this.dockBands(target);
|
|
7356
|
+
this.viewport.attach(pageRoot, false);
|
|
6938
7357
|
}
|
|
6939
7358
|
wireBlocks(root) {
|
|
6940
7359
|
root.querySelectorAll("[data-anchor]").forEach((el) => this.wireBlock(el));
|
|
@@ -8743,14 +9162,7 @@ var RIBBON_CSS = `
|
|
|
8743
9162
|
SHOULD win.
|
|
8744
9163
|
(No backticks in this file's comments: the stylesheet is a template literal.) */
|
|
8745
9164
|
.dxr-scroll { flex: 1 1 auto; min-height: 0; overflow: auto; -webkit-overflow-scrolling: touch; }
|
|
8746
|
-
.dxr[data-chrome] .dxr-surface {
|
|
8747
|
-
.dxr-surface[data-view="continuous"] > * { background: var(--dxr-sheet); }
|
|
8748
|
-
.dxr[data-chrome] .dxr-surface[data-view="continuous"] {
|
|
8749
|
-
padding: 56px 72px;
|
|
8750
|
-
border-radius: 3px;
|
|
8751
|
-
background: var(--dxr-sheet);
|
|
8752
|
-
box-shadow: 0 1px 3px rgba(16, 20, 24, .14), 0 8px 24px rgba(16, 20, 24, .05);
|
|
8753
|
-
}
|
|
9165
|
+
.dxr[data-chrome] .dxr-surface { margin: 26px auto; padding: 0 16px 96px; }
|
|
8754
9166
|
.dxr-surface [contenteditable="true"]:focus {
|
|
8755
9167
|
outline: 2px solid var(--dxr-accent);
|
|
8756
9168
|
outline-offset: 2px;
|
|
@@ -8762,7 +9174,10 @@ var RIBBON_CSS = `
|
|
|
8762
9174
|
so they dock as their own regions. Styled from the same tokens as the ribbon
|
|
8763
9175
|
so the surface reads as one instrument rather than two apps. */
|
|
8764
9176
|
.dxr-surface .docx-hf-band {
|
|
8765
|
-
|
|
9177
|
+
/* Docked outside the zoomed sheet, so it takes the page's on-screen width from the
|
|
9178
|
+
custom property the viewport publishes rather than stretching to the whole surface. */
|
|
9179
|
+
width: min(100%, var(--docx-sheet-width, 100%));
|
|
9180
|
+
margin: 0 auto 14px;
|
|
8766
9181
|
padding: 9px 72px 13px;
|
|
8767
9182
|
border: 1px solid var(--dxr-rule);
|
|
8768
9183
|
border-left: 2px solid #c2ccd9;
|
|
@@ -8770,7 +9185,7 @@ var RIBBON_CSS = `
|
|
|
8770
9185
|
background: var(--dxr-sheet);
|
|
8771
9186
|
}
|
|
8772
9187
|
.dxr-surface .docx-hf-band + .docx-body-flow { margin-top: 0; }
|
|
8773
|
-
.dxr-surface .docx-hf-band[data-hf-band="footer"] { margin: 14px
|
|
9188
|
+
.dxr-surface .docx-hf-band[data-hf-band="footer"] { margin: 14px auto 0; }
|
|
8774
9189
|
.dxr-surface .docx-hf-chrome {
|
|
8775
9190
|
display: flex;
|
|
8776
9191
|
gap: 8px;
|
|
@@ -8825,13 +9240,15 @@ var RIBBON_CSS = `
|
|
|
8825
9240
|
text-transform: none;
|
|
8826
9241
|
}
|
|
8827
9242
|
.dxr-surface .docx-hf-band[data-hf-inherited] { border-style: dashed; }
|
|
8828
|
-
.
|
|
8829
|
-
|
|
8830
|
-
|
|
8831
|
-
|
|
8832
|
-
|
|
9243
|
+
/* The sheet IS the page. The editor's viewport sizes .docx-body-flow to the section's page
|
|
9244
|
+
width and its section wrappers to the authored text column, so the horizontal gutters here
|
|
9245
|
+
are the document's own w:sectPr margins, not a padding this chrome invents; only the
|
|
9246
|
+
vertical breathing room is ours. Centering is left to margin:auto so a page the viewport
|
|
9247
|
+
has zoomed to fit stays centered at its scaled width. */
|
|
8833
9248
|
.dxr[data-chrome] .dxr-surface[data-view="continuous"] .docx-body-flow {
|
|
8834
|
-
|
|
9249
|
+
max-width: 100%;
|
|
9250
|
+
margin: 0 auto;
|
|
9251
|
+
padding: 56px 0;
|
|
8835
9252
|
border-radius: 3px;
|
|
8836
9253
|
background: var(--dxr-sheet);
|
|
8837
9254
|
box-shadow: 0 1px 3px rgba(16, 20, 24, .14), 0 8px 24px rgba(16, 20, 24, .05);
|
|
@@ -8910,9 +9327,11 @@ var RIBBON_CSS = `
|
|
|
8910
9327
|
.dxr[data-chrome="compact"] .dxr-note { display: none; }
|
|
8911
9328
|
.dxr[data-chrome="compact"] .dxr-rail { display: none; }
|
|
8912
9329
|
.dxr[data-chrome="compact"] .dxr-hint { display: none; }
|
|
9330
|
+
/* Compact trims the chrome around the page, never the page: the document's own column width
|
|
9331
|
+
is what the viewport's fit-to-width zoom scales, so a phone shows a whole smaller page
|
|
9332
|
+
instead of a narrower one that breaks its lines somewhere Word never would. */
|
|
8913
9333
|
.dxr[data-chrome="compact"] .dxr-surface { margin: 12px auto; padding: 0 10px 64px; }
|
|
8914
|
-
.dxr[data-chrome="compact"] .dxr-surface[data-view="continuous"] { padding: 22px
|
|
8915
|
-
.dxr[data-chrome="compact"] .dxr-surface[data-view="continuous"] .docx-body-flow { padding: 22px 18px; }
|
|
9334
|
+
.dxr[data-chrome="compact"] .dxr-surface[data-view="continuous"] .docx-body-flow { padding: 22px 0; }
|
|
8916
9335
|
.dxr[data-chrome="compact"] .dxr-surface .docx-hf-band { padding: 9px 18px 13px; }
|
|
8917
9336
|
.dxr[data-chrome="compact"] .dxr-surface .docx-hf-chrome,
|
|
8918
9337
|
.dxr[data-chrome="compact"] .dxr-surface .docx-hf-warning { margin-left: 0; }
|
|
@@ -9662,6 +10081,8 @@ var RibbonSurface = class {
|
|
|
9662
10081
|
fabricateClasses: this.options.fabricateClasses,
|
|
9663
10082
|
editable: this.options.editable,
|
|
9664
10083
|
scale: this.options.scale,
|
|
10084
|
+
columnWidth: this.options.columnWidth,
|
|
10085
|
+
fitToWidth: this.options.fitToWidth,
|
|
9665
10086
|
onEdit: this.options.onEdit,
|
|
9666
10087
|
onMove: this.options.onMove,
|
|
9667
10088
|
paginated,
|
|
@@ -11633,8 +12054,12 @@ export {
|
|
|
11633
12054
|
ComparisonLogLevel,
|
|
11634
12055
|
ConflictResolution,
|
|
11635
12056
|
ContextBoundary,
|
|
12057
|
+
DEFAULT_MARGIN,
|
|
12058
|
+
DEFAULT_PAGE_HEIGHT,
|
|
12059
|
+
DEFAULT_PAGE_WIDTH,
|
|
11636
12060
|
DiffFormat,
|
|
11637
12061
|
DocumentElementType,
|
|
12062
|
+
DocumentViewport,
|
|
11638
12063
|
DocxDiffFormatComparison,
|
|
11639
12064
|
DocxDiffRevisionGranularity,
|
|
11640
12065
|
DocxEditor,
|
|
@@ -11680,6 +12105,7 @@ export {
|
|
|
11680
12105
|
findElementsByType,
|
|
11681
12106
|
findMovePair,
|
|
11682
12107
|
findTextOccurrences,
|
|
12108
|
+
fitScale,
|
|
11683
12109
|
generateAnnotationCss,
|
|
11684
12110
|
generateAnnotationVisibilityCss,
|
|
11685
12111
|
getAnnotations,
|
|
@@ -11703,7 +12129,10 @@ export {
|
|
|
11703
12129
|
mountRibbon,
|
|
11704
12130
|
openDocxSession2 as openDocxSession,
|
|
11705
12131
|
paginateHtml,
|
|
12132
|
+
parseSectionDimensions,
|
|
11706
12133
|
projectAnnotationsOntoHtml,
|
|
12134
|
+
ptToPx,
|
|
12135
|
+
pxToPt,
|
|
11707
12136
|
removeAnnotation,
|
|
11708
12137
|
removeAnnotationFromHtml,
|
|
11709
12138
|
renderBlockHtml,
|