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
@@ -42132,11 +42132,71 @@ Please report this to https://github.com/markedjs/marked.`, e) {
42132
42132
  return JSON.parse(xmljs.xml2json(newXml, null, 2));
42133
42133
  }
42134
42134
  /**
42135
- * Generic method to get a stored custom property from docx
42135
+ * Checks if an element name matches the expected local name, with or without namespace prefix.
42136
+ * This helper supports custom namespace prefixes in DOCX files (e.g., 'op:Properties', 'custom:property').
42137
+ *
42138
+ * @private
42139
+ * @static
42140
+ * @param {string|undefined|null} elementName - The element name to check (may include namespace prefix)
42141
+ * @param {string} expectedLocalName - The expected local name without prefix
42142
+ * @returns {boolean} True if the element name matches (with or without prefix)
42143
+ *
42144
+ * @example
42145
+ * // Exact match without prefix
42146
+ * _matchesElementName('Properties', 'Properties') // => true
42147
+ *
42148
+ * @example
42149
+ * // Match with namespace prefix
42150
+ * _matchesElementName('op:Properties', 'Properties') // => true
42151
+ * _matchesElementName('custom:property', 'property') // => true
42152
+ *
42153
+ * @example
42154
+ * // No match
42155
+ * _matchesElementName('SomeOtherElement', 'Properties') // => false
42156
+ * _matchesElementName(':Properties', 'Properties') // => false (empty prefix)
42157
+ */
42158
+ static _matchesElementName(elementName, expectedLocalName) {
42159
+ if (!elementName || typeof elementName !== "string") return false;
42160
+ if (!expectedLocalName) return false;
42161
+ if (elementName === expectedLocalName) return true;
42162
+ if (elementName.endsWith(`:${expectedLocalName}`)) {
42163
+ const prefix2 = elementName.slice(0, -(expectedLocalName.length + 1));
42164
+ return prefix2.length > 0;
42165
+ }
42166
+ return false;
42167
+ }
42168
+ /**
42169
+ * Generic method to get a stored custom property from docx.
42170
+ * Supports both standard and custom namespace prefixes (e.g., 'op:Properties', 'custom:property').
42171
+ *
42136
42172
  * @static
42137
42173
  * @param {Array} docx - Array of docx file objects
42138
42174
  * @param {string} propertyName - Name of the property to retrieve
42139
42175
  * @returns {string|null} The property value or null if not found
42176
+ *
42177
+ * Returns null in the following cases:
42178
+ * - docx array is empty or doesn't contain 'docProps/custom.xml'
42179
+ * - custom.xml cannot be parsed
42180
+ * - Properties element is not found (with or without namespace prefix)
42181
+ * - Property with the specified name is not found
42182
+ * - Property has malformed structure (missing nested elements or text)
42183
+ * - Any error occurs during parsing or retrieval
42184
+ *
42185
+ * @example
42186
+ * // Standard property without namespace prefix
42187
+ * const version = SuperConverter.getStoredCustomProperty(docx, 'SuperdocVersion');
42188
+ * // => '1.2.3'
42189
+ *
42190
+ * @example
42191
+ * // Property with namespace prefix (e.g., from Office 365)
42192
+ * const guid = SuperConverter.getStoredCustomProperty(docx, 'DocumentGuid');
42193
+ * // Works with both 'Properties' and 'op:Properties' elements
42194
+ * // => 'abc-123-def-456'
42195
+ *
42196
+ * @example
42197
+ * // Non-existent property
42198
+ * const missing = SuperConverter.getStoredCustomProperty(docx, 'NonExistent');
42199
+ * // => null
42140
42200
  */
42141
42201
  static getStoredCustomProperty(docx, propertyName) {
42142
42202
  try {
@@ -42145,10 +42205,16 @@ Please report this to https://github.com/markedjs/marked.`, e) {
42145
42205
  const converter = new _SuperConverter2();
42146
42206
  const content2 = customXml.content;
42147
42207
  const contentJson = converter.parseXmlToJson(content2);
42148
- const properties = contentJson.elements.find((el) => el.name === "Properties");
42149
- if (!properties.elements) return null;
42150
- const property2 = properties.elements.find((el) => el.name === "property" && el.attributes.name === propertyName);
42208
+ const properties = contentJson?.elements?.find((el) => _SuperConverter2._matchesElementName(el.name, "Properties"));
42209
+ if (!properties?.elements) return null;
42210
+ const property2 = properties.elements.find(
42211
+ (el) => _SuperConverter2._matchesElementName(el.name, "property") && el.attributes?.name === propertyName
42212
+ );
42151
42213
  if (!property2) return null;
42214
+ if (!property2.elements?.[0]?.elements?.[0]?.text) {
42215
+ console.warn(`Malformed property structure for "${propertyName}"`);
42216
+ return null;
42217
+ }
42152
42218
  return property2.elements[0].elements[0].text;
42153
42219
  } catch (e) {
42154
42220
  console.warn(`Error getting custom property ${propertyName}:`, e);
@@ -42156,60 +42222,112 @@ Please report this to https://github.com/markedjs/marked.`, e) {
42156
42222
  }
42157
42223
  }
42158
42224
  /**
42159
- * Generic method to set a stored custom property in docx
42225
+ * Generic method to set a stored custom property in docx.
42226
+ * Supports both standard and custom namespace prefixes (e.g., 'op:Properties', 'custom:property').
42227
+ *
42160
42228
  * @static
42161
- * @param {Object} docx - The docx object to store the property in
42229
+ * @param {Object} docx - The docx object to store the property in (converted XML structure)
42162
42230
  * @param {string} propertyName - Name of the property
42163
42231
  * @param {string|Function} value - Value or function that returns the value
42164
42232
  * @param {boolean} preserveExisting - If true, won't overwrite existing values
42165
- * @returns {string} The stored value
42233
+ * @returns {string|null} The stored value, or null if Properties element is not found
42234
+ *
42235
+ * @throws {Error} If an error occurs during property setting (logged as warning)
42236
+ *
42237
+ * @example
42238
+ * // Set a new property
42239
+ * const value = SuperConverter.setStoredCustomProperty(docx, 'MyProperty', 'MyValue');
42240
+ * // => 'MyValue'
42241
+ *
42242
+ * @example
42243
+ * // Set a property with a function
42244
+ * const guid = SuperConverter.setStoredCustomProperty(docx, 'DocumentGuid', () => uuidv4());
42245
+ * // => 'abc-123-def-456'
42246
+ *
42247
+ * @example
42248
+ * // Preserve existing value
42249
+ * SuperConverter.setStoredCustomProperty(docx, 'MyProperty', 'NewValue', true);
42250
+ * // => 'MyValue' (original value preserved)
42251
+ *
42252
+ * @example
42253
+ * // Works with namespace prefixes
42254
+ * // If docx has 'op:Properties' and 'op:property' elements, this will handle them correctly
42255
+ * const version = SuperConverter.setStoredCustomProperty(docx, 'Version', '2.0.0');
42256
+ * // => '2.0.0'
42166
42257
  */
