@harbour-enterprises/superdoc 1.0.0-beta.60 → 1.0.0-beta.62

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.
Files changed (30) hide show
  1. package/dist/chunks/{PdfViewer-4-HewDUK.cjs → PdfViewer-Dm3bZ_1B.cjs} +1 -1
  2. package/dist/chunks/{PdfViewer-C4HeazGQ.es.js → PdfViewer-rmkhzY1H.es.js} +1 -1
  3. package/dist/chunks/{index-BKfoD32c.es.js → index-5vPj3xiM.es.js} +13 -6
  4. package/dist/chunks/{index-9qSCXVF1.cjs → index-VQNmJYMh.cjs} +13 -6
  5. package/dist/chunks/{index-GAzIoyrZ-C17wg4bM.cjs → index-XOsGE2PW-BL-ekicF.cjs} +1 -1
  6. package/dist/chunks/{index-GAzIoyrZ-zhiF5zMK.es.js → index-XOsGE2PW-hNAnvmsK.es.js} +1 -1
  7. package/dist/chunks/{super-editor.es-CJ3Aw1GR.es.js → super-editor.es-BIEE4joF.es.js} +756 -144
  8. package/dist/chunks/{super-editor.es-DCHFBNql.cjs → super-editor.es-CxtR72x8.cjs} +756 -144
  9. package/dist/packages/superdoc/src/core/SuperDoc.d.ts.map +1 -1
  10. package/dist/style.css +44 -56
  11. package/dist/super-editor/ai-writer.es.js +2 -2
  12. package/dist/super-editor/chunks/{converter-DZ7Tkh7u.js → converter-Bo9KIIo_.js} +165 -47
  13. package/dist/super-editor/chunks/{docx-zipper-CZQWEuyi.js → docx-zipper-Cw0Rbwvk.js} +1 -1
  14. package/dist/super-editor/chunks/{editor-CDMuD1Nx.js → editor-v-i8Oo_X.js} +531 -36
  15. package/dist/super-editor/chunks/{index-GAzIoyrZ.js → index-XOsGE2PW.js} +1 -1
  16. package/dist/super-editor/chunks/{toolbar-DL3rTlKm.js → toolbar-CiKH0Ttu.js} +2 -2
  17. package/dist/super-editor/converter.es.js +1 -1
  18. package/dist/super-editor/docx-zipper.es.js +2 -2
  19. package/dist/super-editor/editor.es.js +3 -3
  20. package/dist/super-editor/file-zipper.es.js +1 -1
  21. package/dist/super-editor/style.css +17 -29
  22. package/dist/super-editor/super-editor.es.js +96 -94
  23. package/dist/super-editor/toolbar.es.js +2 -2
  24. package/dist/super-editor.cjs +1 -1
  25. package/dist/super-editor.es.js +1 -1
  26. package/dist/superdoc.cjs +2 -2
  27. package/dist/superdoc.es.js +2 -2
  28. package/dist/superdoc.umd.js +768 -149
  29. package/dist/superdoc.umd.js.map +1 -1
  30. package/package.json +1 -1
@@ -42131,11 +42131,71 @@ const _SuperConverter = class _SuperConverter2 {
42131
42131
  return JSON.parse(xmljs.xml2json(newXml, null, 2));
42132
42132
  }
42133
42133
  /**
42134
- * Generic method to get a stored custom property from docx
42134
+ * Checks if an element name matches the expected local name, with or without namespace prefix.
42135
+ * This helper supports custom namespace prefixes in DOCX files (e.g., 'op:Properties', 'custom:property').
42136
+ *
42137
+ * @private
42138
+ * @static
42139
+ * @param {string|undefined|null} elementName - The element name to check (may include namespace prefix)
42140
+ * @param {string} expectedLocalName - The expected local name without prefix
42141
+ * @returns {boolean} True if the element name matches (with or without prefix)
42142
+ *
42143
+ * @example
42144
+ * // Exact match without prefix
42145
+ * _matchesElementName('Properties', 'Properties') // => true
42146
+ *
42147
+ * @example
42148
+ * // Match with namespace prefix
42149
+ * _matchesElementName('op:Properties', 'Properties') // => true
42150
+ * _matchesElementName('custom:property', 'property') // => true
42151
+ *
42152
+ * @example
42153
+ * // No match
42154
+ * _matchesElementName('SomeOtherElement', 'Properties') // => false
42155
+ * _matchesElementName(':Properties', 'Properties') // => false (empty prefix)
42156
+ */
42157
+ static _matchesElementName(elementName, expectedLocalName) {
42158
+ if (!elementName || typeof elementName !== "string") return false;
42159
+ if (!expectedLocalName) return false;
42160
+ if (elementName === expectedLocalName) return true;
42161
+ if (elementName.endsWith(`:${expectedLocalName}`)) {
42162
+ const prefix2 = elementName.slice(0, -(expectedLocalName.length + 1));
42163
+ return prefix2.length > 0;
42164
+ }
42165
+ return false;
42166
+ }
42167
+ /**
42168
+ * Generic method to get a stored custom property from docx.
42169
+ * Supports both standard and custom namespace prefixes (e.g., 'op:Properties', 'custom:property').
42170
+ *
42135
42171
  * @static
42136
42172
  * @param {Array} docx - Array of docx file objects
42137
42173
  * @param {string} propertyName - Name of the property to retrieve
42138
42174
  * @returns {string|null} The property value or null if not found
42175
+ *
42176
+ * Returns null in the following cases:
42177
+ * - docx array is empty or doesn't contain 'docProps/custom.xml'
42178
+ * - custom.xml cannot be parsed
42179
+ * - Properties element is not found (with or without namespace prefix)
42180
+ * - Property with the specified name is not found
42181
+ * - Property has malformed structure (missing nested elements or text)
42182
+ * - Any error occurs during parsing or retrieval
42183
+ *
42184
+ * @example
42185
+ * // Standard property without namespace prefix
42186
+ * const version = SuperConverter.getStoredCustomProperty(docx, 'SuperdocVersion');
42187
+ * // => '1.2.3'
42188
+ *
42189
+ * @example
42190
+ * // Property with namespace prefix (e.g., from Office 365)
42191
+ * const guid = SuperConverter.getStoredCustomProperty(docx, 'DocumentGuid');
42192
+ * // Works with both 'Properties' and 'op:Properties' elements
42193
+ * // => 'abc-123-def-456'
42194
+ *
42195
+ * @example
42196
+ * // Non-existent property
42197
+ * const missing = SuperConverter.getStoredCustomProperty(docx, 'NonExistent');
42198
+ * // => null
42139
42199
  */
