@a3s-lab/office 0.9.2 → 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 +29 -5
- package/README.md +19 -6
- package/dist/{0~7754.js → 0~5093.js} +1449 -3
- package/dist/0~document-editor.js +8 -1
- package/dist/0~work-docx-export.js +482 -16
- package/dist/0~work-docx-import.js +31 -1142
- package/dist/0~work-office-diagnostics.js +9 -5
- package/dist/4104.js +1 -1
- package/dist/8928.js +763 -149
- package/dist/internal/features/work/work-document-format-change-tracking.d.ts +9 -0
- package/dist/internal/features/work/work-document-format-changes.d.ts +28 -0
- 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-format-change-export.d.ts +17 -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-run-formatting-import.d.ts +10 -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 +28 -0
- package/docs/latest/en/browser-editor-architecture.md +18 -0
- package/package.json +7 -3
package/dist/8928.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Extension, Mark, Node as core_Node, ResizableNodeView, generateHTML, getSchema, mergeAttributes } from "@tiptap/core";
|
|
2
2
|
import { Collaboration, isChangeOrigin } from "@tiptap/extension-collaboration";
|
|
3
3
|
import { NodeSelection, Plugin, PluginKey, TextSelection } from "@tiptap/pm/state";
|
|
4
|
-
import { AddMarkStep, Mapping, RemoveMarkStep, ReplaceStep } from "@tiptap/pm/transform";
|
|
4
|
+
import { AddMarkStep, Mapping, RemoveMarkStep, ReplaceAroundStep, ReplaceStep } from "@tiptap/pm/transform";
|
|
5
5
|
import { defaultDeleteFilter, defaultProtectedNodes, prosemirrorJSONToYXmlFragment, ySyncPluginKey, yXmlFragmentToProsemirrorJSON } from "@tiptap/y-tiptap";
|
|
6
6
|
import extension_color from "@tiptap/extension-color";
|
|
7
7
|
import { Table, TableCell, TableHeader, TableKit, TableRow, TableView, createTable } from "@tiptap/extension-table";
|
|
@@ -8382,6 +8382,570 @@ function work_document_caption_nodes_stringAttribute(value) {
|
|
|
8382
8382
|
function isBookmarkCrossReferenceTarget(target) {
|
|
8383
8383
|
return 'type' in target && 'bookmark' === target.type;
|
|
8384
8384
|
}
|
|
8385
|
+
const DOCUMENT_CHARACTER_FORMAT_MARKS = [
|
|
8386
|
+
'bold',
|
|
8387
|
+
'italic',
|
|
8388
|
+
'underline',
|
|
8389
|
+
'strike',
|
|
8390
|
+
"subscript",
|
|
8391
|
+
"superscript",
|
|
8392
|
+
'textStyle',
|
|
8393
|
+
'highlight'
|
|
8394
|
+
];
|
|
8395
|
+
const CHARACTER_FORMAT_MARK_NAMES = new Set(DOCUMENT_CHARACTER_FORMAT_MARKS);
|
|
8396
|
+
const CHARACTER_FORMAT_MARK_ORDER = new Map(DOCUMENT_CHARACTER_FORMAT_MARKS.map((name, index)=>[
|
|
8397
|
+
name,
|
|
8398
|
+
index
|
|
8399
|
+
]));
|
|
8400
|
+
const MAX_CHARACTER_FORMAT_SNAPSHOT_BYTES = 4096;
|
|
8401
|
+
const MAX_CHARACTER_FORMAT_ATTRIBUTE_LENGTH = 512;
|
|
8402
|
+
const ALLOWED_ATTRIBUTES = {
|
|
8403
|
+
bold: new Set(),
|
|
8404
|
+
italic: new Set(),
|
|
8405
|
+
underline: new Set(),
|
|
8406
|
+
strike: new Set(),
|
|
8407
|
+
subscript: new Set(),
|
|
8408
|
+
superscript: new Set(),
|
|
8409
|
+
textStyle: new Set([
|
|
8410
|
+
'color',
|
|
8411
|
+
'fontFamily',
|
|
8412
|
+
'fontSize',
|
|
8413
|
+
'themeColor',
|
|
8414
|
+
'wordLineHeightFactor',
|
|
8415
|
+
'wordSnapToGrid'
|
|
8416
|
+
]),
|
|
8417
|
+
highlight: new Set([
|
|
8418
|
+
'color',
|
|
8419
|
+
'themeFill'
|
|
8420
|
+
])
|
|
8421
|
+
};
|
|
8422
|
+
function isDocumentCharacterFormatMark(value) {
|
|
8423
|
+
return CHARACTER_FORMAT_MARK_NAMES.has(value);
|
|
8424
|
+
}
|
|
8425
|
+
function serializeDocumentCharacterFormatting(marks) {
|
|
8426
|
+
return JSON.stringify(marks.flatMap((mark)=>{
|
|
8427
|
+
const normalized = normalizeCharacterFormatMark({
|
|
8428
|
+
type: mark.type.name,
|
|
8429
|
+
attrs: mark.attrs
|
|
8430
|
+
});
|
|
8431
|
+
return normalized ? [
|
|
8432
|
+
normalized
|
|
8433
|
+
] : [];
|
|
8434
|
+
}).sort(compareCharacterFormatMarks));
|
|
8435
|
+
}
|
|
8436
|
+
function parseDocumentCharacterFormatting(value) {
|
|
8437
|
+
if ('string' != typeof value || value.length > MAX_CHARACTER_FORMAT_SNAPSHOT_BYTES) return null;
|
|
8438
|
+
let parsed;
|
|
8439
|
+
try {
|
|
8440
|
+
parsed = JSON.parse(value);
|
|
8441
|
+
} catch {
|
|
8442
|
+
return null;
|
|
8443
|
+
}
|
|
8444
|
+
if (!Array.isArray(parsed) || parsed.length > DOCUMENT_CHARACTER_FORMAT_MARKS.length) return null;
|
|
8445
|
+
const result = [];
|
|
8446
|
+
const names = new Set();
|
|
8447
|
+
for (const candidate of parsed){
|
|
8448
|
+
const mark = normalizeCharacterFormatMark(candidate);
|
|
8449
|
+
if (!mark || names.has(mark.type)) return null;
|
|
8450
|
+
names.add(mark.type);
|
|
8451
|
+
result.push(mark);
|
|
8452
|
+
}
|
|
8453
|
+
result.sort(compareCharacterFormatMarks);
|
|
8454
|
+
return JSON.stringify(result) === value ? result : null;
|
|
8455
|
+
}
|
|
8456
|
+
function restoreDocumentCharacterFormatting(transaction, schema, from, to, serialized) {
|
|
8457
|
+
const formatting = parseDocumentCharacterFormatting(serialized);
|
|
8458
|
+
if (!formatting || from < 0 || to <= from || to > transaction.doc.content.size) return false;
|
|
8459
|
+
for (const name of DOCUMENT_CHARACTER_FORMAT_MARKS){
|
|
8460
|
+
const type = schema.marks[name];
|
|
8461
|
+
if (type) transaction.removeMark(from, to, type);
|
|
8462
|
+
}
|
|
8463
|
+
for (const mark of formatting){
|
|
8464
|
+
const type = schema.marks[mark.type];
|
|
8465
|
+
if (!type) return false;
|
|
8466
|
+
transaction.addMark(from, to, createCharacterFormatMark(type, mark));
|
|
8467
|
+
}
|
|
8468
|
+
return true;
|
|
8469
|
+
}
|
|
8470
|
+
function importedDocumentCharacterFormatting(formatting) {
|
|
8471
|
+
const marks = [];
|
|
8472
|
+
for (const name of [
|
|
8473
|
+
'bold',
|
|
8474
|
+
'italic',
|
|
8475
|
+
'underline',
|
|
8476
|
+
'strike',
|
|
8477
|
+
"subscript",
|
|
8478
|
+
"superscript"
|
|
8479
|
+
])if (formatting[name]) marks.push({
|
|
8480
|
+
type: name
|
|
8481
|
+
});
|
|
8482
|
+
const textStyle = compactAttributes({
|
|
8483
|
+
color: formatting.color,
|
|
8484
|
+
fontFamily: formatting.fontFamily,
|
|
8485
|
+
fontSize: void 0 === formatting.fontSize ? void 0 : `${formatting.fontSize}pt`,
|
|
8486
|
+
themeColor: formatting.themeColor,
|
|
8487
|
+
wordLineHeightFactor: formatting.wordLineHeightFactor,
|
|
8488
|
+
wordSnapToGrid: formatting.wordSnapToGrid
|
|
8489
|
+
});
|
|
8490
|
+
if (textStyle) marks.push({
|
|
8491
|
+
type: 'textStyle',
|
|
8492
|
+
attrs: textStyle
|
|
8493
|
+
});
|
|
8494
|
+
const highlight = compactAttributes({
|
|
8495
|
+
color: formatting.backgroundColor,
|
|
8496
|
+
themeFill: formatting.themeFill
|
|
8497
|
+
});
|
|
8498
|
+
if (highlight) marks.push({
|
|
8499
|
+
type: 'highlight',
|
|
8500
|
+
attrs: highlight
|
|
8501
|
+
});
|
|
8502
|
+
marks.sort(compareCharacterFormatMarks);
|
|
8503
|
+
return JSON.stringify(marks);
|
|
8504
|
+
}
|
|
8505
|
+
function normalizeCharacterFormatMark(value) {
|
|
8506
|
+
if (!work_document_format_changes_isRecord(value) || 'string' != typeof value.type) return null;
|
|
8507
|
+
if (!isDocumentCharacterFormatMark(value.type)) return null;
|
|
8508
|
+
const type = value.type;
|
|
8509
|
+
const allowed = ALLOWED_ATTRIBUTES[type];
|
|
8510
|
+
const source = value.attrs;
|
|
8511
|
+
if (void 0 !== source && !work_document_format_changes_isRecord(source)) return null;
|
|
8512
|
+
const attrs = {};
|
|
8513
|
+
for (const [key, candidate] of Object.entries(source ?? {}))if (allowed.has(key) && null != candidate) {
|
|
8514
|
+
if ('string' == typeof candidate) {
|
|
8515
|
+
if (!candidate.length || candidate.length > MAX_CHARACTER_FORMAT_ATTRIBUTE_LENGTH) return null;
|
|
8516
|
+
attrs[key] = candidate;
|
|
8517
|
+
continue;
|
|
8518
|
+
}
|
|
8519
|
+
if ('boolean' == typeof candidate) {
|
|
8520
|
+
attrs[key] = candidate;
|
|
8521
|
+
continue;
|
|
8522
|
+
}
|
|
8523
|
+
if ('number' == typeof candidate && Number.isFinite(candidate)) {
|
|
8524
|
+
attrs[key] = candidate;
|
|
8525
|
+
continue;
|
|
8526
|
+
}
|
|
8527
|
+
return null;
|
|
8528
|
+
}
|
|
8529
|
+
const keys = Object.keys(attrs).sort();
|
|
8530
|
+
const normalizedAttributes = keys.length ? Object.fromEntries(keys.map((key)=>[
|
|
8531
|
+
key,
|
|
8532
|
+
attrs[key]
|
|
8533
|
+
])) : void 0;
|
|
8534
|
+
return {
|
|
8535
|
+
type,
|
|
8536
|
+
...normalizedAttributes ? {
|
|
8537
|
+
attrs: normalizedAttributes
|
|
8538
|
+
} : {}
|
|
8539
|
+
};
|
|
8540
|
+
}
|
|
8541
|
+
function compareCharacterFormatMarks(left, right) {
|
|
8542
|
+
return (CHARACTER_FORMAT_MARK_ORDER.get(left.type) ?? Number.MAX_SAFE_INTEGER) - (CHARACTER_FORMAT_MARK_ORDER.get(right.type) ?? Number.MAX_SAFE_INTEGER);
|
|
8543
|
+
}
|
|
8544
|
+
function createCharacterFormatMark(type, value) {
|
|
8545
|
+
return type.create(value.attrs ?? void 0);
|
|
8546
|
+
}
|
|
8547
|
+
function compactAttributes(value) {
|
|
8548
|
+
const entries = Object.entries(value).filter((entry)=>void 0 !== entry[1]);
|
|
8549
|
+
return entries.length ? Object.fromEntries(entries) : void 0;
|
|
8550
|
+
}
|
|
8551
|
+
function work_document_format_changes_isRecord(value) {
|
|
8552
|
+
return 'object' == typeof value && null !== value && !Array.isArray(value);
|
|
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
|
+
}
|
|
8852
|
+
function trackDocumentFormattingTransaction(transaction, state, type, options, pluginKey) {
|
|
8853
|
+
if (!options.isTracking() || state.doc.eq(transaction.doc)) return;
|
|
8854
|
+
const sync = transaction.getMeta(ySyncPluginKey);
|
|
8855
|
+
if (transaction.getMeta(pluginKey) || sync?.isChangeOrigin || isHistoryTransaction(transaction)) return;
|
|
8856
|
+
const ranges = formattingStepRanges(transaction);
|
|
8857
|
+
const formattedDocument = transaction.doc;
|
|
8858
|
+
let identity = null;
|
|
8859
|
+
for (const range of ranges)for (const segment of formattingSegments(state.doc, formattedDocument, range)){
|
|
8860
|
+
const beforeMarks = textMarksAt(state.doc, segment.from, segment.to);
|
|
8861
|
+
const afterMarks = textMarksAt(formattedDocument, segment.from, segment.to);
|
|
8862
|
+
if (!beforeMarks || !afterMarks) continue;
|
|
8863
|
+
if (state.doc.textBetween(segment.from, segment.to) !== formattedDocument.textBetween(segment.from, segment.to)) continue;
|
|
8864
|
+
const before = serializeDocumentCharacterFormatting(beforeMarks);
|
|
8865
|
+
const after = serializeDocumentCharacterFormatting(afterMarks);
|
|
8866
|
+
if (!(before === after || documentChangeMark(afterMarks))) {
|
|
8867
|
+
identity ??= options.createChange('formatting');
|
|
8868
|
+
transaction.addMark(segment.from, segment.to, type.create({
|
|
8869
|
+
kind: 'formatting',
|
|
8870
|
+
id: identity.id,
|
|
8871
|
+
actorId: identity.actorId ?? '',
|
|
8872
|
+
author: identity.author || 'A3S Work',
|
|
8873
|
+
date: identity.date || new Date().toISOString(),
|
|
8874
|
+
before
|
|
8875
|
+
}));
|
|
8876
|
+
}
|
|
8877
|
+
}
|
|
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
|
+
} : {}
|
|
8888
|
+
});
|
|
8889
|
+
}
|
|
8890
|
+
function formattingStepRanges(transaction) {
|
|
8891
|
+
if (transaction.steps.some((step)=>step instanceof ReplaceStep)) return [];
|
|
8892
|
+
const ranges = [];
|
|
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({
|
|
8894
|
+
from: step.from,
|
|
8895
|
+
to: step.to
|
|
8896
|
+
});
|
|
8897
|
+
return mergeFormattingRanges(ranges);
|
|
8898
|
+
}
|
|
8899
|
+
function mergeFormattingRanges(ranges) {
|
|
8900
|
+
const merged = [];
|
|
8901
|
+
for (const range of ranges.sort((left, right)=>left.from - right.from)){
|
|
8902
|
+
const previous = merged.at(-1);
|
|
8903
|
+
if (!previous || range.from > previous.to) {
|
|
8904
|
+
merged.push({
|
|
8905
|
+
...range
|
|
8906
|
+
});
|
|
8907
|
+
continue;
|
|
8908
|
+
}
|
|
8909
|
+
previous.to = Math.max(previous.to, range.to);
|
|
8910
|
+
}
|
|
8911
|
+
return merged;
|
|
8912
|
+
}
|
|
8913
|
+
function formattingSegments(before, after, range) {
|
|
8914
|
+
const boundaries = new Set([
|
|
8915
|
+
range.from,
|
|
8916
|
+
range.to
|
|
8917
|
+
]);
|
|
8918
|
+
collectFormattingBoundaries(before, range, boundaries);
|
|
8919
|
+
collectFormattingBoundaries(after, range, boundaries);
|
|
8920
|
+
const ordered = Array.from(boundaries).sort((left, right)=>left - right);
|
|
8921
|
+
return ordered.slice(0, -1).flatMap((from, index)=>{
|
|
8922
|
+
const to = ordered[index + 1];
|
|
8923
|
+
return void 0 !== to && from < to ? [
|
|
8924
|
+
{
|
|
8925
|
+
from,
|
|
8926
|
+
to
|
|
8927
|
+
}
|
|
8928
|
+
] : [];
|
|
8929
|
+
});
|
|
8930
|
+
}
|
|
8931
|
+
function collectFormattingBoundaries(document1, range, boundaries) {
|
|
8932
|
+
document1.nodesBetween(range.from, range.to, (node, position)=>{
|
|
8933
|
+
if (!node.isText) return;
|
|
8934
|
+
boundaries.add(Math.max(range.from, position));
|
|
8935
|
+
boundaries.add(Math.min(range.to, position + node.nodeSize));
|
|
8936
|
+
});
|
|
8937
|
+
}
|
|
8938
|
+
function textMarksAt(document1, from, to) {
|
|
8939
|
+
let marks = null;
|
|
8940
|
+
document1.nodesBetween(from, to, (node, position)=>{
|
|
8941
|
+
if (marks || !node.isText || position > from || position + node.nodeSize < to) return;
|
|
8942
|
+
marks = node.marks;
|
|
8943
|
+
});
|
|
8944
|
+
return marks;
|
|
8945
|
+
}
|
|
8946
|
+
function documentChangeMark(marks) {
|
|
8947
|
+
return marks.find((mark)=>'documentChange' === mark.type.name);
|
|
8948
|
+
}
|
|
8385
8949
|
const documentChangePluginKey = new PluginKey('documentChangeTracking');
|
|
8386
8950
|
const CONTINUOUS_INSERTION_WINDOW_MS = 30000;
|
|
8387
8951
|
const DocumentChange = Mark.create({
|
|
@@ -8404,7 +8968,11 @@ const DocumentChange = Mark.create({
|
|
|
8404
8968
|
return {
|
|
8405
8969
|
kind: {
|
|
8406
8970
|
default: 'insertion',
|
|
8407
|
-
parseHTML: (element)=>
|
|
8971
|
+
parseHTML: (element)=>{
|
|
8972
|
+
const declared = element.getAttribute('data-change-kind');
|
|
8973
|
+
if ('formatting' === declared) return 'formatting';
|
|
8974
|
+
return 'del' === element.tagName.toLowerCase() ? 'deletion' : 'insertion';
|
|
8975
|
+
},
|
|
8408
8976
|
renderHTML: (attributes)=>({
|
|
8409
8977
|
'data-change-kind': attributes.kind
|
|
8410
8978
|
})
|
|
@@ -8436,9 +9004,34 @@ const DocumentChange = Mark.create({
|
|
|
8436
9004
|
renderHTML: (attributes)=>({
|
|
8437
9005
|
'data-change-date': attributes.date
|
|
8438
9006
|
})
|
|
9007
|
+
},
|
|
9008
|
+
before: {
|
|
9009
|
+
default: '',
|
|
9010
|
+
parseHTML: (element)=>element.getAttribute('data-change-before') ?? '',
|
|
9011
|
+
renderHTML: (attributes)=>attributes.before ? {
|
|
9012
|
+
'data-change-before': attributes.before
|
|
9013
|
+
} : {}
|
|
8439
9014
|
}
|
|
8440
9015
|
};
|
|
8441
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
|
+
},
|
|
8442
9035
|
parseHTML () {
|
|
8443
9036
|
return [
|
|
8444
9037
|
{
|
|
@@ -8446,12 +9039,16 @@ const DocumentChange = Mark.create({
|
|
|
8446
9039
|
},
|
|
8447
9040
|
{
|
|
8448
9041
|
tag: 'del[data-document-change]'
|
|
9042
|
+
},
|
|
9043
|
+
{
|
|
9044
|
+
tag: 'span[data-document-change][data-change-kind="formatting"]'
|
|
8449
9045
|
}
|
|
8450
9046
|
];
|
|
8451
9047
|
},
|
|
8452
9048
|
renderHTML ({ mark, HTMLAttributes }) {
|
|
9049
|
+
const tag = 'deletion' === mark.attrs.kind ? 'del' : 'formatting' === mark.attrs.kind ? 'span' : 'ins';
|
|
8453
9050
|
return [
|
|
8454
|
-
|
|
9051
|
+
tag,
|
|
8455
9052
|
mergeAttributes(HTMLAttributes, {
|
|
8456
9053
|
'data-document-change': 'true'
|
|
8457
9054
|
}),
|
|
@@ -8491,6 +9088,19 @@ const DocumentChange = Mark.create({
|
|
|
8491
9088
|
return [
|
|
8492
9089
|
new Plugin({
|
|
8493
9090
|
key: documentChangePluginKey,
|
|
9091
|
+
filterTransaction: (transaction, state)=>{
|
|
9092
|
+
trackDocumentFormattingTransaction(transaction, state, changeType, {
|
|
9093
|
+
isTracking: options.isTracking,
|
|
9094
|
+
createChange: (kind)=>{
|
|
9095
|
+
const identity = options.createChange(kind);
|
|
9096
|
+
return {
|
|
9097
|
+
...identity,
|
|
9098
|
+
id: identity.id || createDocumentChangeId()
|
|
9099
|
+
};
|
|
9100
|
+
}
|
|
9101
|
+
}, documentChangePluginKey);
|
|
9102
|
+
return true;
|
|
9103
|
+
},
|
|
8494
9104
|
props: {
|
|
8495
9105
|
handleTextInput: (view, from, to, text)=>{
|
|
8496
9106
|
if (!options.isTracking()) return false;
|
|
@@ -8536,8 +9146,31 @@ const DocumentChange = Mark.create({
|
|
|
8536
9146
|
function collectDocumentChanges(document1) {
|
|
8537
9147
|
const changes = new Map();
|
|
8538
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
|
+
}
|
|
8539
9172
|
if (!node.isText || !node.text) return;
|
|
8540
|
-
const mark =
|
|
9173
|
+
const mark = work_document_changes_documentChangeMark(node.marks);
|
|
8541
9174
|
if (!mark) return;
|
|
8542
9175
|
const kind = changeKind(mark.attrs.kind);
|
|
8543
9176
|
const id = work_document_changes_stringAttribute(mark.attrs.id) || `change-at-${position}`;
|
|
@@ -8566,16 +9199,39 @@ function collectDocumentChanges(document1) {
|
|
|
8566
9199
|
}
|
|
8567
9200
|
function resolveDocumentChangesCommand({ state, tr }, type, decision, ids) {
|
|
8568
9201
|
const segments = documentChangeSegments(state.doc, type).filter((segment)=>!ids || ids.has(segment.id));
|
|
8569
|
-
|
|
8570
|
-
|
|
8571
|
-
|
|
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);
|
|
9206
|
+
tr.setMeta(documentChangePluginKey, {
|
|
9207
|
+
decision
|
|
9208
|
+
});
|
|
9209
|
+
const markRemovals = [];
|
|
9210
|
+
const contentDeletions = [];
|
|
9211
|
+
const formattingRejections = [];
|
|
8572
9212
|
for (const segment of segments){
|
|
8573
|
-
|
|
8574
|
-
|
|
8575
|
-
|
|
8576
|
-
|
|
8577
|
-
|
|
8578
|
-
|
|
9213
|
+
if ('formatting' === segment.kind) {
|
|
9214
|
+
markRemovals.push(segment);
|
|
9215
|
+
if ('reject' === decision) formattingRejections.push(segment);
|
|
9216
|
+
continue;
|
|
9217
|
+
}
|
|
9218
|
+
const removeMark = 'accept' === decision && 'insertion' === segment.kind || 'reject' === decision && 'deletion' === segment.kind;
|
|
9219
|
+
(removeMark ? markRemovals : contentDeletions).push(segment);
|
|
9220
|
+
}
|
|
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
|
+
}
|
|
9229
|
+
for (const segment of markRemovals)tr.removeMark(segment.from, segment.to, type);
|
|
9230
|
+
for (const segment of contentDeletions.sort((left, right)=>right.from - left.from))tr.delete(segment.from, segment.to);
|
|
9231
|
+
return tr.docChanged ? new Set([
|
|
9232
|
+
...segments,
|
|
9233
|
+
...paragraphSegments
|
|
9234
|
+
].map((segment)=>segment.id)).size : 0;
|
|
8579
9235
|
}
|
|
8580
9236
|
function trackedReplacement(transaction, document1, type, from, to, text, createChange) {
|
|
8581
9237
|
if (from !== to) trackDeletion(transaction, document1, type, from, to, changeMark(type, 'deletion', createChange));
|
|
@@ -8622,7 +9278,23 @@ function documentChangeSegments(document1, type) {
|
|
|
8622
9278
|
id: work_document_changes_stringAttribute(mark.attrs.id) || `change-at-${position}`,
|
|
8623
9279
|
kind: changeKind(mark.attrs.kind),
|
|
8624
9280
|
from: position,
|
|
8625
|
-
to: position + node.nodeSize
|
|
9281
|
+
to: position + node.nodeSize,
|
|
9282
|
+
before: work_document_changes_stringAttribute(mark.attrs.before)
|
|
9283
|
+
});
|
|
9284
|
+
});
|
|
9285
|
+
return segments;
|
|
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)
|
|
8626
9298
|
});
|
|
8627
9299
|
});
|
|
8628
9300
|
return segments;
|
|
@@ -8653,14 +9325,15 @@ function adjacentTextRange(document1, position, direction) {
|
|
|
8653
9325
|
to: position + character.length
|
|
8654
9326
|
};
|
|
8655
9327
|
}
|
|
8656
|
-
function changeMark(type, kind, createChange) {
|
|
9328
|
+
function changeMark(type, kind, createChange, before = '') {
|
|
8657
9329
|
const identity = createChange(kind);
|
|
8658
9330
|
return type.create({
|
|
8659
9331
|
kind,
|
|
8660
9332
|
id: identity.id || createDocumentChangeId(),
|
|
8661
9333
|
actorId: identity.actorId ?? '',
|
|
8662
9334
|
author: identity.author || 'A3S Work',
|
|
8663
|
-
date: identity.date || new Date().toISOString()
|
|
9335
|
+
date: identity.date || new Date().toISOString(),
|
|
9336
|
+
before
|
|
8664
9337
|
});
|
|
8665
9338
|
}
|
|
8666
9339
|
function continuousInsertionMark(document1, type, position, createChange) {
|
|
@@ -8674,11 +9347,33 @@ function continuousInsertionMark(document1, type, position, createChange) {
|
|
|
8674
9347
|
if (!Number.isFinite(previousTime) || !Number.isFinite(nextTime) || Math.abs(nextTime - previousTime) > CONTINUOUS_INSERTION_WINDOW_MS) return next;
|
|
8675
9348
|
return previous;
|
|
8676
9349
|
}
|
|
8677
|
-
function
|
|
9350
|
+
function work_document_changes_documentChangeMark(marks) {
|
|
8678
9351
|
return marks.find((mark)=>'documentChange' === mark.type.name);
|
|
8679
9352
|
}
|
|
8680
9353
|
function changeKind(value) {
|
|
8681
|
-
|
|
9354
|
+
if ('deletion' === value || 'formatting' === value) return value;
|
|
9355
|
+
return 'insertion';
|
|
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
|
+
};
|
|
8682
9377
|
}
|
|
8683
9378
|
function work_document_changes_stringAttribute(value) {
|
|
8684
9379
|
return 'string' == typeof value ? value : '';
|
|
@@ -11134,7 +11829,7 @@ const DocumentPageBreak = core_Node.create({
|
|
|
11134
11829
|
});
|
|
11135
11830
|
const DOCUMENT_INDENT_STEP_PX = 24;
|
|
11136
11831
|
const MAX_DOCUMENT_INDENT_LEVEL = 8;
|
|
11137
|
-
const
|
|
11832
|
+
const work_document_paragraph_formatting_MAX_DOCUMENT_INDENT_PX = DOCUMENT_INDENT_STEP_PX * MAX_DOCUMENT_INDENT_LEVEL;
|
|
11138
11833
|
const DOCUMENT_WORD_SINGLE_LINE_HEIGHT = 1.15;
|
|
11139
11834
|
const DocumentParagraphFormatting = Extension.create({
|
|
11140
11835
|
name: 'documentParagraphFormatting',
|
|
@@ -11148,9 +11843,9 @@ const DocumentParagraphFormatting = Extension.create({
|
|
|
11148
11843
|
attributes: {
|
|
11149
11844
|
lineHeight: {
|
|
11150
11845
|
default: null,
|
|
11151
|
-
parseHTML: (element)=>
|
|
11846
|
+
parseHTML: (element)=>work_document_paragraph_formatting_normalizedLineHeight(element.style.lineHeight),
|
|
11152
11847
|
renderHTML: (attributes)=>{
|
|
11153
|
-
const lineHeight =
|
|
11848
|
+
const lineHeight = work_document_paragraph_formatting_normalizedLineHeight(attributes.lineHeight);
|
|
11154
11849
|
return lineHeight ? {
|
|
11155
11850
|
style: `line-height: ${lineHeight}`
|
|
11156
11851
|
} : {};
|
|
@@ -11275,7 +11970,7 @@ function documentParagraphIndent(editor) {
|
|
|
11275
11970
|
});
|
|
11276
11971
|
}
|
|
11277
11972
|
function documentParagraphPagination(editor) {
|
|
11278
|
-
const attributes =
|
|
11973
|
+
const attributes = work_document_paragraph_formatting_activeParagraphAttributes(editor);
|
|
11279
11974
|
return {
|
|
11280
11975
|
keepLines: directBoolean(attributes.keepLines) ?? false,
|
|
11281
11976
|
keepWithNext: directBoolean(attributes.keepWithNext) ?? editor.isActive('heading'),
|
|
@@ -11284,15 +11979,15 @@ function documentParagraphPagination(editor) {
|
|
|
11284
11979
|
};
|
|
11285
11980
|
}
|
|
11286
11981
|
function documentParagraphDirection(editor) {
|
|
11287
|
-
const attributes = editor.isActive('listItem') ? editor.getAttributes('listItem') :
|
|
11982
|
+
const attributes = editor.isActive('listItem') ? editor.getAttributes('listItem') : work_document_paragraph_formatting_activeParagraphAttributes(editor);
|
|
11288
11983
|
return normalizeDocumentParagraphDirection(attributes.paragraphDirection) ?? 'ltr';
|
|
11289
11984
|
}
|
|
11290
11985
|
function documentParagraphSpacing(editor) {
|
|
11291
|
-
const attributes =
|
|
11986
|
+
const attributes = work_document_paragraph_formatting_activeParagraphAttributes(editor);
|
|
11292
11987
|
return {
|
|
11293
11988
|
before: normalizedPointSpacing(attributes.spaceBefore),
|
|
11294
11989
|
after: normalizedPointSpacing(attributes.spaceAfter),
|
|
11295
|
-
lineHeight:
|
|
11990
|
+
lineHeight: work_document_paragraph_formatting_normalizedLineHeight(attributes.lineHeight),
|
|
11296
11991
|
lineRule: normalizedLineRule(attributes.lineRule)
|
|
11297
11992
|
};
|
|
11298
11993
|
}
|
|
@@ -11310,7 +12005,7 @@ function normalizeDocumentParagraphDirection(value) {
|
|
|
11310
12005
|
return 'ltr' === normalized || 'rtl' === normalized ? normalized : null;
|
|
11311
12006
|
}
|
|
11312
12007
|
function setDocumentLineHeightCommand({ chain }, lineHeight) {
|
|
11313
|
-
const value =
|
|
12008
|
+
const value = work_document_paragraph_formatting_normalizedLineHeight(lineHeight);
|
|
11314
12009
|
const lineRule = value ? lineRuleForLineHeight(value) : null;
|
|
11315
12010
|
const attributes = {
|
|
11316
12011
|
lineHeight: value,
|
|
@@ -11338,7 +12033,7 @@ function setDocumentIndentLevelCommand(props, indentLevel, options) {
|
|
|
11338
12033
|
}, options);
|
|
11339
12034
|
}
|
|
11340
12035
|
function setDocumentParagraphIndentCommand({ chain, editor }, indent, options) {
|
|
11341
|
-
const nodeTypes =
|
|
12036
|
+
const nodeTypes = work_document_paragraph_formatting_activeParagraphNodeTypes(editor);
|
|
11342
12037
|
if (!nodeTypes.length) return false;
|
|
11343
12038
|
const normalized = normalizeDocumentParagraphIndent(indent);
|
|
11344
12039
|
const attributes = {
|
|
@@ -11363,7 +12058,7 @@ function setDocumentParagraphDirectionCommand({ chain, editor }, direction, opti
|
|
|
11363
12058
|
return commandChain.run();
|
|
11364
12059
|
}
|
|
11365
12060
|
function setDocumentParagraphPaginationCommand({ chain, editor }, pagination, options) {
|
|
11366
|
-
const nodeTypes =
|
|
12061
|
+
const nodeTypes = work_document_paragraph_formatting_activeParagraphNodeTypes(editor);
|
|
11367
12062
|
if (!nodeTypes.length) return false;
|
|
11368
12063
|
const attributes = {};
|
|
11369
12064
|
for (const key of documentParagraphPaginationKeys)if (Object.hasOwn(pagination, key)) attributes[key] = Boolean(pagination[key]);
|
|
@@ -11374,7 +12069,7 @@ function setDocumentParagraphPaginationCommand({ chain, editor }, pagination, op
|
|
|
11374
12069
|
return commandChain.run();
|
|
11375
12070
|
}
|
|
11376
12071
|
function clearDocumentParagraphPaginationCommand({ chain, editor }, options) {
|
|
11377
|
-
const nodeTypes =
|
|
12072
|
+
const nodeTypes = work_document_paragraph_formatting_activeParagraphNodeTypes(editor);
|
|
11378
12073
|
if (!nodeTypes.length) return false;
|
|
11379
12074
|
const attributes = {
|
|
11380
12075
|
keepLines: null,
|
|
@@ -11388,9 +12083,9 @@ function clearDocumentParagraphPaginationCommand({ chain, editor }, options) {
|
|
|
11388
12083
|
return commandChain.run();
|
|
11389
12084
|
}
|
|
11390
12085
|
function setDocumentParagraphSpacingCommand({ chain, editor }, spacing, options) {
|
|
11391
|
-
const nodeTypes =
|
|
12086
|
+
const nodeTypes = work_document_paragraph_formatting_activeParagraphNodeTypes(editor);
|
|
11392
12087
|
if (!nodeTypes.length) return false;
|
|
11393
|
-
const lineHeight =
|
|
12088
|
+
const lineHeight = work_document_paragraph_formatting_normalizedLineHeight(spacing.lineHeight);
|
|
11394
12089
|
const lineRule = normalizedLineRule(spacing.lineRule) ?? (lineHeight ? lineRuleForLineHeight(lineHeight) : null);
|
|
11395
12090
|
const attributes = {
|
|
11396
12091
|
spaceBefore: normalizedPointSpacing(spacing.before),
|
|
@@ -11405,7 +12100,8 @@ function setDocumentParagraphSpacingCommand({ chain, editor }, spacing, options)
|
|
|
11405
12100
|
return commandChain.run();
|
|
11406
12101
|
}
|
|
11407
12102
|
function clearDocumentFormattingCommand({ chain, editor }) {
|
|
11408
|
-
let commandChain = chain().focus()
|
|
12103
|
+
let commandChain = chain().focus();
|
|
12104
|
+
for (const mark of DOCUMENT_CHARACTER_FORMAT_MARKS)if (editor.schema.marks[mark]) commandChain = commandChain.unsetMark(mark);
|
|
11409
12105
|
if (!editor.isActive('listItem')) commandChain = commandChain.setParagraph();
|
|
11410
12106
|
return commandChain.unsetTextAlign().updateAttributes('paragraph', {
|
|
11411
12107
|
indentLevel: 0,
|
|
@@ -11440,7 +12136,7 @@ function normalizedIndentLevel(value) {
|
|
|
11440
12136
|
if (!Number.isFinite(number)) return 0;
|
|
11441
12137
|
return Math.min(MAX_DOCUMENT_INDENT_LEVEL, Math.max(0, Math.round(4 * number) / 4));
|
|
11442
12138
|
}
|
|
11443
|
-
function
|
|
12139
|
+
function work_document_paragraph_formatting_normalizedLineHeight(value) {
|
|
11444
12140
|
if ('string' != typeof value) return null;
|
|
11445
12141
|
const normalized = value.trim();
|
|
11446
12142
|
if (!normalized || 'normal' === normalized) return null;
|
|
@@ -11475,7 +12171,7 @@ function renderDocumentAutoLineHeight(lineHeight, autoLineHeight = documentAutoL
|
|
|
11475
12171
|
};
|
|
11476
12172
|
}
|
|
11477
12173
|
function lineHeightMultiple(value) {
|
|
11478
|
-
const normalized =
|
|
12174
|
+
const normalized = work_document_paragraph_formatting_normalizedLineHeight(value);
|
|
11479
12175
|
if (!normalized) return null;
|
|
11480
12176
|
const percentage = /^(\d+(?:\.\d+)?)%$/.exec(normalized);
|
|
11481
12177
|
const multiple = percentage ? Number(percentage[1]) / 100 : /^\d+(?:\.\d+)?$/.test(normalized) ? Number(normalized) : NaN;
|
|
@@ -11547,20 +12243,20 @@ function parsedSignedIndentPixels(dataValue, cssValue) {
|
|
|
11547
12243
|
function normalizedIndentPixels(value) {
|
|
11548
12244
|
const number = Number(value);
|
|
11549
12245
|
if (!Number.isFinite(number)) return 0;
|
|
11550
|
-
return Math.min(
|
|
12246
|
+
return Math.min(work_document_paragraph_formatting_MAX_DOCUMENT_INDENT_PX, Math.max(0, Math.round(number)));
|
|
11551
12247
|
}
|
|
11552
12248
|
function normalizedSignedIndentPixels(value) {
|
|
11553
12249
|
const number = Number(value);
|
|
11554
12250
|
if (!Number.isFinite(number)) return 0;
|
|
11555
|
-
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)));
|
|
11556
12252
|
}
|
|
11557
12253
|
function normalizedFirstLineIndent(value, leftIndent) {
|
|
11558
|
-
return Math.max(-leftIndent, Math.min(
|
|
12254
|
+
return Math.max(-leftIndent, Math.min(work_document_paragraph_formatting_MAX_DOCUMENT_INDENT_PX, normalizedSignedIndentPixels(value)));
|
|
11559
12255
|
}
|
|
11560
12256
|
function formatPixelValue(value) {
|
|
11561
12257
|
return Number(value.toFixed(2)).toString();
|
|
11562
12258
|
}
|
|
11563
|
-
function
|
|
12259
|
+
function work_document_paragraph_formatting_activeParagraphAttributes(editor) {
|
|
11564
12260
|
return editor.isActive('heading') ? editor.getAttributes('heading') : editor.getAttributes('paragraph');
|
|
11565
12261
|
}
|
|
11566
12262
|
function paragraphDirectionAttribute() {
|
|
@@ -11615,7 +12311,7 @@ function directBoolean(value) {
|
|
|
11615
12311
|
if (false === value || 'false' === value || '0' === value) return false;
|
|
11616
12312
|
return null;
|
|
11617
12313
|
}
|
|
11618
|
-
function
|
|
12314
|
+
function work_document_paragraph_formatting_activeParagraphNodeTypes(editor) {
|
|
11619
12315
|
const nodeTypes = new Set();
|
|
11620
12316
|
if (editor.isActive('paragraph')) nodeTypes.add('paragraph');
|
|
11621
12317
|
if (editor.isActive('heading')) nodeTypes.add('heading');
|
|
@@ -11632,7 +12328,7 @@ function activeParagraphDirectionNodeTypes(editor) {
|
|
|
11632
12328
|
const { from, to } = editor.state.selection;
|
|
11633
12329
|
if (from === to) return editor.isActive('listItem') ? [
|
|
11634
12330
|
'listItem'
|
|
11635
|
-
] :
|
|
12331
|
+
] : work_document_paragraph_formatting_activeParagraphNodeTypes(editor);
|
|
11636
12332
|
const nodeTypes = new Set();
|
|
11637
12333
|
editor.state.doc.nodesBetween(from, to, (node, _position, parent)=>{
|
|
11638
12334
|
if ('listItem' === node.type.name) nodeTypes.add('listItem');
|
|
@@ -11726,108 +12422,6 @@ function elementForNode(editor, position) {
|
|
|
11726
12422
|
if (!node || node.nodeType !== Node.ELEMENT_NODE) return null;
|
|
11727
12423
|
return node;
|
|
11728
12424
|
}
|
|
11729
|
-
const MAX_DOCUMENT_TAB_POSITION_PX = 4096;
|
|
11730
|
-
const MAX_DOCUMENT_TAB_STOPS = 64;
|
|
11731
|
-
const DocumentParagraphTabStops = Extension.create({
|
|
11732
|
-
name: 'documentParagraphTabStops',
|
|
11733
|
-
addGlobalAttributes () {
|
|
11734
|
-
return [
|
|
11735
|
-
{
|
|
11736
|
-
types: [
|
|
11737
|
-
'paragraph',
|
|
11738
|
-
'heading'
|
|
11739
|
-
],
|
|
11740
|
-
attributes: {
|
|
11741
|
-
tabStops: {
|
|
11742
|
-
default: null,
|
|
11743
|
-
parseHTML: (element)=>normalizeDocumentTabStops(element.dataset.officeTabStops),
|
|
11744
|
-
renderHTML: (attributes)=>{
|
|
11745
|
-
const tabStops = normalizeDocumentTabStops(attributes.tabStops);
|
|
11746
|
-
return tabStops.length ? {
|
|
11747
|
-
'data-office-tab-stops': serializeDocumentTabStops(tabStops)
|
|
11748
|
-
} : {};
|
|
11749
|
-
}
|
|
11750
|
-
}
|
|
11751
|
-
}
|
|
11752
|
-
}
|
|
11753
|
-
];
|
|
11754
|
-
},
|
|
11755
|
-
addCommands () {
|
|
11756
|
-
return {
|
|
11757
|
-
setDocumentParagraphTabStops: (tabStops, options = {})=>({ chain, editor })=>{
|
|
11758
|
-
const nodeTypes = work_document_tab_stops_activeParagraphNodeTypes(editor);
|
|
11759
|
-
if (!nodeTypes.length) return false;
|
|
11760
|
-
const normalized = normalizeDocumentTabStops(tabStops);
|
|
11761
|
-
let commandChain = chain();
|
|
11762
|
-
if (false !== options.restoreFocus) commandChain = commandChain.focus();
|
|
11763
|
-
for (const nodeType of nodeTypes)commandChain = commandChain.updateAttributes(nodeType, {
|
|
11764
|
-
tabStops: normalized.length ? normalized : null
|
|
11765
|
-
});
|
|
11766
|
-
return commandChain.run();
|
|
11767
|
-
}
|
|
11768
|
-
};
|
|
11769
|
-
}
|
|
11770
|
-
});
|
|
11771
|
-
function documentParagraphTabStops(editor) {
|
|
11772
|
-
return normalizeDocumentTabStops(work_document_tab_stops_activeParagraphAttributes(editor).tabStops);
|
|
11773
|
-
}
|
|
11774
|
-
function normalizeDocumentTabStops(value) {
|
|
11775
|
-
const source = parsedTabStopSource(value);
|
|
11776
|
-
const byPosition = new Map();
|
|
11777
|
-
for (const candidate of source.slice(0, 4 * MAX_DOCUMENT_TAB_STOPS)){
|
|
11778
|
-
if (!work_document_tab_stops_isRecord(candidate)) continue;
|
|
11779
|
-
const rawPosition = Number(candidate.position);
|
|
11780
|
-
if (!Number.isFinite(rawPosition) || rawPosition <= 0) continue;
|
|
11781
|
-
const position = normalizedTabPosition(rawPosition);
|
|
11782
|
-
if (!(position <= 0)) byPosition.set(position, {
|
|
11783
|
-
position,
|
|
11784
|
-
alignment: normalizedTabAlignment(candidate.alignment),
|
|
11785
|
-
leader: normalizedTabLeader(candidate.leader)
|
|
11786
|
-
});
|
|
11787
|
-
}
|
|
11788
|
-
return Array.from(byPosition.values()).sort((left, right)=>left.position - right.position).slice(0, MAX_DOCUMENT_TAB_STOPS);
|
|
11789
|
-
}
|
|
11790
|
-
function serializeDocumentTabStops(value) {
|
|
11791
|
-
return JSON.stringify(normalizeDocumentTabStops(value));
|
|
11792
|
-
}
|
|
11793
|
-
function normalizedTabPosition(value) {
|
|
11794
|
-
if (!Number.isFinite(value)) return 0;
|
|
11795
|
-
return Math.min(MAX_DOCUMENT_TAB_POSITION_PX, Math.max(0, Math.round(100 * value) / 100));
|
|
11796
|
-
}
|
|
11797
|
-
function nextDocumentTabAlignment(alignment) {
|
|
11798
|
-
if ('left' === alignment) return 'center';
|
|
11799
|
-
if ('center' === alignment) return 'right';
|
|
11800
|
-
if ('right' === alignment) return 'decimal';
|
|
11801
|
-
return 'left';
|
|
11802
|
-
}
|
|
11803
|
-
function parsedTabStopSource(value) {
|
|
11804
|
-
if (Array.isArray(value)) return value;
|
|
11805
|
-
if ('string' != typeof value || !value.trim()) return [];
|
|
11806
|
-
try {
|
|
11807
|
-
const parsed = JSON.parse(value);
|
|
11808
|
-
return Array.isArray(parsed) ? parsed : [];
|
|
11809
|
-
} catch {
|
|
11810
|
-
return [];
|
|
11811
|
-
}
|
|
11812
|
-
}
|
|
11813
|
-
function normalizedTabAlignment(value) {
|
|
11814
|
-
return 'center' === value || 'right' === value || 'decimal' === value ? value : 'left';
|
|
11815
|
-
}
|
|
11816
|
-
function normalizedTabLeader(value) {
|
|
11817
|
-
return 'dot' === value || 'hyphen' === value || 'underscore' === value || 'middleDot' === value ? value : 'none';
|
|
11818
|
-
}
|
|
11819
|
-
function work_document_tab_stops_activeParagraphAttributes(editor) {
|
|
11820
|
-
return editor.isActive('heading') ? editor.getAttributes('heading') : editor.getAttributes('paragraph');
|
|
11821
|
-
}
|
|
11822
|
-
function work_document_tab_stops_activeParagraphNodeTypes(editor) {
|
|
11823
|
-
const types = [];
|
|
11824
|
-
if (editor.isActive('paragraph')) types.push('paragraph');
|
|
11825
|
-
if (editor.isActive('heading')) types.push('heading');
|
|
11826
|
-
return types;
|
|
11827
|
-
}
|
|
11828
|
-
function work_document_tab_stops_isRecord(value) {
|
|
11829
|
-
return 'object' == typeof value && null !== value && !Array.isArray(value);
|
|
11830
|
-
}
|
|
11831
12425
|
const MAX_DOCUMENT_TEXT_LAYOUT_PARAGRAPHS = 16384;
|
|
11832
12426
|
const MAX_DOCUMENT_TEXT_LAYOUT_RUNS = 16384;
|
|
11833
12427
|
const MAX_DOCUMENT_TEXT_LAYOUT_BYTES = 1048576;
|
|
@@ -16064,9 +16658,9 @@ function changeIdentity(decision) {
|
|
|
16064
16658
|
return `${decision.changeKind}:${decision.changeId}`;
|
|
16065
16659
|
}
|
|
16066
16660
|
function office_document_collaboration_change_decisions_changeKind(value, shared) {
|
|
16067
|
-
if ('insertion' === value || 'deletion' === value) return value;
|
|
16661
|
+
if ('insertion' === value || 'deletion' === value || 'formatting' === value || 'paragraph-formatting' === value) return value;
|
|
16068
16662
|
if (shared) invalidSharedSidecars('tracked-change decision kind');
|
|
16069
|
-
invalidInputSidecars('an insertion or
|
|
16663
|
+
invalidInputSidecars('an insertion, deletion, formatting, or paragraph-formatting tracked-change kind');
|
|
16070
16664
|
}
|
|
16071
16665
|
function decisionAction(value, shared) {
|
|
16072
16666
|
if ('accept' === value || 'reject' === value) return value;
|
|
@@ -16727,7 +17321,14 @@ function strictDocumentChanges(document1) {
|
|
|
16727
17321
|
const changes = new Map();
|
|
16728
17322
|
let valid = true;
|
|
16729
17323
|
document1.descendants((node)=>{
|
|
16730
|
-
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;
|
|
16731
17332
|
const marks = node.marks.filter((mark)=>'documentChange' === mark.type.name);
|
|
16732
17333
|
if (0 === marks.length) return;
|
|
16733
17334
|
if (1 !== marks.length) {
|
|
@@ -16740,10 +17341,11 @@ function strictDocumentChanges(document1) {
|
|
|
16740
17341
|
const author = strictString(mark.attrs.author);
|
|
16741
17342
|
const date = strictString(mark.attrs.date);
|
|
16742
17343
|
const actorId = optionalStrictString(mark.attrs.actorId);
|
|
16743
|
-
if (!id || !kind || null === author || null === date || null === actorId) {
|
|
17344
|
+
if (!id || !kind || null === author || null === date || null === actorId || 'formatting' === kind && !parseDocumentCharacterFormatting(mark.attrs.before)) {
|
|
16744
17345
|
valid = false;
|
|
16745
17346
|
return false;
|
|
16746
17347
|
}
|
|
17348
|
+
if ('formatting' === kind) return;
|
|
16747
17349
|
const current = changes.get(id);
|
|
16748
17350
|
const candidate = {
|
|
16749
17351
|
id,
|
|
@@ -16769,7 +17371,7 @@ function documentSuggestionBaseline(node) {
|
|
|
16769
17371
|
if (node.isText) {
|
|
16770
17372
|
const change = node.marks.find((mark)=>'documentChange' === mark.type.name);
|
|
16771
17373
|
if (change?.attrs.kind === 'insertion') return null;
|
|
16772
|
-
const marks = node.marks.filter((mark)=>'documentChange' !== mark.type.name).map((mark)=>mark.toJSON());
|
|
17374
|
+
const marks = node.marks.filter((mark)=>'documentChange' !== mark.type.name || 'formatting' === mark.attrs.kind).map((mark)=>mark.toJSON());
|
|
16773
17375
|
if (marks.length > 0) return {
|
|
16774
17376
|
...json,
|
|
16775
17377
|
marks
|
|
@@ -16816,7 +17418,19 @@ function optionalStrictString(value) {
|
|
|
16816
17418
|
return strictString(value);
|
|
16817
17419
|
}
|
|
16818
17420
|
function strictChangeKind(value) {
|
|
16819
|
-
return 'insertion' === value || 'deletion' === value ? value : null;
|
|
17421
|
+
return 'insertion' === value || 'deletion' === value || 'formatting' === value ? value : null;
|
|
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));
|
|
16820
17434
|
}
|
|
16821
17435
|
const DOCUMENT_CONTENT_ROOT = 'document.content';
|
|
16822
17436
|
const MAX_DOCUMENT_COMMENT_HISTORY = 100;
|
|
@@ -17468,4 +18082,4 @@ function capturePages(surface) {
|
|
|
17468
18082
|
width: surface.pageWidth
|
|
17469
18083
|
}));
|
|
17470
18084
|
}
|
|
17471
|
-
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, 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, 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 };
|