42167
42258
  static setStoredCustomProperty(docx, propertyName, value, preserveExisting = false) {
42168
- const customLocation = "docProps/custom.xml";
42169
- if (!docx[customLocation]) docx[customLocation] = generateCustomXml();
42170
- const customXml = docx[customLocation];
42171
- const properties = customXml.elements?.find((el) => el.name === "Properties");
42172
- if (!properties) return null;
42173
- if (!properties.elements) properties.elements = [];
42174
- let property2 = properties.elements.find((el) => el.name === "property" && el.attributes.name === propertyName);
42175
- if (property2 && preserveExisting) {
42176
- return property2.elements[0].elements[0].text;
42177
- }
42178
- const finalValue = typeof value === "function" ? value() : value;
42179
- if (!property2) {
42180
- const existingPids = properties.elements.filter((el) => el.attributes?.pid).map((el) => parseInt(el.attributes.pid, 10)).filter(Number.isInteger);
42181
- const pid = existingPids.length > 0 ? Math.max(...existingPids) + 1 : 2;
42182
- property2 = {
42183
- type: "element",
42184
- name: "property",
42185
- attributes: {
42186
- name: propertyName,
42187
- fmtid: "{D5CDD505-2E9C-101B-9397-08002B2CF9AE}",
42188
- pid
42189
- },
42190
- elements: [
42191
- {
42192
- type: "element",
42193
- name: "vt:lpwstr",
42194
- elements: [
42195
- {
42196
- type: "text",
42197
- text: finalValue
42198
- }
42199
- ]
42200
- }
42201
- ]
42202
- };
42203
- properties.elements.push(property2);
42204
- } else {
42205
- property2.elements[0].elements[0].text = finalValue;
42259
+ try {
42260
+ const customLocation = "docProps/custom.xml";
42261
+ if (!docx[customLocation]) docx[customLocation] = generateCustomXml();
42262
+ const customXml = docx[customLocation];
42263
+ const properties = customXml.elements?.find((el) => _SuperConverter2._matchesElementName(el.name, "Properties"));
42264
+ if (!properties) return null;
42265
+ if (!properties.elements) properties.elements = [];
42266
+ let property2 = properties.elements.find(
42267
+ (el) => _SuperConverter2._matchesElementName(el.name, "property") && el.attributes?.name === propertyName
42268
+ );
42269
+ if (property2 && preserveExisting) {
42270
+ if (!property2.elements?.[0]?.elements?.[0]?.text) {
42271
+ console.warn(`Malformed existing property structure for "${propertyName}"`);
42272
+ return null;
42273
+ }
42274
+ return property2.elements[0].elements[0].text;
42275
+ }
42276
+ const finalValue = typeof value === "function" ? value() : value;
42277
+ if (!property2) {
42278
+ const existingPids = properties.elements.filter((el) => el.attributes?.pid).map((el) => parseInt(el.attributes.pid, 10)).filter(Number.isInteger);
42279
+ const pid = existingPids.length > 0 ? Math.max(...existingPids) + 1 : 2;
42280
+ property2 = {
42281
+ type: "element",
42282
+ name: "property",
42283
+ attributes: {
42284
+ name: propertyName,
42285
+ fmtid: "{D5CDD505-2E9C-101B-9397-08002B2CF9AE}",
42286
+ pid
42287
+ },
42288
+ elements: [
42289
+ {
42290
+ type: "element",
42291
+ name: "vt:lpwstr",
42292
+ elements: [
42293
+ {
42294
+ type: "text",
42295
+ text: finalValue
42296
+ }
42297
+ ]
42298
+ }
42299
+ ]
42300
+ };
42301
+ properties.elements.push(property2);
42302
+ } else {
42303
+ if (!property2.elements?.[0]?.elements?.[0]) {
42304
+ console.warn(`Malformed property structure for "${propertyName}", recreating structure`);
42305
+ property2.elements = [
42306
+ {
42307
+ type: "element",
42308
+ name: "vt:lpwstr",
42309
+ elements: [
42310
+ {
42311
+ type: "text",
42312
+ text: finalValue
42313
+ }
42314
+ ]
42315
+ }
42316
+ ];
42317
+ } else {
42318
+ property2.elements[0].elements[0].text = finalValue;
42319
+ }
42320
+ }
42321
+ return finalValue;
42322
+ } catch (e) {
42323
+ console.warn(`Error setting custom property ${propertyName}:`, e);
42324
+ return null;
42206
42325
  }
42207
- return finalValue;
42208
42326
  }
42209
42327
  static getStoredSuperdocVersion(docx) {
42210
42328
  return _SuperConverter2.getStoredCustomProperty(docx, "SuperdocVersion");
42211
42329
  }
42212
- static setStoredSuperdocVersion(docx = this.convertedXml, version2 = "1.0.0-beta.60") {
42330
+ static setStoredSuperdocVersion(docx = this.convertedXml, version2 = "1.0.0-beta.62") {
42213
42331
  return _SuperConverter2.setStoredCustomProperty(docx, "SuperdocVersion", version2, false);
42214
42332
  }
42215
42333
  /**
@@ -67255,7 +67373,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
67255
67373
  const shouldSkipNodeView = (editor) => {
67256
67374
  return isHeadless(editor);
67257
67375
  };
67258
- const summaryVersion = "1.0.0-beta.60";
67376
+ const summaryVersion = "1.0.0-beta.62";
67259
67377
  const nodeKeys = ["group", "content", "marks", "inline", "atom", "defining", "code", "tableRole", "summary"];
67260
67378
  const markKeys = ["group", "inclusive", "excludes", "spanning", "code"];
67261
67379
  function mapAttributes(attrs) {
@@ -68044,7 +68162,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
68044
68162
  { default: remarkStringify2 },
68045
68163
  { default: remarkGfm2 }
68046
68164
  ] = await Promise.all([
68047
- Promise.resolve().then(() => indexGAzIoyrZ),
68165
+ Promise.resolve().then(() => indexXOsGE2PW),
68048
68166
  Promise.resolve().then(() => indexDRCvimau),
68049
68167
  Promise.resolve().then(() => indexC_x_N6Uh),
68050
68168
  Promise.resolve().then(() => indexD_sWOSiG),
@@ -68249,7 +68367,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
68249
68367
  * Process collaboration migrations
68250
68368
  */
68251
68369
  processCollaborationMigrations() {
68252
- console.debug("[checkVersionMigrations] Current editor version", "1.0.0-beta.60");
68370
+ console.debug("[checkVersionMigrations] Current editor version", "1.0.0-beta.62");
68253
68371
  if (!this.options.ydoc) return;
68254
68372
  const metaMap = this.options.ydoc.getMap("meta");
68255
68373
  let docVersion = metaMap.get("version");
@@ -72222,12 +72340,6 @@ Please report this to https://github.com/markedjs/marked.`, e) {
72222
72340
  resolveSpacingIndent: resolveSpacingIndent$1,
72223
72341
  scaleWrapPolygon
72224
72342
  }, Symbol.toStringTag, { value: "Module" }));
72225
- const extractHeaderFooterSpace = (margins) => {
72226
- return {
72227
- headerSpace: margins?.header ?? 0,
72228
- footerSpace: margins?.footer ?? 0
72229
- };
72230
- };
72231
72343
  const hasParagraphStyleContext = (context) => {
72232
72344
  return Boolean(context?.docx);
72233
72345
  };
@@ -79415,6 +79527,408 @@ ${l}
79415
79527
  const hasPmEnd = fragment.pmEnd != null;
79416
79528
  globalValidationStats.record(hasPmStart, hasPmEnd);
79417
79529
  }