42140
42200
  static getStoredCustomProperty(docx, propertyName) {
42141
42201
  try {
@@ -42144,10 +42204,16 @@ const _SuperConverter = class _SuperConverter2 {
42144
42204
  const converter = new _SuperConverter2();
42145
42205
  const content = customXml.content;
42146
42206
  const contentJson = converter.parseXmlToJson(content);
42147
- const properties = contentJson.elements.find((el) => el.name === "Properties");
42148
- if (!properties.elements) return null;
42149
- const property2 = properties.elements.find((el) => el.name === "property" && el.attributes.name === propertyName);
42207
+ const properties = contentJson?.elements?.find((el) => _SuperConverter2._matchesElementName(el.name, "Properties"));
42208
+ if (!properties?.elements) return null;
42209
+ const property2 = properties.elements.find(
42210
+ (el) => _SuperConverter2._matchesElementName(el.name, "property") && el.attributes?.name === propertyName
42211
+ );
42150
42212
  if (!property2) return null;
42213
+ if (!property2.elements?.[0]?.elements?.[0]?.text) {
42214
+ console.warn(`Malformed property structure for "${propertyName}"`);
42215
+ return null;
42216
+ }
42151
42217
  return property2.elements[0].elements[0].text;
42152
42218
  } catch (e) {
42153
42219
  console.warn(`Error getting custom property ${propertyName}:`, e);
@@ -42155,60 +42221,112 @@ const _SuperConverter = class _SuperConverter2 {
42155
42221
  }
42156
42222
  }
42157
42223
  /**
42158
- * Generic method to set a stored custom property in docx
42224
+ * Generic method to set a stored custom property in docx.
42225
+ * Supports both standard and custom namespace prefixes (e.g., 'op:Properties', 'custom:property').
42226
+ *
42159
42227
  * @static
42160
- * @param {Object} docx - The docx object to store the property in
42228
+ * @param {Object} docx - The docx object to store the property in (converted XML structure)
42161
42229
  * @param {string} propertyName - Name of the property
42162
42230
  * @param {string|Function} value - Value or function that returns the value
42163
42231
  * @param {boolean} preserveExisting - If true, won't overwrite existing values
42164
- * @returns {string} The stored value
42232
+ * @returns {string|null} The stored value, or null if Properties element is not found
42233
+ *
42234
+ * @throws {Error} If an error occurs during property setting (logged as warning)
42235
+ *
42236
+ * @example
42237
+ * // Set a new property
42238
+ * const value = SuperConverter.setStoredCustomProperty(docx, 'MyProperty', 'MyValue');
42239
+ * // => 'MyValue'
42240
+ *
42241
+ * @example
42242
+ * // Set a property with a function
42243
+ * const guid = SuperConverter.setStoredCustomProperty(docx, 'DocumentGuid', () => uuidv4());
42244
+ * // => 'abc-123-def-456'
42245
+ *
42246
+ * @example
42247
+ * // Preserve existing value
42248
+ * SuperConverter.setStoredCustomProperty(docx, 'MyProperty', 'NewValue', true);
42249
+ * // => 'MyValue' (original value preserved)
42250
+ *
42251
+ * @example
42252
+ * // Works with namespace prefixes
42253
+ * // If docx has 'op:Properties' and 'op:property' elements, this will handle them correctly
42254
+ * const version = SuperConverter.setStoredCustomProperty(docx, 'Version', '2.0.0');
42255
+ * // => '2.0.0'
42165
42256
  */
42166
42257
  static setStoredCustomProperty(docx, propertyName, value, preserveExisting = false) {
42167
- const customLocation = "docProps/custom.xml";
42168
- if (!docx[customLocation]) docx[customLocation] = generateCustomXml();
42169
- const customXml = docx[customLocation];
42170
- const properties = customXml.elements?.find((el) => el.name === "Properties");
42171
- if (!properties) return null;
42172
- if (!properties.elements) properties.elements = [];
42173
- let property2 = properties.elements.find((el) => el.name === "property" && el.attributes.name === propertyName);
42174
- if (property2 && preserveExisting) {
42175
- return property2.elements[0].elements[0].text;
42176
- }
42177
- const finalValue = typeof value === "function" ? value() : value;
42178
- if (!property2) {
42179
- const existingPids = properties.elements.filter((el) => el.attributes?.pid).map((el) => parseInt(el.attributes.pid, 10)).filter(Number.isInteger);
42180
- const pid = existingPids.length > 0 ? Math.max(...existingPids) + 1 : 2;
42181
- property2 = {
42182
- type: "element",
42183
- name: "property",
42184
- attributes: {
42185
- name: propertyName,
42186
- fmtid: "{D5CDD505-2E9C-101B-9397-08002B2CF9AE}",
42187
- pid
42188
- },
42189
- elements: [
42190
- {
42191
- type: "element",
42192
- name: "vt:lpwstr",
42193
- elements: [
42194
- {
42195
- type: "text",
42196
- text: finalValue
42197
- }
42198
- ]
42199
- }
42200
- ]
42201
- };
42202
- properties.elements.push(property2);
42203
- } else {
42204
- property2.elements[0].elements[0].text = finalValue;
42258
+ try {
42259
+ const customLocation = "docProps/custom.xml";
42260
+ if (!docx[customLocation]) docx[customLocation] = generateCustomXml();
42261
+ const customXml = docx[customLocation];
42262
+ const properties = customXml.elements?.find((el) => _SuperConverter2._matchesElementName(el.name, "Properties"));
42263
+ if (!properties) return null;
42264
+ if (!properties.elements) properties.elements = [];
42265
+ let property2 = properties.elements.find(
42266
+ (el) => _SuperConverter2._matchesElementName(el.name, "property") && el.attributes?.name === propertyName
42267
+ );
42268
+ if (property2 && preserveExisting) {
42269
+ if (!property2.elements?.[0]?.elements?.[0]?.text) {
42270
+ console.warn(`Malformed existing property structure for "${propertyName}"`);
42271
+ return null;
42272
+ }
42273
+ return property2.elements[0].elements[0].text;
42274
+ }
42275
+ const finalValue = typeof value === "function" ? value() : value;
42276
+ if (!property2) {
42277
+ const existingPids = properties.elements.filter((el) => el.attributes?.pid).map((el) => parseInt(el.attributes.pid, 10)).filter(Number.isInteger);
42278
+ const pid = existingPids.length > 0 ? Math.max(...existingPids) + 1 : 2;
42279
+ property2 = {
42280
+ type: "element",
42281
+ name: "property",
42282
+ attributes: {
42283
+ name: propertyName,
42284
+ fmtid: "{D5CDD505-2E9C-101B-9397-08002B2CF9AE}",
42285
+ pid
42286
+ },
42287
+ elements: [
42288
+ {
42289
+ type: "element",
42290
+ name: "vt:lpwstr",
42291
+ elements: [
42292
+ {
42293
+ type: "text",
42294
+ text: finalValue
42295
+ }
42296
+ ]
42297
+ }
42298
+ ]
42299
+ };
42300
+ properties.elements.push(property2);
42301
+ } else {
42302
+ if (!property2.elements?.[0]?.elements?.[0]) {
42303
+ console.warn(`Malformed property structure for "${propertyName}", recreating structure`);
42304
+ property2.elements = [
42305
+ {
42306
+ type: "element",
42307
+ name: "vt:lpwstr",
42308
+ elements: [
42309
+ {
42310
+ type: "text",
42311
+ text: finalValue
42312
+ }
42313
+ ]
42314
+ }
42315
+ ];
42316
+ } else {
42317
+ property2.elements[0].elements[0].text = finalValue;
42318
+ }
42319
+ }
42320
+ return finalValue;
42321
+ } catch (e) {
42322
+ console.warn(`Error setting custom property ${propertyName}:`, e);
42323
+ return null;
42205
42324
  }
42206
- return finalValue;
42207
42325
  }
42208
42326
  static getStoredSuperdocVersion(docx) {
42209
42327
  return _SuperConverter2.getStoredCustomProperty(docx, "SuperdocVersion");
42210
42328
  }
42211
- static setStoredSuperdocVersion(docx = this.convertedXml, version2 = "1.0.0-beta.60") {
42329
+ static setStoredSuperdocVersion(docx = this.convertedXml, version2 = "1.0.0-beta.62") {
42212
42330
  return _SuperConverter2.setStoredCustomProperty(docx, "SuperdocVersion", version2, false);
42213
42331
  }
42214
42332
  /**
@@ -59397,7 +59515,7 @@ const isHeadless = (editor) => {
59397
59515
  const shouldSkipNodeView = (editor) => {
59398
59516
  return isHeadless(editor);
59399
59517
  };
59400
- const summaryVersion = "1.0.0-beta.60";
59518
+ const summaryVersion = "1.0.0-beta.62";
59401
59519
  const nodeKeys = ["group", "content", "marks", "inline", "atom", "defining", "code", "tableRole", "summary"];
59402
59520
  const markKeys = ["group", "inclusive", "excludes", "spanning", "code"];
59403
59521
  function mapAttributes(attrs) {
@@ -60186,7 +60304,7 @@ const _Editor = class _Editor2 extends EventEmitter$1 {
60186
60304
  { default: remarkStringify },
60187
60305
  { default: remarkGfm }
60188
60306
  ] = await Promise.all([
60189
- Promise.resolve().then(() => require("./index-GAzIoyrZ-C17wg4bM.cjs")),
60307
+ Promise.resolve().then(() => require("./index-XOsGE2PW-BL-ekicF.cjs")),
60190
60308
  Promise.resolve().then(() => require("./index-DRCvimau-H4Ck3S9a.cjs")),
60191
60309
  Promise.resolve().then(() => require("./index-C_x_N6Uh-Db3CUJMX.cjs")),
60192
60310
  Promise.resolve().then(() => require("./index-D_sWOSiG-BtDZzJ6I.cjs")),
@@ -60391,7 +60509,7 @@ const _Editor = class _Editor2 extends EventEmitter$1 {
60391
60509
  * Process collaboration migrations
60392
60510
  */
60393
60511
  processCollaborationMigrations() {
60394
- console.debug("[checkVersionMigrations] Current editor version", "1.0.0-beta.60");
60512
+ console.debug("[checkVersionMigrations] Current editor version", "1.0.0-beta.62");
60395
60513
  if (!this.options.ydoc) return;
60396
60514
  const metaMap = this.options.ydoc.getMap("meta");
60397
60515
  let docVersion = metaMap.get("version");
@@ -64364,12 +64482,6 @@ const Engines = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePrope
64364
64482
  resolveSpacingIndent: resolveSpacingIndent$1,
64365
64483
  scaleWrapPolygon
64366
64484
  }, Symbol.toStringTag, { value: "Module" }));
64367
- const extractHeaderFooterSpace = (margins) => {
64368
- return {
64369
- headerSpace: margins?.header ?? 0,
64370
- footerSpace: margins?.footer ?? 0
64371
- };
64372
- };
64373
64485
  const hasParagraphStyleContext = (context) => {
64374
64486
  return Boolean(context?.docx);
64375
64487
  };
@@ -71557,6 +71669,408 @@ function assertFragmentPmPositions(fragment, _context) {
71557
71669
  const hasPmEnd = fragment.pmEnd != null;
71558
71670
  globalValidationStats.record(hasPmStart, hasPmEnd);
71559
71671
  }
71672
+ const DEFAULT_PPI = 96;
71673
+ const DEFAULT_RULER_HEIGHT = 25;
71674
+ const TICK_SPACING_PX = DEFAULT_PPI / 8;
71675
+ function generateRulerDefinition(config2) {
71676
+ const ppi = config2.ppi ?? DEFAULT_PPI;
71677
+ const heightPx = config2.heightPx ?? DEFAULT_RULER_HEIGHT;
71678
+ const { pageSize, pageMargins } = config2;
71679
+ if (!Number.isFinite(ppi) || ppi <= 0) {
71680
+ throw new Error(`Invalid PPI: ${ppi}. Must be a positive finite number.`);
71681
+ }
71682
+ if (!Number.isFinite(pageSize.width) || pageSize.width <= 0) {
71683
+ throw new Error(`Invalid page width: ${pageSize.width}. Must be a positive finite number.`);
71684
+ }
71685
+ if (!Number.isFinite(pageSize.height) || pageSize.height <= 0) {
71686
+ throw new Error(`Invalid page height: ${pageSize.height}. Must be a positive finite number.`);
71687
+ }
71688
+ if (!Number.isFinite(pageMargins.left) || pageMargins.left < 0) {
71689
+ throw new Error(`Invalid left margin: ${pageMargins.left}. Must be a non-negative finite number.`);
71690
+ }
71691
+ if (!Number.isFinite(pageMargins.right) || pageMargins.right < 0) {
71692
+ throw new Error(`Invalid right margin: ${pageMargins.right}. Must be a non-negative finite number.`);
71693
+ }
71694
+ if (pageMargins.left + pageMargins.right >= pageSize.width) {
71695
+ throw new Error(
71696
+ `Invalid margins: left (${pageMargins.left}) + right (${pageMargins.right}) must be less than page width (${pageSize.width}).`
71697
+ );
71698
+ }
71699
+ const widthPx = pageSize.width * ppi;
71700
+ const ticks = [];
71701
+ let currentX = 0;
71702
+ for (let inch = 0; inch < pageSize.width; inch++) {
71703
+ const remaining = pageSize.width - inch;
71704
+ ticks.push({
71705
+ size: "main",
71706
+ height: "20%",
71707
+ label: inch,
71708
+ x: currentX
71709
+ });
71710
+ currentX += TICK_SPACING_PX;
71711
+ for (let i = 0; i < 3; i++) {
71712
+ ticks.push({
71713
+ size: "eighth",
71714
+ height: "10%",
71715
+ x: currentX
71716
+ });
71717
+ currentX += TICK_SPACING_PX;
71718
+ }
71719
+ ticks.push({
71720
+ size: "half",
71721
+ height: "40%",
71722
+ x: currentX
71723
+ });
71724
+ currentX += TICK_SPACING_PX;
71725
+ if (remaining <= 0.5) break;
71726
+ for (let i = 0; i < 3; i++) {
71727
+ ticks.push({
71728
+ size: "eighth",
71729
+ height: "10%",
71730
+ x: currentX
71731
+ });
71732
+ currentX += TICK_SPACING_PX;
71733
+ }
71734
+ }
71735
+ return {
71736
+ widthPx,
71737
+ heightPx,
71738
+ ticks,
71739
+ leftMarginPx: pageMargins.left * ppi,
71740
+ rightMarginPx: widthPx - pageMargins.right * ppi,
71741
+ pageWidthInches: pageSize.width
71742
+ };
71743
+ }
71744
+ function calculateMarginFromHandle(handleX, side, pageWidthPx, ppi = DEFAULT_PPI) {
71745
+ if (side === "left") {
71746
+ return handleX / ppi;
71747
+ } else {
71748
+ return (pageWidthPx - handleX) / ppi;
71749
+ }
71750
+ }
71751
+ function clampHandlePosition(handleX, side, otherHandleX, pageWidthPx, minContentWidthPx = 200) {
71752
+ if (!Number.isFinite(handleX)) {
71753
+ throw new Error(`Invalid handleX: ${handleX}. Must be a finite number.`);
71754
+ }
71755
+ if (!Number.isFinite(otherHandleX)) {
71756
+ throw new Error(`Invalid otherHandleX: ${otherHandleX}. Must be a finite number.`);
71757
+ }
71758
+ if (!Number.isFinite(pageWidthPx)) {
71759
+ throw new Error(`Invalid pageWidthPx: ${pageWidthPx}. Must be a finite number.`);
71760
+ }
71761
+ if (!Number.isFinite(minContentWidthPx)) {
71762
+ throw new Error(`Invalid minContentWidthPx: ${minContentWidthPx}. Must be a finite number.`);
71763
+ }
71764
+ if (side === "left") {
71765
+ const min2 = 0;
71766
+ const max2 = otherHandleX - minContentWidthPx;
71767
+ return Math.max(min2, Math.min(max2, handleX));
71768
+ } else {
71769
+ const min2 = otherHandleX + minContentWidthPx;
71770
+ const max2 = pageWidthPx;
71771
+ return Math.max(min2, Math.min(max2, handleX));
71772
+ }
71773
+ }
71774
+ function generateRulerDefinitionFromPx(config2) {
71775
+ const ppi = config2.ppi ?? DEFAULT_PPI;
71776
+ const heightPx = config2.heightPx ?? DEFAULT_RULER_HEIGHT;
71777
+ const { pageWidthPx, leftMarginPx, rightMarginPx } = config2;
71778
+ if (!Number.isFinite(ppi) || ppi <= 0) {
71779
+ throw new Error(`Invalid PPI: ${ppi}. Must be a positive finite number.`);
71780
+ }
71781
+ if (!Number.isFinite(pageWidthPx) || pageWidthPx <= 0) {
71782
+ throw new Error(`Invalid page width: ${pageWidthPx}px. Must be a positive finite number.`);
71783
+ }
71784
+ if (!Number.isFinite(config2.pageHeightPx) || config2.pageHeightPx <= 0) {
71785
+ throw new Error(`Invalid page height: ${config2.pageHeightPx}px. Must be a positive finite number.`);
71786
+ }
71787
+ if (!Number.isFinite(leftMarginPx) || leftMarginPx < 0) {
71788
+ throw new Error(`Invalid left margin: ${leftMarginPx}px. Must be a non-negative finite number.`);
71789
+ }
71790
+ if (!Number.isFinite(rightMarginPx) || rightMarginPx < 0) {
71791
+ throw new Error(`Invalid right margin: ${rightMarginPx}px. Must be a non-negative finite number.`);
71792
+ }
71793
+ if (leftMarginPx + rightMarginPx >= pageWidthPx) {
71794
+ throw new Error(
71795
+ `Invalid margins: left (${leftMarginPx}px) + right (${rightMarginPx}px) must be less than page width (${pageWidthPx}px).`
71796
+ );
71797
+ }
71798
+ const pageWidthInches = pageWidthPx / ppi;
71799
+ const ticks = [];
71800
+ let currentX = 0;
71801
+ for (let inch = 0; inch < pageWidthInches; inch++) {
71802
+ const remaining = pageWidthInches - inch;
71803
+ ticks.push({
71804
+ size: "main",
71805
+ height: "20%",
71806
+ label: inch,
71807
+ x: currentX
71808
+ });
71809
+ currentX += TICK_SPACING_PX;
71810
+ for (let i = 0; i < 3; i++) {
71811
+ ticks.push({
71812
+ size: "eighth",
71813
+ height: "10%",
71814
+ x: currentX
71815
+ });
71816
+ currentX += TICK_SPACING_PX;
71817
+ }
71818
+ ticks.push({
71819
+ size: "half",
71820
+ height: "40%",
71821
+ x: currentX
71822
+ });
71823
+ currentX += TICK_SPACING_PX;
71824
+ if (remaining <= 0.5) break;
71825
+ for (let i = 0; i < 3; i++) {
71826
+ ticks.push({
71827
+ size: "eighth",
71828
+ height: "10%",
71829
+ x: currentX
71830
+ });
71831
+ currentX += TICK_SPACING_PX;
71832
+ }
71833
+ }
71834
+ return {
71835
+ widthPx: pageWidthPx,
71836
+ heightPx,
71837
+ ticks,
71838
+ leftMarginPx,
71839
+ rightMarginPx: pageWidthPx - rightMarginPx,
71840
+ pageWidthInches
71841
+ };
71842
+ }
71843
+ const RULER_CLASS_NAMES = {
71844
+ /** Main ruler container */
71845
+ ruler: "superdoc-ruler",
71846
+ /** Tick mark element */
71847
+ tick: "superdoc-ruler-tick",
71848
+ /** Main (inch) tick */
71849
+ tickMain: "superdoc-ruler-tick--main",
71850
+ /** Half-inch tick */
71851
+ tickHalf: "superdoc-ruler-tick--half",
71852
+ /** Eighth-inch tick */
71853
+ tickEighth: "superdoc-ruler-tick--eighth",
71854
+ /** Inch label number */
71855
+ label: "superdoc-ruler-label",
71856
+ /** Margin handle */
71857
+ handle: "superdoc-ruler-handle",
71858
+ /** Left margin handle */
71859
+ handleLeft: "superdoc-ruler-handle--left",
71860
+ /** Right margin handle */
71861
+ handleRight: "superdoc-ruler-handle--right",
71862
+ /** Vertical indicator line during drag */
71863
+ indicator: "superdoc-ruler-indicator"
71864
+ };
71865
+ function createRulerElement(options) {
71866
+ const { definition, doc: doc2, interactive = false } = options;
71867
+ if (!Number.isFinite(definition.widthPx) || definition.widthPx <= 0) {
71868
+ console.warn(`[createRulerElement] Invalid ruler width: ${definition.widthPx}px. Using minimum width of 1px.`);
71869
+ definition.widthPx = Math.max(1, definition.widthPx || 1);
71870
+ }
71871
+ if (!definition.ticks || definition.ticks.length === 0) {
71872
+ console.warn("[createRulerElement] Ruler definition has no ticks. Ruler will be empty.");
71873
+ }
71874
+ const ruler = doc2.createElement("div");
71875
+ ruler.className = RULER_CLASS_NAMES.ruler;
71876
+ ruler.style.cssText = `
71877
+ position: relative;
71878
+ width: ${definition.widthPx}px;
71879
+ height: ${definition.heightPx}px;
71880
+ display: flex;
71881
+ align-items: flex-end;
71882
+ box-sizing: border-box;
71883
+ user-select: none;
71884
+ pointer-events: ${interactive ? "auto" : "none"};
71885
+ `;
71886
+ for (const tick of definition.ticks) {
71887
+ const tickEl = createTickElement(tick, doc2);
71888
+ ruler.appendChild(tickEl);
71889
+ }
71890
+ if (interactive) {
71891
+ const leftHandle = createHandleElement("left", definition.leftMarginPx, doc2, options);
71892
+ const rightHandle = createHandleElement("right", definition.rightMarginPx, doc2, options);
71893
+ ruler.appendChild(leftHandle);
71894
+ ruler.appendChild(rightHandle);
71895
+ }
71896
+ return ruler;
71897
+ }
71898
+ function createTickElement(tick, doc2) {
71899
+ const el = doc2.createElement("div");
71900
+ const sizeClass = tick.size === "main" ? RULER_CLASS_NAMES.tickMain : tick.size === "half" ? RULER_CLASS_NAMES.tickHalf : RULER_CLASS_NAMES.tickEighth;
71901
+ el.className = `${RULER_CLASS_NAMES.tick} ${sizeClass}`;
71902
+ el.style.cssText = `
71903
+ position: absolute;
71904
+ left: ${tick.x}px;
71905
+ bottom: 0;
71906
+ width: 1px;
71907
+ height: ${tick.height};
71908
+ background-color: #666;
71909
+ pointer-events: none;
71910
+ `;
71911
+ if (tick.label !== void 0) {
71912
+ const label = doc2.createElement("span");
71913
+ label.className = RULER_CLASS_NAMES.label;
71914
+ label.textContent = String(tick.label);
71915
+ label.style.cssText = `
71916
+ position: absolute;
71917
+ top: -16px;
71918
+ left: -2px;
71919
+ font-size: 10px;
71920
+ color: #666;
71921
+ pointer-events: none;
71922
+ user-select: none;
71923
+ `;
71924
+ el.appendChild(label);
71925
+ }
71926
+ return el;
71927
+ }
71928
+ function createHandleElement(side, x2, doc2, options) {
71929
+ const handle = doc2.createElement("div");
71930
+ const sideClass = side === "left" ? RULER_CLASS_NAMES.handleLeft : RULER_CLASS_NAMES.handleRight;
71931
+ handle.className = `${RULER_CLASS_NAMES.handle} ${sideClass}`;
71932
+ handle.dataset.side = side;
71933
+ handle.style.cssText = `
71934
+ position: absolute;
71935
+ left: ${x2}px;
71936
+ top: 0;
71937
+ width: 5px;
71938
+ height: 20px;
71939
+ margin-left: -2px;
71940
+ background-color: #ccc;
71941
+ border-radius: 4px 4px 0 0;
71942
+ cursor: grab;
71943
+ transition: background-color 150ms ease;
71944
+ z-index: 10;
71945
+ `;
71946
+ handle.addEventListener("mouseenter", () => {
71947
+ if (!handle.dataset.dragging) {
71948
+ handle.style.backgroundColor = "rgba(37, 99, 235, 0.4)";
71949
+ }
71950
+ });
71951
+ handle.addEventListener("mouseleave", () => {
71952
+ if (!handle.dataset.dragging) {
71953
+ handle.style.backgroundColor = "#ccc";
71954
+ }
71955
+ });
71956
+ if (options.onDragStart || options.onDrag || options.onDragEnd) {
71957
+ setupHandleDrag(handle, side, options);
71958
+ }
71959
+ return handle;
71960
+ }
71961
+ function setupHandleDrag(handle, side, options) {
71962
+ let offsetX = 0;
71963
+ const onPointerDown = (event) => {
71964
+ event.preventDefault();
71965
+ handle.dataset.dragging = "true";
71966
+ handle.style.backgroundColor = "rgba(37, 99, 235, 0.4)";
71967
+ handle.style.cursor = "grabbing";
71968
+ const rect = handle.getBoundingClientRect();
71969
+ offsetX = event.clientX - rect.left - rect.width / 2;
71970
+ handle.setPointerCapture(event.pointerId);
71971
+ options.onDragStart?.(side, event);
71972
+ };
71973
+ const onPointerMove = (event) => {
71974
+ if (handle.dataset.dragging !== "true") return;
71975
+ const ruler = handle.parentElement;
71976
+ if (!ruler) return;
71977
+ const rulerRect = ruler.getBoundingClientRect();
71978
+ const newX = event.clientX - rulerRect.left - offsetX;
71979
+ options.onDrag?.(side, newX, event);
71980
+ };
71981
+ const onPointerUp = (event) => {
71982
+ if (handle.dataset.dragging !== "true") return;
71983
+ handle.dataset.dragging = "";
71984
+ handle.style.backgroundColor = "#ccc";
71985
+ handle.style.cursor = "grab";
71986
+ handle.releasePointerCapture(event.pointerId);
71987
+ const ruler = handle.parentElement;
71988
+ if (!ruler) return;
71989
+ const rulerRect = ruler.getBoundingClientRect();
71990
+ const finalX = event.clientX - rulerRect.left - offsetX;
71991
+ options.onDragEnd?.(side, finalX, event);
71992
+ };
71993
+ handle.addEventListener("pointerdown", onPointerDown);
71994
+ handle.addEventListener("pointermove", onPointerMove);
71995
+ handle.addEventListener("pointerup", onPointerUp);
71996
+ handle.addEventListener("pointercancel", onPointerUp);
71997
+ }
71998
+ const RULER_STYLES = `
71999
+ /* Ruler container */
72000
+ .${RULER_CLASS_NAMES.ruler} {
72001
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
72002
+ background-color: transparent;
72003
+ }
72004
+
72005
+ /* Tick marks base styling */
72006
+ .${RULER_CLASS_NAMES.tick} {
72007
+ flex-shrink: 0;
72008
+ }
72009
+
72010
+ /* Handle hover and active states */
72011
+ .${RULER_CLASS_NAMES.handle}:hover {
72012
+ background-color: rgba(37, 99, 235, 0.4) !important;
72013
+ }
72014
+
72015
+ .${RULER_CLASS_NAMES.handle}:active,
72016
+ .${RULER_CLASS_NAMES.handle}[data-dragging="true"] {
72017
+ background-color: rgba(37, 99, 235, 0.6) !important;
72018
+ cursor: grabbing !important;
72019
+ }
72020
+
72021
+ /* Vertical indicator animation */
72022
+ .${RULER_CLASS_NAMES.indicator} {
72023
+ transition: left 16ms linear;
72024
+ }
72025
+
72026
+ /* Print mode: hide rulers */
72027
+ @media print {
72028
+ .${RULER_CLASS_NAMES.ruler} {
72029
+ display: none !important;
72030
+ }
72031
+ }
72032
+
72033
+ /* High contrast mode support */
72034
+ @media (prefers-contrast: high) {
72035
+ .${RULER_CLASS_NAMES.tick} {
72036
+ background-color: #000 !important;
72037
+ }
72038
+
72039
+ .${RULER_CLASS_NAMES.label} {
72040
+ color: #000 !important;
72041
+ }
72042
+
72043
+ .${RULER_CLASS_NAMES.handle} {
72044
+ background-color: #666 !important;
72045
+ border: 1px solid #000;
72046
+ }
72047
+
72048
+ .${RULER_CLASS_NAMES.handle}:hover,
72049
+ .${RULER_CLASS_NAMES.handle}:active {
72050
+ background-color: #0066cc !important;
72051
+ }
72052
+ }
72053
+
72054
+ /* Reduced motion support */
72055
+ @media (prefers-reduced-motion: reduce) {
72056
+ .${RULER_CLASS_NAMES.handle} {
72057
+ transition: none !important;
72058
+ }
72059
+
72060
+ .${RULER_CLASS_NAMES.indicator} {
72061
+ transition: none !important;
72062
+ }
72063
+ }
72064
+ `;
72065
+ let rulerStylesInjected = false;
72066
+ function ensureRulerStyles(doc2) {
72067
+ if (rulerStylesInjected || !doc2) return;
72068
+ const styleEl = doc2.createElement("style");
72069
+ styleEl.setAttribute("data-superdoc-ruler-styles", "true");
72070
+ styleEl.textContent = RULER_STYLES;
72071
+ doc2.head?.appendChild(styleEl);
72072
+ rulerStylesInjected = true;
72073
+ }
71560
72074
  function isMinimalWordLayout(value) {
71561
72075
  if (typeof value !== "object" || value === null) {
71562
72076
  return false;
@@ -71603,6 +72117,7 @@ function isMinimalWordLayout(value) {
71603
72117
  }
71604
72118
  const LIST_MARKER_GAP$1 = 8;
71605
72119
  const DEFAULT_TAB_INTERVAL_PX$1 = 48;
72120
+ const DEFAULT_PAGE_HEIGHT_PX = 1056;
71606
72121
  const COMMENT_EXTERNAL_COLOR = "#B1124B";
71607
72122
  const COMMENT_INTERNAL_COLOR = "#078383";
71608
72123
  const COMMENT_INACTIVE_ALPHA = "22";
@@ -71845,6 +72360,9 @@ const _DomPainter = class _DomPainter2 {
71845
72360
  ensureFieldAnnotationStyles(doc2);
71846
72361
  ensureSdtContainerStyles(doc2);
71847
72362
  ensureImageSelectionStyles(doc2);
72363
+ if (this.options.ruler?.enabled) {
72364
+ ensureRulerStyles(doc2);
72365
+ }
71848
72366
  mount2.classList.add(CLASS_NAMES$1.container);
71849
72367
  if (this.mount && this.mount !== mount2) {
71850
72368
  this.resetState();
@@ -72102,6 +72620,12 @@ const _DomPainter = class _DomPainter2 {
72102
72620
  const el = this.doc.createElement("div");
72103
72621
  el.classList.add(CLASS_NAMES$1.page);
72104
72622
  applyStyles$2(el, pageStyles(width, height, this.getEffectivePageStyles()));
72623
+ if (this.options.ruler?.enabled) {
72624
+ const rulerEl = this.renderPageRuler(width, page);
72625
+ if (rulerEl) {
72626
+ el.appendChild(rulerEl);
72627
+ }
72628
+ }
72105
72629
  const contextBase = {
72106
72630
  pageNumber: page.number,
72107
72631
  totalPages: this.totalPages,
@@ -72114,6 +72638,70 @@ const _DomPainter = class _DomPainter2 {
72114
72638
  this.renderDecorationsForPage(el, page);
72115
72639
  return el;
72116
72640
  }
72641
+ /**
72642
+ * Render a ruler element for a page.
72643
+ *
72644
+ * Creates a horizontal ruler with tick marks and optional interactive margin handles.
72645
+ * The ruler is positioned at the top of the page and displays inch measurements.
72646
+ *
72647
+ * @param pageWidthPx - Page width in pixels
72648
+ * @param page - Page data containing margins and optional size information
72649
+ * @returns Ruler element, or null if this.doc is unavailable or page margins are missing
72650
+ *
72651
+ * Side effects:
72652
+ * - Creates DOM elements and applies inline styles
72653
+ * - May invoke the onMarginChange callback if interactive mode is enabled
72654
+ *
72655
+ * Fallback behavior:
72656
+ * - Uses DEFAULT_PAGE_HEIGHT_PX (1056px = 11 inches) if page.size.h is not available
72657
+ * - Defaults margins to 0 if not explicitly provided
72658
+ */
72659
+ renderPageRuler(pageWidthPx, page) {
72660
+ if (!this.doc) {
72661
+ console.warn("[renderPageRuler] Cannot render ruler: document is not available.");
72662
+ return null;
72663
+ }
72664
+ if (!page.margins) {
72665
+ console.warn(`[renderPageRuler] Cannot render ruler for page ${page.number}: margins not available.`);
72666
+ return null;
72667
+ }
72668
+ const margins = page.margins;
72669
+ const leftMargin = margins.left ?? 0;
72670
+ const rightMargin = margins.right ?? 0;
72671
+ try {
72672
+ const rulerDefinition = generateRulerDefinitionFromPx({
72673
+ pageWidthPx,
72674
+ pageHeightPx: page.size?.h ?? DEFAULT_PAGE_HEIGHT_PX,
72675
+ leftMarginPx: leftMargin,
72676
+ rightMarginPx: rightMargin
72677
+ });
72678
+ const interactive = this.options.ruler?.interactive ?? false;
72679
+ const onMarginChange = this.options.ruler?.onMarginChange;
72680
+ const rulerEl = createRulerElement({
72681
+ definition: rulerDefinition,
72682
+ doc: this.doc,
72683
+ interactive,
72684
+ onDragEnd: interactive && onMarginChange ? (side, x2) => {
72685
+ try {
72686
+ const ppi = 96;
72687
+ const marginInches = side === "left" ? x2 / ppi : (pageWidthPx - x2) / ppi;
72688
+ onMarginChange(side, marginInches);
72689
+ } catch (error) {
72690
+ console.error("[renderPageRuler] Error in onMarginChange callback:", error);
72691
+ }
72692
+ } : void 0
72693
+ });
72694
+ rulerEl.style.position = "absolute";
72695
+ rulerEl.style.top = "0";
72696
+ rulerEl.style.left = "0";
72697
+ rulerEl.style.zIndex = "20";
72698
+ rulerEl.dataset.pageNumber = String(page.number);
72699
+ return rulerEl;
72700
+ } catch (error) {
72701
+ console.error(`[renderPageRuler] Failed to create ruler for page ${page.number}:`, error);
72702
+ return null;
72703
+ }
72704
+ }
72117
72705
  renderDecorationsForPage(pageEl, page) {
72118
72706
  this.renderDecorationSection(pageEl, page, "header");
72119
72707
  this.renderDecorationSection(pageEl, page, "footer");
@@ -72145,6 +72733,7 @@ const _DomPainter = class _DomPainter2 {
72145
72733
  container.style.height = `${data.height}px`;
72146
72734
  container.style.top = `${Math.max(0, offset2)}px`;
72147
72735
  container.style.zIndex = "1";
72736
+ container.style.overflow = "visible";
72148
72737
  let footerYOffset = 0;
72149
72738
  if (kind === "footer" && data.fragments.length > 0) {
72150
72739
  const contentHeight = typeof data.contentHeight === "number" ? data.contentHeight : data.fragments.reduce((max2, f2) => {
@@ -74914,7 +75503,8 @@ const createDomPainter = (options) => {
74914
75503
  layoutMode: options.layoutMode,
74915
75504
  headerProvider: options.headerProvider,
74916
75505
  footerProvider: options.footerProvider,
74917
- virtualization: options.virtualization
75506
+ virtualization: options.virtualization,
75507
+ ruler: options.ruler
74918
75508
  });
74919
75509
  return {
74920
75510
  paint(layout, mount2) {
@@ -81156,7 +81746,14 @@ async function measureParagraphBlock(block, maxWidth) {
81156
81746
  leftJustifiedMarkerSpace = markerBoxWidth + gutterWidth;
81157
81747
  }
81158
81748
  }
81159
- const initialAvailableWidth = Math.max(1, contentWidth - firstLineOffset - leftJustifiedMarkerSpace);
81749
+ let initialAvailableWidth;
81750
+ const isFirstLineIndentMode = wordLayout?.firstLineIndentMode === true;
81751
+ const textStartPx = wordLayout?.textStartPx;
81752
+ if (isFirstLineIndentMode && typeof textStartPx === "number" && textStartPx > 0) {
81753
+ initialAvailableWidth = Math.max(1, maxWidth - textStartPx - indentRight);
81754
+ } else {
81755
+ initialAvailableWidth = Math.max(1, contentWidth - firstLineOffset - leftJustifiedMarkerSpace);
81756
+ }
81160
81757
  const tabStops = buildTabStopsPx(
81161
81758
  indent,
81162
81759
  block.attrs?.tabs,
@@ -83132,7 +83729,9 @@ class HeaderFooterLayoutAdapter {
83132
83729
  const batch = {};
83133
83730
  let hasBlocks = false;
83134
83731
  descriptors.forEach((descriptor) => {
83135
- if (!descriptor.variant) return;
83732
+ if (!descriptor.variant) {
83733
+ return;
83734
+ }
83136
83735
  const blocks = __privateMethod$1(this, _HeaderFooterLayoutAdapter_instances, getBlocks_fn).call(this, descriptor);
83137
83736
  if (blocks && blocks.length > 0) {
83138
83737
  batch[descriptor.variant] = blocks;
@@ -85442,9 +86041,11 @@ updateLocalAwarenessCursor_fn = function() {
85442
86041
  if (typeof provider.awareness.setLocalStateField !== "function") {
85443
86042
  return;
85444
86043
  }
85445
- const ystate = ySyncPluginKey.getState(__privateGet$1(this, _editor3).state);
86044
+ const editorState = __privateGet$1(this, _editor3)?.state;
86045
+ if (!editorState) return;
86046
+ const ystate = ySyncPluginKey.getState(editorState);
85446
86047
  if (!ystate?.binding?.mapping) return;
85447
- const { selection } = __privateGet$1(this, _editor3).state;
86048
+ const { selection } = editorState;
85448
86049
  const { anchor, head } = selection;
85449
86050
  try {
85450
86051
  const relAnchor = absolutePositionToRelativePosition(anchor, ystate.type, ystate.binding.mapping);
@@ -85462,7 +86063,9 @@ updateLocalAwarenessCursor_fn = function() {
85462
86063
  normalizeAwarenessStates_fn = function() {
85463
86064
  const provider = __privateGet$1(this, _options).collaborationProvider;
85464
86065
  if (!provider?.awareness) return /* @__PURE__ */ new Map();
85465
- const ystate = ySyncPluginKey.getState(__privateGet$1(this, _editor3).state);
86066
+ const editorState = __privateGet$1(this, _editor3)?.state;
86067
+ if (!editorState) return /* @__PURE__ */ new Map();
86068
+ const ystate = ySyncPluginKey.getState(editorState);
85466
86069
  if (!ystate) return /* @__PURE__ */ new Map();
85467
86070
  const states = provider.awareness?.getStates();
85468
86071
  const normalized = /* @__PURE__ */ new Map();
@@ -86255,7 +86858,8 @@ ensurePainter_fn = function(blocks, measures) {
86255
86858
  virtualization: __privateGet$1(this, _layoutOptions).virtualization,
86256
86859
  pageStyles: __privateGet$1(this, _layoutOptions).pageStyles,
86257
86860
  headerProvider: __privateGet$1(this, _headerDecorationProvider),
86258
- footerProvider: __privateGet$1(this, _footerDecorationProvider)
86861
+ footerProvider: __privateGet$1(this, _footerDecorationProvider),
86862
+ ruler: __privateGet$1(this, _layoutOptions).ruler
86259
86863
  }));
86260
86864
  }
86261
86865
  return __privateGet$1(this, _domPainter);
@@ -86394,14 +86998,20 @@ computeHeaderFooterConstraints_fn = function() {
86394
86998
  const margins = __privateGet$1(this, _layoutOptions).margins ?? DEFAULT_MARGINS;
86395
86999
  const marginLeft = margins.left ?? DEFAULT_MARGINS.left;
86396
87000
  const marginRight = margins.right ?? DEFAULT_MARGINS.right;
86397
- const width = pageSize.w - (marginLeft + marginRight);
86398
- if (!Number.isFinite(width) || width <= 0) {
87001
+ const bodyContentWidth = pageSize.w - (marginLeft + marginRight);
87002
+ if (!Number.isFinite(bodyContentWidth) || bodyContentWidth <= 0) {
86399
87003
  return null;
86400
87004
  }
86401
- const { headerSpace, footerSpace } = extractHeaderFooterSpace(margins);
86402
- const height = Math.max(headerSpace, footerSpace, 1);
87005
+ const measurementWidth = bodyContentWidth;
87006
+ const marginTop = margins.top ?? DEFAULT_MARGINS.top;
87007
+ const marginBottom = margins.bottom ?? DEFAULT_MARGINS.bottom;
87008
+ const headerMargin = margins.header ?? 0;
87009
+ const footerMargin = margins.footer ?? 0;
87010
+ const headerContentSpace = Math.max(marginTop - headerMargin, 0);
87011
+ const footerContentSpace = Math.max(marginBottom - footerMargin, 0);
87012
+ const height = Math.max(headerContentSpace, footerContentSpace, 1);
86403
87013
  return {
86404
- width,
87014
+ width: measurementWidth,
86405
87015
  height,
86406
87016
  // Pass actual page dimensions for page-relative anchor positioning in headers/footers
86407
87017
  pageWidth: pageSize.w,
@@ -120341,6 +120951,7 @@ const _SuperToolbar = class _SuperToolbar2 extends EventEmitter2 {
120341
120951
  */
120342
120952
  toggleRuler: () => {
120343
120953
  this.superdoc.toggleRuler();
120954
+ this.updateToolbarState();
120344
120955
  },
120345
120956
  /**
120346
120957
  * Initiates the image upload process
@@ -120766,6 +121377,13 @@ const _SuperToolbar = class _SuperToolbar2 extends EventEmitter2 {
120766
121377
  item.activate();
120767
121378
  }
120768
121379
  }
121380
+ if (item.name.value === "ruler") {
121381
+ if (this.superdoc?.config?.rulers) {
121382
+ item.activate();
121383
+ } else {
121384
+ item.deactivate();
121385
+ }
121386
+ }
120769
121387
  });
120770
121388
  }
120771
121389
  /**
@@ -122226,8 +122844,12 @@ const _sfc_main$7 = /* @__PURE__ */ vue.defineComponent({
122226
122844
  };
122227
122845
  }
122228
122846
  });
122229
- const _hoisted_1$4 = { class: "numbering" };
122847
+ const _hoisted_1$4 = {
122848
+ key: 0,
122849
+ class: "numbering"
122850
+ };
122230
122851
  const MIN_WIDTH = 200;
122852
+ const PPI = 96;
122231
122853
  const alignment = "flex-end";
122232
122854
  const _sfc_main$6 = {
122233
122855
  __name: "Ruler",
@@ -122250,7 +122872,7 @@ const _sfc_main$6 = {
122250
122872
  const emit = __emit;
122251
122873
  const props = __props;
122252
122874
  const ruler = vue.ref(null);
122253
- const rulerDefinition = vue.ref([]);
122875
+ const rulerDefinition = vue.ref(null);
122254
122876
  const rulerHandleOriginalColor = vue.ref("#CCCCCC");
122255
122877
  const rulerHandleActiveColor = vue.ref("#2563EB66");
122256
122878
  const pageSize = vue.ref(null);
@@ -122263,45 +122885,32 @@ const _sfc_main$6 = {
122263
122885
  const initialX = vue.ref(0);
122264
122886
  let offsetX = 0;
122265
122887
  const initRuler = () => {
122266
- if (props.editor.options.mode !== "docx") return;
122267
- const rulerItems = [];
122888
+ if (props.editor.options.mode !== "docx") return null;
122268
122889
  const { pageMargins: docMargins, pageSize: docSize } = props.editor.getPageStyles();
122269
122890
  pageSize.value = docSize;
122270
122891
  pageMargins.value = docMargins;
122271
- rightHandle.x = docSize.width * 96 - docMargins.right * 96;
122272
- leftHandle.x = docMargins.left * 96;
122273
- for (let i2 = 0; i2 < docSize.width; i2++) {
122274
- const marginNum = 0.0625 * 96 - 0.5;
122275
- const margin = `${marginNum}px`;
122276
- const diff = docSize.width - i2;
122277
- rulerItems.push(...generateSection(1, "main", "20%", margin, i2));
122278
- rulerItems.push(...generateSection(3, "eighth", "10%", margin));
122279
- rulerItems.push(...generateSection(1, "half", "40%", margin));
122280
- if (diff <= 0.5) break;
122281
- rulerItems.push(...generateSection(3, "eighth", "10%", margin));
122282
- }
122283
- return rulerItems;
122284
- };
122285
- const generateSection = (qty, size2, height, margin, index2) => {
122286
- return Array.from({ length: qty }, (_2, i2) => {
122287
- const item = {
122288
- className: `${size2}-unit ruler-section`,
122289
- height,
122290
- margin
122291
- };
122292
- if (index2 !== void 0) item.numbering = index2;
122293
- return item;
122892
+ const definition = generateRulerDefinition({
122893
+ pageSize: { width: docSize.width, height: docSize.height },
122894
+ pageMargins: {
122895
+ left: docMargins.left,
122896
+ right: docMargins.right,
122897
+ top: docMargins.top ?? 1,
122898
+ bottom: docMargins.bottom ?? 1
122899
+ }
122294
122900
  });
122901
+ leftHandle.x = definition.leftMarginPx;
122902
+ rightHandle.x = definition.rightMarginPx;
122903
+ return definition;
122295
122904
  };
122296
- const getStyle = vue.computed(() => (unit) => {
122905
+ const getTickStyle = vue.computed(() => (tick) => {
122297
122906
  return {
122907
+ position: "absolute",
122908
+ left: `${tick.x}px`,
122909
+ bottom: "0",
122298
122910
  width: "1px",
122299
- minWidth: "1px",
122300
- maxWidth: "1px",
122301
- height: unit.height,
122302
- backgroundColor: unit.color || "#666",
122303
- marginLeft: unit.numbering === 0 ? null : unit.margin,
122304
- marginRight: unit.margin
122911
+ height: tick.height,
122912
+ backgroundColor: "#666",
122913
+ pointerEvents: "none"
122305
122914
  };
122306
122915
  });
122307
122916
  const getHandlePosition = vue.computed(() => (side) => {
@@ -122313,7 +122922,8 @@ const _sfc_main$6 = {
122313
122922
  const getVerticalIndicatorStyle = vue.computed(() => {
122314
122923
  if (!ruler.value) return;
122315
122924
  const parentElement = ruler.value.parentElement;
122316
- const editor = parentElement.querySelector(".super-editor");
122925
+ const editor = parentElement?.querySelector(".super-editor") ?? document.querySelector(".super-editor");
122926
+ if (!editor) return { left: `${currentHandle.value.x}px`, minHeight: "100%" };
122317
122927
  const editorBounds = editor.getBoundingClientRect();
122318
122928
  return {
122319
122929
  left: `${currentHandle.value.x}px`,
@@ -122330,22 +122940,11 @@ const _sfc_main$6 = {
122330
122940
  showVerticalIndicator.value = true;
122331
122941
  };
122332
122942
  const handleMouseMove2 = (event) => {
122333
- if (!isDragging.value) return;
122943
+ if (!isDragging.value || !pageSize.value) return;
122334
122944
  const newLeft = event.clientX - offsetX;
122335
- currentHandle.value.x = newLeft;
122336
- if (currentHandle.value.side === "left") {
122337
- if (newLeft <= 0) {
122338
- currentHandle.value.x = 0;
122339
- } else if (newLeft >= rightHandle.x - MIN_WIDTH) {
122340
- currentHandle.value.x = rightHandle.x - MIN_WIDTH;
122341
- }
122342
- } else {
122343
- if (newLeft >= pageSize.value.width * 96) {
122344
- currentHandle.value.x = pageSize.value.width * 96;
122345
- } else if (newLeft <= leftHandle.x + MIN_WIDTH) {
122346
- currentHandle.value.x = leftHandle.x + MIN_WIDTH;
122347
- }
122348
- }
122945
+ const pageWidthPx = pageSize.value.width * PPI;
122946
+ const otherHandleX = currentHandle.value.side === "left" ? rightHandle.x : leftHandle.x;
122947
+ currentHandle.value.x = clampHandlePosition(newLeft, currentHandle.value.side, otherHandleX, pageWidthPx, MIN_WIDTH);
122349
122948
  };
122350
122949
  const handleMouseUp = () => {
122351
122950
  isDragging.value = false;
@@ -122366,14 +122965,17 @@ const _sfc_main$6 = {
122366
122965
  rulerHandleOriginalColor.value = "#CCC";
122367
122966
  };
122368
122967
  const getNewMarginValue = () => {
122369
- if (currentHandle.value.side === "left") return currentHandle.value.x / 96;
122370
- else return (pageSize.value.width * 96 - currentHandle.value.x) / 96;
122968
+ if (!pageSize.value) return 0;
122969
+ const pageWidthPx = pageSize.value.width * PPI;
122970
+ return calculateMarginFromHandle(currentHandle.value.x, currentHandle.value.side, pageWidthPx, PPI);
122371
122971
  };
122372
122972
  const getStyleVars = vue.computed(() => {
122973
+ const width = rulerDefinition.value?.widthPx ?? pageSize.value?.width * PPI ?? 816;
122373
122974
  return {
122374
122975
  "--alignment": alignment,
122375
122976
  "--ruler-handle-color": rulerHandleOriginalColor.value,
122376
- "--ruler-handle-active-color": rulerHandleActiveColor.value
122977
+ "--ruler-handle-active-color": rulerHandleActiveColor.value,
122978
+ "--ruler-width": `${width}px`
122377
122979
  };
122378
122980
  });
122379
122981
  vue.onMounted(() => {
@@ -122409,32 +123011,20 @@ const _sfc_main$6 = {
122409
123011
  class: "vertical-indicator",
122410
123012
  style: vue.normalizeStyle(getVerticalIndicatorStyle.value)
122411
123013
  }, null, 4)) : vue.createCommentVNode("", true),
122412
- (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(rulerDefinition.value, (unit) => {
123014
+ rulerDefinition.value ? (vue.openBlock(true), vue.createElementBlock(vue.Fragment, { key: 1 }, vue.renderList(rulerDefinition.value.ticks, (tick, index2) => {
122413
123015
  return vue.openBlock(), vue.createElementBlock("div", {
122414
- class: vue.normalizeClass(unit.className),
122415
- style: vue.normalizeStyle(getStyle.value(unit))
123016
+ key: index2,
123017
+ class: vue.normalizeClass(["ruler-tick", `ruler-tick--${tick.size}`]),
123018
+ style: vue.normalizeStyle(getTickStyle.value(tick))
122416
123019
  }, [
122417
- vue.createBaseVNode("div", _hoisted_1$4, vue.toDisplayString(unit.numbering), 1),
122418
- (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(unit.elements, (half) => {
122419
- return vue.openBlock(), vue.createElementBlock("div", {
122420
- class: vue.normalizeClass(half.className),
122421
- style: vue.normalizeStyle(getStyle.value(half))
122422
- }, [
122423
- (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(half.elements, (quarter) => {
122424
- return vue.openBlock(), vue.createElementBlock("div", {
122425
- class: vue.normalizeClass(quarter.className),
122426
- style: vue.normalizeStyle(getStyle.value(quarter))
122427
- }, null, 6);
122428
- }), 256))
122429
- ], 6);
122430
- }), 256))
123020
+ tick.label !== void 0 ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_1$4, vue.toDisplayString(tick.label), 1)) : vue.createCommentVNode("", true)
122431
123021
  ], 6);
122432
- }), 256))
123022
+ }), 128)) : vue.createCommentVNode("", true)
122433
123023
  ], 4);
122434
123024
  };
122435
123025
  }
122436
123026
  };
122437
- const Ruler = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["__scopeId", "data-v-79f9a944"]]);
123027
+ const Ruler = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["__scopeId", "data-v-b9f4f30a"]]);
122438
123028
  const _sfc_main$5 = {
122439
123029
  __name: "GenericPopover",
122440
123030
  props: {
@@ -123615,7 +124205,7 @@ function adjustPaginationBreaks(editorElem, editor) {
123615
124205
  const BlankDOCX = "data:application/octet-stream;base64,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";
123616
124206
  const _hoisted_1$1 = { class: "super-editor-container" };
123617
124207
  const _hoisted_2 = {
123618
- key: 1,
124208
+ key: 2,
123619
124209
  class: "placeholder-editor"
123620
124210
  };
123621
124211
  const _hoisted_3 = { class: "placeholder-title" };
@@ -123660,6 +124250,19 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
123660
124250
  const active = activeEditor.value;
123661
124251
  return active?.options ? Boolean(active.options.disableContextMenu) : Boolean(props.options.disableContextMenu);
123662
124252
  });
124253
+ const rulersVisible = vue.ref(Boolean(props.options.rulers));
124254
+ vue.watch(
124255
+ () => props.options,
124256
+ (newOptions) => {
124257
+ const rulers = newOptions?.rulers;
124258
+ if (rulers && typeof rulers === "object" && "value" in rulers) {
124259
+ rulersVisible.value = Boolean(rulers.value);
124260
+ } else {
124261
+ rulersVisible.value = Boolean(rulers);
124262
+ }
124263
+ },
124264
+ { immediate: true, deep: true }
124265
+ );
123663
124266
  const message = useMessage();
123664
124267
  const editorWrapper = vue.ref(null);
123665
124268
  const editorElem = vue.ref(null);
@@ -124072,8 +124675,17 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
124072
124675
  });
124073
124676
  return (_ctx, _cache) => {
124074
124677
  return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$1, [
124075
- __props.options.rulers && !!activeEditor.value ? (vue.openBlock(), vue.createBlock(Ruler, {
124678
+ __props.options.rulerContainer && rulersVisible.value && !!activeEditor.value ? (vue.openBlock(), vue.createBlock(vue.Teleport, {
124076
124679
  key: 0,
124680
+ to: __props.options.rulerContainer
124681
+ }, [
124682
+ vue.createVNode(Ruler, {
124683
+ class: "ruler superdoc-ruler",
124684
+ editor: activeEditor.value,
124685
+ onMarginChange: handleMarginChange
124686
+ }, null, 8, ["editor"])
124687
+ ], 8, ["to"])) : rulersVisible.value && !!activeEditor.value ? (vue.openBlock(), vue.createBlock(Ruler, {
124688
+ key: 1,
124077
124689
  class: "ruler",
124078
124690
  editor: activeEditor.value,
124079
124691
  onMarginChange: handleMarginChange
@@ -124167,7 +124779,7 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
124167
124779
  })
124168
124780
  ])) : vue.createCommentVNode("", true),
124169
124781
  activeEditor.value ? (vue.openBlock(), vue.createBlock(GenericPopover, {
124170
- key: 2,
124782
+ key: 3,
124171
124783
  editor: activeEditor.value,
124172
124784
  visible: popoverControls.visible,
124173
124785
  position: popoverControls.position,
@@ -124182,7 +124794,7 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
124182
124794
  };
124183
124795
  }
124184
124796
  });
124185
- const SuperEditor = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-a935d3e2"]]);
124797
+ const SuperEditor = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-cb3fe66f"]]);
124186
124798
  const _hoisted_1 = ["innerHTML"];
124187
124799
  const _sfc_main = {
124188
124800
  __name: "SuperInput",