@univerjs/docs 1.0.0-alpha.2 → 1.0.0-alpha.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/cjs/index.js CHANGED
@@ -316,6 +316,27 @@ var DocStateEmitService = class extends _univerjs_core.RxDisposable {
316
316
  //#endregion
317
317
  //#region src/commands/mutations/core-editing.mutation.ts
318
318
  const RichTextEditingMutationId = "doc.mutation.rich-text-editing";
319
+ function getSegmentType(documentDataModel, segmentId) {
320
+ if (!segmentId) return "body";
321
+ const { headers, footers } = documentDataModel.getSnapshot();
322
+ if (headers === null || headers === void 0 ? void 0 : headers[segmentId]) return "header";
323
+ if (footers === null || footers === void 0 ? void 0 : footers[segmentId]) return "footer";
324
+ return "body";
325
+ }
326
+ function assertValidDocBodyStructure(documentDataModel, segmentId) {
327
+ const segmentModel = documentDataModel.getSelfOrHeaderFooterModel(segmentId);
328
+ const body = segmentModel === null || segmentModel === void 0 ? void 0 : segmentModel.getBody();
329
+ if (!body) return;
330
+ const segmentType = getSegmentType(documentDataModel, segmentId);
331
+ const issues = (0, _univerjs_core.validateDocBodyStructure)(body, {
332
+ segmentType,
333
+ segmentId: segmentId || void 0
334
+ });
335
+ if (!issues.length) return;
336
+ const detail = issues.map((issue) => `${issue.code}${issue.index == null ? "" : `@${issue.index}`}`).join(", ");
337
+ const segmentLabel = segmentId ? `${segmentType} ${segmentId}` : segmentType;
338
+ throw new Error(`[DocStructure] ${segmentLabel}: ${detail}`);
339
+ }
319
340
  /**
320
341
  * The core mutator to change rich text actions. The execution result would be undo mutation params. Could be directly
321
342
  * send to undo redo service (will be used by the triggering command).
@@ -343,6 +364,12 @@ const RichTextEditingMutation = {
343
364
  };
344
365
  const undoActions = _univerjs_core.JSONX.invertWithDoc(actions, documentDataModel.getSnapshot());
345
366
  documentDataModel.apply(actions);
367
+ try {
368
+ assertValidDocBodyStructure(documentDataModel, segmentId);
369
+ } catch (error) {
370
+ documentDataModel.apply(undoActions);
371
+ throw error;
372
+ }
346
373
  documentViewModel === null || documentViewModel === void 0 || documentViewModel.reset(documentDataModel);
347
374
  if (!noNeedSetTextRange && textRanges && trigger != null && !isSync) queueMicrotask(() => {
348
375
  docSelectionManagerService.replaceDocRanges(textRanges, {
@@ -387,14 +414,16 @@ const InsertTextCommand = {
387
414
  id: "doc.command.insert-text",
388
415
  type: _univerjs_core.CommandType.COMMAND,
389
416
  handler: (accessor, params) => {
390
- var _docDataModel$getSelf, _activeRange$segmentI;
417
+ var _ref, _ref2, _docDataModel$getSelf;
391
418
  const commandService = accessor.get(_univerjs_core.ICommandService);
392
419
  const { range, segmentId, body, unitId, cursorOffset } = params;
393
420
  const docSelectionManagerService = accessor.get(DocSelectionManagerService);
394
421
  const docDataModel = accessor.get(_univerjs_core.IUniverInstanceService).getUnit(unitId, _univerjs_core.UniverInstanceType.UNIVER_DOC);
395
422
  if (docDataModel == null) return false;
396
423
  const activeRange = docSelectionManagerService.getActiveTextRange();
397
- const originBody = (_docDataModel$getSelf = docDataModel.getSelfOrHeaderFooterModel((_activeRange$segmentI = activeRange === null || activeRange === void 0 ? void 0 : activeRange.segmentId) !== null && _activeRange$segmentI !== void 0 ? _activeRange$segmentI : "")) === null || _docDataModel$getSelf === void 0 ? void 0 : _docDataModel$getSelf.getBody();
424
+ const rangeSegmentId = "segmentId" in range ? range.segmentId : void 0;
425
+ const targetSegmentId = (_ref = (_ref2 = segmentId !== null && segmentId !== void 0 ? segmentId : rangeSegmentId) !== null && _ref2 !== void 0 ? _ref2 : activeRange === null || activeRange === void 0 ? void 0 : activeRange.segmentId) !== null && _ref !== void 0 ? _ref : "";
426
+ const originBody = (_docDataModel$getSelf = docDataModel.getSelfOrHeaderFooterModel(targetSegmentId)) === null || _docDataModel$getSelf === void 0 ? void 0 : _docDataModel$getSelf.getBody();
398
427
  if (originBody == null) return false;
399
428
  const { startOffset, collapsed } = range;
400
429
  const cursorMove = cursorOffset !== null && cursorOffset !== void 0 ? cursorOffset : body.dataStream.length;
@@ -477,14 +506,12 @@ const DeleteTextCommand = {
477
506
  };
478
507
  const textX = new _univerjs_core.TextX();
479
508
  const jsonX = _univerjs_core.JSONX.getInstance();
480
- textX.push({
481
- t: _univerjs_core.TextXActionType.RETAIN,
482
- len: start - 0
483
- });
484
- textX.push({
485
- t: _univerjs_core.TextXActionType.DELETE,
486
- len: end - start + 1
487
- });
509
+ textX.push(..._univerjs_core.BuildTextUtils.selection.delete([{
510
+ ...range,
511
+ startOffset: start,
512
+ endOffset: end + 1,
513
+ collapsed: false
514
+ }], body));
488
515
  const path = (0, _univerjs_core.getRichTextEditPath)(docDataModel, segmentId);
489
516
  doMutation.params.actions = jsonX.editOp(textX.serialize(), path);
490
517
  const result = commandService.syncExecuteCommand(doMutation.id, doMutation.params);
@@ -559,10 +586,13 @@ function getEmptyHeaderFooterBody() {
559
586
  spaceBelow: { v: 0 }
560
587
  }
561
588
  }],
562
- sectionBreaks: [{ startIndex: 1 }]
589
+ sectionBreaks: [{
590
+ sectionId: (0, _univerjs_core.createSectionId)(/* @__PURE__ */ new Set()),
591
+ startIndex: 1
592
+ }]
563
593
  };