79530
+ const DEFAULT_PPI = 96;
79531
+ const DEFAULT_RULER_HEIGHT = 25;
79532
+ const TICK_SPACING_PX = DEFAULT_PPI / 8;
79533
+ function generateRulerDefinition(config2) {
79534
+ const ppi = config2.ppi ?? DEFAULT_PPI;
79535
+ const heightPx = config2.heightPx ?? DEFAULT_RULER_HEIGHT;
79536
+ const { pageSize, pageMargins } = config2;
79537
+ if (!Number.isFinite(ppi) || ppi <= 0) {
79538
+ throw new Error(`Invalid PPI: ${ppi}. Must be a positive finite number.`);
79539
+ }
79540
+ if (!Number.isFinite(pageSize.width) || pageSize.width <= 0) {
79541
+ throw new Error(`Invalid page width: ${pageSize.width}. Must be a positive finite number.`);
79542
+ }
79543
+ if (!Number.isFinite(pageSize.height) || pageSize.height <= 0) {
79544
+ throw new Error(`Invalid page height: ${pageSize.height}. Must be a positive finite number.`);
79545
+ }
79546
+ if (!Number.isFinite(pageMargins.left) || pageMargins.left < 0) {
79547
+ throw new Error(`Invalid left margin: ${pageMargins.left}. Must be a non-negative finite number.`);
79548
+ }
79549
+ if (!Number.isFinite(pageMargins.right) || pageMargins.right < 0) {
79550
+ throw new Error(`Invalid right margin: ${pageMargins.right}. Must be a non-negative finite number.`);
79551
+ }
79552
+ if (pageMargins.left + pageMargins.right >= pageSize.width) {
79553
+ throw new Error(
79554
+ `Invalid margins: left (${pageMargins.left}) + right (${pageMargins.right}) must be less than page width (${pageSize.width}).`
79555
+ );
79556
+ }
79557
+ const widthPx = pageSize.width * ppi;
79558
+ const ticks = [];
79559
+ let currentX = 0;
79560
+ for (let inch = 0; inch < pageSize.width; inch++) {
79561
+ const remaining = pageSize.width - inch;
79562
+ ticks.push({
79563
+ size: "main",
79564
+ height: "20%",
79565
+ label: inch,
79566
+ x: currentX
79567
+ });
79568
+ currentX += TICK_SPACING_PX;
79569
+ for (let i2 = 0; i2 < 3; i2++) {
79570
+ ticks.push({
79571
+ size: "eighth",
79572
+ height: "10%",
79573
+ x: currentX
79574
+ });
79575
+ currentX += TICK_SPACING_PX;
79576
+ }
79577
+ ticks.push({
79578
+ size: "half",
79579
+ height: "40%",
79580
+ x: currentX
79581
+ });
79582
+ currentX += TICK_SPACING_PX;
79583
+ if (remaining <= 0.5) break;
79584
+ for (let i2 = 0; i2 < 3; i2++) {
79585
+ ticks.push({
79586
+ size: "eighth",
79587
+ height: "10%",
79588
+ x: currentX
79589
+ });
79590
+ currentX += TICK_SPACING_PX;
79591
+ }
79592
+ }
79593
+ return {
79594
+ widthPx,
79595
+ heightPx,
79596
+ ticks,
79597
+ leftMarginPx: pageMargins.left * ppi,
79598
+ rightMarginPx: widthPx - pageMargins.right * ppi,
79599
+ pageWidthInches: pageSize.width
79600
+ };
79601
+ }
79602
+ function calculateMarginFromHandle(handleX, side, pageWidthPx, ppi = DEFAULT_PPI) {
79603
+ if (side === "left") {
79604
+ return handleX / ppi;
79605
+ } else {
79606
+ return (pageWidthPx - handleX) / ppi;
79607
+ }
79608
+ }
79609
+ function clampHandlePosition(handleX, side, otherHandleX, pageWidthPx, minContentWidthPx = 200) {
79610
+ if (!Number.isFinite(handleX)) {
79611
+ throw new Error(`Invalid handleX: ${handleX}. Must be a finite number.`);
79612
+ }
79613
+ if (!Number.isFinite(otherHandleX)) {
79614
+ throw new Error(`Invalid otherHandleX: ${otherHandleX}. Must be a finite number.`);
79615
+ }
79616
+ if (!Number.isFinite(pageWidthPx)) {
79617
+ throw new Error(`Invalid pageWidthPx: ${pageWidthPx}. Must be a finite number.`);
79618
+ }
79619
+ if (!Number.isFinite(minContentWidthPx)) {
79620
+ throw new Error(`Invalid minContentWidthPx: ${minContentWidthPx}. Must be a finite number.`);
79621
+ }
79622
+ if (side === "left") {
79623
+ const min2 = 0;
79624
+ const max2 = otherHandleX - minContentWidthPx;
79625
+ return Math.max(min2, Math.min(max2, handleX));
79626
+ } else {
79627
+ const min2 = otherHandleX + minContentWidthPx;
79628
+ const max2 = pageWidthPx;
79629
+ return Math.max(min2, Math.min(max2, handleX));
79630
+ }
79631
+ }
79632
+ function generateRulerDefinitionFromPx(config2) {
79633
+ const ppi = config2.ppi ?? DEFAULT_PPI;
79634
+ const heightPx = config2.heightPx ?? DEFAULT_RULER_HEIGHT;
79635
+ const { pageWidthPx, leftMarginPx, rightMarginPx } = config2;
79636
+ if (!Number.isFinite(ppi) || ppi <= 0) {
79637
+ throw new Error(`Invalid PPI: ${ppi}. Must be a positive finite number.`);
79638
+ }
79639
+ if (!Number.isFinite(pageWidthPx) || pageWidthPx <= 0) {
79640
+ throw new Error(`Invalid page width: ${pageWidthPx}px. Must be a positive finite number.`);
79641
+ }
79642
+ if (!Number.isFinite(config2.pageHeightPx) || config2.pageHeightPx <= 0) {
79643
+ throw new Error(`Invalid page height: ${config2.pageHeightPx}px. Must be a positive finite number.`);
79644
+ }
79645
+ if (!Number.isFinite(leftMarginPx) || leftMarginPx < 0) {
79646
+ throw new Error(`Invalid left margin: ${leftMarginPx}px. Must be a non-negative finite number.`);
79647
+ }
79648
+ if (!Number.isFinite(rightMarginPx) || rightMarginPx < 0) {
79649
+ throw new Error(`Invalid right margin: ${rightMarginPx}px. Must be a non-negative finite number.`);
79650
+ }
79651
+ if (leftMarginPx + rightMarginPx >= pageWidthPx) {
79652
+ throw new Error(
79653
+ `Invalid margins: left (${leftMarginPx}px) + right (${rightMarginPx}px) must be less than page width (${pageWidthPx}px).`
79654
+ );
79655
+ }
79656
+ const pageWidthInches = pageWidthPx / ppi;
79657
+ const ticks = [];
79658
+ let currentX = 0;
79659
+ for (let inch = 0; inch < pageWidthInches; inch++) {
79660
+ const remaining = pageWidthInches - inch;
79661
+ ticks.push({
79662
+ size: "main",
79663
+ height: "20%",
79664
+ label: inch,
79665
+ x: currentX
79666
+ });
79667
+ currentX += TICK_SPACING_PX;
79668
+ for (let i2 = 0; i2 < 3; i2++) {
79669
+ ticks.push({
79670
+ size: "eighth",
79671
+ height: "10%",
79672
+ x: currentX
79673
+ });
79674
+ currentX += TICK_SPACING_PX;
79675
+ }
79676
+ ticks.push({
79677
+ size: "half",
79678
+ height: "40%",
79679
+ x: currentX
79680
+ });
79681
+ currentX += TICK_SPACING_PX;
79682
+ if (remaining <= 0.5) break;
79683
+ for (let i2 = 0; i2 < 3; i2++) {
79684
+ ticks.push({
79685
+ size: "eighth",
79686
+ height: "10%",
79687
+ x: currentX
79688
+ });
79689
+ currentX += TICK_SPACING_PX;
79690
+ }
79691
+ }
79692
+ return {
79693
+ widthPx: pageWidthPx,
79694
+ heightPx,
79695
+ ticks,
79696
+ leftMarginPx,
79697
+ rightMarginPx: pageWidthPx - rightMarginPx,
79698
+ pageWidthInches
79699
+ };
79700
+ }
79701
+ const RULER_CLASS_NAMES = {
79702
+ /** Main ruler container */
79703
+ ruler: "superdoc-ruler",
79704
+ /** Tick mark element */
79705
+ tick: "superdoc-ruler-tick",
79706
+ /** Main (inch) tick */
79707
+ tickMain: "superdoc-ruler-tick--main",
79708
+ /** Half-inch tick */
79709
+ tickHalf: "superdoc-ruler-tick--half",
79710
+ /** Eighth-inch tick */
79711
+ tickEighth: "superdoc-ruler-tick--eighth",
79712
+ /** Inch label number */
79713
+ label: "superdoc-ruler-label",
79714
+ /** Margin handle */
79715
+ handle: "superdoc-ruler-handle",
79716
+ /** Left margin handle */
79717
+ handleLeft: "superdoc-ruler-handle--left",
79718
+ /** Right margin handle */
79719
+ handleRight: "superdoc-ruler-handle--right",
79720
+ /** Vertical indicator line during drag */
79721
+ indicator: "superdoc-ruler-indicator"
79722
+ };
79723
+ function createRulerElement(options) {
79724
+ const { definition: definition2, doc: doc2, interactive = false } = options;
79725
+ if (!Number.isFinite(definition2.widthPx) || definition2.widthPx <= 0) {
79726
+ console.warn(`[createRulerElement] Invalid ruler width: ${definition2.widthPx}px. Using minimum width of 1px.`);
79727
+ definition2.widthPx = Math.max(1, definition2.widthPx || 1);
79728
+ }
79729
+ if (!definition2.ticks || definition2.ticks.length === 0) {
79730
+ console.warn("[createRulerElement] Ruler definition has no ticks. Ruler will be empty.");
79731
+ }
79732
+ const ruler = doc2.createElement("div");
79733
+ ruler.className = RULER_CLASS_NAMES.ruler;
79734
+ ruler.style.cssText = `
79735
+ position: relative;
79736
+ width: ${definition2.widthPx}px;
79737
+ height: ${definition2.heightPx}px;
79738
+ display: flex;
79739
+ align-items: flex-end;
79740
+ box-sizing: border-box;
79741
+ user-select: none;
79742
+ pointer-events: ${interactive ? "auto" : "none"};
79743
+ `;
79744
+ for (const tick of definition2.ticks) {
79745
+ const tickEl = createTickElement(tick, doc2);
79746
+ ruler.appendChild(tickEl);
79747
+ }
79748
+ if (interactive) {
79749
+ const leftHandle = createHandleElement("left", definition2.leftMarginPx, doc2, options);
79750
+ const rightHandle = createHandleElement("right", definition2.rightMarginPx, doc2, options);
79751
+ ruler.appendChild(leftHandle);
79752
+ ruler.appendChild(rightHandle);
79753
+ }
79754
+ return ruler;
79755
+ }
79756
+ function createTickElement(tick, doc2) {
79757
+ const el = doc2.createElement("div");
79758
+ const sizeClass = tick.size === "main" ? RULER_CLASS_NAMES.tickMain : tick.size === "half" ? RULER_CLASS_NAMES.tickHalf : RULER_CLASS_NAMES.tickEighth;
79759
+ el.className = `${RULER_CLASS_NAMES.tick} ${sizeClass}`;
79760
+ el.style.cssText = `
79761
+ position: absolute;
79762
+ left: ${tick.x}px;
79763
+ bottom: 0;
79764
+ width: 1px;
79765
+ height: ${tick.height};
79766
+ background-color: #666;
79767
+ pointer-events: none;
79768
+ `;
79769
+ if (tick.label !== void 0) {
79770
+ const label = doc2.createElement("span");
79771
+ label.className = RULER_CLASS_NAMES.label;
79772
+ label.textContent = String(tick.label);
79773
+ label.style.cssText = `
79774
+ position: absolute;
79775
+ top: -16px;
79776
+ left: -2px;
79777
+ font-size: 10px;
79778
+ color: #666;
79779
+ pointer-events: none;
79780
+ user-select: none;
79781
+ `;
79782
+ el.appendChild(label);
79783
+ }
79784
+ return el;
79785
+ }
79786
+ function createHandleElement(side, x2, doc2, options) {
79787
+ const handle2 = doc2.createElement("div");
79788
+ const sideClass = side === "left" ? RULER_CLASS_NAMES.handleLeft : RULER_CLASS_NAMES.handleRight;
79789
+ handle2.className = `${RULER_CLASS_NAMES.handle} ${sideClass}`;
79790
+ handle2.dataset.side = side;
79791
+ handle2.style.cssText = `
79792
+ position: absolute;
79793
+ left: ${x2}px;
79794
+ top: 0;
79795
+ width: 5px;
79796
+ height: 20px;
79797
+ margin-left: -2px;
79798
+ background-color: #ccc;
79799
+ border-radius: 4px 4px 0 0;
79800
+ cursor: grab;
79801
+ transition: background-color 150ms ease;
79802
+ z-index: 10;
79803
+ `;
79804
+ handle2.addEventListener("mouseenter", () => {
79805
+ if (!handle2.dataset.dragging) {
79806
+ handle2.style.backgroundColor = "rgba(37, 99, 235, 0.4)";
79807
+ }
79808
+ });
79809
+ handle2.addEventListener("mouseleave", () => {
79810
+ if (!handle2.dataset.dragging) {
79811
+ handle2.style.backgroundColor = "#ccc";
79812
+ }
79813
+ });
79814
+ if (options.onDragStart || options.onDrag || options.onDragEnd) {
79815
+ setupHandleDrag(handle2, side, options);
79816
+ }
79817
+ return handle2;
79818
+ }
79819
+ function setupHandleDrag(handle2, side, options) {
79820
+ let offsetX = 0;
79821
+ const onPointerDown = (event) => {
79822
+ event.preventDefault();
79823
+ handle2.dataset.dragging = "true";
79824
+ handle2.style.backgroundColor = "rgba(37, 99, 235, 0.4)";
79825
+ handle2.style.cursor = "grabbing";
79826
+ const rect = handle2.getBoundingClientRect();
79827
+ offsetX = event.clientX - rect.left - rect.width / 2;
79828
+ handle2.setPointerCapture(event.pointerId);
79829
+ options.onDragStart?.(side, event);
79830
+ };
79831
+ const onPointerMove = (event) => {
79832
+ if (handle2.dataset.dragging !== "true") return;
79833
+ const ruler = handle2.parentElement;
79834
+ if (!ruler) return;
79835
+ const rulerRect = ruler.getBoundingClientRect();
79836
+ const newX = event.clientX - rulerRect.left - offsetX;
79837
+ options.onDrag?.(side, newX, event);
79838
+ };
79839
+ const onPointerUp = (event) => {
79840
+ if (handle2.dataset.dragging !== "true") return;
79841
+ handle2.dataset.dragging = "";
79842
+ handle2.style.backgroundColor = "#ccc";
79843
+ handle2.style.cursor = "grab";
79844
+ handle2.releasePointerCapture(event.pointerId);
79845
+ const ruler = handle2.parentElement;
79846
+ if (!ruler) return;
79847
+ const rulerRect = ruler.getBoundingClientRect();
79848
+ const finalX = event.clientX - rulerRect.left - offsetX;
79849
+ options.onDragEnd?.(side, finalX, event);
79850
+ };
79851
+ handle2.addEventListener("pointerdown", onPointerDown);
79852
+ handle2.addEventListener("pointermove", onPointerMove);
79853
+ handle2.addEventListener("pointerup", onPointerUp);
79854
+ handle2.addEventListener("pointercancel", onPointerUp);
79855
+ }
79856
+ const RULER_STYLES = `
79857
+ /* Ruler container */
79858
+ .${RULER_CLASS_NAMES.ruler} {
79859
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
79860
+ background-color: transparent;
79861
+ }
79862
+
79863
+ /* Tick marks base styling */
79864
+ .${RULER_CLASS_NAMES.tick} {
79865
+ flex-shrink: 0;
79866
+ }
79867
+
79868
+ /* Handle hover and active states */
79869
+ .${RULER_CLASS_NAMES.handle}:hover {
79870
+ background-color: rgba(37, 99, 235, 0.4) !important;
79871
+ }
79872
+
79873
+ .${RULER_CLASS_NAMES.handle}:active,
79874
+ .${RULER_CLASS_NAMES.handle}[data-dragging="true"] {
79875
+ background-color: rgba(37, 99, 235, 0.6) !important;
79876
+ cursor: grabbing !important;
79877
+ }
79878
+
79879
+ /* Vertical indicator animation */
79880
+ .${RULER_CLASS_NAMES.indicator} {
79881
+ transition: left 16ms linear;
79882
+ }
79883
+
79884
+ /* Print mode: hide rulers */
79885
+ @media print {
79886
+ .${RULER_CLASS_NAMES.ruler} {
79887
+ display: none !important;
79888
+ }
79889
+ }
79890
+
79891
+ /* High contrast mode support */
79892
+ @media (prefers-contrast: high) {
79893
+ .${RULER_CLASS_NAMES.tick} {
79894
+ background-color: #000 !important;
79895
+ }
79896
+
79897
+ .${RULER_CLASS_NAMES.label} {
79898
+ color: #000 !important;
79899
+ }
79900
+
79901
+ .${RULER_CLASS_NAMES.handle} {
79902
+ background-color: #666 !important;
79903
+ border: 1px solid #000;
79904
+ }
79905
+
79906
+ .${RULER_CLASS_NAMES.handle}:hover,
79907
+ .${RULER_CLASS_NAMES.handle}:active {
79908
+ background-color: #0066cc !important;
79909
+ }
79910
+ }
79911
+
79912
+ /* Reduced motion support */
79913
+ @media (prefers-reduced-motion: reduce) {
79914
+ .${RULER_CLASS_NAMES.handle} {
79915
+ transition: none !important;
79916
+ }
79917
+
79918
+ .${RULER_CLASS_NAMES.indicator} {
79919
+ transition: none !important;
79920
+ }
79921
+ }
79922
+ `;
79923
+ let rulerStylesInjected = false;
79924
+ function ensureRulerStyles(doc2) {
79925
+ if (rulerStylesInjected || !doc2) return;
79926
+ const styleEl = doc2.createElement("style");
79927
+ styleEl.setAttribute("data-superdoc-ruler-styles", "true");
79928
+ styleEl.textContent = RULER_STYLES;
79929
+ doc2.head?.appendChild(styleEl);
79930
+ rulerStylesInjected = true;
79931
+ }
79418
79932
  function isMinimalWordLayout(value) {
79419
79933
  if (typeof value !== "object" || value === null) {
79420
79934
  return false;
@@ -79461,6 +79975,7 @@ ${l}
79461
79975
  }
79462
79976
  const LIST_MARKER_GAP$1 = 8;
79463
79977
  const DEFAULT_TAB_INTERVAL_PX$1 = 48;
79978
+ const DEFAULT_PAGE_HEIGHT_PX = 1056;
79464
79979
  const COMMENT_EXTERNAL_COLOR = "#B1124B";
79465
79980
  const COMMENT_INTERNAL_COLOR = "#078383";
79466
79981
  const COMMENT_INACTIVE_ALPHA = "22";
@@ -79703,6 +80218,9 @@ ${l}
79703
80218
  ensureFieldAnnotationStyles(doc2);
79704
80219
  ensureSdtContainerStyles(doc2);
79705
80220
  ensureImageSelectionStyles(doc2);
80221
+ if (this.options.ruler?.enabled) {
80222
+ ensureRulerStyles(doc2);
80223
+ }
79706
80224
  mount2.classList.add(CLASS_NAMES$1.container);
79707
80225
  if (this.mount && this.mount !== mount2) {
79708
80226
  this.resetState();
@@ -79960,6 +80478,12 @@ ${l}
79960
80478
  const el = this.doc.createElement("div");
79961
80479
  el.classList.add(CLASS_NAMES$1.page);
79962
80480
  applyStyles$2(el, pageStyles(width, height, this.getEffectivePageStyles()));
80481
+ if (this.options.ruler?.enabled) {
80482
+ const rulerEl = this.renderPageRuler(width, page);
80483
+ if (rulerEl) {
80484
+ el.appendChild(rulerEl);
80485
+ }
80486
+ }
79963
80487
  const contextBase = {
79964
80488
  pageNumber: page.number,
79965
80489
  totalPages: this.totalPages,
@@ -79972,6 +80496,70 @@ ${l}
79972
80496
  this.renderDecorationsForPage(el, page);
79973
80497
  return el;
79974
80498
  }
80499
+ /**
80500
+ * Render a ruler element for a page.
80501
+ *
80502
+ * Creates a horizontal ruler with tick marks and optional interactive margin handles.
80503
+ * The ruler is positioned at the top of the page and displays inch measurements.
80504
+ *
80505
+ * @param pageWidthPx - Page width in pixels
80506
+ * @param page - Page data containing margins and optional size information
80507
+ * @returns Ruler element, or null if this.doc is unavailable or page margins are missing
80508
+ *
80509
+ * Side effects:
80510
+ * - Creates DOM elements and applies inline styles
80511
+ * - May invoke the onMarginChange callback if interactive mode is enabled
80512
+ *
80513
+ * Fallback behavior:
80514
+ * - Uses DEFAULT_PAGE_HEIGHT_PX (1056px = 11 inches) if page.size.h is not available
80515
+ * - Defaults margins to 0 if not explicitly provided
80516
+ */
80517
+ renderPageRuler(pageWidthPx, page) {
80518
+ if (!this.doc) {
80519
+ console.warn("[renderPageRuler] Cannot render ruler: document is not available.");
80520
+ return null;
80521
+ }
80522
+ if (!page.margins) {
80523
+ console.warn(`[renderPageRuler] Cannot render ruler for page ${page.number}: margins not available.`);
80524
+ return null;
80525
+ }
80526
+ const margins = page.margins;
80527
+ const leftMargin = margins.left ?? 0;
80528
+ const rightMargin = margins.right ?? 0;
80529
+ try {
80530
+ const rulerDefinition = generateRulerDefinitionFromPx({
80531
+ pageWidthPx,
80532
+ pageHeightPx: page.size?.h ?? DEFAULT_PAGE_HEIGHT_PX,
80533
+ leftMarginPx: leftMargin,
80534
+ rightMarginPx: rightMargin
80535
+ });
80536
+ const interactive = this.options.ruler?.interactive ?? false;
80537
+ const onMarginChange = this.options.ruler?.onMarginChange;
80538
+ const rulerEl = createRulerElement({
80539
+ definition: rulerDefinition,
80540
+ doc: this.doc,
80541
+ interactive,
80542
+ onDragEnd: interactive && onMarginChange ? (side, x2) => {
80543
+ try {
80544
+ const ppi = 96;
80545
+ const marginInches = side === "left" ? x2 / ppi : (pageWidthPx - x2) / ppi;
80546
+ onMarginChange(side, marginInches);
80547
+ } catch (error) {
80548
+ console.error("[renderPageRuler] Error in onMarginChange callback:", error);
80549
+ }
80550
+ } : void 0
80551
+ });
80552
+ rulerEl.style.position = "absolute";
80553
+ rulerEl.style.top = "0";
80554
+ rulerEl.style.left = "0";
80555
+ rulerEl.style.zIndex = "20";
80556
+ rulerEl.dataset.pageNumber = String(page.number);
80557
+ return rulerEl;
80558
+ } catch (error) {
80559
+ console.error(`[renderPageRuler] Failed to create ruler for page ${page.number}:`, error);
80560
+ return null;
80561
+ }
80562
+ }
79975
80563
  renderDecorationsForPage(pageEl, page) {
79976
80564
  this.renderDecorationSection(pageEl, page, "header");
79977
80565
  this.renderDecorationSection(pageEl, page, "footer");
@@ -80003,6 +80591,7 @@ ${l}
80003
80591
  container.style.height = `${data.height}px`;
80004
80592
  container.style.top = `${Math.max(0, offset2)}px`;
80005
80593
  container.style.zIndex = "1";
80594
+ container.style.overflow = "visible";
80006
80595
  let footerYOffset = 0;
80007
80596
  if (kind === "footer" && data.fragments.length > 0) {
80008
80597
  const contentHeight = typeof data.contentHeight === "number" ? data.contentHeight : data.fragments.reduce((max2, f2) => {
@@ -82772,7 +83361,8 @@ ${l}
82772
83361
  layoutMode: options.layoutMode,
82773
83362
  headerProvider: options.headerProvider,
82774
83363
  footerProvider: options.footerProvider,
82775
- virtualization: options.virtualization
83364
+ virtualization: options.virtualization,
83365
+ ruler: options.ruler
82776
83366
  });
82777
83367
  return {
82778
83368
  paint(layout, mount2) {
@@ -89014,7 +89604,14 @@ ${l}
89014
89604
  leftJustifiedMarkerSpace = markerBoxWidth + gutterWidth;
89015
89605
  }
89016
89606
  }
89017
- const initialAvailableWidth = Math.max(1, contentWidth - firstLineOffset - leftJustifiedMarkerSpace);
89607
+ let initialAvailableWidth;
89608
+ const isFirstLineIndentMode = wordLayout?.firstLineIndentMode === true;
89609
+ const textStartPx = wordLayout?.textStartPx;
89610
+ if (isFirstLineIndentMode && typeof textStartPx === "number" && textStartPx > 0) {
89611
+ initialAvailableWidth = Math.max(1, maxWidth - textStartPx - indentRight);
89612
+ } else {
89613
+ initialAvailableWidth = Math.max(1, contentWidth - firstLineOffset - leftJustifiedMarkerSpace);
89614
+ }
89018
89615
  const tabStops = buildTabStopsPx(
89019
89616
  indent2,
89020
89617
  block.attrs?.tabs,
@@ -90990,7 +91587,9 @@ ${l}
90990
91587
  const batch2 = {};
90991
91588
  let hasBlocks = false;
90992
91589
  descriptors.forEach((descriptor) => {
90993
- if (!descriptor.variant) return;
91590
+ if (!descriptor.variant) {
91591
+ return;
91592
+ }
90994
91593
  const blocks2 = __privateMethod$1(this, _HeaderFooterLayoutAdapter_instances, getBlocks_fn).call(this, descriptor);
90995
91594
  if (blocks2 && blocks2.length > 0) {
90996
91595
  batch2[descriptor.variant] = blocks2;
@@ -93300,9 +93899,11 @@ ${l}
93300
93899
  if (typeof provider2.awareness.setLocalStateField !== "function") {
93301
93900
  return;
93302
93901
  }
93303
- const ystate = ySyncPluginKey.getState(__privateGet$1(this, _editor3).state);
93902
+ const editorState = __privateGet$1(this, _editor3)?.state;
93903
+ if (!editorState) return;
93904
+ const ystate = ySyncPluginKey.getState(editorState);
93304
93905
  if (!ystate?.binding?.mapping) return;
93305
- const { selection } = __privateGet$1(this, _editor3).state;
93906
+ const { selection } = editorState;
93306
93907
  const { anchor, head } = selection;
93307
93908
  try {
93308
93909
  const relAnchor = absolutePositionToRelativePosition(anchor, ystate.type, ystate.binding.mapping);
@@ -93320,7 +93921,9 @@ ${l}
93320
93921
  normalizeAwarenessStates_fn = function() {
93321
93922
  const provider2 = __privateGet$1(this, _options).collaborationProvider;
93322
93923
  if (!provider2?.awareness) return /* @__PURE__ */ new Map();
93323
- const ystate = ySyncPluginKey.getState(__privateGet$1(this, _editor3).state);
93924
+ const editorState = __privateGet$1(this, _editor3)?.state;
93925
+ if (!editorState) return /* @__PURE__ */ new Map();
93926
+ const ystate = ySyncPluginKey.getState(editorState);
93324
93927
  if (!ystate) return /* @__PURE__ */ new Map();
93325
93928
  const states = provider2.awareness?.getStates();
93326
93929
  const normalized = /* @__PURE__ */ new Map();
@@ -94113,7 +94716,8 @@ ${l}
94113
94716
  virtualization: __privateGet$1(this, _layoutOptions).virtualization,
94114
94717
  pageStyles: __privateGet$1(this, _layoutOptions).pageStyles,
94115
94718
  headerProvider: __privateGet$1(this, _headerDecorationProvider),
94116
- footerProvider: __privateGet$1(this, _footerDecorationProvider)
94719
+ footerProvider: __privateGet$1(this, _footerDecorationProvider),
94720
+ ruler: __privateGet$1(this, _layoutOptions).ruler
94117
94721
  }));
94118
94722
  }
94119
94723
  return __privateGet$1(this, _domPainter);
@@ -94252,14 +94856,20 @@ ${l}
94252
94856
  const margins = __privateGet$1(this, _layoutOptions).margins ?? DEFAULT_MARGINS;
94253
94857
  const marginLeft = margins.left ?? DEFAULT_MARGINS.left;
94254
94858
  const marginRight = margins.right ?? DEFAULT_MARGINS.right;
94255
- const width = pageSize.w - (marginLeft + marginRight);
94256
- if (!Number.isFinite(width) || width <= 0) {
94859
+ const bodyContentWidth = pageSize.w - (marginLeft + marginRight);
94860
+ if (!Number.isFinite(bodyContentWidth) || bodyContentWidth <= 0) {
94257
94861
  return null;
94258
94862
  }
94259
- const { headerSpace, footerSpace } = extractHeaderFooterSpace(margins);
94260
- const height = Math.max(headerSpace, footerSpace, 1);
94863
+ const measurementWidth = bodyContentWidth;
94864
+ const marginTop = margins.top ?? DEFAULT_MARGINS.top;
94865
+ const marginBottom = margins.bottom ?? DEFAULT_MARGINS.bottom;
94866
+ const headerMargin = margins.header ?? 0;
94867
+ const footerMargin = margins.footer ?? 0;
94868
+ const headerContentSpace = Math.max(marginTop - headerMargin, 0);
94869
+ const footerContentSpace = Math.max(marginBottom - footerMargin, 0);
94870
+ const height = Math.max(headerContentSpace, footerContentSpace, 1);
94261
94871
  return {
94262
- width,
94872
+ width: measurementWidth,
94263
94873
  height,
94264
94874
  // Pass actual page dimensions for page-relative anchor positioning in headers/footers
94265
94875
  pageWidth: pageSize.w,
@@ -128199,6 +128809,7 @@ ${style2}
128199
128809
  */
128200
128810
  toggleRuler: () => {
128201
128811
  this.superdoc.toggleRuler();
128812
+ this.updateToolbarState();
128202
128813
  },
128203
128814
  /**
128204
128815
  * Initiates the image upload process
@@ -128624,6 +129235,13 @@ ${style2}
128624
129235
  item.activate();
128625
129236
  }
128626
129237
  }
129238
+ if (item.name.value === "ruler") {
129239
+ if (this.superdoc?.config?.rulers) {
129240
+ item.activate();
129241
+ } else {
129242
+ item.deactivate();
129243
+ }
129244
+ }
128627
129245
  });
128628
129246
  }
128629
129247
  /**
@@ -130057,8 +130675,12 @@ ${style2}
130057
130675
  };
130058
130676
  }
130059
130677
  };
130060
- const _hoisted_1$4$1 = { class: "numbering" };
130678
+ const _hoisted_1$4$1 = {
130679
+ key: 0,
130680
+ class: "numbering"
130681
+ };
130061
130682
  const MIN_WIDTH = 200;
130683
+ const PPI = 96;
130062
130684
  const alignment = "flex-end";
130063
130685
  const _sfc_main$6$1 = {
130064
130686
  __name: "Ruler",
@@ -130081,7 +130703,7 @@ ${style2}
130081
130703
  const emit2 = __emit;
130082
130704
  const props = __props;
130083
130705
  const ruler = ref(null);
130084
- const rulerDefinition = ref([]);
130706
+ const rulerDefinition = ref(null);
130085
130707
  const rulerHandleOriginalColor = ref("#CCCCCC");
130086
130708
  const rulerHandleActiveColor = ref("#2563EB66");
130087
130709
  const pageSize = ref(null);
@@ -130094,45 +130716,32 @@ ${style2}
130094
130716
  const initialX = ref(0);
130095
130717
  let offsetX = 0;
130096
130718
  const initRuler = () => {
130097
- if (props.editor.options.mode !== "docx") return;
130098
- const rulerItems = [];
130719
+ if (props.editor.options.mode !== "docx") return null;
130099
130720
  const { pageMargins: docMargins, pageSize: docSize } = props.editor.getPageStyles();
130100
130721
  pageSize.value = docSize;
130101
130722
  pageMargins.value = docMargins;
130102
- rightHandle.x = docSize.width * 96 - docMargins.right * 96;
130103
- leftHandle.x = docMargins.left * 96;
130104
- for (let i2 = 0; i2 < docSize.width; i2++) {
130105
- const marginNum = 0.0625 * 96 - 0.5;
130106
- const margin = `${marginNum}px`;
130107
- const diff = docSize.width - i2;
130108
- rulerItems.push(...generateSection(1, "main", "20%", margin, i2));
130109
- rulerItems.push(...generateSection(3, "eighth", "10%", margin));
130110
- rulerItems.push(...generateSection(1, "half", "40%", margin));
130111
- if (diff <= 0.5) break;
130112
- rulerItems.push(...generateSection(3, "eighth", "10%", margin));
130113
- }
130114
- return rulerItems;
130115
- };
130116
- const generateSection = (qty, size2, height, margin, index2) => {
130117
- return Array.from({ length: qty }, (_2, i2) => {
130118
- const item = {
130119
- className: `${size2}-unit ruler-section`,
130120
- height,
130121
- margin
130122
- };
130123
- if (index2 !== void 0) item.numbering = index2;
130124
- return item;
130723
+ const definition2 = generateRulerDefinition({
130724
+ pageSize: { width: docSize.width, height: docSize.height },
130725
+ pageMargins: {
130726
+ left: docMargins.left,
130727
+ right: docMargins.right,
130728
+ top: docMargins.top ?? 1,
130729
+ bottom: docMargins.bottom ?? 1
130730
+ }
130125
130731
  });
130732
+ leftHandle.x = definition2.leftMarginPx;
130733
+ rightHandle.x = definition2.rightMarginPx;
130734
+ return definition2;
130126
130735
  };
130127
- const getStyle = computed(() => (unit) => {
130736
+ const getTickStyle = computed(() => (tick) => {
130128
130737
  return {
130738
+ position: "absolute",
130739
+ left: `${tick.x}px`,
130740
+ bottom: "0",
130129
130741
  width: "1px",
130130
- minWidth: "1px",
130131
- maxWidth: "1px",
130132
- height: unit.height,
130133
- backgroundColor: unit.color || "#666",
130134
- marginLeft: unit.numbering === 0 ? null : unit.margin,
130135
- marginRight: unit.margin
130742
+ height: tick.height,
130743
+ backgroundColor: "#666",
130744
+ pointerEvents: "none"
130136
130745
  };
130137
130746
  });
130138
130747
  const getHandlePosition = computed(() => (side) => {
@@ -130144,7 +130753,8 @@ ${style2}
130144
130753
  const getVerticalIndicatorStyle = computed(() => {
130145
130754
  if (!ruler.value) return;
130146
130755
  const parentElement = ruler.value.parentElement;
130147
- const editor = parentElement.querySelector(".super-editor");
130756
+ const editor = parentElement?.querySelector(".super-editor") ?? document.querySelector(".super-editor");
130757
+ if (!editor) return { left: `${currentHandle.value.x}px`, minHeight: "100%" };
130148
130758
  const editorBounds = editor.getBoundingClientRect();
130149
130759
  return {
130150
130760
  left: `${currentHandle.value.x}px`,
@@ -130161,22 +130771,11 @@ ${style2}
130161
130771
  showVerticalIndicator.value = true;
130162
130772
  };
130163
130773
  const handleMouseMove2 = (event) => {
130164
- if (!isDragging.value) return;
130774
+ if (!isDragging.value || !pageSize.value) return;
130165
130775
  const newLeft = event.clientX - offsetX;
130166
- currentHandle.value.x = newLeft;
130167
- if (currentHandle.value.side === "left") {
130168
- if (newLeft <= 0) {
130169
- currentHandle.value.x = 0;
130170
- } else if (newLeft >= rightHandle.x - MIN_WIDTH) {
130171
- currentHandle.value.x = rightHandle.x - MIN_WIDTH;
130172
- }
130173
- } else {
130174
- if (newLeft >= pageSize.value.width * 96) {
130175
- currentHandle.value.x = pageSize.value.width * 96;
130176
- } else if (newLeft <= leftHandle.x + MIN_WIDTH) {
130177
- currentHandle.value.x = leftHandle.x + MIN_WIDTH;
130178
- }
130179
- }
130776
+ const pageWidthPx = pageSize.value.width * PPI;
130777
+ const otherHandleX = currentHandle.value.side === "left" ? rightHandle.x : leftHandle.x;
130778
+ currentHandle.value.x = clampHandlePosition(newLeft, currentHandle.value.side, otherHandleX, pageWidthPx, MIN_WIDTH);
130180
130779
  };
130181
130780
  const handleMouseUp = () => {
130182
130781
  isDragging.value = false;
@@ -130197,14 +130796,17 @@ ${style2}
130197
130796
  rulerHandleOriginalColor.value = "#CCC";
130198
130797
  };
130199
130798
  const getNewMarginValue = () => {
130200
- if (currentHandle.value.side === "left") return currentHandle.value.x / 96;
130201
- else return (pageSize.value.width * 96 - currentHandle.value.x) / 96;
130799
+ if (!pageSize.value) return 0;
130800
+ const pageWidthPx = pageSize.value.width * PPI;
130801
+ return calculateMarginFromHandle(currentHandle.value.x, currentHandle.value.side, pageWidthPx, PPI);
130202
130802
  };
130203
130803
  const getStyleVars = computed(() => {
130804
+ const width = rulerDefinition.value?.widthPx ?? pageSize.value?.width * PPI ?? 816;
130204
130805
  return {
130205
130806
  "--alignment": alignment,
130206
130807
  "--ruler-handle-color": rulerHandleOriginalColor.value,
130207
- "--ruler-handle-active-color": rulerHandleActiveColor.value
130808
+ "--ruler-handle-active-color": rulerHandleActiveColor.value,
130809
+ "--ruler-width": `${width}px`
130208
130810
  };
130209
130811
  });
130210
130812
  onMounted(() => {
@@ -130240,32 +130842,20 @@ ${style2}
130240
130842
  class: "vertical-indicator",
130241
130843
  style: normalizeStyle(getVerticalIndicatorStyle.value)
130242
130844
  }, null, 4)) : createCommentVNode("", true),
130243
- (openBlock(true), createElementBlock(Fragment, null, renderList(rulerDefinition.value, (unit) => {
130845
+ rulerDefinition.value ? (openBlock(true), createElementBlock(Fragment, { key: 1 }, renderList(rulerDefinition.value.ticks, (tick, index2) => {
130244
130846
  return openBlock(), createElementBlock("div", {
130245
- class: normalizeClass(unit.className),
130246
- style: normalizeStyle(getStyle.value(unit))
130847
+ key: index2,
130848
+ class: normalizeClass(["ruler-tick", `ruler-tick--${tick.size}`]),
130849
+ style: normalizeStyle(getTickStyle.value(tick))
130247
130850
  }, [
130248
- createBaseVNode("div", _hoisted_1$4$1, toDisplayString(unit.numbering), 1),
130249
- (openBlock(true), createElementBlock(Fragment, null, renderList(unit.elements, (half) => {
130250
- return openBlock(), createElementBlock("div", {
130251
- class: normalizeClass(half.className),
130252
- style: normalizeStyle(getStyle.value(half))
130253
- }, [
130254
- (openBlock(true), createElementBlock(Fragment, null, renderList(half.elements, (quarter) => {
130255
- return openBlock(), createElementBlock("div", {
130256
- class: normalizeClass(quarter.className),
130257
- style: normalizeStyle(getStyle.value(quarter))
130258
- }, null, 6);
130259
- }), 256))
130260
- ], 6);
130261
- }), 256))
130851
+ tick.label !== void 0 ? (openBlock(), createElementBlock("span", _hoisted_1$4$1, toDisplayString(tick.label), 1)) : createCommentVNode("", true)
130262
130852
  ], 6);
130263
- }), 256))
130853
+ }), 128)) : createCommentVNode("", true)
130264
130854
  ], 4);
130265
130855
  };
130266
130856
  }
130267
130857
  };
130268
- const Ruler = /* @__PURE__ */ _export_sfc$1(_sfc_main$6$1, [["__scopeId", "data-v-79f9a944"]]);
130858
+ const Ruler = /* @__PURE__ */ _export_sfc$1(_sfc_main$6$1, [["__scopeId", "data-v-b9f4f30a"]]);
130269
130859
  const _sfc_main$5$1 = {
130270
130860
  __name: "GenericPopover",
130271
130861
  props: {
@@ -131446,7 +132036,7 @@ ${style2}
131446
132036
  const BlankDOCX$1 = "data:application/octet-stream;base64,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";
131447
132037
  const _hoisted_1$1$1 = { class: "super-editor-container" };
131448
132038
  const _hoisted_2$a = {
131449
- key: 1,
132039
+ key: 2,
131450
132040
  class: "placeholder-editor"
131451
132041
  };
131452
132042
  const _hoisted_3$8 = { class: "placeholder-title" };
@@ -131491,6 +132081,19 @@ ${style2}
131491
132081
  const active = activeEditor.value;
131492
132082
  return active?.options ? Boolean(active.options.disableContextMenu) : Boolean(props.options.disableContextMenu);
131493
132083
  });
132084
+ const rulersVisible = ref(Boolean(props.options.rulers));
132085
+ watch(
132086
+ () => props.options,
132087
+ (newOptions) => {
132088
+ const rulers = newOptions?.rulers;
132089
+ if (rulers && typeof rulers === "object" && "value" in rulers) {
132090
+ rulersVisible.value = Boolean(rulers.value);
132091
+ } else {
132092
+ rulersVisible.value = Boolean(rulers);
132093
+ }
132094
+ },
132095
+ { immediate: true, deep: true }
132096
+ );
131494
132097
  const message = useMessage();
131495
132098
  const editorWrapper = ref(null);
131496
132099
  const editorElem = ref(null);
@@ -131903,8 +132506,17 @@ ${style2}
131903
132506
  });
131904
132507
  return (_ctx, _cache) => {
131905
132508
  return openBlock(), createElementBlock("div", _hoisted_1$1$1, [
131906
- __props.options.rulers && !!activeEditor.value ? (openBlock(), createBlock(Ruler, {
132509
+ __props.options.rulerContainer && rulersVisible.value && !!activeEditor.value ? (openBlock(), createBlock(Teleport, {
131907
132510
  key: 0,
132511
+ to: __props.options.rulerContainer
132512
+ }, [
132513
+ createVNode(Ruler, {
132514
+ class: "ruler superdoc-ruler",
132515
+ editor: activeEditor.value,
132516
+ onMarginChange: handleMarginChange
132517
+ }, null, 8, ["editor"])
132518
+ ], 8, ["to"])) : rulersVisible.value && !!activeEditor.value ? (openBlock(), createBlock(Ruler, {
132519
+ key: 1,
131908
132520
  class: "ruler",
131909
132521
  editor: activeEditor.value,
131910
132522
  onMarginChange: handleMarginChange
@@ -131998,7 +132610,7 @@ ${style2}
131998
132610
  })
131999
132611
  ])) : createCommentVNode("", true),
132000
132612
  activeEditor.value ? (openBlock(), createBlock(GenericPopover, {
132001
- key: 2,
132613
+ key: 3,
132002
132614
  editor: activeEditor.value,
132003
132615
  visible: popoverControls.visible,
132004
132616
  position: popoverControls.position,
@@ -132013,7 +132625,7 @@ ${style2}
132013
132625
  };
132014
132626
  }
132015
132627
  });
132016
- const SuperEditor = /* @__PURE__ */ _export_sfc$1(_sfc_main$1$1, [["__scopeId", "data-v-a935d3e2"]]);
132628
+ const SuperEditor = /* @__PURE__ */ _export_sfc$1(_sfc_main$1$1, [["__scopeId", "data-v-cb3fe66f"]]);
132017
132629
  const _hoisted_1$h = ["innerHTML"];
132018
132630
  const _sfc_main$i = {
132019
132631
  __name: "SuperInput",
@@ -148624,6 +149236,7 @@ ${style2}
148624
149236
  markdown: doc2.markdown,
148625
149237
  documentMode: proxy.$superdoc.config.documentMode,
148626
149238
  rulers: doc2.rulers,
149239
+ rulerContainer: proxy.$superdoc.config.rulerContainer,
148627
149240
  isInternal: proxy.$superdoc.config.isInternal,
148628
149241
  annotations: proxy.$superdoc.config.annotations,
148629
149242
  isCommentsEnabled: Boolean(commentsModuleConfig.value),
@@ -148999,7 +149612,7 @@ ${style2}
148999
149612
  "file-source": doc2.data,
149000
149613
  state: doc2.state,
149001
149614
  "document-id": doc2.id,
149002
- options: editorOptions(doc2),
149615
+ options: { ...editorOptions(doc2), rulers: doc2.rulers },
149003
149616
  onEditorReady,
149004
149617
  onPageMarginsChange: ($event) => handleSuperEditorPageMarginsChange(doc2, $event)
149005
149618
  }, null, 8, ["file-source", "state", "document-id", "options", "onPageMarginsChange"])) : createCommentVNode("", true)
@@ -149052,7 +149665,7 @@ ${style2}
149052
149665
  };
149053
149666
  }
149054
149667
  };
149055
- const App = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-5b2a75a6"]]);
149668
+ const App = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-e229774d"]]);
149056
149669
  const createSuperdocVueApp = () => {
149057
149670
  const app = createApp(App);
149058
149671
  const pinia = createPinia();
@@ -149232,7 +149845,7 @@ ${style2}
149232
149845
  this.config.colors = shuffleArray(this.config.colors);
149233
149846
  this.userColorMap = /* @__PURE__ */ new Map();
149234
149847
  this.colorIndex = 0;
149235
- this.version = "1.0.0-beta.60";
149848
+ this.version = "1.0.0-beta.62";
149236
149849
  this.#log("🦋 [superdoc] Using SuperDoc version:", this.version);
149237
149850
  this.superdocId = config2.superdocId || v4();
149238
149851
  this.colors = this.config.colors;
@@ -149573,6 +150186,10 @@ ${style2}
149573
150186
  const moduleConfig = this.config.modules?.toolbar || {};
149574
150187
  this.toolbarElement = this.config.modules?.toolbar?.selector || this.config.toolbar;
149575
150188
  this.toolbar = null;
150189
+ const excludeItems = [...moduleConfig.excludeItems || []];
150190
+ if (!this.config.rulers) {
150191
+ excludeItems.push("ruler");
150192
+ }
149576
150193
  const config2 = {
149577
150194
  selector: this.toolbarElement || null,
149578
150195
  isDev: this.isDev || false,
@@ -149587,7 +150204,9 @@ ${style2}
149587
150204
  superdoc: this,
149588
150205
  aiApiKey: this.config.modules?.ai?.apiKey,
149589
150206
  aiEndpoint: this.config.modules?.ai?.endpoint,
149590
- ...moduleConfig
150207
+ ...moduleConfig,
150208
+ excludeItems
150209
+ // Override moduleConfig.excludeItems with our computed list
149591
150210
  };
149592
150211
  this.toolbar = new SuperToolbar(config2);
149593
150212
  this.toolbar.on("superdoc-command", this.onToolbarCommand.bind(this));
@@ -151698,7 +152317,7 @@ ${style2}
151698
152317
  value && typeof value === "object" && "byteLength" in value && "byteOffset" in value
151699
152318
  );
151700
152319
  }
151701
- const indexGAzIoyrZ = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
152320
+ const indexXOsGE2PW = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
151702
152321
  __proto__: null,
151703
152322
  unified
151704
152323
  }, Symbol.toStringTag, { value: "Module" }));