@a3s-lab/office 0.10.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/COLLABORATION_ROADMAP.md +22 -12
- package/README.md +17 -14
- package/dist/{0~4705.js → 0~5093.js} +959 -10
- package/dist/0~document-editor.js +1 -0
- package/dist/0~work-docx-export.js +225 -6
- package/dist/0~work-docx-import.js +24 -753
- package/dist/0~work-office-diagnostics.js +6 -4
- package/dist/4104.js +1 -1
- package/dist/8928.js +448 -137
- package/dist/internal/features/work/work-document-format-change-tracking.d.ts +1 -1
- package/dist/internal/features/work/work-document-paragraph-format-change-tracking.d.ts +7 -0
- package/dist/internal/features/work/work-document-paragraph-format-changes.d.ts +8 -0
- package/dist/internal/features/work/work-docx-import.d.ts +3 -1
- package/dist/internal/features/work/work-docx-paragraph-alignment-import.d.ts +1 -0
- package/dist/internal/features/work/work-docx-paragraph-borders-import.d.ts +1 -0
- package/dist/internal/features/work/work-docx-paragraph-direction-import.d.ts +1 -0
- package/dist/internal/features/work/work-docx-paragraph-format-change-export.d.ts +13 -0
- package/dist/internal/features/work/work-docx-paragraph-format-change-import.d.ts +17 -0
- package/dist/internal/features/work/work-docx-paragraph-indent-import.d.ts +1 -0
- package/dist/internal/features/work/work-docx-paragraph-pagination-import.d.ts +1 -0
- package/dist/internal/features/work/work-docx-paragraph-shading-import.d.ts +1 -0
- package/dist/internal/features/work/work-docx-paragraph-spacing-import.d.ts +1 -0
- package/dist/internal/features/work/work-docx-tab-stop-import.d.ts +1 -0
- package/dist/internal/features/work/work-types.d.ts +1 -1
- package/dist/office-kernel.wasm +0 -0
- package/dist/styles.css +8 -0
- package/docs/latest/en/browser-editor-architecture.md +18 -0
- package/package.json +5 -3
package/dist/8928.js
CHANGED
|
@@ -8551,12 +8551,309 @@ function compactAttributes(value) {
|
|
|
8551
8551
|
function work_document_format_changes_isRecord(value) {
|
|
8552
8552
|
return 'object' == typeof value && null !== value && !Array.isArray(value);
|
|
8553
8553
|
}
|
|
8554
|
+
const MAX_DOCUMENT_TAB_POSITION_PX = 4096;
|
|
8555
|
+
const MAX_DOCUMENT_TAB_STOPS = 64;
|
|
8556
|
+
const DocumentParagraphTabStops = Extension.create({
|
|
8557
|
+
name: 'documentParagraphTabStops',
|
|
8558
|
+
addGlobalAttributes () {
|
|
8559
|
+
return [
|
|
8560
|
+
{
|
|
8561
|
+
types: [
|
|
8562
|
+
'paragraph',
|
|
8563
|
+
'heading'
|
|
8564
|
+
],
|
|
8565
|
+
attributes: {
|
|
8566
|
+
tabStops: {
|
|
8567
|
+
default: null,
|
|
8568
|
+
parseHTML: (element)=>normalizeDocumentTabStops(element.dataset.officeTabStops),
|
|
8569
|
+
renderHTML: (attributes)=>{
|
|
8570
|
+
const tabStops = normalizeDocumentTabStops(attributes.tabStops);
|
|
8571
|
+
return tabStops.length ? {
|
|
8572
|
+
'data-office-tab-stops': serializeDocumentTabStops(tabStops)
|
|
8573
|
+
} : {};
|
|
8574
|
+
}
|
|
8575
|
+
}
|
|
8576
|
+
}
|
|
8577
|
+
}
|
|
8578
|
+
];
|
|
8579
|
+
},
|
|
8580
|
+
addCommands () {
|
|
8581
|
+
return {
|
|
8582
|
+
setDocumentParagraphTabStops: (tabStops, options = {})=>({ chain, editor })=>{
|
|
8583
|
+
const nodeTypes = activeParagraphNodeTypes(editor);
|
|
8584
|
+
if (!nodeTypes.length) return false;
|
|
8585
|
+
const normalized = normalizeDocumentTabStops(tabStops);
|
|
8586
|
+
let commandChain = chain();
|
|
8587
|
+
if (false !== options.restoreFocus) commandChain = commandChain.focus();
|
|
8588
|
+
for (const nodeType of nodeTypes)commandChain = commandChain.updateAttributes(nodeType, {
|
|
8589
|
+
tabStops: normalized.length ? normalized : null
|
|
8590
|
+
});
|
|
8591
|
+
return commandChain.run();
|
|
8592
|
+
}
|
|
8593
|
+
};
|
|
8594
|
+
}
|
|
8595
|
+
});
|
|
8596
|
+
function documentParagraphTabStops(editor) {
|
|
8597
|
+
return normalizeDocumentTabStops(activeParagraphAttributes(editor).tabStops);
|
|
8598
|
+
}
|
|
8599
|
+
function normalizeDocumentTabStops(value) {
|
|
8600
|
+
const source = parsedTabStopSource(value);
|
|
8601
|
+
const byPosition = new Map();
|
|
8602
|
+
for (const candidate of source.slice(0, 4 * MAX_DOCUMENT_TAB_STOPS)){
|
|
8603
|
+
if (!work_document_tab_stops_isRecord(candidate)) continue;
|
|
8604
|
+
const rawPosition = Number(candidate.position);
|
|
8605
|
+
if (!Number.isFinite(rawPosition) || rawPosition <= 0) continue;
|
|
8606
|
+
const position = normalizedTabPosition(rawPosition);
|
|
8607
|
+
if (!(position <= 0)) byPosition.set(position, {
|
|
8608
|
+
position,
|
|
8609
|
+
alignment: normalizedTabAlignment(candidate.alignment),
|
|
8610
|
+
leader: normalizedTabLeader(candidate.leader)
|
|
8611
|
+
});
|
|
8612
|
+
}
|
|
8613
|
+
return Array.from(byPosition.values()).sort((left, right)=>left.position - right.position).slice(0, MAX_DOCUMENT_TAB_STOPS);
|
|
8614
|
+
}
|
|
8615
|
+
function serializeDocumentTabStops(value) {
|
|
8616
|
+
return JSON.stringify(normalizeDocumentTabStops(value));
|
|
8617
|
+
}
|
|
8618
|
+
function normalizedTabPosition(value) {
|
|
8619
|
+
if (!Number.isFinite(value)) return 0;
|
|
8620
|
+
return Math.min(MAX_DOCUMENT_TAB_POSITION_PX, Math.max(0, Math.round(100 * value) / 100));
|
|
8621
|
+
}
|
|
8622
|
+
function nextDocumentTabAlignment(alignment) {
|
|
8623
|
+
if ('left' === alignment) return 'center';
|
|
8624
|
+
if ('center' === alignment) return 'right';
|
|
8625
|
+
if ('right' === alignment) return 'decimal';
|
|
8626
|
+
return 'left';
|
|
8627
|
+
}
|
|
8628
|
+
function parsedTabStopSource(value) {
|
|
8629
|
+
if (Array.isArray(value)) return value;
|
|
8630
|
+
if ('string' != typeof value || !value.trim()) return [];
|
|
8631
|
+
try {
|
|
8632
|
+
const parsed = JSON.parse(value);
|
|
8633
|
+
return Array.isArray(parsed) ? parsed : [];
|
|
8634
|
+
} catch {
|
|
8635
|
+
return [];
|
|
8636
|
+
}
|
|
8637
|
+
}
|
|
8638
|
+
function normalizedTabAlignment(value) {
|
|
8639
|
+
return 'center' === value || 'right' === value || 'decimal' === value ? value : 'left';
|
|
8640
|
+
}
|
|
8641
|
+
function normalizedTabLeader(value) {
|
|
8642
|
+
return 'dot' === value || 'hyphen' === value || 'underscore' === value || 'middleDot' === value ? value : 'none';
|
|
8643
|
+
}
|
|
8644
|
+
function activeParagraphAttributes(editor) {
|
|
8645
|
+
return editor.isActive('heading') ? editor.getAttributes('heading') : editor.getAttributes('paragraph');
|
|
8646
|
+
}
|
|
8647
|
+
function activeParagraphNodeTypes(editor) {
|
|
8648
|
+
const types = [];
|
|
8649
|
+
if (editor.isActive('paragraph')) types.push('paragraph');
|
|
8650
|
+
if (editor.isActive('heading')) types.push('heading');
|
|
8651
|
+
return types;
|
|
8652
|
+
}
|
|
8653
|
+
function work_document_tab_stops_isRecord(value) {
|
|
8654
|
+
return 'object' == typeof value && null !== value && !Array.isArray(value);
|
|
8655
|
+
}
|
|
8656
|
+
const DOCUMENT_PARAGRAPH_FORMAT_ATTRIBUTES = [
|
|
8657
|
+
'textAlign',
|
|
8658
|
+
'paragraphDirection',
|
|
8659
|
+
'indentLevel',
|
|
8660
|
+
'rightIndent',
|
|
8661
|
+
'firstLineIndent',
|
|
8662
|
+
'spaceBefore',
|
|
8663
|
+
'spaceAfter',
|
|
8664
|
+
'lineHeight',
|
|
8665
|
+
'lineRule',
|
|
8666
|
+
'autoLineHeight',
|
|
8667
|
+
'keepLines',
|
|
8668
|
+
'keepWithNext',
|
|
8669
|
+
'pageBreakBefore',
|
|
8670
|
+
'widowControl',
|
|
8671
|
+
'contextualSpacing',
|
|
8672
|
+
'outlineLevel',
|
|
8673
|
+
'tabStops',
|
|
8674
|
+
'paragraphBorders',
|
|
8675
|
+
'paragraphShading',
|
|
8676
|
+
'defaultCollapsed'
|
|
8677
|
+
];
|
|
8678
|
+
const MAX_PARAGRAPH_FORMAT_SNAPSHOT_BYTES = 65536;
|
|
8679
|
+
const MAX_DOCUMENT_INDENT_PX = 192;
|
|
8680
|
+
function serializeDocumentParagraphFormatting(attributes) {
|
|
8681
|
+
return JSON.stringify(normalizeParagraphFormatting(attributes));
|
|
8682
|
+
}
|
|
8683
|
+
function parseDocumentParagraphFormatting(value) {
|
|
8684
|
+
if ('string' != typeof value || !value.length || value.length > MAX_PARAGRAPH_FORMAT_SNAPSHOT_BYTES) return null;
|
|
8685
|
+
let parsed;
|
|
8686
|
+
try {
|
|
8687
|
+
parsed = JSON.parse(value);
|
|
8688
|
+
} catch {
|
|
8689
|
+
return null;
|
|
8690
|
+
}
|
|
8691
|
+
if (!work_document_paragraph_format_changes_isRecord(parsed)) return null;
|
|
8692
|
+
const keys = Object.keys(parsed);
|
|
8693
|
+
if (keys.length !== DOCUMENT_PARAGRAPH_FORMAT_ATTRIBUTES.length || keys.some((key, index)=>key !== DOCUMENT_PARAGRAPH_FORMAT_ATTRIBUTES[index])) return null;
|
|
8694
|
+
const normalized = normalizeParagraphFormatting(parsed);
|
|
8695
|
+
return JSON.stringify(normalized) === value ? normalized : null;
|
|
8696
|
+
}
|
|
8697
|
+
function restoredDocumentParagraphAttributes(attributes, serialized) {
|
|
8698
|
+
const formatting = parseDocumentParagraphFormatting(serialized);
|
|
8699
|
+
if (!formatting) return null;
|
|
8700
|
+
return clearDocumentParagraphChangeAttributes({
|
|
8701
|
+
...attributes,
|
|
8702
|
+
...formatting
|
|
8703
|
+
});
|
|
8704
|
+
}
|
|
8705
|
+
function clearDocumentParagraphChangeAttributes(attributes) {
|
|
8706
|
+
return {
|
|
8707
|
+
...attributes,
|
|
8708
|
+
paragraphChangeKind: null,
|
|
8709
|
+
paragraphChangeId: '',
|
|
8710
|
+
paragraphChangeActorId: '',
|
|
8711
|
+
paragraphChangeAuthor: '',
|
|
8712
|
+
paragraphChangeDate: '',
|
|
8713
|
+
paragraphChangeBefore: ''
|
|
8714
|
+
};
|
|
8715
|
+
}
|
|
8716
|
+
function normalizeParagraphFormatting(source) {
|
|
8717
|
+
const indentLevel = quarterNumber(source.indentLevel, 0, 8, 0);
|
|
8718
|
+
const leftIndent = 24 * indentLevel;
|
|
8719
|
+
const serializedBorders = serializeDocumentParagraphBorders(source.paragraphBorders);
|
|
8720
|
+
const serializedShading = serializeDocumentParagraphShading(source.paragraphShading);
|
|
8721
|
+
const tabStops = normalizeDocumentTabStops(source.tabStops);
|
|
8722
|
+
return {
|
|
8723
|
+
textAlign: oneOfOrNull(source.textAlign, [
|
|
8724
|
+
'left',
|
|
8725
|
+
'center',
|
|
8726
|
+
'right',
|
|
8727
|
+
'justify'
|
|
8728
|
+
]),
|
|
8729
|
+
paragraphDirection: oneOfOrNull(source.paragraphDirection, [
|
|
8730
|
+
'ltr',
|
|
8731
|
+
'rtl'
|
|
8732
|
+
]),
|
|
8733
|
+
indentLevel,
|
|
8734
|
+
rightIndent: integerNumber(source.rightIndent, 0, MAX_DOCUMENT_INDENT_PX, 0),
|
|
8735
|
+
firstLineIndent: integerNumber(source.firstLineIndent, -leftIndent, MAX_DOCUMENT_INDENT_PX, 0),
|
|
8736
|
+
spaceBefore: quarterNumberOrNull(source.spaceBefore, 0, 720),
|
|
8737
|
+
spaceAfter: quarterNumberOrNull(source.spaceAfter, 0, 720),
|
|
8738
|
+
lineHeight: normalizedLineHeight(source.lineHeight),
|
|
8739
|
+
lineRule: oneOfOrNull(source.lineRule, [
|
|
8740
|
+
'auto',
|
|
8741
|
+
'exact',
|
|
8742
|
+
'atLeast'
|
|
8743
|
+
]),
|
|
8744
|
+
autoLineHeight: decimalNumberOrNull(source.autoLineHeight, 0, 20, 4),
|
|
8745
|
+
keepLines: booleanOrNull(source.keepLines),
|
|
8746
|
+
keepWithNext: booleanOrNull(source.keepWithNext),
|
|
8747
|
+
pageBreakBefore: booleanOrNull(source.pageBreakBefore),
|
|
8748
|
+
widowControl: booleanOrNull(source.widowControl),
|
|
8749
|
+
contextualSpacing: booleanOrNull(source.contextualSpacing),
|
|
8750
|
+
outlineLevel: integerNumberOrNull(source.outlineLevel, 0, 9),
|
|
8751
|
+
tabStops: tabStops.length ? JSON.parse(serializeDocumentTabStops(tabStops)) : null,
|
|
8752
|
+
paragraphBorders: serializedBorders ? JSON.parse(serializedBorders) : null,
|
|
8753
|
+
paragraphShading: serializedShading ? JSON.parse(serializedShading) : null,
|
|
8754
|
+
defaultCollapsed: booleanOrNull(source.defaultCollapsed)
|
|
8755
|
+
};
|
|
8756
|
+
}
|
|
8757
|
+
function normalizedLineHeight(value) {
|
|
8758
|
+
if (null == value || '' === value) return null;
|
|
8759
|
+
if ('string' != typeof value || value.trim() !== value) return null;
|
|
8760
|
+
return /^(?:\d+(?:\.\d+)?|\d+(?:\.\d+)?(?:px|pt|%))$/i.test(value) ? value : null;
|
|
8761
|
+
}
|
|
8762
|
+
function oneOfOrNull(value, allowed) {
|
|
8763
|
+
return 'string' == typeof value && allowed.includes(value) ? value : null;
|
|
8764
|
+
}
|
|
8765
|
+
function booleanOrNull(value) {
|
|
8766
|
+
return 'boolean' == typeof value ? value : null;
|
|
8767
|
+
}
|
|
8768
|
+
function quarterNumber(value, minimum, maximum, fallback) {
|
|
8769
|
+
const number = Number(value);
|
|
8770
|
+
if (!Number.isFinite(number)) return fallback;
|
|
8771
|
+
return Math.min(maximum, Math.max(minimum, Math.round(4 * number) / 4));
|
|
8772
|
+
}
|
|
8773
|
+
function quarterNumberOrNull(value, minimum, maximum) {
|
|
8774
|
+
if (null == value || '' === value) return null;
|
|
8775
|
+
return quarterNumber(value, minimum, maximum, minimum);
|
|
8776
|
+
}
|
|
8777
|
+
function integerNumber(value, minimum, maximum, fallback) {
|
|
8778
|
+
const number = Number(value);
|
|
8779
|
+
if (!Number.isFinite(number)) return fallback;
|
|
8780
|
+
return Math.min(maximum, Math.max(minimum, Math.round(number)));
|
|
8781
|
+
}
|
|
8782
|
+
function integerNumberOrNull(value, minimum, maximum) {
|
|
8783
|
+
if (null == value || '' === value) return null;
|
|
8784
|
+
const number = Number(value);
|
|
8785
|
+
if (!Number.isSafeInteger(number) || number < minimum || number > maximum) return null;
|
|
8786
|
+
return number;
|
|
8787
|
+
}
|
|
8788
|
+
function decimalNumberOrNull(value, minimumExclusive, maximum, precision) {
|
|
8789
|
+
if (null == value || '' === value) return null;
|
|
8790
|
+
const number = Number(value);
|
|
8791
|
+
if (!Number.isFinite(number) || number <= minimumExclusive || number > maximum) return null;
|
|
8792
|
+
return Number(number.toFixed(precision));
|
|
8793
|
+
}
|
|
8794
|
+
function work_document_paragraph_format_changes_isRecord(value) {
|
|
8795
|
+
return 'object' == typeof value && null !== value && !Array.isArray(value);
|
|
8796
|
+
}
|
|
8797
|
+
function trackDocumentParagraphFormattingTransaction(transaction, state, options) {
|
|
8798
|
+
if (!transaction.steps.some((step)=>step instanceof ReplaceAroundStep)) return false;
|
|
8799
|
+
let identity = null;
|
|
8800
|
+
let tracked = false;
|
|
8801
|
+
state.doc.descendants((before, position)=>{
|
|
8802
|
+
if (!isParagraph(before)) return;
|
|
8803
|
+
const after = transaction.doc.nodeAt(position);
|
|
8804
|
+
if (!after || after.type !== before.type || !isParagraph(after)) return;
|
|
8805
|
+
const previous = serializeDocumentParagraphFormatting(before.attrs);
|
|
8806
|
+
const current = serializeDocumentParagraphFormatting(after.attrs);
|
|
8807
|
+
if (previous === current || !sameContentIgnoringMarks(before, after)) return;
|
|
8808
|
+
if ('paragraph-formatting' === after.attrs.paragraphChangeKind) return;
|
|
8809
|
+
identity ??= options.createChange();
|
|
8810
|
+
transaction.setNodeMarkup(position, void 0, {
|
|
8811
|
+
...after.attrs,
|
|
8812
|
+
paragraphChangeKind: 'paragraph-formatting',
|
|
8813
|
+
paragraphChangeId: identity.id,
|
|
8814
|
+
paragraphChangeActorId: identity.actorId ?? '',
|
|
8815
|
+
paragraphChangeAuthor: identity.author || 'A3S Work',
|
|
8816
|
+
paragraphChangeDate: identity.date || new Date().toISOString(),
|
|
8817
|
+
paragraphChangeBefore: previous
|
|
8818
|
+
});
|
|
8819
|
+
tracked = true;
|
|
8820
|
+
});
|
|
8821
|
+
return tracked;
|
|
8822
|
+
}
|
|
8823
|
+
function isParagraph(node) {
|
|
8824
|
+
return 'paragraph' === node.type.name || 'heading' === node.type.name;
|
|
8825
|
+
}
|
|
8826
|
+
function sameContentIgnoringMarks(before, after) {
|
|
8827
|
+
return JSON.stringify(childContentIgnoringMarks(before)) === JSON.stringify(childContentIgnoringMarks(after));
|
|
8828
|
+
}
|
|
8829
|
+
function childContentIgnoringMarks(node) {
|
|
8830
|
+
const content = [];
|
|
8831
|
+
node.forEach((child)=>{
|
|
8832
|
+
content.push(contentIgnoringMarks(child));
|
|
8833
|
+
});
|
|
8834
|
+
return content;
|
|
8835
|
+
}
|
|
8836
|
+
function contentIgnoringMarks(node) {
|
|
8837
|
+
if (node.isText) return {
|
|
8838
|
+
type: node.type.name,
|
|
8839
|
+
text: node.text ?? ''
|
|
8840
|
+
};
|
|
8841
|
+
const content = childContentIgnoringMarks(node);
|
|
8842
|
+
return {
|
|
8843
|
+
type: node.type.name,
|
|
8844
|
+
...Object.keys(node.attrs).length ? {
|
|
8845
|
+
attrs: node.attrs
|
|
8846
|
+
} : {},
|
|
8847
|
+
...content.length ? {
|
|
8848
|
+
content
|
|
8849
|
+
} : {}
|
|
8850
|
+
};
|
|
8851
|
+
}
|
|
8554
8852
|
function trackDocumentFormattingTransaction(transaction, state, type, options, pluginKey) {
|
|
8555
8853
|
if (!options.isTracking() || state.doc.eq(transaction.doc)) return;
|
|
8556
8854
|
const sync = transaction.getMeta(ySyncPluginKey);
|
|
8557
8855
|
if (transaction.getMeta(pluginKey) || sync?.isChangeOrigin || isHistoryTransaction(transaction)) return;
|
|
8558
8856
|
const ranges = formattingStepRanges(transaction);
|
|
8559
|
-
if (!ranges.length) return;
|
|
8560
8857
|
const formattedDocument = transaction.doc;
|
|
8561
8858
|
let identity = null;
|
|
8562
8859
|
for (const range of ranges)for (const segment of formattingSegments(state.doc, formattedDocument, range)){
|
|
@@ -8567,7 +8864,7 @@ function trackDocumentFormattingTransaction(transaction, state, type, options, p
|
|
|
8567
8864
|
const before = serializeDocumentCharacterFormatting(beforeMarks);
|
|
8568
8865
|
const after = serializeDocumentCharacterFormatting(afterMarks);
|
|
8569
8866
|
if (!(before === after || documentChangeMark(afterMarks))) {
|
|
8570
|
-
identity ??= options.createChange();
|
|
8867
|
+
identity ??= options.createChange('formatting');
|
|
8571
8868
|
transaction.addMark(segment.from, segment.to, type.create({
|
|
8572
8869
|
kind: 'formatting',
|
|
8573
8870
|
id: identity.id,
|
|
@@ -8578,12 +8875,20 @@ function trackDocumentFormattingTransaction(transaction, state, type, options, p
|
|
|
8578
8875
|
}));
|
|
8579
8876
|
}
|
|
8580
8877
|
}
|
|
8581
|
-
|
|
8582
|
-
|
|
8878
|
+
const paragraphFormatting = trackDocumentParagraphFormattingTransaction(transaction, state, {
|
|
8879
|
+
createChange: ()=>options.createChange('paragraph-formatting')
|
|
8880
|
+
});
|
|
8881
|
+
if (identity || paragraphFormatting) transaction.setMeta(pluginKey, {
|
|
8882
|
+
...identity ? {
|
|
8883
|
+
formatting: true
|
|
8884
|
+
} : {},
|
|
8885
|
+
...paragraphFormatting ? {
|
|
8886
|
+
paragraphFormatting: true
|
|
8887
|
+
} : {}
|
|
8583
8888
|
});
|
|
8584
8889
|
}
|
|
8585
8890
|
function formattingStepRanges(transaction) {
|
|
8586
|
-
if (transaction.steps.some((step)=>step instanceof ReplaceStep
|
|
8891
|
+
if (transaction.steps.some((step)=>step instanceof ReplaceStep)) return [];
|
|
8587
8892
|
const ranges = [];
|
|
8588
8893
|
for (const step of transaction.steps)if ((step instanceof AddMarkStep || step instanceof RemoveMarkStep) && isDocumentCharacterFormatMark(step.mark.type.name) && step.from < step.to) ranges.push({
|
|
8589
8894
|
from: step.from,
|
|
@@ -8709,6 +9014,24 @@ const DocumentChange = Mark.create({
|
|
|
8709
9014
|
}
|
|
8710
9015
|
};
|
|
8711
9016
|
},
|
|
9017
|
+
addGlobalAttributes () {
|
|
9018
|
+
return [
|
|
9019
|
+
{
|
|
9020
|
+
types: [
|
|
9021
|
+
'paragraph',
|
|
9022
|
+
'heading'
|
|
9023
|
+
],
|
|
9024
|
+
attributes: {
|
|
9025
|
+
paragraphChangeKind: paragraphChangeAttribute('kind', 'data-change-kind'),
|
|
9026
|
+
paragraphChangeId: paragraphChangeAttribute('id', 'data-change-id'),
|
|
9027
|
+
paragraphChangeActorId: paragraphChangeAttribute('actorId', 'data-change-actor-id'),
|
|
9028
|
+
paragraphChangeAuthor: paragraphChangeAttribute('author', 'data-change-author'),
|
|
9029
|
+
paragraphChangeDate: paragraphChangeAttribute('date', 'data-change-date'),
|
|
9030
|
+
paragraphChangeBefore: paragraphChangeAttribute('before', 'data-change-before')
|
|
9031
|
+
}
|
|
9032
|
+
}
|
|
9033
|
+
];
|
|
9034
|
+
},
|
|
8712
9035
|
parseHTML () {
|
|
8713
9036
|
return [
|
|
8714
9037
|
{
|
|
@@ -8768,8 +9091,8 @@ const DocumentChange = Mark.create({
|
|
|
8768
9091
|
filterTransaction: (transaction, state)=>{
|
|
8769
9092
|
trackDocumentFormattingTransaction(transaction, state, changeType, {
|
|
8770
9093
|
isTracking: options.isTracking,
|
|
8771
|
-
createChange: ()=>{
|
|
8772
|
-
const identity = options.createChange(
|
|
9094
|
+
createChange: (kind)=>{
|
|
9095
|
+
const identity = options.createChange(kind);
|
|
8773
9096
|
return {
|
|
8774
9097
|
...identity,
|
|
8775
9098
|
id: identity.id || createDocumentChangeId()
|
|
@@ -8823,6 +9146,29 @@ const DocumentChange = Mark.create({
|
|
|
8823
9146
|
function collectDocumentChanges(document1) {
|
|
8824
9147
|
const changes = new Map();
|
|
8825
9148
|
document1.descendants((node, position)=>{
|
|
9149
|
+
if (('paragraph' === node.type.name || 'heading' === node.type.name) && 'paragraph-formatting' === node.attrs.paragraphChangeKind) {
|
|
9150
|
+
const id = work_document_changes_stringAttribute(node.attrs.paragraphChangeId) || `paragraph-change-at-${position}`;
|
|
9151
|
+
const key = `paragraph-formatting:${id}`;
|
|
9152
|
+
const from = position + 1;
|
|
9153
|
+
const to = from + node.content.size;
|
|
9154
|
+
const current = changes.get(key);
|
|
9155
|
+
if (current) {
|
|
9156
|
+
current.from = Math.min(current.from, from);
|
|
9157
|
+
current.to = Math.max(current.to, to);
|
|
9158
|
+
current.text = `${current.text}\n${node.textContent}`;
|
|
9159
|
+
} else changes.set(key, {
|
|
9160
|
+
id,
|
|
9161
|
+
kind: 'paragraph-formatting',
|
|
9162
|
+
...work_document_changes_stringAttribute(node.attrs.paragraphChangeActorId) ? {
|
|
9163
|
+
actorId: work_document_changes_stringAttribute(node.attrs.paragraphChangeActorId)
|
|
9164
|
+
} : {},
|
|
9165
|
+
author: work_document_changes_stringAttribute(node.attrs.paragraphChangeAuthor) || '未知审阅者',
|
|
9166
|
+
date: work_document_changes_stringAttribute(node.attrs.paragraphChangeDate),
|
|
9167
|
+
from,
|
|
9168
|
+
to,
|
|
9169
|
+
text: node.textContent
|
|
9170
|
+
});
|
|
9171
|
+
}
|
|
8826
9172
|
if (!node.isText || !node.text) return;
|
|
8827
9173
|
const mark = work_document_changes_documentChangeMark(node.marks);
|
|
8828
9174
|
if (!mark) return;
|
|
@@ -8853,8 +9199,10 @@ function collectDocumentChanges(document1) {
|
|
|
8853
9199
|
}
|
|
8854
9200
|
function resolveDocumentChangesCommand({ state, tr }, type, decision, ids) {
|
|
8855
9201
|
const segments = documentChangeSegments(state.doc, type).filter((segment)=>!ids || ids.has(segment.id));
|
|
8856
|
-
|
|
8857
|
-
if (
|
|
9202
|
+
const paragraphSegments = paragraphChangeSegments(state.doc).filter((segment)=>!ids || ids.has(segment.id));
|
|
9203
|
+
if (!segments.length && !paragraphSegments.length) return 0;
|
|
9204
|
+
if (paragraphSegments.some((segment)=>!parseDocumentParagraphFormatting(segment.before)) || 'reject' === decision && segments.some((segment)=>'formatting' === segment.kind && !parseDocumentCharacterFormatting(segment.before))) return 0;
|
|
9205
|
+
closeHistory(tr);
|
|
8858
9206
|
tr.setMeta(documentChangePluginKey, {
|
|
8859
9207
|
decision
|
|
8860
9208
|
});
|
|
@@ -8871,9 +9219,19 @@ function resolveDocumentChangesCommand({ state, tr }, type, decision, ids) {
|
|
|
8871
9219
|
(removeMark ? markRemovals : contentDeletions).push(segment);
|
|
8872
9220
|
}
|
|
8873
9221
|
for (const segment of formattingRejections)restoreDocumentCharacterFormatting(tr, state.schema, segment.from, segment.to, segment.before);
|
|
9222
|
+
for (const segment of paragraphSegments){
|
|
9223
|
+
const node = tr.doc.nodeAt(segment.position);
|
|
9224
|
+
if (!node || 'paragraph' !== node.type.name && 'heading' !== node.type.name) return 0;
|
|
9225
|
+
const attributes = 'reject' === decision ? restoredDocumentParagraphAttributes(node.attrs, segment.before) : clearDocumentParagraphChangeAttributes(node.attrs);
|
|
9226
|
+
if (!attributes) return 0;
|
|
9227
|
+
tr.setNodeMarkup(segment.position, void 0, attributes);
|
|
9228
|
+
}
|
|
8874
9229
|
for (const segment of markRemovals)tr.removeMark(segment.from, segment.to, type);
|
|
8875
9230
|
for (const segment of contentDeletions.sort((left, right)=>right.from - left.from))tr.delete(segment.from, segment.to);
|
|
8876
|
-
return tr.docChanged ? new Set(
|
|
9231
|
+
return tr.docChanged ? new Set([
|
|
9232
|
+
...segments,
|
|
9233
|
+
...paragraphSegments
|
|
9234
|
+
].map((segment)=>segment.id)).size : 0;
|
|
8877
9235
|
}
|
|
8878
9236
|
function trackedReplacement(transaction, document1, type, from, to, text, createChange) {
|
|
8879
9237
|
if (from !== to) trackDeletion(transaction, document1, type, from, to, changeMark(type, 'deletion', createChange));
|
|
@@ -8926,6 +9284,21 @@ function documentChangeSegments(document1, type) {
|
|
|
8926
9284
|
});
|
|
8927
9285
|
return segments;
|
|
8928
9286
|
}
|
|
9287
|
+
function paragraphChangeSegments(document1) {
|
|
9288
|
+
const segments = [];
|
|
9289
|
+
document1.descendants((node, position)=>{
|
|
9290
|
+
if ('paragraph' !== node.type.name && 'heading' !== node.type.name || 'paragraph-formatting' !== node.attrs.paragraphChangeKind) return;
|
|
9291
|
+
segments.push({
|
|
9292
|
+
id: work_document_changes_stringAttribute(node.attrs.paragraphChangeId) || `paragraph-change-at-${position}`,
|
|
9293
|
+
kind: 'paragraph-formatting',
|
|
9294
|
+
position,
|
|
9295
|
+
from: position + 1,
|
|
9296
|
+
to: position + 1 + node.content.size,
|
|
9297
|
+
before: work_document_changes_stringAttribute(node.attrs.paragraphChangeBefore)
|
|
9298
|
+
});
|
|
9299
|
+
});
|
|
9300
|
+
return segments;
|
|
9301
|
+
}
|
|
8929
9302
|
function markFragment(fragment, insertion, type) {
|
|
8930
9303
|
const nodes = [];
|
|
8931
9304
|
fragment.forEach((node)=>{
|
|
@@ -8981,6 +9354,27 @@ function changeKind(value) {
|
|
|
8981
9354
|
if ('deletion' === value || 'formatting' === value) return value;
|
|
8982
9355
|
return 'insertion';
|
|
8983
9356
|
}
|
|
9357
|
+
function paragraphChangeAttribute(field, htmlName) {
|
|
9358
|
+
const modelName = `paragraphChange${field[0]?.toUpperCase() ?? ''}${field.slice(1)}`;
|
|
9359
|
+
return {
|
|
9360
|
+
default: 'kind' === field ? null : '',
|
|
9361
|
+
parseHTML: (element)=>{
|
|
9362
|
+
if ('true' !== element.getAttribute('data-document-change') || 'paragraph-formatting' !== element.getAttribute('data-change-kind')) return 'kind' === field ? null : '';
|
|
9363
|
+
return 'kind' === field ? 'paragraph-formatting' : element.getAttribute(htmlName) ?? '';
|
|
9364
|
+
},
|
|
9365
|
+
renderHTML: (attributes)=>{
|
|
9366
|
+
if ('paragraph-formatting' !== attributes.paragraphChangeKind) return {};
|
|
9367
|
+
if ('kind' === field) return {
|
|
9368
|
+
'data-document-change': 'true',
|
|
9369
|
+
'data-change-kind': 'paragraph-formatting'
|
|
9370
|
+
};
|
|
9371
|
+
const value = work_document_changes_stringAttribute(attributes[modelName]);
|
|
9372
|
+
return value ? {
|
|
9373
|
+
[htmlName]: value
|
|
9374
|
+
} : {};
|
|
9375
|
+
}
|
|
9376
|
+
};
|
|
9377
|
+
}
|
|
8984
9378
|
function work_document_changes_stringAttribute(value) {
|
|
8985
9379
|
return 'string' == typeof value ? value : '';
|
|
8986
9380
|
}
|
|
@@ -11435,7 +11829,7 @@ const DocumentPageBreak = core_Node.create({
|
|
|
11435
11829
|
});
|
|
11436
11830
|
const DOCUMENT_INDENT_STEP_PX = 24;
|
|
11437
11831
|
const MAX_DOCUMENT_INDENT_LEVEL = 8;
|
|
11438
|
-
const
|
|
11832
|
+
const work_document_paragraph_formatting_MAX_DOCUMENT_INDENT_PX = DOCUMENT_INDENT_STEP_PX * MAX_DOCUMENT_INDENT_LEVEL;
|
|
11439
11833
|
const DOCUMENT_WORD_SINGLE_LINE_HEIGHT = 1.15;
|
|
11440
11834
|
const DocumentParagraphFormatting = Extension.create({
|
|
11441
11835
|
name: 'documentParagraphFormatting',
|
|
@@ -11449,9 +11843,9 @@ const DocumentParagraphFormatting = Extension.create({
|
|
|
11449
11843
|
attributes: {
|
|
11450
11844
|
lineHeight: {
|
|
11451
11845
|
default: null,
|
|
11452
|
-
parseHTML: (element)=>
|
|
11846
|
+
parseHTML: (element)=>work_document_paragraph_formatting_normalizedLineHeight(element.style.lineHeight),
|
|
11453
11847
|
renderHTML: (attributes)=>{
|
|
11454
|
-
const lineHeight =
|
|
11848
|
+
const lineHeight = work_document_paragraph_formatting_normalizedLineHeight(attributes.lineHeight);
|
|
11455
11849
|
return lineHeight ? {
|
|
11456
11850
|
style: `line-height: ${lineHeight}`
|
|
11457
11851
|
} : {};
|
|
@@ -11576,7 +11970,7 @@ function documentParagraphIndent(editor) {
|
|
|
11576
11970
|
});
|
|
11577
11971
|
}
|
|
11578
11972
|
function documentParagraphPagination(editor) {
|
|
11579
|
-
const attributes =
|
|
11973
|
+
const attributes = work_document_paragraph_formatting_activeParagraphAttributes(editor);
|
|
11580
11974
|
return {
|
|
11581
11975
|
keepLines: directBoolean(attributes.keepLines) ?? false,
|
|
11582
11976
|
keepWithNext: directBoolean(attributes.keepWithNext) ?? editor.isActive('heading'),
|
|
@@ -11585,15 +11979,15 @@ function documentParagraphPagination(editor) {
|
|
|
11585
11979
|
};
|
|
11586
11980
|
}
|
|
11587
11981
|
function documentParagraphDirection(editor) {
|
|
11588
|
-
const attributes = editor.isActive('listItem') ? editor.getAttributes('listItem') :
|
|
11982
|
+
const attributes = editor.isActive('listItem') ? editor.getAttributes('listItem') : work_document_paragraph_formatting_activeParagraphAttributes(editor);
|
|
11589
11983
|
return normalizeDocumentParagraphDirection(attributes.paragraphDirection) ?? 'ltr';
|
|
11590
11984
|
}
|
|
11591
11985
|
function documentParagraphSpacing(editor) {
|
|
11592
|
-
const attributes =
|
|
11986
|
+
const attributes = work_document_paragraph_formatting_activeParagraphAttributes(editor);
|
|
11593
11987
|
return {
|
|
11594
11988
|
before: normalizedPointSpacing(attributes.spaceBefore),
|
|
11595
11989
|
after: normalizedPointSpacing(attributes.spaceAfter),
|
|
11596
|
-
lineHeight:
|
|
11990
|
+
lineHeight: work_document_paragraph_formatting_normalizedLineHeight(attributes.lineHeight),
|
|
11597
11991
|
lineRule: normalizedLineRule(attributes.lineRule)
|
|
11598
11992
|
};
|
|
11599
11993
|
}
|
|
@@ -11611,7 +12005,7 @@ function normalizeDocumentParagraphDirection(value) {
|
|
|
11611
12005
|
return 'ltr' === normalized || 'rtl' === normalized ? normalized : null;
|
|
11612
12006
|
}
|
|
11613
12007
|
function setDocumentLineHeightCommand({ chain }, lineHeight) {
|
|
11614
|
-
const value =
|
|
12008
|
+
const value = work_document_paragraph_formatting_normalizedLineHeight(lineHeight);
|
|
11615
12009
|
const lineRule = value ? lineRuleForLineHeight(value) : null;
|
|
11616
12010
|
const attributes = {
|
|
11617
12011
|
lineHeight: value,
|
|
@@ -11639,7 +12033,7 @@ function setDocumentIndentLevelCommand(props, indentLevel, options) {
|
|
|
11639
12033
|
}, options);
|
|
11640
12034
|
}
|
|
11641
12035
|
function setDocumentParagraphIndentCommand({ chain, editor }, indent, options) {
|
|
11642
|
-
const nodeTypes =
|
|
12036
|
+
const nodeTypes = work_document_paragraph_formatting_activeParagraphNodeTypes(editor);
|
|
11643
12037
|
if (!nodeTypes.length) return false;
|
|
11644
12038
|
const normalized = normalizeDocumentParagraphIndent(indent);
|
|
11645
12039
|
const attributes = {
|
|
@@ -11664,7 +12058,7 @@ function setDocumentParagraphDirectionCommand({ chain, editor }, direction, opti
|
|
|
11664
12058
|
return commandChain.run();
|
|
11665
12059
|
}
|
|
11666
12060
|
function setDocumentParagraphPaginationCommand({ chain, editor }, pagination, options) {
|
|
11667
|
-
const nodeTypes =
|
|
12061
|
+
const nodeTypes = work_document_paragraph_formatting_activeParagraphNodeTypes(editor);
|
|
11668
12062
|
if (!nodeTypes.length) return false;
|
|
11669
12063
|
const attributes = {};
|
|
11670
12064
|
for (const key of documentParagraphPaginationKeys)if (Object.hasOwn(pagination, key)) attributes[key] = Boolean(pagination[key]);
|
|
@@ -11675,7 +12069,7 @@ function setDocumentParagraphPaginationCommand({ chain, editor }, pagination, op
|
|
|
11675
12069
|
return commandChain.run();
|
|
11676
12070
|
}
|
|
11677
12071
|
function clearDocumentParagraphPaginationCommand({ chain, editor }, options) {
|
|
11678
|
-
const nodeTypes =
|
|
12072
|
+
const nodeTypes = work_document_paragraph_formatting_activeParagraphNodeTypes(editor);
|
|
11679
12073
|
if (!nodeTypes.length) return false;
|
|
11680
12074
|
const attributes = {
|
|
11681
12075
|
keepLines: null,
|
|
@@ -11689,9 +12083,9 @@ function clearDocumentParagraphPaginationCommand({ chain, editor }, options) {
|
|
|
11689
12083
|
return commandChain.run();
|
|
11690
12084
|
}
|
|
11691
12085
|
function setDocumentParagraphSpacingCommand({ chain, editor }, spacing, options) {
|
|
11692
|
-
const nodeTypes =
|
|
12086
|
+
const nodeTypes = work_document_paragraph_formatting_activeParagraphNodeTypes(editor);
|
|
11693
12087
|
if (!nodeTypes.length) return false;
|
|
11694
|
-
const lineHeight =
|
|
12088
|
+
const lineHeight = work_document_paragraph_formatting_normalizedLineHeight(spacing.lineHeight);
|
|
11695
12089
|
const lineRule = normalizedLineRule(spacing.lineRule) ?? (lineHeight ? lineRuleForLineHeight(lineHeight) : null);
|
|
11696
12090
|
const attributes = {
|
|
11697
12091
|
spaceBefore: normalizedPointSpacing(spacing.before),
|
|
@@ -11742,7 +12136,7 @@ function normalizedIndentLevel(value) {
|
|
|
11742
12136
|
if (!Number.isFinite(number)) return 0;
|
|
11743
12137
|
return Math.min(MAX_DOCUMENT_INDENT_LEVEL, Math.max(0, Math.round(4 * number) / 4));
|
|
11744
12138
|
}
|
|
11745
|
-
function
|
|
12139
|
+
function work_document_paragraph_formatting_normalizedLineHeight(value) {
|
|
11746
12140
|
if ('string' != typeof value) return null;
|
|
11747
12141
|
const normalized = value.trim();
|
|
11748
12142
|
if (!normalized || 'normal' === normalized) return null;
|
|
@@ -11777,7 +12171,7 @@ function renderDocumentAutoLineHeight(lineHeight, autoLineHeight = documentAutoL
|
|
|
11777
12171
|
};
|
|
11778
12172
|
}
|
|
11779
12173
|
function lineHeightMultiple(value) {
|
|
11780
|
-
const normalized =
|
|
12174
|
+
const normalized = work_document_paragraph_formatting_normalizedLineHeight(value);
|
|
11781
12175
|
if (!normalized) return null;
|
|
11782
12176
|
const percentage = /^(\d+(?:\.\d+)?)%$/.exec(normalized);
|
|
11783
12177
|
const multiple = percentage ? Number(percentage[1]) / 100 : /^\d+(?:\.\d+)?$/.test(normalized) ? Number(normalized) : NaN;
|
|
@@ -11849,20 +12243,20 @@ function parsedSignedIndentPixels(dataValue, cssValue) {
|
|
|
11849
12243
|
function normalizedIndentPixels(value) {
|
|
11850
12244
|
const number = Number(value);
|
|
11851
12245
|
if (!Number.isFinite(number)) return 0;
|
|
11852
|
-
return Math.min(
|
|
12246
|
+
return Math.min(work_document_paragraph_formatting_MAX_DOCUMENT_INDENT_PX, Math.max(0, Math.round(number)));
|
|
11853
12247
|
}
|
|
11854
12248
|
function normalizedSignedIndentPixels(value) {
|
|
11855
12249
|
const number = Number(value);
|
|
11856
12250
|
if (!Number.isFinite(number)) return 0;
|
|
11857
|
-
return Math.min(
|
|
12251
|
+
return Math.min(work_document_paragraph_formatting_MAX_DOCUMENT_INDENT_PX, Math.max(-work_document_paragraph_formatting_MAX_DOCUMENT_INDENT_PX, Math.round(number)));
|
|
11858
12252
|
}
|
|
11859
12253
|
function normalizedFirstLineIndent(value, leftIndent) {
|
|
11860
|
-
return Math.max(-leftIndent, Math.min(
|
|
12254
|
+
return Math.max(-leftIndent, Math.min(work_document_paragraph_formatting_MAX_DOCUMENT_INDENT_PX, normalizedSignedIndentPixels(value)));
|
|
11861
12255
|
}
|
|
11862
12256
|
function formatPixelValue(value) {
|
|
11863
12257
|
return Number(value.toFixed(2)).toString();
|
|
11864
12258
|
}
|
|
11865
|
-
function
|
|
12259
|
+
function work_document_paragraph_formatting_activeParagraphAttributes(editor) {
|
|
11866
12260
|
return editor.isActive('heading') ? editor.getAttributes('heading') : editor.getAttributes('paragraph');
|
|
11867
12261
|
}
|
|
11868
12262
|
function paragraphDirectionAttribute() {
|
|
@@ -11917,7 +12311,7 @@ function directBoolean(value) {
|
|
|
11917
12311
|
if (false === value || 'false' === value || '0' === value) return false;
|
|
11918
12312
|
return null;
|
|
11919
12313
|
}
|
|
11920
|
-
function
|
|
12314
|
+
function work_document_paragraph_formatting_activeParagraphNodeTypes(editor) {
|
|
11921
12315
|
const nodeTypes = new Set();
|
|
11922
12316
|
if (editor.isActive('paragraph')) nodeTypes.add('paragraph');
|
|
11923
12317
|
if (editor.isActive('heading')) nodeTypes.add('heading');
|
|
@@ -11934,7 +12328,7 @@ function activeParagraphDirectionNodeTypes(editor) {
|
|
|
11934
12328
|
const { from, to } = editor.state.selection;
|
|
11935
12329
|
if (from === to) return editor.isActive('listItem') ? [
|
|
11936
12330
|
'listItem'
|
|
11937
|
-
] :
|
|
12331
|
+
] : work_document_paragraph_formatting_activeParagraphNodeTypes(editor);
|
|
11938
12332
|
const nodeTypes = new Set();
|
|
11939
12333
|
editor.state.doc.nodesBetween(from, to, (node, _position, parent)=>{
|
|
11940
12334
|
if ('listItem' === node.type.name) nodeTypes.add('listItem');
|
|
@@ -12028,108 +12422,6 @@ function elementForNode(editor, position) {
|
|
|
12028
12422
|
if (!node || node.nodeType !== Node.ELEMENT_NODE) return null;
|
|
12029
12423
|
return node;
|
|
12030
12424
|
}
|
|
12031
|
-
const MAX_DOCUMENT_TAB_POSITION_PX = 4096;
|
|
12032
|
-
const MAX_DOCUMENT_TAB_STOPS = 64;
|
|
12033
|
-
const DocumentParagraphTabStops = Extension.create({
|
|
12034
|
-
name: 'documentParagraphTabStops',
|
|
12035
|
-
addGlobalAttributes () {
|
|
12036
|
-
return [
|
|
12037
|
-
{
|
|
12038
|
-
types: [
|
|
12039
|
-
'paragraph',
|
|
12040
|
-
'heading'
|
|
12041
|
-
],
|
|
12042
|
-
attributes: {
|
|
12043
|
-
tabStops: {
|
|
12044
|
-
default: null,
|
|
12045
|
-
parseHTML: (element)=>normalizeDocumentTabStops(element.dataset.officeTabStops),
|
|
12046
|
-
renderHTML: (attributes)=>{
|
|
12047
|
-
const tabStops = normalizeDocumentTabStops(attributes.tabStops);
|
|
12048
|
-
return tabStops.length ? {
|
|
12049
|
-
'data-office-tab-stops': serializeDocumentTabStops(tabStops)
|
|
12050
|
-
} : {};
|
|
12051
|
-
}
|
|
12052
|
-
}
|
|
12053
|
-
}
|
|
12054
|
-
}
|
|
12055
|
-
];
|
|
12056
|
-
},
|
|
12057
|
-
addCommands () {
|
|
12058
|
-
return {
|
|
12059
|
-
setDocumentParagraphTabStops: (tabStops, options = {})=>({ chain, editor })=>{
|
|
12060
|
-
const nodeTypes = work_document_tab_stops_activeParagraphNodeTypes(editor);
|
|
12061
|
-
if (!nodeTypes.length) return false;
|
|
12062
|
-
const normalized = normalizeDocumentTabStops(tabStops);
|
|
12063
|
-
let commandChain = chain();
|
|
12064
|
-
if (false !== options.restoreFocus) commandChain = commandChain.focus();
|
|
12065
|
-
for (const nodeType of nodeTypes)commandChain = commandChain.updateAttributes(nodeType, {
|
|
12066
|
-
tabStops: normalized.length ? normalized : null
|
|
12067
|
-
});
|
|
12068
|
-
return commandChain.run();
|
|
12069
|
-
}
|
|
12070
|
-
};
|
|
12071
|
-
}
|
|
12072
|
-
});
|
|
12073
|
-
function documentParagraphTabStops(editor) {
|
|
12074
|
-
return normalizeDocumentTabStops(work_document_tab_stops_activeParagraphAttributes(editor).tabStops);
|
|
12075
|
-
}
|
|
12076
|
-
function normalizeDocumentTabStops(value) {
|
|
12077
|
-
const source = parsedTabStopSource(value);
|
|
12078
|
-
const byPosition = new Map();
|
|
12079
|
-
for (const candidate of source.slice(0, 4 * MAX_DOCUMENT_TAB_STOPS)){
|
|
12080
|
-
if (!work_document_tab_stops_isRecord(candidate)) continue;
|
|
12081
|
-
const rawPosition = Number(candidate.position);
|
|
12082
|
-
if (!Number.isFinite(rawPosition) || rawPosition <= 0) continue;
|
|
12083
|
-
const position = normalizedTabPosition(rawPosition);
|
|
12084
|
-
if (!(position <= 0)) byPosition.set(position, {
|
|
12085
|
-
position,
|
|
12086
|
-
alignment: normalizedTabAlignment(candidate.alignment),
|
|
12087
|
-
leader: normalizedTabLeader(candidate.leader)
|
|
12088
|
-
});
|
|
12089
|
-
}
|
|
12090
|
-
return Array.from(byPosition.values()).sort((left, right)=>left.position - right.position).slice(0, MAX_DOCUMENT_TAB_STOPS);
|
|
12091
|
-
}
|
|
12092
|
-
function serializeDocumentTabStops(value) {
|
|
12093
|
-
return JSON.stringify(normalizeDocumentTabStops(value));
|
|
12094
|
-
}
|
|
12095
|
-
function normalizedTabPosition(value) {
|
|
12096
|
-
if (!Number.isFinite(value)) return 0;
|
|
12097
|
-
return Math.min(MAX_DOCUMENT_TAB_POSITION_PX, Math.max(0, Math.round(100 * value) / 100));
|
|
12098
|
-
}
|
|
12099
|
-
function nextDocumentTabAlignment(alignment) {
|
|
12100
|
-
if ('left' === alignment) return 'center';
|
|
12101
|
-
if ('center' === alignment) return 'right';
|
|
12102
|
-
if ('right' === alignment) return 'decimal';
|
|
12103
|
-
return 'left';
|
|
12104
|
-
}
|
|
12105
|
-
function parsedTabStopSource(value) {
|
|
12106
|
-
if (Array.isArray(value)) return value;
|
|
12107
|
-
if ('string' != typeof value || !value.trim()) return [];
|
|
12108
|
-
try {
|
|
12109
|
-
const parsed = JSON.parse(value);
|
|
12110
|
-
return Array.isArray(parsed) ? parsed : [];
|
|
12111
|
-
} catch {
|
|
12112
|
-
return [];
|
|
12113
|
-
}
|
|
12114
|
-
}
|
|
12115
|
-
function normalizedTabAlignment(value) {
|
|
12116
|
-
return 'center' === value || 'right' === value || 'decimal' === value ? value : 'left';
|
|
12117
|
-
}
|
|
12118
|
-
function normalizedTabLeader(value) {
|
|
12119
|
-
return 'dot' === value || 'hyphen' === value || 'underscore' === value || 'middleDot' === value ? value : 'none';
|
|
12120
|
-
}
|
|
12121
|
-
function work_document_tab_stops_activeParagraphAttributes(editor) {
|
|
12122
|
-
return editor.isActive('heading') ? editor.getAttributes('heading') : editor.getAttributes('paragraph');
|
|
12123
|
-
}
|
|
12124
|
-
function work_document_tab_stops_activeParagraphNodeTypes(editor) {
|
|
12125
|
-
const types = [];
|
|
12126
|
-
if (editor.isActive('paragraph')) types.push('paragraph');
|
|
12127
|
-
if (editor.isActive('heading')) types.push('heading');
|
|
12128
|
-
return types;
|
|
12129
|
-
}
|
|
12130
|
-
function work_document_tab_stops_isRecord(value) {
|
|
12131
|
-
return 'object' == typeof value && null !== value && !Array.isArray(value);
|
|
12132
|
-
}
|
|
12133
12425
|
const MAX_DOCUMENT_TEXT_LAYOUT_PARAGRAPHS = 16384;
|
|
12134
12426
|
const MAX_DOCUMENT_TEXT_LAYOUT_RUNS = 16384;
|
|
12135
12427
|
const MAX_DOCUMENT_TEXT_LAYOUT_BYTES = 1048576;
|
|
@@ -16366,9 +16658,9 @@ function changeIdentity(decision) {
|
|
|
16366
16658
|
return `${decision.changeKind}:${decision.changeId}`;
|
|
16367
16659
|
}
|
|
16368
16660
|
function office_document_collaboration_change_decisions_changeKind(value, shared) {
|
|
16369
|
-
if ('insertion' === value || 'deletion' === value || 'formatting' === value) return value;
|
|
16661
|
+
if ('insertion' === value || 'deletion' === value || 'formatting' === value || 'paragraph-formatting' === value) return value;
|
|
16370
16662
|
if (shared) invalidSharedSidecars('tracked-change decision kind');
|
|
16371
|
-
invalidInputSidecars('an insertion, deletion, or formatting tracked-change kind');
|
|
16663
|
+
invalidInputSidecars('an insertion, deletion, formatting, or paragraph-formatting tracked-change kind');
|
|
16372
16664
|
}
|
|
16373
16665
|
function decisionAction(value, shared) {
|
|
16374
16666
|
if ('accept' === value || 'reject' === value) return value;
|
|
@@ -17029,7 +17321,14 @@ function strictDocumentChanges(document1) {
|
|
|
17029
17321
|
const changes = new Map();
|
|
17030
17322
|
let valid = true;
|
|
17031
17323
|
document1.descendants((node)=>{
|
|
17032
|
-
if (!valid
|
|
17324
|
+
if (!valid) return;
|
|
17325
|
+
if ('paragraph' === node.type.name || 'heading' === node.type.name) {
|
|
17326
|
+
if (!strictParagraphFormattingChange(node)) {
|
|
17327
|
+
valid = false;
|
|
17328
|
+
return false;
|
|
17329
|
+
}
|
|
17330
|
+
}
|
|
17331
|
+
if (!node.isText || !node.text) return;
|
|
17033
17332
|
const marks = node.marks.filter((mark)=>'documentChange' === mark.type.name);
|
|
17034
17333
|
if (0 === marks.length) return;
|
|
17035
17334
|
if (1 !== marks.length) {
|
|
@@ -17121,6 +17420,18 @@ function optionalStrictString(value) {
|
|
|
17121
17420
|
function strictChangeKind(value) {
|
|
17122
17421
|
return 'insertion' === value || 'deletion' === value || 'formatting' === value ? value : null;
|
|
17123
17422
|
}
|
|
17423
|
+
function strictParagraphFormattingChange(node) {
|
|
17424
|
+
const kind = node.attrs.paragraphChangeKind;
|
|
17425
|
+
const fields = [
|
|
17426
|
+
node.attrs.paragraphChangeId,
|
|
17427
|
+
node.attrs.paragraphChangeActorId,
|
|
17428
|
+
node.attrs.paragraphChangeAuthor,
|
|
17429
|
+
node.attrs.paragraphChangeDate,
|
|
17430
|
+
node.attrs.paragraphChangeBefore
|
|
17431
|
+
];
|
|
17432
|
+
if ('paragraph-formatting' !== kind) return (null == kind || '' === kind) && fields.every((field)=>null == field || '' === field);
|
|
17433
|
+
return Boolean(strictString(node.attrs.paragraphChangeId) && null !== optionalStrictString(node.attrs.paragraphChangeActorId) && strictString(node.attrs.paragraphChangeAuthor) && strictString(node.attrs.paragraphChangeDate) && parseDocumentParagraphFormatting(node.attrs.paragraphChangeBefore));
|
|
17434
|
+
}
|
|
17124
17435
|
const DOCUMENT_CONTENT_ROOT = 'document.content';
|
|
17125
17436
|
const MAX_DOCUMENT_COMMENT_HISTORY = 100;
|
|
17126
17437
|
const mountedDocumentBindings = new WeakMap();
|
|
@@ -17771,4 +18082,4 @@ function capturePages(surface) {
|
|
|
17771
18082
|
width: surface.pageWidth
|
|
17772
18083
|
}));
|
|
17773
18084
|
}
|
|
17774
|
-
export { DEFAULT_DOCUMENT_TABLE_CELL_FORMAT, DEFAULT_DOCUMENT_TABLE_CELL_MARGINS, DEFAULT_DOCUMENT_TABLE_GEOMETRY, DOCUMENT_BOOKMARK_DUPLICATE_MESSAGE, DOCUMENT_PAGE_BORDER_EDGES, DOCUMENT_PAGE_MARGIN_KEYS, DOCUMENT_PARAGRAPH_BORDER_EDGES, DOCUMENT_PARAGRAPH_BORDER_STYLES, DOCUMENT_PARAGRAPH_SHADING_PATTERNS, DOCUMENT_TABLE_ROW_ID_ATTRIBUTE, DOCUMENT_TABLE_ROW_TEXT_ID_ATTRIBUTE, DOCUMENT_TABLE_STYLE_OPTIONS, DocumentEquation, DocumentImage, DocumentParagraphFormatting, DocumentParagraphIdentity, DocumentSubscript, DocumentSuperscript, DocumentTableRowIdentity, DocxThemePatchCollector, MAX_DOCUMENT_IMAGE_RELATIVE_HEIGHT, MAX_DOCUMENT_NUMBERING_START, activeDocumentBookmark, activeDocumentSection, activeDocumentTableStyle, applyDocumentImageCropToElement, applyDocumentImageIdentityToElement, applyDocumentImageLayerToElement, applyDocumentImageWrapContourToElement, applyDocumentPageGeometry, applyDocumentParagraphIdentityToElement, applyDocumentTableGeometryToElement, applyDocumentTableRowIdentityToElement, canChangeDocumentIndent, canInsertDocumentComment, canSetDocumentTableRowRepeatHeader, clampDocumentMargin, collectDocumentChanges, collectDocumentCommentAnchors, collectDocumentNotes, collectDocumentTextLayoutParagraphs, createDocumentBibliography, createDocumentEquationElement, createDocumentImageIdentityRegistry, createDocumentNoteElement, createDocumentParagraphIdentityRegistry, createWorkDocumentExtensions, createWorkDocumentModel, createWorkDocumentModelFromContent, createWorkOfficeDocumentCollaborationBinding as createOfficeDocumentCollaborationBinding, defaultDocumentImageWrapContour, documentAutoLineHeight, documentBookmarkNameExists, documentBookmarkReferenceInstruction, documentBulletListStyle, documentCaptionKind, documentCaptionLabel, documentCitationCount, documentCitationInstruction, documentCitationStyle, documentCitationStyleDetails, documentCitationTags, documentCitationTagsFromInstruction, documentCommentDraftRange, documentCommentViews, documentContentLayoutProperties, documentEquationFromElement, documentEquationText, documentImageCropFromElement, documentImageIdentityFromElement, documentImageLayerFromElement, documentImageLayoutFromElement, documentImageLayoutOptions, documentImagePositionFromElement, documentImageProperties, documentImageWrapContourFromElement, documentInitialSectionLayout, documentModelForContent, documentNoteKey, documentNoteKind, documentOrderedListState, documentPageBordersVisible, documentPageChromeLegacyFields, documentPageGeometryForLayout, documentPageHorizontalMarginTwips, documentPageMarginBody, documentPageMarginsForLayout, documentPageMetrics, documentParagraphBordersDomAttributes, documentParagraphDirection, documentParagraphIdentityFromElement, documentParagraphIndent, documentParagraphPagination, documentParagraphShadingDomAttributes, documentParagraphSpacing, documentParagraphTabStops, documentSectionById, documentSectionDomAttributes, documentSections, documentTabLeaderLabel, documentTableBordersFromElement, documentTableCellFormat, documentTableCellMarginOverridesFromElement, documentTableColumnPercentagesFromElement, documentTableGeometryFromElement, documentTableHorizontalAlignment, documentTableRowIdentityFromElement, documentTableRowOptions, documentTableSizing, documentTextLayoutBatches, documentWordLineHeightFactor, docxBookmarkReferenceTarget, docxDocumentFieldKind, editorDocumentBookmarkReferenceTargets, editorDocumentCaptionTargets, importedDocumentCharacterFormatting, initializeWorkOfficeDocumentCollaboration as initializeOfficeDocumentCollaboration, isContourImageLayout, isDocumentParagraphArtBorderStyle, isValidDocumentCitationTag, materializeWorkDocumentContent, measureDocumentLayoutBlocksIncrementally, millimetersToPixels, mountWorkLiveDocumentCapture, nextDocumentTabAlignment, normalizeDocumentBookmarkName, normalizeDocumentBookmarkNativeId, normalizeDocumentBookmarkReferencesHtml, normalizeDocumentBookmarksHtml, normalizeDocumentCaptionsHtml, normalizeDocumentCitationsHtml, normalizeDocumentColumns, normalizeDocumentEquation, normalizeDocumentFieldsHtml, normalizeDocumentHtml, normalizeDocumentImageAlignment, normalizeDocumentImageCrop, normalizeDocumentImageIdentity, normalizeDocumentImageLayer, normalizeDocumentImageLayoutOptions, normalizeDocumentImagePosition, normalizeDocumentImageWrapContour, normalizeDocumentImageWrapSide, normalizeDocumentNotesHtml, normalizeDocumentPageBorders, normalizeDocumentPageChrome, normalizeDocumentPageGeometry, normalizeDocumentPageMargins, normalizeDocumentPaperSource, normalizeDocumentParagraphBorder, normalizeDocumentParagraphBorders, normalizeDocumentParagraphId, normalizeDocumentParagraphIdentity, normalizeDocumentParagraphIndent, normalizeDocumentTabStops, normalizeDocumentTableBorderStyle, normalizeDocumentTableBorderWidth, normalizeDocumentTableRowHeightRule, normalizeDocumentTableRowIdentity, normalizeDocumentTableVerticalAlign, normalizeTableColor, normalizedTabPosition, pageTwipsToMillimeters, parseDocumentCharacterFormatting, parseDocumentParagraphBordersElement, parseDocumentParagraphShadingElement, parseDocxThemeReference, patchDocxThemeReferences, positionWorkLiveDocumentCapture, readWorkOfficeDocumentCollaboration as readOfficeDocumentCollaboration, renderDocumentAutoLineHeight, renderDocumentTableBorders, renderDocumentTableCellMarginOverrides, resolveDocumentPageBorders, resolveDocumentPageChrome, resolveDocumentPageMargins, resolveDocumentPageSize, resolveWorkDocumentEditorInput, retainAnchoredDocumentComments, sanitizeDocumentPageChromeHtml, serializeDocumentTabStops, serializeDocxThemeReference, serializeWorkDocumentNode, setCustomDocumentColumns, supportedDocxBookmarkReferenceInstruction, syncDocumentContentFromHtml, uniqueDocumentImageIdentity, uniqueDocumentParagraphIdentity, updateDocumentColumnWidth, updateDocumentCustomPageMillimeters, updateDocumentGutterPosition, updateDocumentMirrorMargins, updateDocumentPageChromeVariant, updateDocumentPageMarginMillimeters, updateDocumentPageMarginMode, updateDocumentPageOrientation, updateDocumentPaperSizePreset, validateDocumentBookmarkName, workDocumentSchema, workOfficeDocumentCollaborationFragment as officeDocumentCollaborationFragment, work_document_page_margins_twipsToMillimeters, wrapsBesideImage };
|
|
18085
|
+
export { DEFAULT_DOCUMENT_TABLE_CELL_FORMAT, DEFAULT_DOCUMENT_TABLE_CELL_MARGINS, DEFAULT_DOCUMENT_TABLE_GEOMETRY, DOCUMENT_BOOKMARK_DUPLICATE_MESSAGE, DOCUMENT_PAGE_BORDER_EDGES, DOCUMENT_PAGE_MARGIN_KEYS, DOCUMENT_PARAGRAPH_BORDER_EDGES, DOCUMENT_PARAGRAPH_BORDER_STYLES, DOCUMENT_PARAGRAPH_SHADING_PATTERNS, DOCUMENT_TABLE_ROW_ID_ATTRIBUTE, DOCUMENT_TABLE_ROW_TEXT_ID_ATTRIBUTE, DOCUMENT_TABLE_STYLE_OPTIONS, DocumentEquation, DocumentImage, DocumentParagraphFormatting, DocumentParagraphIdentity, DocumentSubscript, DocumentSuperscript, DocumentTableRowIdentity, DocxThemePatchCollector, MAX_DOCUMENT_IMAGE_RELATIVE_HEIGHT, MAX_DOCUMENT_NUMBERING_START, activeDocumentBookmark, activeDocumentSection, activeDocumentTableStyle, applyDocumentImageCropToElement, applyDocumentImageIdentityToElement, applyDocumentImageLayerToElement, applyDocumentImageWrapContourToElement, applyDocumentPageGeometry, applyDocumentParagraphIdentityToElement, applyDocumentTableGeometryToElement, applyDocumentTableRowIdentityToElement, canChangeDocumentIndent, canInsertDocumentComment, canSetDocumentTableRowRepeatHeader, clampDocumentMargin, collectDocumentChanges, collectDocumentCommentAnchors, collectDocumentNotes, collectDocumentTextLayoutParagraphs, createDocumentBibliography, createDocumentEquationElement, createDocumentImageIdentityRegistry, createDocumentNoteElement, createDocumentParagraphIdentityRegistry, createWorkDocumentExtensions, createWorkDocumentModel, createWorkDocumentModelFromContent, createWorkOfficeDocumentCollaborationBinding as createOfficeDocumentCollaborationBinding, defaultDocumentImageWrapContour, documentAutoLineHeight, documentBookmarkNameExists, documentBookmarkReferenceInstruction, documentBulletListStyle, documentCaptionKind, documentCaptionLabel, documentCitationCount, documentCitationInstruction, documentCitationStyle, documentCitationStyleDetails, documentCitationTags, documentCitationTagsFromInstruction, documentCommentDraftRange, documentCommentViews, documentContentLayoutProperties, documentEquationFromElement, documentEquationText, documentImageCropFromElement, documentImageIdentityFromElement, documentImageLayerFromElement, documentImageLayoutFromElement, documentImageLayoutOptions, documentImagePositionFromElement, documentImageProperties, documentImageWrapContourFromElement, documentInitialSectionLayout, documentModelForContent, documentNoteKey, documentNoteKind, documentOrderedListState, documentPageBordersVisible, documentPageChromeLegacyFields, documentPageGeometryForLayout, documentPageHorizontalMarginTwips, documentPageMarginBody, documentPageMarginsForLayout, documentPageMetrics, documentParagraphBordersDomAttributes, documentParagraphDirection, documentParagraphIdentityFromElement, documentParagraphIndent, documentParagraphPagination, documentParagraphShadingDomAttributes, documentParagraphSpacing, documentParagraphTabStops, documentSectionById, documentSectionDomAttributes, documentSections, documentTabLeaderLabel, documentTableBordersFromElement, documentTableCellFormat, documentTableCellMarginOverridesFromElement, documentTableColumnPercentagesFromElement, documentTableGeometryFromElement, documentTableHorizontalAlignment, documentTableRowIdentityFromElement, documentTableRowOptions, documentTableSizing, documentTextLayoutBatches, documentWordLineHeightFactor, docxBookmarkReferenceTarget, docxDocumentFieldKind, editorDocumentBookmarkReferenceTargets, editorDocumentCaptionTargets, importedDocumentCharacterFormatting, initializeWorkOfficeDocumentCollaboration as initializeOfficeDocumentCollaboration, isContourImageLayout, isDocumentParagraphArtBorderStyle, isValidDocumentCitationTag, materializeWorkDocumentContent, measureDocumentLayoutBlocksIncrementally, millimetersToPixels, mountWorkLiveDocumentCapture, nextDocumentTabAlignment, normalizeDocumentBookmarkName, normalizeDocumentBookmarkNativeId, normalizeDocumentBookmarkReferencesHtml, normalizeDocumentBookmarksHtml, normalizeDocumentCaptionsHtml, normalizeDocumentCitationsHtml, normalizeDocumentColumns, normalizeDocumentEquation, normalizeDocumentFieldsHtml, normalizeDocumentHtml, normalizeDocumentImageAlignment, normalizeDocumentImageCrop, normalizeDocumentImageIdentity, normalizeDocumentImageLayer, normalizeDocumentImageLayoutOptions, normalizeDocumentImagePosition, normalizeDocumentImageWrapContour, normalizeDocumentImageWrapSide, normalizeDocumentNotesHtml, normalizeDocumentPageBorders, normalizeDocumentPageChrome, normalizeDocumentPageGeometry, normalizeDocumentPageMargins, normalizeDocumentPaperSource, normalizeDocumentParagraphBorder, normalizeDocumentParagraphBorders, normalizeDocumentParagraphId, normalizeDocumentParagraphIdentity, normalizeDocumentParagraphIndent, normalizeDocumentTabStops, normalizeDocumentTableBorderStyle, normalizeDocumentTableBorderWidth, normalizeDocumentTableRowHeightRule, normalizeDocumentTableRowIdentity, normalizeDocumentTableVerticalAlign, normalizeTableColor, normalizedTabPosition, pageTwipsToMillimeters, parseDocumentCharacterFormatting, parseDocumentParagraphBordersElement, parseDocumentParagraphFormatting, parseDocumentParagraphShadingElement, parseDocxThemeReference, patchDocxThemeReferences, positionWorkLiveDocumentCapture, readWorkOfficeDocumentCollaboration as readOfficeDocumentCollaboration, renderDocumentAutoLineHeight, renderDocumentTableBorders, renderDocumentTableCellMarginOverrides, resolveDocumentPageBorders, resolveDocumentPageChrome, resolveDocumentPageMargins, resolveDocumentPageSize, resolveWorkDocumentEditorInput, retainAnchoredDocumentComments, sanitizeDocumentPageChromeHtml, serializeDocumentParagraphFormatting, serializeDocumentTabStops, serializeDocxThemeReference, serializeWorkDocumentNode, setCustomDocumentColumns, supportedDocxBookmarkReferenceInstruction, syncDocumentContentFromHtml, uniqueDocumentImageIdentity, uniqueDocumentParagraphIdentity, updateDocumentColumnWidth, updateDocumentCustomPageMillimeters, updateDocumentGutterPosition, updateDocumentMirrorMargins, updateDocumentPageChromeVariant, updateDocumentPageMarginMillimeters, updateDocumentPageMarginMode, updateDocumentPageOrientation, updateDocumentPaperSizePreset, validateDocumentBookmarkName, workDocumentSchema, workOfficeDocumentCollaborationFragment as officeDocumentCollaborationFragment, work_document_page_margins_twipsToMillimeters, wrapsBesideImage };
|