564
594
  }
565
- function createHeaderFooterAction(segmentId, createType, documentStyle, actions, createMode = "single") {
595
+ function createHeaderFooterAction(segmentId, createType, headerFooterConfig, actions, createMode = "single", configPath = ["documentStyle"]) {
566
596
  const jsonX = _univerjs_core.JSONX.getInstance();
567
597
  const ID_LEN = 6;
568
598
  const firstSegmentId = segmentId !== null && segmentId !== void 0 ? segmentId : (0, _univerjs_core.generateRandomId)(ID_LEN);
@@ -611,11 +641,11 @@ function createHeaderFooterAction(segmentId, createType, documentStyle, actions,
611
641
  actions.push(insertPairAction);
612
642
  linkedSegmentIds.push([pairKey, secondSegmentId]);
613
643
  }
614
- for (const [k, id] of linkedSegmentIds) if (documentStyle[k] != null) {
615
- const replaceAction = jsonX.replaceOp(["documentStyle", k], documentStyle[k], id);
644
+ for (const [k, id] of linkedSegmentIds) if (headerFooterConfig[k] != null) {
645
+ const replaceAction = jsonX.replaceOp([...configPath, k], headerFooterConfig[k], id);
616
646
  actions.push(replaceAction);
617
647
  } else {
618
- const insertAction = jsonX.insertOp(["documentStyle", k], id);
648
+ const insertAction = jsonX.insertOp([...configPath, k], id);
619
649
  actions.push(insertAction);
620
650
  }
621
651
  return actions;
@@ -624,21 +654,31 @@ const CreateHeaderFooterCommand = {
624
654
  id: "doc.command.create-header-footer",
625
655
  type: _univerjs_core.CommandType.COMMAND,
626
656
  handler: (accessor, params) => {
657
+ var _body$sectionBreaks$f, _body$sectionBreaks, _body$sectionBreaks2;
627
658
  const commandService = accessor.get(_univerjs_core.ICommandService);
628
659
  const univerInstanceService = accessor.get(_univerjs_core.IUniverInstanceService);
629
- const { unitId, segmentId, createType, headerFooterProps, createMode = "single" } = params;
660
+ const { unitId, segmentId, createType, headerFooterProps, createMode = "single", sectionId } = params;
630
661
  const docDataModel = univerInstanceService.getUnit(unitId, _univerjs_core.UniverInstanceType.UNIVER_DOC);
631
662
  if (docDataModel == null) return false;
632
- const { documentStyle } = docDataModel.getSnapshot();
663
+ const { documentStyle, body } = docDataModel.getSnapshot();
633
664
  if (documentStyle.documentFlavor === _univerjs_core.DocumentFlavor.MODERN) return false;
634
665
  const rawActions = [];
635
666
  const jsonX = _univerjs_core.JSONX.getInstance();
636
- if (createType != null) createHeaderFooterAction(segmentId, createType, documentStyle, rawActions, createMode);
667
+ const sectionIndex = sectionId == null ? -1 : (_body$sectionBreaks$f = body === null || body === void 0 || (_body$sectionBreaks = body.sectionBreaks) === null || _body$sectionBreaks === void 0 ? void 0 : _body$sectionBreaks.findIndex((section) => section.sectionId === sectionId)) !== null && _body$sectionBreaks$f !== void 0 ? _body$sectionBreaks$f : -1;
668
+ const sectionBreak = sectionIndex < 0 ? void 0 : body === null || body === void 0 || (_body$sectionBreaks2 = body.sectionBreaks) === null || _body$sectionBreaks2 === void 0 ? void 0 : _body$sectionBreaks2[sectionIndex];
669
+ if (sectionId != null && !sectionBreak) return false;
670
+ const headerFooterConfig = sectionBreak !== null && sectionBreak !== void 0 ? sectionBreak : documentStyle;
671
+ const configPath = sectionId == null ? ["documentStyle"] : [
672
+ "body",
673
+ "sectionBreaks",
674
+ sectionIndex
675
+ ];
676
+ if (createType != null) createHeaderFooterAction(segmentId, createType, headerFooterConfig, rawActions, createMode, configPath);
637
677
  if (headerFooterProps != null) Object.keys(headerFooterProps).forEach((key) => {
638
678
  const value = headerFooterProps[key];
639
- const oldValue = documentStyle[key];
679
+ const oldValue = headerFooterConfig[key];
640
680
  if (value === oldValue) return;
641
- const action = oldValue === void 0 ? jsonX.insertOp(["documentStyle", key], value) : jsonX.replaceOp(["documentStyle", key], oldValue, value);
681
+ const action = oldValue === void 0 ? jsonX.insertOp([...configPath, key], value) : jsonX.replaceOp([...configPath, key], oldValue, value);
642
682
  rawActions.push(action);
643
683
  });
644
684
  if (rawActions.length === 0) return false;
@@ -661,10 +701,457 @@ const CreateHeaderFooterCommand = {
661
701
  }
662
702
  };
663
703
 
704
+ //#endregion
705
+ //#region src/commands/commands/set-document-default-paragraph-style.command.ts
706
+ const SetDocumentDefaultParagraphStyleCommand = {
707
+ id: "doc.command.set-default-paragraph-style",
708
+ type: _univerjs_core.CommandType.COMMAND,
709
+ handler: (accessor, params) => {
710
+ if (params == null) return false;
711
+ const commandService = accessor.get(_univerjs_core.ICommandService);
712
+ const documentDataModel = accessor.get(_univerjs_core.IUniverInstanceService).getUnit(params.unitId, _univerjs_core.UniverInstanceType.UNIVER_DOC);
713
+ if (documentDataModel == null) return false;
714
+ const oldStyle = documentDataModel.getSnapshot().documentStyle.defaultParagraphStyle;
715
+ const jsonX = _univerjs_core.JSONX.getInstance();
716
+ const path = ["documentStyle", "defaultParagraphStyle"];
717
+ const rawActions = [];
718
+ if (params.defaultParagraphStyle == null) {
719
+ if (oldStyle != null) rawActions.push(jsonX.removeOp(path, oldStyle));
720
+ } else if (oldStyle == null) {
721
+ const newStyle = Object.fromEntries(Object.entries(params.defaultParagraphStyle).filter(([, value]) => value != null).map(([key, value]) => [key, _univerjs_core.Tools.deepClone(value)]));
722
+ if (Object.keys(newStyle).length > 0) rawActions.push(jsonX.insertOp(path, newStyle));
723
+ } else Object.entries(params.defaultParagraphStyle).forEach(([key, value]) => {
724
+ const oldValue = oldStyle[key];
725
+ const propertyPath = [...path, key];
726
+ if (value == null) {
727
+ if (oldValue != null) rawActions.push(jsonX.removeOp(propertyPath, oldValue));
728
+ } else if (oldValue == null) rawActions.push(jsonX.insertOp(propertyPath, _univerjs_core.Tools.deepClone(value)));
729
+ else rawActions.push(jsonX.replaceOp(propertyPath, oldValue, _univerjs_core.Tools.deepClone(value)));
730
+ });
731
+ const actions = rawActions.reduce((acc, action) => _univerjs_core.JSONX.compose(acc, action), null);
732
+ if (rawActions.length === 0 || _univerjs_core.JSONX.isNoop(actions)) return false;
733
+ const mutation = {
734
+ id: RichTextEditingMutation.id,
735
+ params: {
736
+ unitId: params.unitId,
737
+ actions,
738
+ textRanges: null,
739
+ noNeedSetTextRange: true,
740
+ debounce: true,
741
+ isEditing: false
742
+ }
743
+ };
744
+ return Boolean(commandService.syncExecuteCommand(mutation.id, mutation.params));
745
+ }
746
+ };
747
+
748
+ //#endregion
749
+ //#region src/utils/sections.ts
750
+ /** Returns document-level section breaks, excluding table-cell and modern-column sentinels. */
751
+ function getTopLevelSectionBreaks(body) {
752
+ var _body$sectionBreaks;
753
+ const sectionBreakByIndex = new Map(((_body$sectionBreaks = body.sectionBreaks) !== null && _body$sectionBreaks !== void 0 ? _body$sectionBreaks : []).map((sectionBreak) => [sectionBreak.startIndex, sectionBreak]));
754
+ const result = [];
755
+ let tableCellDepth = 0;
756
+ let columnDepth = 0;
757
+ for (let index = 0; index < body.dataStream.length; index++) {
758
+ const token = body.dataStream[index];
759
+ if (token === _univerjs_core.DataStreamTreeTokenType.TABLE_CELL_START) tableCellDepth++;
760
+ else if (token === _univerjs_core.DataStreamTreeTokenType.TABLE_CELL_END) tableCellDepth = Math.max(0, tableCellDepth - 1);
761
+ else if (token === _univerjs_core.DataStreamTreeTokenType.COLUMN_START) columnDepth++;
762
+ else if (token === _univerjs_core.DataStreamTreeTokenType.COLUMN_END) columnDepth = Math.max(0, columnDepth - 1);
763
+ else if (token === _univerjs_core.DataStreamTreeTokenType.SECTION_BREAK && tableCellDepth === 0 && columnDepth === 0) {
764
+ const sectionBreak = sectionBreakByIndex.get(index);
765
+ if (sectionBreak) result.push(sectionBreak);
766
+ }
767
+ }
768
+ return result;
769
+ }
770
+
771
+ //#endregion
772
+ //#region src/commands/commands/set-section-header-footer-link.command.ts
773
+ const SetSectionHeaderFooterLinkCommand = {
774
+ id: "doc.command.set-section-header-footer-link",
775
+ type: _univerjs_core.CommandType.COMMAND,
776
+ handler: (accessor, params) => {
777
+ var _snapshot$body$sectio, _snapshot$body$sectio2;
778
+ if (!params) return false;
779
+ const instanceService = accessor.get(_univerjs_core.IUniverInstanceService);
780
+ const commandService = accessor.get(_univerjs_core.ICommandService);
781
+ const documentDataModel = instanceService.getUnit(params.unitId, _univerjs_core.UniverInstanceType.UNIVER_DOC);
782
+ const snapshot = documentDataModel === null || documentDataModel === void 0 ? void 0 : documentDataModel.getSnapshot();
783
+ if (!documentDataModel || !(snapshot === null || snapshot === void 0 ? void 0 : snapshot.body) || snapshot.documentStyle.documentFlavor !== _univerjs_core.DocumentFlavor.TRADITIONAL) return false;
784
+ const sections = getTopLevelSectionBreaks(snapshot.body);
785
+ const sectionIndex = sections.findIndex((section) => section.sectionId === params.sectionId);
786
+ if (sectionIndex <= 0) return false;
787
+ const storageIndex = (_snapshot$body$sectio = (_snapshot$body$sectio2 = snapshot.body.sectionBreaks) === null || _snapshot$body$sectio2 === void 0 ? void 0 : _snapshot$body$sectio2.findIndex((item) => item.sectionId === params.sectionId)) !== null && _snapshot$body$sectio !== void 0 ? _snapshot$body$sectio : -1;
788
+ if (storageIndex < 0) return false;
789
+ const context = {
790
+ snapshot,
791
+ sections,
792
+ sectionIndex,
793
+ storageIndex,
794
+ key: (0, _univerjs_core.getSectionHeaderFooterReferenceKey)(params.kind, params.variant)
795
+ };
796
+ const rawActions = params.linkedToPrevious ? buildLinkActions(context, params.kind) : buildUnlinkActions(context, params.kind, params.segmentId);
797
+ if (!rawActions) return false;
798
+ const mutation = {
799
+ id: RichTextEditingMutation.id,
800
+ params: {
801
+ unitId: params.unitId,
802
+ actions: rawActions.reduce((actions, action) => _univerjs_core.JSONX.compose(actions, action), null),
803
+ textRanges: null,
804
+ noNeedSetTextRange: true,
805
+ debounce: true,
806
+ isEditing: false,
807
+ trigger: SetSectionHeaderFooterLinkCommand.id
808
+ }
809
+ };
810
+ return Boolean(commandService.syncExecuteCommand(mutation.id, mutation.params));
811
+ }
812
+ };
813
+ function buildLinkActions(context, kind) {
814
+ const { snapshot, sections, sectionIndex, storageIndex, key } = context;
815
+ const section = sections[sectionIndex];
816
+ const explicitSegmentId = section[key];
817
+ if (typeof explicitSegmentId !== "string" || !explicitSegmentId) return null;
818
+ const jsonX = _univerjs_core.JSONX.getInstance();
819
+ const actions = [jsonX.removeOp([
820
+ "body",
821
+ "sectionBreaks",
822
+ storageIndex,
823
+ key
824
+ ], explicitSegmentId)];
825
+ const referenceKeys = kind === "header" ? [
826
+ "defaultHeaderId",
827
+ "firstPageHeaderId",
828
+ "evenPageHeaderId"
829
+ ] : [
830
+ "defaultFooterId",
831
+ "firstPageFooterId",
832
+ "evenPageFooterId"
833
+ ];
834
+ const referencedByDocument = referenceKeys.some((referenceKey) => snapshot.documentStyle[referenceKey] === explicitSegmentId);
835
+ const referencedBySection = sections.some((item) => referenceKeys.some((referenceKey) => !(item.sectionId === section.sectionId && referenceKey === key) && item[referenceKey] === explicitSegmentId));
836
+ const resources = kind === "header" ? snapshot.headers : snapshot.footers;
837
+ if (!referencedByDocument && !referencedBySection && (resources === null || resources === void 0 ? void 0 : resources[explicitSegmentId])) actions.push(jsonX.removeOp([kind === "header" ? "headers" : "footers", explicitSegmentId], resources[explicitSegmentId]));
838
+ return actions;
839
+ }
840
+ function buildUnlinkActions(context, kind, requestedSegmentId) {
841
+ const { snapshot, sections, sectionIndex, storageIndex, key } = context;
842
+ const explicitSegmentId = sections[sectionIndex][key];
843
+ if (typeof explicitSegmentId === "string" && explicitSegmentId) return null;
844
+ const sourceSegmentId = (0, _univerjs_core.resolveSectionHeaderFooterReference)(snapshot.documentStyle, sections, sectionIndex - 1, key).segmentId;
845
+ const segmentId = requestedSegmentId !== null && requestedSegmentId !== void 0 ? requestedSegmentId : (0, _univerjs_core.generateRandomId)(6);
846
+ const resources = kind === "header" ? snapshot.headers : snapshot.footers;
847
+ if (resources === null || resources === void 0 ? void 0 : resources[segmentId]) return null;
848
+ const source = sourceSegmentId ? resources === null || resources === void 0 ? void 0 : resources[sourceSegmentId] : void 0;
849
+ const idKey = kind === "header" ? "headerId" : "footerId";
850
+ const resource = source ? {
851
+ ..._univerjs_core.Tools.deepClone(source),
852
+ [idKey]: segmentId
853
+ } : {
854
+ [idKey]: segmentId,
855
+ body: getEmptyHeaderFooterBody()
856
+ };
857
+ const jsonX = _univerjs_core.JSONX.getInstance();
858
+ return [jsonX.insertOp([kind === "header" ? "headers" : "footers", segmentId], resource), jsonX.insertOp([
859
+ "body",
860
+ "sectionBreaks",
861
+ storageIndex,
862
+ key
863
+ ], segmentId)];
864
+ }
865
+
866
+ //#endregion
867
+ //#region src/commands/commands/update-document-section.command.ts
868
+ const UpdateDocumentSectionCommand = {
869
+ id: "doc.command.update-section",
870
+ type: _univerjs_core.CommandType.COMMAND,
871
+ handler: (accessor, params) => {
872
+ if (!(params === null || params === void 0 ? void 0 : params.updates.length) || params.updates.some(({ sectionId, config }) => !sectionId || Object.keys(config).length === 0)) return false;
873
+ const instanceService = accessor.get(_univerjs_core.IUniverInstanceService);
874
+ const commandService = accessor.get(_univerjs_core.ICommandService);
875
+ const documentDataModel = instanceService.getUnit(params.unitId, _univerjs_core.UniverInstanceType.UNIVER_DOC);
876
+ if (!documentDataModel || documentDataModel.getDocumentStyle().documentFlavor !== _univerjs_core.DocumentFlavor.TRADITIONAL) return false;
877
+ const body = documentDataModel.getBody();
878
+ if (!body) return false;
879
+ const updates = new Map(params.updates.map(({ sectionId, config }) => [sectionId, config]));
880
+ if (updates.size !== params.updates.length) return false;
881
+ const selectedIds = new Set(updates.keys());
882
+ const sections = getTopLevelSectionBreaks(body).filter((section) => selectedIds.has(section.sectionId)).sort((left, right) => left.startIndex - right.startIndex);
883
+ if (sections.length !== selectedIds.size) return false;
884
+ const cursor = new _univerjs_core.MemoryCursor();
885
+ const textX = new _univerjs_core.TextX();
886
+ for (const section of sections) {
887
+ textX.push({
888
+ t: _univerjs_core.TextXActionType.RETAIN,
889
+ len: section.startIndex - cursor.cursor
890
+ });
891
+ textX.push({
892
+ t: _univerjs_core.TextXActionType.RETAIN,
893
+ len: 1,
894
+ coverType: _univerjs_core.UpdateDocsAttributeType.REPLACE,
895
+ body: {
896
+ dataStream: "",
897
+ sectionBreaks: [{
898
+ ..._univerjs_core.Tools.deepClone(section),
899
+ ..._univerjs_core.Tools.deepClone(updates.get(section.sectionId)),
900
+ sectionId: section.sectionId,
901
+ startIndex: 0
902
+ }]
903
+ }
904
+ });
905
+ cursor.moveCursorTo(section.startIndex + 1);
906
+ }
907
+ const jsonX = _univerjs_core.JSONX.getInstance();
908
+ const mutation = {
909
+ id: RichTextEditingMutation.id,
910
+ params: {
911
+ unitId: params.unitId,
912
+ actions: jsonX.editOp(textX.serialize(), (0, _univerjs_core.getRichTextEditPath)(documentDataModel)),
913
+ textRanges: null,
914
+ noNeedSetTextRange: true,
915
+ debounce: true,
916
+ isEditing: false,
917
+ trigger: UpdateDocumentSectionCommand.id
918
+ }
919
+ };
920
+ return Boolean(commandService.syncExecuteCommand(mutation.id, mutation.params));
921
+ }
922
+ };
923
+ const InsertDocumentSectionBreakCommand = {
924
+ id: "doc.command.insert-section-break",
925
+ type: _univerjs_core.CommandType.COMMAND,
926
+ handler: (accessor, params) => {
927
+ var _body$sectionBreaks, _body$tables, _body$columnGroups, _body$blockRanges, _params$config;
928
+ if (!params) return false;
929
+ const context = getTraditionalDocumentContext(accessor, params.unitId);
930
+ if (!context || !params.sectionId || !Number.isInteger(params.offset)) return false;
931
+ const { body, documentDataModel, commandService } = context;
932
+ if (params.offset < 0 || params.offset > body.dataStream.length || ((_body$sectionBreaks = body.sectionBreaks) === null || _body$sectionBreaks === void 0 ? void 0 : _body$sectionBreaks.some((section) => section.sectionId === params.sectionId)) || ((_body$tables = body.tables) === null || _body$tables === void 0 ? void 0 : _body$tables.some((range) => (0, _univerjs_core.containsInteriorInsertionOffset)((0, _univerjs_core.getTableRangeInterval)(range), params.offset))) || ((_body$columnGroups = body.columnGroups) === null || _body$columnGroups === void 0 ? void 0 : _body$columnGroups.some((range) => (0, _univerjs_core.containsInteriorInsertionOffset)((0, _univerjs_core.getColumnGroupRangeInterval)(range), params.offset))) || ((_body$blockRanges = body.blockRanges) === null || _body$blockRanges === void 0 ? void 0 : _body$blockRanges.some((range) => (0, _univerjs_core.containsInteriorInsertionOffset)((0, _univerjs_core.getBlockRangeInterval)(range), params.offset)))) return false;
933
+ const textX = new _univerjs_core.TextX();
934
+ textX.retain(params.offset);
935
+ textX.insert(1, {
936
+ dataStream: _univerjs_core.DataStreamTreeTokenType.SECTION_BREAK,
937
+ sectionBreaks: [{
938
+ ..._univerjs_core.Tools.deepClone((_params$config = params.config) !== null && _params$config !== void 0 ? _params$config : {}),
939
+ sectionId: params.sectionId,
940
+ startIndex: 0
941
+ }]
942
+ });
943
+ return executeSectionTextX(commandService, documentDataModel, textX, InsertDocumentSectionBreakCommand.id);
944
+ }
945
+ };
946
+ const DeleteDocumentSectionBreakCommand = {
947
+ id: "doc.command.delete-section-break",
948
+ type: _univerjs_core.CommandType.COMMAND,
949
+ handler: (accessor, params) => {
950
+ if (!params) return false;
951
+ const context = getTraditionalDocumentContext(accessor, params.unitId);
952
+ if (!context || !params.sectionId) return false;
953
+ const sections = getTopLevelSectionBreaks(context.body);
954
+ if (sections.length <= 1) return false;
955
+ const section = sections.find((item) => item.sectionId === params.sectionId);
956
+ if (!section) return false;
957
+ const textX = new _univerjs_core.TextX();
958
+ textX.retain(section.startIndex);
959
+ textX.delete(1);
960
+ return executeSectionTextX(context.commandService, context.documentDataModel, textX, DeleteDocumentSectionBreakCommand.id);
961
+ }
962
+ };
963
+ function getTraditionalDocumentContext(accessor, unitId) {
964
+ if (!unitId) return null;
965
+ const documentDataModel = accessor.get(_univerjs_core.IUniverInstanceService).getUnit(unitId, _univerjs_core.UniverInstanceType.UNIVER_DOC);
966
+ const body = documentDataModel === null || documentDataModel === void 0 ? void 0 : documentDataModel.getBody();
967
+ if (!documentDataModel || !body || documentDataModel.getDocumentStyle().documentFlavor !== _univerjs_core.DocumentFlavor.TRADITIONAL) return null;
968
+ return {
969
+ body,
970
+ documentDataModel,
971
+ commandService: accessor.get(_univerjs_core.ICommandService)
972
+ };
973
+ }
974
+ function executeSectionTextX(commandService, documentDataModel, textX, trigger) {
975
+ const actions = _univerjs_core.JSONX.getInstance().editOp(textX.serialize(), (0, _univerjs_core.getRichTextEditPath)(documentDataModel));
976
+ return Boolean(commandService.syncExecuteCommand(RichTextEditingMutation.id, {
977
+ unitId: documentDataModel.getUnitId(),
978
+ actions,
979
+ textRanges: null,
980
+ noNeedSetTextRange: true,
981
+ debounce: true,
982
+ isEditing: false,
983
+ trigger
984
+ }));
985
+ }
986
+
987
+ //#endregion
988
+ //#region src/embed-host-anchor.ts
989
+ const EMBED_DOCS_CUSTOM_BLOCK_DEFAULT_COMPONENT_KEY = "UniverEmbedDocsCustomBlock";
990
+ const DEFAULT_CUSTOM_BLOCK_SIZE = {
991
+ width: 720,
992
+ height: 360
993
+ };
994
+ const SHEET_LIKE_CUSTOM_BLOCK_SIZE = {
995
+ width: 960,
996
+ height: 480
997
+ };
998
+ const SLIDE_CUSTOM_BLOCK_SIZE = {
999
+ width: 720,
1000
+ height: 405
1001
+ };
1002
+ function createDocsCustomBlockInsertMutation(params) {
1003
+ return createRichTextMutation(params.unitId, params.segmentId, createInsertCustomBlockActions(params));
1004
+ }
1005
+ function createDocsCustomBlockRemoveMutation(params) {
1006
+ return createRichTextMutation(params.unitId, params.segmentId, createRemoveCustomBlockActions(params));
1007
+ }
1008
+ function createInsertCustomBlockActions(params) {
1009
+ const textX = new _univerjs_core.TextX();
1010
+ if (params.startIndex > 0) textX.push({
1011
+ t: _univerjs_core.TextXActionType.RETAIN,
1012
+ len: params.startIndex
1013
+ });
1014
+ textX.push({
1015
+ t: _univerjs_core.TextXActionType.INSERT,
1016
+ body: {
1017
+ dataStream: "\b",
1018
+ customBlocks: [{
1019
+ startIndex: 0,
1020
+ blockId: params.blockId
1021
+ }]
1022
+ },
1023
+ len: 1
1024
+ });
1025
+ return composeActions([toBodyEditActions(textX, params.segmentId), createDrawingInsertActions(params)]);
1026
+ }
1027
+ function createRemoveCustomBlockActions(params) {
1028
+ const textX = new _univerjs_core.TextX();
1029
+ if (params.startIndex > 0) textX.push({
1030
+ t: _univerjs_core.TextXActionType.RETAIN,
1031
+ len: params.startIndex
1032
+ });
1033
+ textX.push({
1034
+ t: _univerjs_core.TextXActionType.DELETE,
1035
+ len: 1
1036
+ });
1037
+ return composeActions([toBodyEditActions(textX, params.segmentId), createDrawingRemoveActions(params)]);
1038
+ }
1039
+ function createDocsCustomBlockDrawing(params) {
1040
+ var _params$componentKey;
1041
+ const size = resolveDocsCustomBlockSize(params.childType);
1042
+ const isInline = params.interactionMode === "inline";
1043
+ return {
1044
+ unitId: params.unitId,
1045
+ subUnitId: params.unitId,
1046
+ drawingId: params.blockId,
1047
+ drawingType: _univerjs_core.DrawingTypeEnum.DRAWING_DOM,
1048
+ componentKey: (_params$componentKey = params.componentKey) !== null && _params$componentKey !== void 0 ? _params$componentKey : EMBED_DOCS_CUSTOM_BLOCK_DEFAULT_COMPONENT_KEY,
1049
+ data: createEmbedDocsCustomBlockData(params),
1050
+ title: params.blockId,
1051
+ description: "Univer embedded unit custom block",
1052
+ layoutType: isInline ? _univerjs_core.PositionedObjectLayoutType.INLINE : _univerjs_core.PositionedObjectLayoutType.WRAP_TOP_AND_BOTTOM,
1053
+ allowTransform: false,
1054
+ docTransform: {
1055
+ size: {
1056
+ width: size.width,
1057
+ height: size.height
1058
+ },
1059
+ positionH: {
1060
+ relativeFrom: isInline ? _univerjs_core.ObjectRelativeFromH.PAGE : _univerjs_core.ObjectRelativeFromH.COLUMN,
1061
+ ...isInline ? { posOffset: 0 } : { align: _univerjs_core.AlignTypeH.LEFT }
1062
+ },
1063
+ positionV: {
1064
+ relativeFrom: isInline ? _univerjs_core.ObjectRelativeFromV.PAGE : _univerjs_core.ObjectRelativeFromV.PARAGRAPH,
1065
+ posOffset: 0
1066
+ },
1067
+ angle: 0
1068
+ },
1069
+ transform: {
1070
+ left: 0,
1071
+ top: 0,
1072
+ width: size.width,
1073
+ height: size.height
1074
+ }
1075
+ };
1076
+ }
1077
+ function resolveDocsCustomBlockSize(childType) {
1078
+ if (childType === _univerjs_core.UniverInstanceType.UNIVER_SHEET || childType === _univerjs_core.UniverInstanceType.UNIVER_BASE) return SHEET_LIKE_CUSTOM_BLOCK_SIZE;
1079
+ if (childType === _univerjs_core.UniverInstanceType.UNIVER_SLIDE) return SLIDE_CUSTOM_BLOCK_SIZE;
1080
+ return DEFAULT_CUSTOM_BLOCK_SIZE;
1081
+ }
1082
+ function isSheetLikeDocsCustomBlockChildType(childType) {
1083
+ return childType === _univerjs_core.UniverInstanceType.UNIVER_SHEET || childType === _univerjs_core.UniverInstanceType.UNIVER_BASE;
1084
+ }
1085
+ function createEmbedDocsCustomBlockData(params) {
1086
+ var _params$embedId, _params$interactionMo;
1087
+ return {
1088
+ version: 1,
1089
+ embedId: (_params$embedId = params.embedId) !== null && _params$embedId !== void 0 ? _params$embedId : params.blockId,
1090
+ hostUnitId: params.unitId,
1091
+ hostAnchorId: params.blockId,
1092
+ childUnitId: params.childUnitId,
1093
+ childType: params.childType,
1094
+ interactionMode: (_params$interactionMo = params.interactionMode) !== null && _params$interactionMo !== void 0 ? _params$interactionMo : "block"
1095
+ };
1096
+ }
1097
+ function isEmbedDocsCustomBlockData(data) {
1098
+ if (!data || typeof data !== "object") return false;
1099
+ const candidate = data;
1100
+ return candidate.version === 1 && typeof candidate.embedId === "string" && typeof candidate.hostAnchorId === "string";
1101
+ }
1102
+ function shouldUseInlineTextSelectionForDocsCustomBlockDrawing(drawing) {
1103
+ const data = drawing && typeof drawing === "object" ? drawing.data : void 0;
1104
+ if (!isEmbedDocsCustomBlockData(data)) return true;
1105
+ return data.interactionMode === "inline";
1106
+ }
1107
+ function createRichTextMutation(unitId, segmentId, actions) {
1108
+ return {
1109
+ id: RichTextEditingMutation.id,
1110
+ params: {
1111
+ unitId,
1112
+ segmentId,
1113
+ actions,
1114
+ textRanges: [],
1115
+ isEditing: false,
1116
+ noNeedSetTextRange: true
1117
+ }
1118
+ };
1119
+ }
1120
+ function toBodyEditActions(textX, segmentId) {
1121
+ const action = _univerjs_core.JSONX.getInstance().editOp(textX.serialize(), segmentId ? [
1122
+ "headers",
1123
+ segmentId,
1124
+ "body"
1125
+ ] : ["body"]);
1126
+ return action !== null && action !== void 0 ? action : [];
1127
+ }
1128
+ function createDrawingInsertActions(params) {
1129
+ var _jsonX$insertOp, _jsonX$insertOp2, _params$drawingOrderI;
1130
+ if (params.segmentId) return [];
1131
+ const jsonX = _univerjs_core.JSONX.getInstance();
1132
+ const drawing = createDocsCustomBlockDrawing(params);
1133
+ return composeActions([(_jsonX$insertOp = jsonX.insertOp(["drawings", params.blockId], drawing)) !== null && _jsonX$insertOp !== void 0 ? _jsonX$insertOp : [], (_jsonX$insertOp2 = jsonX.insertOp(["drawingsOrder", (_params$drawingOrderI = params.drawingOrderIndex) !== null && _params$drawingOrderI !== void 0 ? _params$drawingOrderI : 0], params.blockId)) !== null && _jsonX$insertOp2 !== void 0 ? _jsonX$insertOp2 : []]);
1134
+ }
1135
+ function createDrawingRemoveActions(params) {
1136
+ var _jsonX$removeOp, _jsonX$removeOp2, _params$drawingOrderI2;
1137
+ if (params.segmentId) return [];
1138
+ const jsonX = _univerjs_core.JSONX.getInstance();
1139
+ const drawing = createDocsCustomBlockDrawing(params);
1140
+ return composeActions([(_jsonX$removeOp = jsonX.removeOp(["drawings", params.blockId], drawing)) !== null && _jsonX$removeOp !== void 0 ? _jsonX$removeOp : [], (_jsonX$removeOp2 = jsonX.removeOp(["drawingsOrder", (_params$drawingOrderI2 = params.drawingOrderIndex) !== null && _params$drawingOrderI2 !== void 0 ? _params$drawingOrderI2 : 0], params.blockId)) !== null && _jsonX$removeOp2 !== void 0 ? _jsonX$removeOp2 : []]);
1141
+ }
1142
+ function composeActions(actions) {
1143
+ return actions.reduce((composed, action) => {
1144
+ var _JSONX$compose;
1145
+ if (!action || _univerjs_core.JSONX.isNoop(action) || action.length === 0) return composed;
1146
+ if (!composed || _univerjs_core.JSONX.isNoop(composed) || composed.length === 0) return action;
1147
+ return (_JSONX$compose = _univerjs_core.JSONX.compose(composed, action)) !== null && _JSONX$compose !== void 0 ? _JSONX$compose : [];
1148
+ }, []);
1149
+ }
1150
+
664
1151
  //#endregion
665
1152
  //#region package.json
666
1153
  var name = "@univerjs/docs";
667
- var version = "1.0.0-alpha.2";
1154
+ var version = "1.0.0-alpha.3";
668
1155
 
669
1156
  //#endregion
670
1157
  //#region src/commands/mutations/docs-rename.mutation.ts
@@ -987,6 +1474,11 @@ let UniverDocsPlugin = class UniverDocsPlugin extends _univerjs_core.Plugin {
987
1474
  DeleteTextCommand,
988
1475
  UpdateTextCommand,
989
1476
  CreateHeaderFooterCommand,
1477
+ SetDocumentDefaultParagraphStyleCommand,
1478
+ SetSectionHeaderFooterLinkCommand,
1479
+ UpdateDocumentSectionCommand,
1480
+ InsertDocumentSectionBreakCommand,
1481
+ DeleteDocumentSectionBreakCommand,
990
1482
  RichTextEditingMutation,
991
1483
  DocsRenameMutation,
992
1484
  SetTextSelectionsOperation
@@ -1182,6 +1674,35 @@ function deleteCustomRangeFactory(accessor, params) {
1182
1674
  return doMutation;
1183
1675
  }
1184
1676
 
1677
+ //#endregion
1678
+ //#region src/utils/paragraphs.ts
1679
+ /** Builds paragraph metadata for inserted paragraph tokens, including horizontal-rule borders. */
1680
+ function generateParagraphs(dataStream, prevParagraph, borderBottom, existingParagraphIds = []) {
1681
+ const paragraphs = [];
1682
+ const existingIds = new Set(existingParagraphIds);
1683
+ for (let i = 0, len = dataStream.length; i < len; i++) {
1684
+ if (dataStream[i] !== _univerjs_core.DataStreamTreeTokenType.PARAGRAPH) continue;
1685
+ paragraphs.push({
1686
+ startIndex: i,
1687
+ paragraphId: (0, _univerjs_core.createParagraphId)(existingIds)
1688
+ });
1689
+ }
1690
+ for (const paragraph of paragraphs) {
1691
+ if (prevParagraph === null || prevParagraph === void 0 ? void 0 : prevParagraph.bullet) paragraph.bullet = _univerjs_core.Tools.deepClone(prevParagraph.bullet);
1692
+ if (prevParagraph === null || prevParagraph === void 0 ? void 0 : prevParagraph.paragraphStyle) {
1693
+ paragraph.paragraphStyle = _univerjs_core.Tools.deepClone(prevParagraph.paragraphStyle);
1694
+ delete paragraph.paragraphStyle.borderBottom;
1695
+ if (prevParagraph.paragraphStyle.headingId) paragraph.paragraphStyle.headingId = (0, _univerjs_core.generateRandomId)(6);
1696
+ }
1697
+ if (borderBottom) {
1698
+ var _paragraph$paragraphS;
1699
+ (_paragraph$paragraphS = paragraph.paragraphStyle) !== null && _paragraph$paragraphS !== void 0 || (paragraph.paragraphStyle = {});
1700
+ paragraph.paragraphStyle.borderBottom = _univerjs_core.Tools.deepClone(borderBottom);
1701
+ }
1702
+ }
1703
+ return paragraphs;
1704
+ }
1705
+
1185
1706
  //#endregion
1186
1707
  //#region src/utils/replace-selection-factory.ts
1187
1708
  function replaceSelectionFactory(accessor, params) {
@@ -1224,6 +1745,22 @@ function replaceSelectionFactory(accessor, params) {
1224
1745
  return doMutation;
1225
1746
  }
1226
1747
 
1748
+ //#endregion
1749
+ //#region src/utils/section-columns.ts
1750
+ /** Creates explicit OOXML section columns from a count, gap, and optional widths. */
1751
+ function createSectionColumnProperties(documentStyle, section, columnCount, gap, widths) {
1752
+ var _ref, _section$pageSize$wid, _section$pageSize, _documentStyle$pageSi, _ref2, _section$marginLeft, _ref3, _section$marginRight;
1753
+ if (columnCount <= 1) return [];
1754
+ const safeGap = Math.max(0, gap);
1755
+ const pageWidth = (_ref = (_section$pageSize$wid = section === null || section === void 0 || (_section$pageSize = section.pageSize) === null || _section$pageSize === void 0 ? void 0 : _section$pageSize.width) !== null && _section$pageSize$wid !== void 0 ? _section$pageSize$wid : documentStyle === null || documentStyle === void 0 || (_documentStyle$pageSi = documentStyle.pageSize) === null || _documentStyle$pageSi === void 0 ? void 0 : _documentStyle$pageSi.width) !== null && _ref !== void 0 ? _ref : _univerjs_core.PAGE_SIZE[_univerjs_core.PaperType.A4].width;
1756
+ const contentWidth = Math.max(0, pageWidth - ((_ref2 = (_section$marginLeft = section === null || section === void 0 ? void 0 : section.marginLeft) !== null && _section$marginLeft !== void 0 ? _section$marginLeft : documentStyle === null || documentStyle === void 0 ? void 0 : documentStyle.marginLeft) !== null && _ref2 !== void 0 ? _ref2 : 72) - ((_ref3 = (_section$marginRight = section === null || section === void 0 ? void 0 : section.marginRight) !== null && _section$marginRight !== void 0 ? _section$marginRight : documentStyle === null || documentStyle === void 0 ? void 0 : documentStyle.marginRight) !== null && _ref3 !== void 0 ? _ref3 : 72));
1757
+ const availableWidth = Math.max(0, contentWidth - safeGap * (columnCount - 1));
1758
+ return (widths !== null && widths !== void 0 ? widths : Array.from({ length: columnCount }, () => availableWidth / columnCount)).map((width, index) => ({
1759
+ width: Math.max(0, width),
1760
+ paddingEnd: index === columnCount - 1 ? 0 : safeGap
1761
+ }));
1762
+ }
1763
+
1227
1764
  //#endregion
1228
1765
  //#region src/utils/util.ts
1229
1766
  function consumeContentInsertRange(accessor, unitId) {
@@ -1240,6 +1777,7 @@ function isHeaderFooterSelection(range) {
1240
1777
  //#endregion
1241
1778
  exports.CreateHeaderFooterCommand = CreateHeaderFooterCommand;
1242
1779
  exports.DOC_INTERCEPTOR_POINT = DOC_INTERCEPTOR_POINT;
1780
+ exports.DeleteDocumentSectionBreakCommand = DeleteDocumentSectionBreakCommand;
1243
1781
  exports.DeleteTextCommand = DeleteTextCommand;
1244
1782
  exports.DocBlockMoveValidatorService = DocBlockMoveValidatorService;
1245
1783
  exports.DocContentInsertService = DocContentInsertService;
@@ -1268,10 +1806,14 @@ Object.defineProperty(exports, 'DocStateChangeManagerService', {
1268
1806
  }
1269
1807
  });
1270
1808
  exports.DocStateEmitService = DocStateEmitService;
1809
+ exports.EMBED_DOCS_CUSTOM_BLOCK_DEFAULT_COMPONENT_KEY = EMBED_DOCS_CUSTOM_BLOCK_DEFAULT_COMPONENT_KEY;
1271
1810
  exports.HeaderFooterType = HeaderFooterType;
1272
1811
  exports.IDocStateChangeInterceptorService = IDocStateChangeInterceptorService;
1812
+ exports.InsertDocumentSectionBreakCommand = InsertDocumentSectionBreakCommand;
1273
1813
  exports.InsertTextCommand = InsertTextCommand;
1274
1814
  exports.RichTextEditingMutation = RichTextEditingMutation;
1815
+ exports.SetDocumentDefaultParagraphStyleCommand = SetDocumentDefaultParagraphStyleCommand;
1816
+ exports.SetSectionHeaderFooterLinkCommand = SetSectionHeaderFooterLinkCommand;
1275
1817
  exports.SetTextSelectionsOperation = SetTextSelectionsOperation;
1276
1818
  Object.defineProperty(exports, 'UniverDocsPlugin', {
1277
1819
  enumerable: true,
@@ -1279,10 +1821,24 @@ Object.defineProperty(exports, 'UniverDocsPlugin', {
1279
1821
  return UniverDocsPlugin;
1280
1822
  }
1281
1823
  });
1824
+ exports.UpdateDocumentSectionCommand = UpdateDocumentSectionCommand;
1282
1825
  exports.UpdateTextCommand = UpdateTextCommand;
1283
1826
  exports.addCustomRangeBySelectionFactory = addCustomRangeBySelectionFactory;
1284
1827
  exports.addCustomRangeFactory = addCustomRangeFactory;
1285
1828
  exports.consumeContentInsertRange = consumeContentInsertRange;
1829
+ exports.createDocsCustomBlockDrawing = createDocsCustomBlockDrawing;
1830
+ exports.createDocsCustomBlockInsertMutation = createDocsCustomBlockInsertMutation;
1831
+ exports.createDocsCustomBlockRemoveMutation = createDocsCustomBlockRemoveMutation;
1832
+ exports.createEmbedDocsCustomBlockData = createEmbedDocsCustomBlockData;
1833
+ exports.createInsertCustomBlockActions = createInsertCustomBlockActions;
1834
+ exports.createRemoveCustomBlockActions = createRemoveCustomBlockActions;
1835
+ exports.createSectionColumnProperties = createSectionColumnProperties;
1286
1836
  exports.deleteCustomRangeFactory = deleteCustomRangeFactory;
1837
+ exports.generateParagraphs = generateParagraphs;
1838
+ exports.getTopLevelSectionBreaks = getTopLevelSectionBreaks;
1839
+ exports.isEmbedDocsCustomBlockData = isEmbedDocsCustomBlockData;
1287
1840
  exports.isHeaderFooterSelection = isHeaderFooterSelection;
1288
- exports.replaceSelectionFactory = replaceSelectionFactory;
1841
+ exports.isSheetLikeDocsCustomBlockChildType = isSheetLikeDocsCustomBlockChildType;
1842
+ exports.replaceSelectionFactory = replaceSelectionFactory;
1843
+ exports.resolveDocsCustomBlockSize = resolveDocsCustomBlockSize;
1844
+ exports.shouldUseInlineTextSelectionForDocsCustomBlockDrawing = shouldUseInlineTextSelectionForDocsCustomBlockDrawing;