@a3s-lab/office 0.1.0 → 0.2.1
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/README.md +98 -24
- package/dist/0~2582.js +485 -0
- package/dist/0~4595.js +14 -7
- package/dist/0~4750.js +939 -0
- package/dist/{0~work-document-paragraph-formatting.js → 0~5861.js} +174 -3
- package/dist/0~7048.js +8 -6
- package/dist/0~9512.js +7 -4
- package/dist/0~document-editor.js +3147 -531
- package/dist/0~markdown-editor.js +26 -1
- package/dist/0~presentation-editor.js +68 -12
- package/dist/0~spreadsheet-editor.js +37 -17
- package/dist/0~work-document-extensions.js +588 -13
- package/dist/0~work-document-model-codec.js +1 -1
- package/dist/0~work-docx-bibliography.js +1 -1
- package/dist/0~work-docx-export.js +116 -55
- package/dist/0~work-docx-import.js +690 -99
- package/dist/0~work-office-diagnostics.js +2 -2
- package/dist/{4704.js → 2881.js} +162 -71
- package/dist/4104.js +2 -62
- package/dist/internal/features/work/editors/document-comment-window.d.ts +37 -0
- package/dist/internal/features/work/editors/document-navigation-panel.d.ts +3 -1
- package/dist/internal/features/work/editors/document-navigation-window.d.ts +64 -0
- package/dist/internal/features/work/editors/document-outline-navigation.d.ts +11 -0
- package/dist/internal/features/work/editors/document-page-navigation.d.ts +11 -1
- package/dist/internal/features/work/editors/document-page-thumbnail.d.ts +31 -0
- package/dist/internal/features/work/editors/document-picture-properties-dialog-model.d.ts +28 -0
- package/dist/internal/features/work/editors/document-picture-properties-dialog.d.ts +4 -0
- package/dist/internal/features/work/editors/document-search-navigation.d.ts +12 -0
- package/dist/internal/features/work/editors/document-table-margins-popover.d.ts +4 -0
- package/dist/internal/features/work/editors/document-table-properties-dialog-model.d.ts +51 -0
- package/dist/internal/features/work/editors/document-table-properties-dialog-sections.d.ts +19 -0
- package/dist/internal/features/work/editors/document-table-properties-dialog.d.ts +8 -0
- package/dist/internal/features/work/editors/office-task-pane.d.ts +1 -1
- package/dist/internal/features/work/editors/presentation-chart-panel.d.ts +2 -1
- package/dist/internal/features/work/editors/presentation-comments-panel.d.ts +2 -1
- package/dist/internal/features/work/editors/spreadsheet-workbook-panel.d.ts +2 -1
- package/dist/internal/features/work/editors/use-document-pagination.d.ts +6 -0
- package/dist/internal/features/work/editors/use-presentation-review-commands.d.ts +1 -1
- package/dist/internal/features/work/work-document-image-layout.d.ts +11 -0
- package/dist/internal/features/work/work-document-page-capture.d.ts +15 -0
- package/dist/internal/features/work/work-document-paragraph-formatting.d.ts +4 -0
- package/dist/internal/features/work/work-document-section.d.ts +3 -1
- package/dist/internal/features/work/work-document-table-borders.d.ts +20 -0
- package/dist/internal/features/work/work-document-table-cell-formatting.d.ts +8 -5
- package/dist/internal/features/work/work-document-table-geometry.d.ts +41 -0
- package/dist/internal/features/work/work-document-table-property-changes.d.ts +25 -0
- package/dist/internal/features/work/work-document-table-sizing.d.ts +15 -2
- package/dist/internal/features/work/work-document-word-line-metrics.d.ts +11 -0
- package/dist/internal/features/work/work-docx-document-layout.d.ts +2 -0
- package/dist/internal/features/work/work-docx-paragraph-alignment-import.d.ts +2 -1
- package/dist/internal/features/work/work-docx-paragraph-direction-import.d.ts +2 -1
- package/dist/internal/features/work/work-docx-paragraph-indent-import.d.ts +2 -1
- package/dist/internal/features/work/work-docx-paragraph-pagination-import.d.ts +2 -1
- package/dist/internal/features/work/work-docx-paragraph-spacing-import.d.ts +3 -2
- package/dist/internal/features/work/work-docx-paragraph-styles.d.ts +2 -2
- package/dist/internal/features/work/work-docx-run-formatting-import.d.ts +8 -1
- package/dist/internal/features/work/work-docx-tab-stop-import.d.ts +2 -1
- package/dist/internal/features/work/work-docx-table-cell-export.d.ts +1 -1
- package/dist/internal/features/work/work-docx-table-cell-import.d.ts +14 -4
- package/dist/internal/features/work/work-docx-table-sizing-export.d.ts +1 -1
- package/dist/internal/features/work/work-docx-table-sizing-import.d.ts +4 -3
- package/dist/internal/features/work/work-docx-table-styles.d.ts +22 -0
- package/dist/internal/features/work/work-types.d.ts +6 -0
- package/dist/office-kernel.wasm +0 -0
- package/dist/styles.css +1288 -233
- package/docs/{browser-editor-architecture.md → latest/en/browser-editor-architecture.md} +144 -35
- package/package.json +9 -5
- package/dist/0~6552.js +0 -787
- package/dist/0~8155.js +0 -299
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import jszip from "jszip";
|
|
2
2
|
import { contentTypeForPart, directChildren, bytesToDataUrl, OoxmlPackage, firstDescendant, descendants, directChild, childPath, attribute } from "./8715.js";
|
|
3
3
|
import { docxCaptionSequenceKind, docxFieldOccurrences, docxCaptionBookmark, docxFieldResultText, docxCaptionReferenceTarget } from "./0~152.js";
|
|
4
|
-
import { documentContentLayoutProperties, documentPageChromeLegacyFields, normalizeDocumentFieldsHtml, documentInitialSectionLayout, documentSectionDomAttributes, documentCaptionLabel, normalizeDocumentPageChrome, normalizeDocumentCitationsHtml, normalizeDocumentColumns, normalizeDocumentCaptionsHtml, normalizeDocumentNotesHtml, documentCitationTagsFromInstruction, docxDocumentFieldKind, createDocumentNoteElement } from "./
|
|
5
|
-
import { normalizeDocumentImageAlignment,
|
|
6
|
-
import { normalizeDocumentParagraphIndent } from "./0~
|
|
4
|
+
import { documentContentLayoutProperties, documentPageChromeLegacyFields, normalizeDocumentFieldsHtml, documentInitialSectionLayout, documentSectionDomAttributes, documentCaptionLabel, normalizeDocumentPageChrome, normalizeDocumentCitationsHtml, normalizeDocumentColumns, normalizeDocumentCaptionsHtml, normalizeDocumentNotesHtml, documentCitationTagsFromInstruction, docxDocumentFieldKind, createDocumentNoteElement } from "./2881.js";
|
|
5
|
+
import { renderDocumentTableBorders, renderDocumentTableCellMarginOverrides, normalizeDocumentImageAlignment, documentTableBordersFromElement, normalizeDocumentImageLayoutOptions, normalizeDocumentTabStops, DEFAULT_DOCUMENT_TABLE_GEOMETRY, DEFAULT_DOCUMENT_TABLE_CELL_MARGINS, serializeDocumentTabStops, applyDocumentTableGeometryToElement } from "./0~4750.js";
|
|
6
|
+
import { normalizeDocumentParagraphIndent, documentAutoLineHeight, documentWordLineHeightFactor, renderDocumentAutoLineHeight } from "./0~5861.js";
|
|
7
7
|
import { readDocxBibliography } from "./0~work-docx-bibliography.js";
|
|
8
8
|
import { importDocxPageColor } from "./0~work-docx-page-color.js";
|
|
9
9
|
const WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
|
|
@@ -1332,21 +1332,23 @@ function createDocxParagraphStyleResolver(stylesDocument) {
|
|
|
1332
1332
|
function resolveDocxParagraphStyleResolver(source) {
|
|
1333
1333
|
return source && 'styles' in source ? source : createDocxParagraphStyleResolver(source);
|
|
1334
1334
|
}
|
|
1335
|
-
function docxParagraphPropertySources(directProperties, resolver) {
|
|
1335
|
+
function docxParagraphPropertySources(directProperties, resolver, contextualProperties = []) {
|
|
1336
1336
|
const sources = [];
|
|
1337
1337
|
if (resolver.defaultProperties) sources.push(resolver.defaultProperties);
|
|
1338
1338
|
const styleReference = directProperties ? directChild(directProperties, 'pStyle') : void 0;
|
|
1339
1339
|
const styleId = (styleReference ? wordAttribute(styleReference, 'val')?.trim() : void 0) || resolver.defaultStyleId;
|
|
1340
1340
|
if (styleId) sources.push(...stylePropertySources(resolver.styles, styleId, 'paragraphProperties'));
|
|
1341
|
+
sources.push(...contextualProperties);
|
|
1341
1342
|
if (directProperties) sources.push(directProperties);
|
|
1342
1343
|
return sources;
|
|
1343
1344
|
}
|
|
1344
|
-
function docxRunPropertySources(paragraphProperties, runProperties, resolver) {
|
|
1345
|
+
function docxRunPropertySources(paragraphProperties, runProperties, resolver, contextualProperties = []) {
|
|
1345
1346
|
const sources = [];
|
|
1346
1347
|
if (resolver.defaultRunProperties) sources.push(resolver.defaultRunProperties);
|
|
1347
1348
|
const paragraphStyleReference = paragraphProperties ? directChild(paragraphProperties, 'pStyle') : void 0;
|
|
1348
1349
|
const paragraphStyleId = (paragraphStyleReference ? wordAttribute(paragraphStyleReference, 'val')?.trim() : void 0) || resolver.defaultStyleId;
|
|
1349
1350
|
if (paragraphStyleId) sources.push(...stylePropertySources(resolver.styles, paragraphStyleId, 'runProperties'));
|
|
1351
|
+
sources.push(...contextualProperties);
|
|
1350
1352
|
const paragraphRunProperties = paragraphProperties ? directChild(paragraphProperties, 'rPr') : void 0;
|
|
1351
1353
|
if (paragraphRunProperties) sources.push(paragraphRunProperties);
|
|
1352
1354
|
const characterStyleReference = runProperties ? directChild(runProperties, 'rStyle') : void 0;
|
|
@@ -1379,15 +1381,266 @@ function onOffAttribute(element, name) {
|
|
|
1379
1381
|
function wordAttribute(element, name) {
|
|
1380
1382
|
return attribute(element, name) ?? attribute(element, `w:${name}`);
|
|
1381
1383
|
}
|
|
1384
|
+
const work_docx_table_styles_MAX_STYLE_INHERITANCE_DEPTH = 64;
|
|
1385
|
+
const DEFAULT_TABLE_LOOK = {
|
|
1386
|
+
firstRow: true,
|
|
1387
|
+
lastRow: false,
|
|
1388
|
+
firstColumn: true,
|
|
1389
|
+
lastColumn: false,
|
|
1390
|
+
noHorizontalBand: false,
|
|
1391
|
+
noVerticalBand: true
|
|
1392
|
+
};
|
|
1393
|
+
const TABLE_LOOK_BITS = {
|
|
1394
|
+
firstRow: 0x0020,
|
|
1395
|
+
lastRow: 0x0040,
|
|
1396
|
+
firstColumn: 0x0080,
|
|
1397
|
+
lastColumn: 0x0100,
|
|
1398
|
+
noHorizontalBand: 0x0200,
|
|
1399
|
+
noVerticalBand: 0x0400
|
|
1400
|
+
};
|
|
1401
|
+
function createDocxTableStyleResolver(stylesDocument) {
|
|
1402
|
+
if (!stylesDocument) return {
|
|
1403
|
+
tableStyles: new Map()
|
|
1404
|
+
};
|
|
1405
|
+
const tableStyles = new Map();
|
|
1406
|
+
let defaultStyleId;
|
|
1407
|
+
for (const style of descendants(stylesDocument, 'style')){
|
|
1408
|
+
if ('table' !== work_docx_table_styles_wordAttribute(style, 'type')) continue;
|
|
1409
|
+
const styleId = work_docx_table_styles_wordAttribute(style, 'styleId')?.trim();
|
|
1410
|
+
if (!styleId) continue;
|
|
1411
|
+
const basedOn = directChild(style, 'basedOn');
|
|
1412
|
+
const conditional = new Map();
|
|
1413
|
+
for (const conditionalStyle of directChildren(style, 'tblStylePr')){
|
|
1414
|
+
const type = work_docx_table_styles_wordAttribute(conditionalStyle, 'type')?.trim();
|
|
1415
|
+
if (type) conditional.set(type, styleLayer(conditionalStyle));
|
|
1416
|
+
}
|
|
1417
|
+
tableStyles.set(styleId, {
|
|
1418
|
+
...styleLayer(style),
|
|
1419
|
+
basedOn: basedOn ? work_docx_table_styles_wordAttribute(basedOn, 'val')?.trim() || void 0 : void 0,
|
|
1420
|
+
conditional
|
|
1421
|
+
});
|
|
1422
|
+
if (!defaultStyleId && work_docx_table_styles_onOffAttribute(style, 'default')) defaultStyleId = styleId;
|
|
1423
|
+
}
|
|
1424
|
+
return {
|
|
1425
|
+
defaultStyleId,
|
|
1426
|
+
tableStyles
|
|
1427
|
+
};
|
|
1428
|
+
}
|
|
1429
|
+
function resolveDocxTableStyleResolver(source) {
|
|
1430
|
+
return source && 'tableStyles' in source ? source : createDocxTableStyleResolver(source);
|
|
1431
|
+
}
|
|
1432
|
+
function docxTablePropertySources(table, resolver) {
|
|
1433
|
+
const directTableProperties = directChild(table, 'tblPr');
|
|
1434
|
+
const styleReference = directTableProperties ? directChild(directTableProperties, 'tblStyle') : void 0;
|
|
1435
|
+
const styleId = (styleReference ? work_docx_table_styles_wordAttribute(styleReference, 'val')?.trim() : void 0) || resolver.defaultStyleId;
|
|
1436
|
+
const sources = styleId ? tableStyleChain(resolver.tableStyles, styleId).map(({ tableProperties })=>tableProperties).filter((properties)=>Boolean(properties)) : [];
|
|
1437
|
+
if (directTableProperties) sources.push(directTableProperties);
|
|
1438
|
+
return sources;
|
|
1439
|
+
}
|
|
1440
|
+
function docxTableCellStyleLayers(cell, resolver) {
|
|
1441
|
+
const table = work_docx_table_styles_closestAncestor(cell, 'tbl');
|
|
1442
|
+
if (!table) return [];
|
|
1443
|
+
const directTableProperties = directChild(table, 'tblPr');
|
|
1444
|
+
const styleReference = directTableProperties ? directChild(directTableProperties, 'tblStyle') : void 0;
|
|
1445
|
+
const styleId = (styleReference ? work_docx_table_styles_wordAttribute(styleReference, 'val')?.trim() : void 0) || resolver.defaultStyleId;
|
|
1446
|
+
if (!styleId) return [];
|
|
1447
|
+
const styles = tableStyleChain(resolver.tableStyles, styleId);
|
|
1448
|
+
if (!styles.length) return [];
|
|
1449
|
+
const unconditionalLayers = styles.map(styleLayerFromStyle);
|
|
1450
|
+
const propertySources = unconditionalLayers.map(({ tableProperties })=>tableProperties).filter((properties)=>Boolean(properties));
|
|
1451
|
+
if (directTableProperties) propertySources.push(directTableProperties);
|
|
1452
|
+
const position = tableCellPosition(table, cell);
|
|
1453
|
+
if (!position) return unconditionalLayers;
|
|
1454
|
+
const look = resolveTableLook(propertySources);
|
|
1455
|
+
const rowBandSize = resolveBandSize(propertySources, 'tblStyleRowBandSize');
|
|
1456
|
+
const columnBandSize = resolveBandSize(propertySources, 'tblStyleColBandSize');
|
|
1457
|
+
const layers = [
|
|
1458
|
+
...unconditionalLayers
|
|
1459
|
+
];
|
|
1460
|
+
for (const condition of applicableConditions(position, look, rowBandSize, columnBandSize))for (const style of styles){
|
|
1461
|
+
const layer = style.conditional.get(condition);
|
|
1462
|
+
if (layer) layers.push(layer);
|
|
1463
|
+
}
|
|
1464
|
+
return layers;
|
|
1465
|
+
}
|
|
1466
|
+
function docxTableRunPropertySources(element, resolver) {
|
|
1467
|
+
const cell = work_docx_table_styles_closestAncestor(element, 'tc');
|
|
1468
|
+
if (!cell) return [];
|
|
1469
|
+
const sources = [];
|
|
1470
|
+
for (const layer of docxTableCellStyleLayers(cell, resolver)){
|
|
1471
|
+
const paragraphRunProperties = layer.paragraphProperties ? directChild(layer.paragraphProperties, 'rPr') : void 0;
|
|
1472
|
+
if (paragraphRunProperties) sources.push(paragraphRunProperties);
|
|
1473
|
+
if (layer.runProperties) sources.push(layer.runProperties);
|
|
1474
|
+
}
|
|
1475
|
+
return sources;
|
|
1476
|
+
}
|
|
1477
|
+
function docxTableParagraphPropertySources(element, resolver) {
|
|
1478
|
+
const cell = work_docx_table_styles_closestAncestor(element, 'tc');
|
|
1479
|
+
if (!cell) return [];
|
|
1480
|
+
return docxTableCellStyleLayers(cell, resolver).map(({ paragraphProperties })=>paragraphProperties).filter((properties)=>Boolean(properties));
|
|
1481
|
+
}
|
|
1482
|
+
function styleLayer(parent) {
|
|
1483
|
+
return {
|
|
1484
|
+
tableProperties: directChild(parent, 'tblPr'),
|
|
1485
|
+
cellProperties: directChild(parent, 'tcPr'),
|
|
1486
|
+
paragraphProperties: directChild(parent, 'pPr'),
|
|
1487
|
+
runProperties: directChild(parent, 'rPr')
|
|
1488
|
+
};
|
|
1489
|
+
}
|
|
1490
|
+
function styleLayerFromStyle(style) {
|
|
1491
|
+
return {
|
|
1492
|
+
tableProperties: style.tableProperties,
|
|
1493
|
+
cellProperties: style.cellProperties,
|
|
1494
|
+
paragraphProperties: style.paragraphProperties,
|
|
1495
|
+
runProperties: style.runProperties
|
|
1496
|
+
};
|
|
1497
|
+
}
|
|
1498
|
+
function tableStyleChain(styles, styleId) {
|
|
1499
|
+
const inherited = [];
|
|
1500
|
+
const visited = new Set();
|
|
1501
|
+
let currentStyleId = styleId;
|
|
1502
|
+
let depth = 0;
|
|
1503
|
+
while(currentStyleId && depth < work_docx_table_styles_MAX_STYLE_INHERITANCE_DEPTH && !visited.has(currentStyleId)){
|
|
1504
|
+
depth += 1;
|
|
1505
|
+
visited.add(currentStyleId);
|
|
1506
|
+
const style = styles.get(currentStyleId);
|
|
1507
|
+
if (!style) break;
|
|
1508
|
+
inherited.push(style);
|
|
1509
|
+
currentStyleId = style.basedOn;
|
|
1510
|
+
}
|
|
1511
|
+
return inherited.reverse();
|
|
1512
|
+
}
|
|
1513
|
+
function applicableConditions(position, look, rowBandSize, columnBandSize) {
|
|
1514
|
+
const conditions = [
|
|
1515
|
+
'wholeTable'
|
|
1516
|
+
];
|
|
1517
|
+
const isFirstRow = 0 === position.rowIndex;
|
|
1518
|
+
const isLastRow = position.rowIndex === position.rowCount - 1;
|
|
1519
|
+
const isFirstColumn = 0 === position.columnStart;
|
|
1520
|
+
const isLastColumn = position.columnEnd === position.columnCount - 1;
|
|
1521
|
+
if (!look.noVerticalBand) {
|
|
1522
|
+
const offset = look.firstColumn ? 1 : 0;
|
|
1523
|
+
const bandIndex = position.columnStart - offset;
|
|
1524
|
+
if (bandIndex >= 0) conditions.push(Math.floor(bandIndex / columnBandSize) % 2 === 0 ? 'band1Vert' : 'band2Vert');
|
|
1525
|
+
}
|
|
1526
|
+
if (!look.noHorizontalBand) {
|
|
1527
|
+
const offset = look.firstRow ? 1 : 0;
|
|
1528
|
+
const bandIndex = position.rowIndex - offset;
|
|
1529
|
+
if (bandIndex >= 0) conditions.push(Math.floor(bandIndex / rowBandSize) % 2 === 0 ? 'band1Horz' : 'band2Horz');
|
|
1530
|
+
}
|
|
1531
|
+
if (look.firstColumn && isFirstColumn) conditions.push('firstCol');
|
|
1532
|
+
if (look.lastColumn && isLastColumn) conditions.push('lastCol');
|
|
1533
|
+
if (look.firstRow && isFirstRow) conditions.push('firstRow');
|
|
1534
|
+
if (look.lastRow && isLastRow) conditions.push('lastRow');
|
|
1535
|
+
if (look.firstRow && isFirstRow && look.firstColumn && isFirstColumn) conditions.push('nwCell');
|
|
1536
|
+
if (look.firstRow && isFirstRow && look.lastColumn && isLastColumn) conditions.push('neCell');
|
|
1537
|
+
if (look.lastRow && isLastRow && look.firstColumn && isFirstColumn) conditions.push('swCell');
|
|
1538
|
+
if (look.lastRow && isLastRow && look.lastColumn && isLastColumn) conditions.push('seCell');
|
|
1539
|
+
return conditions;
|
|
1540
|
+
}
|
|
1541
|
+
function resolveTableLook(propertySources) {
|
|
1542
|
+
const look = {
|
|
1543
|
+
...DEFAULT_TABLE_LOOK
|
|
1544
|
+
};
|
|
1545
|
+
for (const properties of propertySources){
|
|
1546
|
+
const element = directChild(properties, 'tblLook');
|
|
1547
|
+
if (!element) continue;
|
|
1548
|
+
const encoded = work_docx_table_styles_wordAttribute(element, 'val')?.trim();
|
|
1549
|
+
if (encoded && /^[0-9a-f]{1,4}$/i.test(encoded)) {
|
|
1550
|
+
const value = Number.parseInt(encoded, 16);
|
|
1551
|
+
look.firstRow = Boolean(value & TABLE_LOOK_BITS.firstRow);
|
|
1552
|
+
look.lastRow = Boolean(value & TABLE_LOOK_BITS.lastRow);
|
|
1553
|
+
look.firstColumn = Boolean(value & TABLE_LOOK_BITS.firstColumn);
|
|
1554
|
+
look.lastColumn = Boolean(value & TABLE_LOOK_BITS.lastColumn);
|
|
1555
|
+
look.noHorizontalBand = Boolean(value & TABLE_LOOK_BITS.noHorizontalBand);
|
|
1556
|
+
look.noVerticalBand = Boolean(value & TABLE_LOOK_BITS.noVerticalBand);
|
|
1557
|
+
}
|
|
1558
|
+
assignLookFlag(look, 'firstRow', element, 'firstRow');
|
|
1559
|
+
assignLookFlag(look, 'lastRow', element, 'lastRow');
|
|
1560
|
+
assignLookFlag(look, 'firstColumn', element, 'firstColumn');
|
|
1561
|
+
assignLookFlag(look, 'lastColumn', element, 'lastColumn');
|
|
1562
|
+
assignLookFlag(look, 'noHorizontalBand', element, 'noHBand');
|
|
1563
|
+
assignLookFlag(look, 'noVerticalBand', element, 'noVBand');
|
|
1564
|
+
}
|
|
1565
|
+
return look;
|
|
1566
|
+
}
|
|
1567
|
+
function assignLookFlag(look, key, element, attributeName) {
|
|
1568
|
+
const value = onOffValue(work_docx_table_styles_wordAttribute(element, attributeName));
|
|
1569
|
+
if (void 0 !== value) look[key] = value;
|
|
1570
|
+
}
|
|
1571
|
+
function resolveBandSize(propertySources, propertyName) {
|
|
1572
|
+
let size = 1;
|
|
1573
|
+
for (const properties of propertySources){
|
|
1574
|
+
const element = directChild(properties, propertyName);
|
|
1575
|
+
const value = Number(element ? work_docx_table_styles_wordAttribute(element, 'val') : void 0);
|
|
1576
|
+
if (Number.isInteger(value) && value > 0 && value <= 64) size = value;
|
|
1577
|
+
}
|
|
1578
|
+
return size;
|
|
1579
|
+
}
|
|
1580
|
+
function tableCellPosition(table, targetCell) {
|
|
1581
|
+
const rows = descendants(table, 'tr').filter((row)=>work_docx_table_styles_closestAncestor(row, 'tbl') === table);
|
|
1582
|
+
const targetRow = work_docx_table_styles_closestAncestor(targetCell, 'tr');
|
|
1583
|
+
if (!targetRow) return null;
|
|
1584
|
+
const rowIndex = rows.indexOf(targetRow);
|
|
1585
|
+
if (rowIndex < 0) return null;
|
|
1586
|
+
const cells = rowCells(targetRow);
|
|
1587
|
+
const cellIndex = cells.indexOf(targetCell);
|
|
1588
|
+
if (cellIndex < 0) return null;
|
|
1589
|
+
const columnStart = rowGridOffset(targetRow, 'gridBefore') + cells.slice(0, cellIndex).reduce((total, cell)=>total + cellGridSpan(cell), 0);
|
|
1590
|
+
const columnEnd = columnStart + cellGridSpan(targetCell) - 1;
|
|
1591
|
+
const columnCount = Math.max(1, ...rows.map((row)=>rowGridOffset(row, 'gridBefore') + rowCells(row).reduce((total, cell)=>total + cellGridSpan(cell), 0) + rowGridOffset(row, 'gridAfter')));
|
|
1592
|
+
return {
|
|
1593
|
+
rowIndex,
|
|
1594
|
+
rowCount: rows.length,
|
|
1595
|
+
columnStart,
|
|
1596
|
+
columnEnd,
|
|
1597
|
+
columnCount
|
|
1598
|
+
};
|
|
1599
|
+
}
|
|
1600
|
+
function rowCells(row) {
|
|
1601
|
+
return descendants(row, 'tc').filter((cell)=>work_docx_table_styles_closestAncestor(cell, 'tr') === row);
|
|
1602
|
+
}
|
|
1603
|
+
function cellGridSpan(cell) {
|
|
1604
|
+
const properties = directChild(cell, 'tcPr');
|
|
1605
|
+
const gridSpan = properties ? directChild(properties, 'gridSpan') : void 0;
|
|
1606
|
+
const value = Number(gridSpan ? work_docx_table_styles_wordAttribute(gridSpan, 'val') : void 0);
|
|
1607
|
+
return Number.isInteger(value) && value > 0 && value <= 256 ? value : 1;
|
|
1608
|
+
}
|
|
1609
|
+
function rowGridOffset(row, propertyName) {
|
|
1610
|
+
const properties = directChild(row, 'trPr');
|
|
1611
|
+
const element = properties ? directChild(properties, propertyName) : void 0;
|
|
1612
|
+
const value = Number(element ? work_docx_table_styles_wordAttribute(element, 'val') : void 0);
|
|
1613
|
+
return Number.isInteger(value) && value > 0 && value <= 256 ? value : 0;
|
|
1614
|
+
}
|
|
1615
|
+
function work_docx_table_styles_closestAncestor(element, localName) {
|
|
1616
|
+
let current = element;
|
|
1617
|
+
while(current){
|
|
1618
|
+
if (current.localName === localName) return current;
|
|
1619
|
+
current = current.parentElement;
|
|
1620
|
+
}
|
|
1621
|
+
return null;
|
|
1622
|
+
}
|
|
1623
|
+
function work_docx_table_styles_onOffAttribute(element, name) {
|
|
1624
|
+
return onOffValue(work_docx_table_styles_wordAttribute(element, name)) ?? false;
|
|
1625
|
+
}
|
|
1626
|
+
function onOffValue(value) {
|
|
1627
|
+
if (null == value) return;
|
|
1628
|
+
const normalized = value.trim().toLowerCase();
|
|
1629
|
+
return '0' !== normalized && 'false' !== normalized && 'off' !== normalized;
|
|
1630
|
+
}
|
|
1631
|
+
function work_docx_table_styles_wordAttribute(element, name) {
|
|
1632
|
+
return attribute(element, name) ?? attribute(element, `w:${name}`);
|
|
1633
|
+
}
|
|
1382
1634
|
const work_docx_paragraph_direction_import_WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
|
|
1383
1635
|
const work_docx_paragraph_direction_import_XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
|
|
1384
1636
|
const PARAGRAPH_DIRECTION_MARKER_PATTERN = /__A3S_WORK_PARAGRAPH_DIRECTION_\d+__/g;
|
|
1385
|
-
function markDocxParagraphDirections(document, styleSource) {
|
|
1637
|
+
function markDocxParagraphDirections(document, styleSource, tableStyleSource) {
|
|
1386
1638
|
const paragraphs = [];
|
|
1387
1639
|
const styles = resolveDocxParagraphStyleResolver(styleSource);
|
|
1640
|
+
const tableStyles = resolveDocxTableStyleResolver(tableStyleSource);
|
|
1388
1641
|
for (const paragraph of descendants(document, 'p')){
|
|
1389
1642
|
let properties = directChild(paragraph, 'pPr');
|
|
1390
|
-
const sources = docxParagraphPropertySources(properties, styles);
|
|
1643
|
+
const sources = docxParagraphPropertySources(properties, styles, docxTableParagraphPropertySources(paragraph, tableStyles));
|
|
1391
1644
|
const direction = paragraphDirection(sources);
|
|
1392
1645
|
if (!direction) continue;
|
|
1393
1646
|
properties ??= insertParagraphProperties(document, paragraph);
|
|
@@ -1425,11 +1678,11 @@ function paragraphDirection(propertySources) {
|
|
|
1425
1678
|
let direction = null;
|
|
1426
1679
|
for (const properties of propertySources){
|
|
1427
1680
|
const bidi = directChild(properties, 'bidi');
|
|
1428
|
-
if (bidi) direction =
|
|
1681
|
+
if (bidi) direction = work_docx_paragraph_direction_import_onOffValue(bidi) ? 'rtl' : 'ltr';
|
|
1429
1682
|
}
|
|
1430
1683
|
return direction;
|
|
1431
1684
|
}
|
|
1432
|
-
function
|
|
1685
|
+
function work_docx_paragraph_direction_import_onOffValue(element) {
|
|
1433
1686
|
const value = (attribute(element, 'val') ?? attribute(element, 'w:val'))?.trim().toLowerCase();
|
|
1434
1687
|
return '0' !== value && 'false' !== value && 'off' !== value;
|
|
1435
1688
|
}
|
|
@@ -1461,12 +1714,13 @@ function work_docx_paragraph_direction_import_textNodes(root) {
|
|
|
1461
1714
|
const work_docx_paragraph_alignment_import_WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
|
|
1462
1715
|
const work_docx_paragraph_alignment_import_XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
|
|
1463
1716
|
const PARAGRAPH_ALIGNMENT_MARKER_PATTERN = /__A3S_WORK_PARAGRAPH_ALIGNMENT_\d+__/g;
|
|
1464
|
-
function markDocxParagraphAlignments(document, styleSource) {
|
|
1717
|
+
function markDocxParagraphAlignments(document, styleSource, tableStyleSource) {
|
|
1465
1718
|
const paragraphs = [];
|
|
1466
1719
|
const styles = resolveDocxParagraphStyleResolver(styleSource);
|
|
1720
|
+
const tableStyles = resolveDocxTableStyleResolver(tableStyleSource);
|
|
1467
1721
|
for (const paragraph of descendants(document, 'p')){
|
|
1468
1722
|
let properties = directChild(paragraph, 'pPr');
|
|
1469
|
-
const sources = docxParagraphPropertySources(properties, styles);
|
|
1723
|
+
const sources = docxParagraphPropertySources(properties, styles, docxTableParagraphPropertySources(paragraph, tableStyles));
|
|
1470
1724
|
const alignment = paragraphAlignment(sources);
|
|
1471
1725
|
if (!alignment) continue;
|
|
1472
1726
|
properties ??= work_docx_paragraph_alignment_import_insertParagraphProperties(document, paragraph);
|
|
@@ -1591,12 +1845,13 @@ const work_docx_paragraph_indent_import_WORD_NAMESPACE = 'http://schemas.openxml
|
|
|
1591
1845
|
const work_docx_paragraph_indent_import_XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
|
|
1592
1846
|
const TWIPS_PER_CSS_PIXEL = 15;
|
|
1593
1847
|
const PARAGRAPH_INDENT_MARKER_PATTERN = /__A3S_WORK_PARAGRAPH_INDENT_\d+__/g;
|
|
1594
|
-
function markDocxParagraphIndents(document, styleSource) {
|
|
1848
|
+
function markDocxParagraphIndents(document, styleSource, tableStyleSource) {
|
|
1595
1849
|
const paragraphs = [];
|
|
1596
1850
|
const styles = resolveDocxParagraphStyleResolver(styleSource);
|
|
1851
|
+
const tableStyles = resolveDocxTableStyleResolver(tableStyleSource);
|
|
1597
1852
|
for (const paragraph of descendants(document, 'p')){
|
|
1598
1853
|
let properties = directChild(paragraph, 'pPr');
|
|
1599
|
-
const sources = docxParagraphPropertySources(properties, styles);
|
|
1854
|
+
const sources = docxParagraphPropertySources(properties, styles, docxTableParagraphPropertySources(paragraph, tableStyles));
|
|
1600
1855
|
if (sources.some((source)=>directChild(source, 'numPr'))) continue;
|
|
1601
1856
|
const indent = paragraphIndent(sources);
|
|
1602
1857
|
if (!indent.left && !indent.right && !indent.firstLine) continue;
|
|
@@ -1709,13 +1964,14 @@ function work_docx_paragraph_indent_import_textNodes(root) {
|
|
|
1709
1964
|
const work_docx_paragraph_pagination_import_WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
|
|
1710
1965
|
const work_docx_paragraph_pagination_import_XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
|
|
1711
1966
|
const PARAGRAPH_PAGINATION_MARKER_PATTERN = /__A3S_WORK_PARAGRAPH_PAGINATION_\d+__/g;
|
|
1712
|
-
function markDocxParagraphPagination(document, styleSource) {
|
|
1967
|
+
function markDocxParagraphPagination(document, styleSource, tableStyleSource) {
|
|
1713
1968
|
const paragraphs = [];
|
|
1714
1969
|
const styles = resolveDocxParagraphStyleResolver(styleSource);
|
|
1970
|
+
const tableStyles = resolveDocxTableStyleResolver(tableStyleSource);
|
|
1715
1971
|
for (const paragraph of descendants(document, 'p')){
|
|
1716
1972
|
let properties = directChild(paragraph, 'pPr');
|
|
1717
1973
|
if (properties && directChild(properties, 'numPr')) continue;
|
|
1718
|
-
const pagination = paragraphPagination(docxParagraphPropertySources(properties, styles));
|
|
1974
|
+
const pagination = paragraphPagination(docxParagraphPropertySources(properties, styles, docxTableParagraphPropertySources(paragraph, tableStyles)));
|
|
1719
1975
|
if (!Object.keys(pagination).length) continue;
|
|
1720
1976
|
properties ??= work_docx_paragraph_pagination_import_insertParagraphProperties(document, paragraph);
|
|
1721
1977
|
const marker = `__A3S_WORK_PARAGRAPH_PAGINATION_${paragraphs.length + 1}__`;
|
|
@@ -1803,12 +2059,13 @@ function work_docx_paragraph_pagination_import_textNodes(root) {
|
|
|
1803
2059
|
const work_docx_paragraph_spacing_import_WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
|
|
1804
2060
|
const work_docx_paragraph_spacing_import_XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
|
|
1805
2061
|
const PARAGRAPH_SPACING_MARKER_PATTERN = /__A3S_WORK_PARAGRAPH_SPACING_\d+__/g;
|
|
1806
|
-
function markDocxParagraphSpacing(document, styleSource) {
|
|
2062
|
+
function markDocxParagraphSpacing(document, styleSource, tableStyleSource) {
|
|
1807
2063
|
const paragraphs = [];
|
|
1808
2064
|
const styles = resolveDocxParagraphStyleResolver(styleSource);
|
|
2065
|
+
const tableStyles = resolveDocxTableStyleResolver(tableStyleSource);
|
|
1809
2066
|
for (const paragraph of descendants(document, 'p')){
|
|
1810
2067
|
let properties = directChild(paragraph, 'pPr');
|
|
1811
|
-
const sources = docxParagraphPropertySources(properties, styles);
|
|
2068
|
+
const sources = docxParagraphPropertySources(properties, styles, docxTableParagraphPropertySources(paragraph, tableStyles));
|
|
1812
2069
|
if (sources.some((source)=>directChild(source, 'numPr'))) continue;
|
|
1813
2070
|
const spacing = paragraphSpacing(sources);
|
|
1814
2071
|
if (!Object.keys(spacing).length) continue;
|
|
@@ -1885,6 +2142,14 @@ function applyParagraphSpacing(element, spacing) {
|
|
|
1885
2142
|
}
|
|
1886
2143
|
if (spacing.lineHeight) element.style.lineHeight = spacing.lineHeight;
|
|
1887
2144
|
if (spacing.lineRule) element.dataset.officeLineRule = spacing.lineRule;
|
|
2145
|
+
if ('auto' === spacing.lineRule) {
|
|
2146
|
+
const autoLineHeight = documentAutoLineHeight(spacing.lineHeight);
|
|
2147
|
+
for (const [name, value] of Object.entries(renderDocumentAutoLineHeight(spacing.lineHeight, autoLineHeight)))if ('style' === name) for (const declaration of value.split(';')){
|
|
2148
|
+
const separator = declaration.indexOf(':');
|
|
2149
|
+
if (!(separator < 0)) element.style.setProperty(declaration.slice(0, separator).trim(), declaration.slice(separator + 1).trim());
|
|
2150
|
+
}
|
|
2151
|
+
else element.setAttribute(name, value);
|
|
2152
|
+
}
|
|
1888
2153
|
}
|
|
1889
2154
|
function work_docx_paragraph_spacing_import_insertParagraphMarker(document, paragraph, properties, marker) {
|
|
1890
2155
|
const run = document.createElementNS(work_docx_paragraph_spacing_import_WORD_NAMESPACE, 'w:r');
|
|
@@ -2020,10 +2285,11 @@ function isDocxThemeResolver(source) {
|
|
|
2020
2285
|
const work_docx_run_formatting_import_WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
|
|
2021
2286
|
const work_docx_run_formatting_import_XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
|
|
2022
2287
|
const RUN_FORMATTING_MARKER_PATTERN = /__A3S_WORK_RUN_(?:START|END)_\d+__/g;
|
|
2023
|
-
function markDocxRunFormatting(document, styleSource, themeSource) {
|
|
2288
|
+
function markDocxRunFormatting(document, styleSource, themeSource, tableStyleSource) {
|
|
2024
2289
|
const runs = [];
|
|
2025
2290
|
const styles = resolveDocxParagraphStyleResolver(styleSource);
|
|
2026
2291
|
const theme = resolveDocxThemeResolver(themeSource);
|
|
2292
|
+
const tableStyles = resolveDocxTableStyleResolver(tableStyleSource);
|
|
2027
2293
|
for (const run of descendants(document, 'r')){
|
|
2028
2294
|
const runText = directRunText(run);
|
|
2029
2295
|
if (!runText || runText.includes('__A3S_')) continue;
|
|
@@ -2031,7 +2297,7 @@ function markDocxRunFormatting(document, styleSource, themeSource) {
|
|
|
2031
2297
|
if (!paragraph) continue;
|
|
2032
2298
|
const paragraphProperties = directChild(paragraph, 'pPr');
|
|
2033
2299
|
const runProperties = directChild(run, 'rPr');
|
|
2034
|
-
const formatting = resolvedRunFormatting(docxRunPropertySources(paragraphProperties, runProperties, styles), theme);
|
|
2300
|
+
const formatting = resolvedRunFormatting(docxRunPropertySources(paragraphProperties, runProperties, styles, docxTableRunPropertySources(run, tableStyles)), theme);
|
|
2035
2301
|
if (!Object.keys(formatting).length) continue;
|
|
2036
2302
|
const index = runs.length + 1;
|
|
2037
2303
|
const startMarker = `__A3S_WORK_RUN_START_${index}__`;
|
|
@@ -2050,8 +2316,9 @@ function markDocxRunFormatting(document, styleSource, themeSource) {
|
|
|
2050
2316
|
function applyImportedDocxRunFormattingMarkers(document, markers) {
|
|
2051
2317
|
const replacements = new Map();
|
|
2052
2318
|
for (const marker of markers.runs){
|
|
2053
|
-
|
|
2054
|
-
replacements.set(marker.
|
|
2319
|
+
const markup = formattingMarkup(document, marker.formatting);
|
|
2320
|
+
replacements.set(marker.startMarker, markup.start);
|
|
2321
|
+
replacements.set(marker.endMarker, markup.end);
|
|
2055
2322
|
}
|
|
2056
2323
|
document.body.innerHTML = document.body.innerHTML.replace(RUN_FORMATTING_MARKER_PATTERN, (marker)=>replacements.get(marker) ?? '');
|
|
2057
2324
|
}
|
|
@@ -2063,7 +2330,18 @@ function resolvedRunFormatting(propertySources, theme) {
|
|
|
2063
2330
|
let fontSize;
|
|
2064
2331
|
let color;
|
|
2065
2332
|
let backgroundColor;
|
|
2333
|
+
let bold;
|
|
2334
|
+
let italic;
|
|
2335
|
+
let underline;
|
|
2336
|
+
let strike;
|
|
2337
|
+
let snapToGrid;
|
|
2066
2338
|
for (const properties of propertySources){
|
|
2339
|
+
bold = overriddenBoolean(bold, onOffProperty(properties, 'b'));
|
|
2340
|
+
italic = overriddenBoolean(italic, onOffProperty(properties, 'i'));
|
|
2341
|
+
underline = overriddenBoolean(underline, underlineProperty(properties));
|
|
2342
|
+
strike = overriddenBoolean(strike, onOffProperty(properties, 'strike'));
|
|
2343
|
+
strike = overriddenBoolean(strike, onOffProperty(properties, 'dstrike'));
|
|
2344
|
+
snapToGrid = overriddenBoolean(snapToGrid, onOffProperty(properties, 'snapToGrid'));
|
|
2067
2345
|
const runFonts = directChild(properties, 'rFonts');
|
|
2068
2346
|
if (runFonts) {
|
|
2069
2347
|
assignFont(fonts, 'ascii', resolvedFont(runFonts, 'ascii', 'asciiTheme', theme));
|
|
@@ -2094,19 +2372,42 @@ function resolvedRunFormatting(propertySources, theme) {
|
|
|
2094
2372
|
else if (fill && /^[0-9a-f]{6}$/i.test(fill)) backgroundColor = `#${fill.toLowerCase()}`;
|
|
2095
2373
|
}
|
|
2096
2374
|
}
|
|
2097
|
-
|
|
2375
|
+
let fontFamily = uniqueFonts([
|
|
2098
2376
|
fonts.eastAsia,
|
|
2099
2377
|
fonts.hAnsi,
|
|
2100
2378
|
fonts.ascii,
|
|
2101
2379
|
fonts.complex
|
|
2102
2380
|
]);
|
|
2381
|
+
if (!fontFamily) fontFamily = uniqueFonts([
|
|
2382
|
+
docxThemeFont(theme, 'minorEastAsia'),
|
|
2383
|
+
docxThemeFont(theme, 'minorHAnsi'),
|
|
2384
|
+
docxThemeFont(theme, 'minorAscii'),
|
|
2385
|
+
docxThemeFont(theme, 'minorBidi')
|
|
2386
|
+
]);
|
|
2387
|
+
const hasRunPropertySource = propertySources.length > 0;
|
|
2103
2388
|
return {
|
|
2389
|
+
...void 0 !== bold || hasRunPropertySource ? {
|
|
2390
|
+
bold: bold ?? false
|
|
2391
|
+
} : {},
|
|
2392
|
+
...void 0 !== italic || hasRunPropertySource ? {
|
|
2393
|
+
italic: italic ?? false
|
|
2394
|
+
} : {},
|
|
2395
|
+
...void 0 !== underline || hasRunPropertySource ? {
|
|
2396
|
+
underline: underline ?? false
|
|
2397
|
+
} : {},
|
|
2398
|
+
...void 0 !== strike || hasRunPropertySource ? {
|
|
2399
|
+
strike: strike ?? false
|
|
2400
|
+
} : {},
|
|
2104
2401
|
...fontFamily ? {
|
|
2105
|
-
fontFamily
|
|
2402
|
+
fontFamily,
|
|
2403
|
+
wordLineHeightFactor: documentWordLineHeightFactor(fontFamily)
|
|
2106
2404
|
} : {},
|
|
2107
2405
|
...void 0 !== fontSize ? {
|
|
2108
2406
|
fontSize
|
|
2109
2407
|
} : {},
|
|
2408
|
+
...void 0 !== snapToGrid ? {
|
|
2409
|
+
wordSnapToGrid: snapToGrid
|
|
2410
|
+
} : {},
|
|
2110
2411
|
...color ? {
|
|
2111
2412
|
color
|
|
2112
2413
|
} : {},
|
|
@@ -2127,14 +2428,57 @@ function work_docx_run_formatting_import_markerText(document, marker) {
|
|
|
2127
2428
|
text.textContent = marker;
|
|
2128
2429
|
return text;
|
|
2129
2430
|
}
|
|
2130
|
-
function
|
|
2431
|
+
function formattingMarkup(document, formatting) {
|
|
2131
2432
|
const span = document.createElement('span');
|
|
2433
|
+
if (false === formatting.bold) span.style.fontWeight = 'normal';
|
|
2434
|
+
if (false === formatting.italic) span.style.fontStyle = 'normal';
|
|
2435
|
+
if ((false === formatting.underline || false === formatting.strike) && !formatting.underline && !formatting.strike) span.style.textDecorationLine = 'none';
|
|
2132
2436
|
if (formatting.fontFamily) span.style.fontFamily = formatting.fontFamily;
|
|
2437
|
+
if (void 0 !== formatting.wordLineHeightFactor) {
|
|
2438
|
+
const factor = formatLineHeightFactor(formatting.wordLineHeightFactor);
|
|
2439
|
+
span.dataset.officeWordLineHeightFactor = factor;
|
|
2440
|
+
span.style.setProperty('--work-document-word-line-height-factor', factor);
|
|
2441
|
+
}
|
|
2442
|
+
if (void 0 !== formatting.wordSnapToGrid) span.dataset.officeWordSnapToGrid = String(formatting.wordSnapToGrid);
|
|
2133
2443
|
if (void 0 !== formatting.fontSize) span.style.fontSize = `${work_docx_run_formatting_import_formatNumber(formatting.fontSize)}pt`;
|
|
2134
2444
|
if (formatting.color) span.style.color = formatting.color;
|
|
2135
2445
|
if (formatting.backgroundColor) span.style.backgroundColor = formatting.backgroundColor;
|
|
2136
2446
|
const html = span.outerHTML;
|
|
2137
|
-
|
|
2447
|
+
const tags = [
|
|
2448
|
+
...formatting.bold ? [
|
|
2449
|
+
'strong'
|
|
2450
|
+
] : [],
|
|
2451
|
+
...formatting.italic ? [
|
|
2452
|
+
'em'
|
|
2453
|
+
] : [],
|
|
2454
|
+
...formatting.underline ? [
|
|
2455
|
+
'u'
|
|
2456
|
+
] : [],
|
|
2457
|
+
...formatting.strike ? [
|
|
2458
|
+
's'
|
|
2459
|
+
] : []
|
|
2460
|
+
];
|
|
2461
|
+
return {
|
|
2462
|
+
start: `${html.slice(0, html.indexOf('>') + 1)}${tags.map((tag)=>`<${tag}>`).join('')}`,
|
|
2463
|
+
end: `${[
|
|
2464
|
+
...tags
|
|
2465
|
+
].reverse().map((tag)=>`</${tag}>`).join('')}</span>`
|
|
2466
|
+
};
|
|
2467
|
+
}
|
|
2468
|
+
function overriddenBoolean(current, next) {
|
|
2469
|
+
return void 0 === next ? current : next;
|
|
2470
|
+
}
|
|
2471
|
+
function onOffProperty(properties, propertyName) {
|
|
2472
|
+
const element = directChild(properties, propertyName);
|
|
2473
|
+
if (!element) return;
|
|
2474
|
+
const value = work_docx_run_formatting_import_wordAttribute(element, 'val')?.trim().toLowerCase();
|
|
2475
|
+
return '0' !== value && 'false' !== value && 'off' !== value;
|
|
2476
|
+
}
|
|
2477
|
+
function underlineProperty(properties) {
|
|
2478
|
+
const element = directChild(properties, 'u');
|
|
2479
|
+
if (!element) return;
|
|
2480
|
+
const value = work_docx_run_formatting_import_wordAttribute(element, 'val')?.trim().toLowerCase();
|
|
2481
|
+
return '0' !== value && 'false' !== value && 'off' !== value && 'none' !== value;
|
|
2138
2482
|
}
|
|
2139
2483
|
function directRunText(run) {
|
|
2140
2484
|
return Array.from(run.children).filter((child)=>'t' === child.localName || 'delText' === child.localName).map((child)=>child.textContent ?? '').join('');
|
|
@@ -2200,18 +2544,22 @@ function wordHighlightColor(value) {
|
|
|
2200
2544
|
function work_docx_run_formatting_import_formatNumber(value) {
|
|
2201
2545
|
return Number(value.toFixed(2)).toString();
|
|
2202
2546
|
}
|
|
2547
|
+
function formatLineHeightFactor(value) {
|
|
2548
|
+
return Number(value.toFixed(4)).toString();
|
|
2549
|
+
}
|
|
2203
2550
|
const work_docx_tab_stop_import_WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
|
|
2204
2551
|
const work_docx_tab_stop_import_XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
|
|
2205
2552
|
const work_docx_tab_stop_import_TWIPS_PER_CSS_PIXEL = 15;
|
|
2206
2553
|
const PARAGRAPH_TAB_STOP_MARKER_PATTERN = /__A3S_WORK_PARAGRAPH_TAB_STOPS_\d+__/g;
|
|
2207
2554
|
const INLINE_TAB_MARKER_PATTERN = /__A3S_WORK_INLINE_TAB_\d+__/g;
|
|
2208
|
-
function markDocxParagraphTabStops(document, styleSource) {
|
|
2555
|
+
function markDocxParagraphTabStops(document, styleSource, tableStyleSource) {
|
|
2209
2556
|
const paragraphs = [];
|
|
2210
2557
|
const inlineTabs = [];
|
|
2211
2558
|
const styles = resolveDocxParagraphStyleResolver(styleSource);
|
|
2559
|
+
const tableStyles = resolveDocxTableStyleResolver(tableStyleSource);
|
|
2212
2560
|
for (const paragraph of descendants(document, 'p')){
|
|
2213
2561
|
let properties = directChild(paragraph, 'pPr');
|
|
2214
|
-
const tabStops = resolvedParagraphTabStops(docxParagraphPropertySources(properties, styles));
|
|
2562
|
+
const tabStops = resolvedParagraphTabStops(docxParagraphPropertySources(properties, styles, docxTableParagraphPropertySources(paragraph, tableStyles)));
|
|
2215
2563
|
if (tabStops.length) {
|
|
2216
2564
|
properties ??= work_docx_tab_stop_import_insertParagraphProperties(document, paragraph);
|
|
2217
2565
|
const marker = `__A3S_WORK_PARAGRAPH_TAB_STOPS_${paragraphs.length + 1}__`;
|
|
@@ -2357,20 +2705,42 @@ function work_docx_tab_stop_import_textNodes(root) {
|
|
|
2357
2705
|
while(walker.nextNode())nodes.push(walker.currentNode);
|
|
2358
2706
|
return nodes;
|
|
2359
2707
|
}
|
|
2708
|
+
const TABLE_BORDER_EDGES = [
|
|
2709
|
+
'top',
|
|
2710
|
+
'right',
|
|
2711
|
+
'bottom',
|
|
2712
|
+
'left'
|
|
2713
|
+
];
|
|
2360
2714
|
const work_docx_table_cell_import_WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
|
|
2361
2715
|
const work_docx_table_cell_import_XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
|
|
2362
2716
|
const TABLE_CELL_MARKER_PATTERN = /__A3S_WORK_TABLE_CELL_\d+__/g;
|
|
2363
|
-
|
|
2717
|
+
const PIXELS_PER_TWIP = 96 / 1440;
|
|
2718
|
+
function markDocxTableCells(document, themeSource, tableStyleSource) {
|
|
2364
2719
|
const cells = [];
|
|
2720
|
+
const theme = resolveDocxThemeResolver(themeSource);
|
|
2721
|
+
const tableStyles = resolveDocxTableStyleResolver(tableStyleSource);
|
|
2365
2722
|
for (const cell of descendants(document, 'tc')){
|
|
2366
2723
|
const properties = directChild(cell, 'tcPr');
|
|
2367
|
-
const
|
|
2368
|
-
const
|
|
2369
|
-
const
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2724
|
+
const table = work_docx_table_cell_import_closestAncestor(cell, 'tbl');
|
|
2725
|
+
const directTableProperties = table ? directChild(table, 'tblPr') : void 0;
|
|
2726
|
+
const layers = [
|
|
2727
|
+
...docxTableCellStyleLayers(cell, tableStyles),
|
|
2728
|
+
...directTableProperties ? [
|
|
2729
|
+
{
|
|
2730
|
+
tableProperties: directTableProperties
|
|
2731
|
+
}
|
|
2732
|
+
] : [],
|
|
2733
|
+
...properties ? [
|
|
2734
|
+
{
|
|
2735
|
+
cellProperties: properties
|
|
2736
|
+
}
|
|
2737
|
+
] : []
|
|
2738
|
+
];
|
|
2739
|
+
const borders = importedTableCellBorders(cell, layers, theme);
|
|
2740
|
+
const backgroundColor = importedTableCellBackgroundColor(layers, theme);
|
|
2741
|
+
const verticalAlign = importedTableCellVerticalAlign(layers);
|
|
2742
|
+
const margins = importedTableCellMargins(layers);
|
|
2743
|
+
if (!backgroundColor && !verticalAlign && !borders && !margins) continue;
|
|
2374
2744
|
const paragraph = firstTableCellParagraph(document, cell);
|
|
2375
2745
|
if (!paragraph) continue;
|
|
2376
2746
|
const marker = `__A3S_WORK_TABLE_CELL_${cells.length + 1}__`;
|
|
@@ -2383,10 +2753,11 @@ function markDocxTableCells(document) {
|
|
|
2383
2753
|
...verticalAlign ? {
|
|
2384
2754
|
verticalAlign
|
|
2385
2755
|
} : {},
|
|
2386
|
-
...
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2756
|
+
...borders ? {
|
|
2757
|
+
borders
|
|
2758
|
+
} : {},
|
|
2759
|
+
...margins ? {
|
|
2760
|
+
margins
|
|
2390
2761
|
} : {}
|
|
2391
2762
|
});
|
|
2392
2763
|
}
|
|
@@ -2422,44 +2793,130 @@ function applyCellFormat(cell, format) {
|
|
|
2422
2793
|
cell.dataset.officeCellVerticalAlign = format.verticalAlign;
|
|
2423
2794
|
cell.style.verticalAlign = format.verticalAlign;
|
|
2424
2795
|
}
|
|
2425
|
-
if (format.
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2796
|
+
if (format.borders) {
|
|
2797
|
+
const borders = documentTableBordersFromElement(cell, {
|
|
2798
|
+
color: '#cfd5df',
|
|
2799
|
+
style: 'solid',
|
|
2800
|
+
width: 1
|
|
2801
|
+
});
|
|
2802
|
+
for (const edge of TABLE_BORDER_EDGES){
|
|
2803
|
+
const border = format.borders[edge];
|
|
2804
|
+
if (border) borders[edge] = {
|
|
2805
|
+
...border
|
|
2806
|
+
};
|
|
2807
|
+
}
|
|
2808
|
+
const rendered = renderDocumentTableBorders(borders);
|
|
2809
|
+
for (const [name, value] of Object.entries(rendered))if ('style' !== name) cell.setAttribute(name, value);
|
|
2810
|
+
cell.style.cssText = `${cell.style.cssText}; ${rendered.style}`;
|
|
2811
|
+
}
|
|
2812
|
+
if (format.margins) {
|
|
2813
|
+
const rendered = renderDocumentTableCellMarginOverrides(format.margins);
|
|
2814
|
+
for (const [name, value] of Object.entries(rendered))if ('style' !== name) cell.setAttribute(name, value);
|
|
2815
|
+
if (rendered.style) cell.style.cssText = `${cell.style.cssText}; ${rendered.style}`;
|
|
2816
|
+
}
|
|
2817
|
+
}
|
|
2818
|
+
function importedTableCellMargins(layers) {
|
|
2819
|
+
const margins = {};
|
|
2820
|
+
for (const layer of layers){
|
|
2821
|
+
const marginElement = layer.cellProperties ? directChild(layer.cellProperties, 'tcMar') : void 0;
|
|
2822
|
+
if (!marginElement) continue;
|
|
2823
|
+
const children = new Map(directChildren(marginElement).map((margin)=>[
|
|
2824
|
+
margin.localName,
|
|
2825
|
+
margin
|
|
2826
|
+
]));
|
|
2827
|
+
assignCellMargin(margins, 'top', children.get('top'));
|
|
2828
|
+
assignCellMargin(margins, 'right', children.get('right') ?? children.get('end'));
|
|
2829
|
+
assignCellMargin(margins, 'bottom', children.get('bottom'));
|
|
2830
|
+
assignCellMargin(margins, 'left', children.get('left') ?? children.get('start'));
|
|
2831
|
+
}
|
|
2832
|
+
return Object.keys(margins).length ? margins : null;
|
|
2833
|
+
}
|
|
2834
|
+
function assignCellMargin(target, side, element) {
|
|
2835
|
+
if (!element) return;
|
|
2836
|
+
const type = attribute(element, 'type');
|
|
2837
|
+
if (type && 'dxa' !== type) return;
|
|
2838
|
+
const twips = Number(attribute(element, 'w'));
|
|
2839
|
+
if (!Number.isFinite(twips) || twips < 0) return;
|
|
2840
|
+
target[side] = Math.round(twips * PIXELS_PER_TWIP * 100) / 100;
|
|
2841
|
+
}
|
|
2842
|
+
function importedTableCellBorders(cell, layers, theme) {
|
|
2843
|
+
const borders = {};
|
|
2844
|
+
for (const layer of layers){
|
|
2845
|
+
if (layer.tableProperties) mergeBorders(borders, tableBordersForCell(cell, layer.tableProperties, theme));
|
|
2846
|
+
if (layer.cellProperties) mergeBorders(borders, borderEdges(directChild(layer.cellProperties, 'tcBorders'), theme));
|
|
2430
2847
|
}
|
|
2848
|
+
return Object.keys(borders).length ? borders : null;
|
|
2431
2849
|
}
|
|
2432
|
-
function
|
|
2850
|
+
function tableBordersForCell(cell, properties, theme) {
|
|
2433
2851
|
const table = work_docx_table_cell_import_closestAncestor(cell, 'tbl');
|
|
2434
|
-
const
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
const
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
'insideH',
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2852
|
+
const borders = borderElementMap(directChild(properties, 'tblBorders'));
|
|
2853
|
+
if (!table || !borders.size) return {};
|
|
2854
|
+
const row = work_docx_table_cell_import_closestAncestor(cell, 'tr');
|
|
2855
|
+
if (!row) return {};
|
|
2856
|
+
const rows = descendants(table, 'tr').filter((candidate)=>work_docx_table_cell_import_closestAncestor(candidate, 'tbl') === table);
|
|
2857
|
+
const cells = descendants(row, 'tc').filter((candidate)=>work_docx_table_cell_import_closestAncestor(candidate, 'tr') === row);
|
|
2858
|
+
const rowIndex = rows.indexOf(row);
|
|
2859
|
+
const cellIndex = cells.indexOf(cell);
|
|
2860
|
+
if (rowIndex < 0 || cellIndex < 0) return {};
|
|
2861
|
+
return compactBorders({
|
|
2862
|
+
top: parseBorder(borders.get(0 === rowIndex ? 'top' : 'insideH'), theme),
|
|
2863
|
+
right: parseBorder(borderElement(borders, cellIndex === cells.length - 1 ? [
|
|
2864
|
+
'right',
|
|
2865
|
+
'end'
|
|
2866
|
+
] : [
|
|
2867
|
+
'insideV'
|
|
2868
|
+
]), theme),
|
|
2869
|
+
bottom: parseBorder(borders.get(rowIndex === rows.length - 1 ? 'bottom' : 'insideH'), theme),
|
|
2870
|
+
left: parseBorder(borderElement(borders, 0 === cellIndex ? [
|
|
2871
|
+
'left',
|
|
2872
|
+
'start'
|
|
2873
|
+
] : [
|
|
2874
|
+
'insideV'
|
|
2875
|
+
]), theme)
|
|
2876
|
+
});
|
|
2877
|
+
}
|
|
2878
|
+
function mergeBorders(target, source) {
|
|
2879
|
+
for (const edge of TABLE_BORDER_EDGES){
|
|
2880
|
+
const border = source[edge];
|
|
2881
|
+
if (border) target[edge] = border;
|
|
2882
|
+
}
|
|
2883
|
+
}
|
|
2884
|
+
function borderEdges(borders, theme) {
|
|
2885
|
+
const edges = borderElementMap(borders);
|
|
2886
|
+
return compactBorders({
|
|
2887
|
+
top: parseBorder(edges.get('top'), theme),
|
|
2888
|
+
right: parseBorder(borderElement(edges, [
|
|
2889
|
+
'right',
|
|
2890
|
+
'end'
|
|
2891
|
+
]), theme),
|
|
2892
|
+
bottom: parseBorder(edges.get('bottom'), theme),
|
|
2893
|
+
left: parseBorder(borderElement(edges, [
|
|
2894
|
+
'left',
|
|
2895
|
+
'start'
|
|
2896
|
+
]), theme)
|
|
2897
|
+
});
|
|
2898
|
+
}
|
|
2899
|
+
function borderElementMap(borders) {
|
|
2900
|
+
return new Map(borders ? directChildren(borders).map((edge)=>[
|
|
2453
2901
|
edge.localName,
|
|
2454
2902
|
edge
|
|
2455
|
-
]));
|
|
2456
|
-
const formats = edgeNames.map((name)=>parseBorder(edgeElements.get(name)));
|
|
2457
|
-
if (formats.some((format)=>!format)) return null;
|
|
2458
|
-
const first = formats[0];
|
|
2459
|
-
if (!first) return null;
|
|
2460
|
-
return formats.every((format)=>format?.color === first.color && format.style === first.style && format.width === first.width) ? first : null;
|
|
2903
|
+
]) : []);
|
|
2461
2904
|
}
|
|
2462
|
-
function
|
|
2905
|
+
function borderElement(borders, names) {
|
|
2906
|
+
for (const name of names){
|
|
2907
|
+
const edge = borders.get(name);
|
|
2908
|
+
if (edge) return edge;
|
|
2909
|
+
}
|
|
2910
|
+
}
|
|
2911
|
+
function compactBorders(borders) {
|
|
2912
|
+
const result = {};
|
|
2913
|
+
for (const edge of TABLE_BORDER_EDGES){
|
|
2914
|
+
const border = borders[edge];
|
|
2915
|
+
if (border) result[edge] = border;
|
|
2916
|
+
}
|
|
2917
|
+
return result;
|
|
2918
|
+
}
|
|
2919
|
+
function parseBorder(edge, theme) {
|
|
2463
2920
|
if (!edge) return null;
|
|
2464
2921
|
const style = tableBorderStyle(attribute(edge, 'val'));
|
|
2465
2922
|
if (!style) return null;
|
|
@@ -2468,7 +2925,8 @@ function parseBorder(edge) {
|
|
|
2468
2925
|
style,
|
|
2469
2926
|
width: 0
|
|
2470
2927
|
};
|
|
2471
|
-
const
|
|
2928
|
+
const themed = docxThemeColor(theme, attribute(edge, 'themeColor'), attribute(edge, 'themeTint'), attribute(edge, 'themeShade'));
|
|
2929
|
+
const color = themed ? `#${themed}` : ooxmlColor(attribute(edge, 'color')) ?? '#000000';
|
|
2472
2930
|
const size = Number(attribute(edge, 'sz'));
|
|
2473
2931
|
const width = Number.isFinite(size) && size > 0 ? size / 6 : 1;
|
|
2474
2932
|
return {
|
|
@@ -2477,6 +2935,30 @@ function parseBorder(edge) {
|
|
|
2477
2935
|
width: Math.max(0.5, Math.min(6, Math.round(2 * width) / 2))
|
|
2478
2936
|
};
|
|
2479
2937
|
}
|
|
2938
|
+
function importedTableCellBackgroundColor(layers, theme) {
|
|
2939
|
+
let color = null;
|
|
2940
|
+
for (const layer of layers){
|
|
2941
|
+
const tableShading = layer.tableProperties ? directChild(layer.tableProperties, 'shd') : void 0;
|
|
2942
|
+
const cellShading = layer.cellProperties ? directChild(layer.cellProperties, 'shd') : void 0;
|
|
2943
|
+
if (tableShading) color = tableCellBackgroundColor(tableShading, theme);
|
|
2944
|
+
if (cellShading) color = tableCellBackgroundColor(cellShading, theme);
|
|
2945
|
+
}
|
|
2946
|
+
return color;
|
|
2947
|
+
}
|
|
2948
|
+
function tableCellBackgroundColor(shading, theme) {
|
|
2949
|
+
const themed = docxThemeColor(theme, attribute(shading, 'themeFill'), attribute(shading, 'themeFillTint'), attribute(shading, 'themeFillShade'));
|
|
2950
|
+
return themed ? `#${themed}` : ooxmlColor(attribute(shading, 'fill'));
|
|
2951
|
+
}
|
|
2952
|
+
function importedTableCellVerticalAlign(layers) {
|
|
2953
|
+
let alignment = null;
|
|
2954
|
+
for (const layer of layers){
|
|
2955
|
+
const element = layer.cellProperties ? directChild(layer.cellProperties, 'vAlign') : void 0;
|
|
2956
|
+
if (!element) continue;
|
|
2957
|
+
const value = tableVerticalAlign(attribute(element, 'val'));
|
|
2958
|
+
if (value) alignment = value;
|
|
2959
|
+
}
|
|
2960
|
+
return alignment;
|
|
2961
|
+
}
|
|
2480
2962
|
function tableBorderStyle(value) {
|
|
2481
2963
|
const normalized = value?.trim();
|
|
2482
2964
|
if (!normalized) return null;
|
|
@@ -2532,7 +3014,7 @@ function work_docx_table_cell_import_textNodes(root) {
|
|
|
2532
3014
|
const work_docx_table_row_import_WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
|
|
2533
3015
|
const work_docx_table_row_import_XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
|
|
2534
3016
|
const TABLE_ROW_MARKER_PATTERN = /__A3S_WORK_TABLE_ROW_\d+__/g;
|
|
2535
|
-
const
|
|
3017
|
+
const work_docx_table_row_import_PIXELS_PER_TWIP = 96 / 1440;
|
|
2536
3018
|
function markDocxTableRows(document) {
|
|
2537
3019
|
const rows = [];
|
|
2538
3020
|
for (const row of descendants(document, 'tr')){
|
|
@@ -2625,7 +3107,7 @@ function tableRowHeightRule(value) {
|
|
|
2625
3107
|
}
|
|
2626
3108
|
function work_docx_table_row_import_twipsToPixels(value) {
|
|
2627
3109
|
if (!Number.isFinite(value) || value <= 0) return null;
|
|
2628
|
-
return Math.round(value *
|
|
3110
|
+
return Math.round(value * work_docx_table_row_import_PIXELS_PER_TWIP * 100) / 100;
|
|
2629
3111
|
}
|
|
2630
3112
|
function work_docx_table_row_import_closestAncestor(element, localName) {
|
|
2631
3113
|
let current = element;
|
|
@@ -2647,21 +3129,19 @@ const work_docx_table_sizing_import_WORD_NAMESPACE = 'http://schemas.openxmlform
|
|
|
2647
3129
|
const work_docx_table_sizing_import_XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
|
|
2648
3130
|
const TABLE_SIZING_MARKER_PATTERN = /__A3S_WORK_TABLE_SIZING_\d+__/g;
|
|
2649
3131
|
const work_docx_table_sizing_import_PIXELS_PER_TWIP = 96 / 1440;
|
|
2650
|
-
function markDocxTableSizing(document) {
|
|
3132
|
+
function markDocxTableSizing(document, tableStyleSource) {
|
|
2651
3133
|
const tables = [];
|
|
3134
|
+
const tableStyles = resolveDocxTableStyleResolver(tableStyleSource);
|
|
2652
3135
|
for (const table of descendants(document, 'tbl')){
|
|
2653
3136
|
const paragraph = firstTableParagraph(document, table);
|
|
2654
3137
|
if (!paragraph) continue;
|
|
2655
|
-
const properties = directChild(table, 'tblPr');
|
|
2656
|
-
const layout = properties ? directChild(properties, 'tblLayout') : void 0;
|
|
2657
|
-
const preferredWidth = properties ? directChild(properties, 'tblW') : void 0;
|
|
2658
3138
|
const grid = directChild(table, 'tblGrid');
|
|
2659
|
-
const columnWidths = grid ? directChildren(grid, 'gridCol').map((column)=>work_docx_table_sizing_import_twipsToPixels(Number(attribute(column, 'w')))).filter((width)=>null !== width) : [];
|
|
3139
|
+
const columnWidths = grid ? directChildren(grid, 'gridCol').map((column)=>work_docx_table_sizing_import_twipsToPixels(Number(attribute(column, 'w')), false)).filter((width)=>null !== width) : [];
|
|
2660
3140
|
const marker = `__A3S_WORK_TABLE_SIZING_${tables.length + 1}__`;
|
|
2661
3141
|
insertMarker(document, paragraph, marker);
|
|
2662
3142
|
tables.push({
|
|
2663
3143
|
marker,
|
|
2664
|
-
|
|
3144
|
+
geometry: importedTableGeometry(docxTablePropertySources(table, tableStyles)),
|
|
2665
3145
|
columnWidths
|
|
2666
3146
|
});
|
|
2667
3147
|
}
|
|
@@ -2680,8 +3160,9 @@ function applyImportedDocxTableSizingMarkers(document, markers) {
|
|
|
2680
3160
|
node.data = node.data.replace(TABLE_SIZING_MARKER_PATTERN, (marker)=>{
|
|
2681
3161
|
const sizing = tableByMarker.get(marker);
|
|
2682
3162
|
if (table instanceof HTMLTableElement && sizing) {
|
|
2683
|
-
table.dataset.
|
|
2684
|
-
|
|
3163
|
+
table.dataset.officeTableImported = 'true';
|
|
3164
|
+
applyDocumentTableGeometryToElement(table, sizing.geometry);
|
|
3165
|
+
if (sizing.columnWidths.length) applyColumnWidths(table, sizing.columnWidths);
|
|
2685
3166
|
}
|
|
2686
3167
|
return '';
|
|
2687
3168
|
});
|
|
@@ -2691,12 +3172,104 @@ function applyImportedDocxTableSizingMarkers(document, markers) {
|
|
|
2691
3172
|
function hasImportedDocxTableSizingMarkers(markers) {
|
|
2692
3173
|
return markers.tables.length > 0;
|
|
2693
3174
|
}
|
|
2694
|
-
function
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
3175
|
+
function importedTableGeometry(propertySources) {
|
|
3176
|
+
let layout = DEFAULT_DOCUMENT_TABLE_GEOMETRY.layout;
|
|
3177
|
+
let width = {
|
|
3178
|
+
type: 'auto',
|
|
3179
|
+
value: null
|
|
3180
|
+
};
|
|
3181
|
+
let alignment = DEFAULT_DOCUMENT_TABLE_GEOMETRY.alignment;
|
|
3182
|
+
let indent = DEFAULT_DOCUMENT_TABLE_GEOMETRY.indent;
|
|
3183
|
+
let cellMargins = {
|
|
3184
|
+
...DEFAULT_DOCUMENT_TABLE_CELL_MARGINS
|
|
3185
|
+
};
|
|
3186
|
+
for (const properties of propertySources){
|
|
3187
|
+
const layoutElement = directChild(properties, 'tblLayout');
|
|
3188
|
+
const layoutValue = layoutElement ? importedTableLayout(attribute(layoutElement, 'type')) : null;
|
|
3189
|
+
if (layoutValue) layout = layoutValue;
|
|
3190
|
+
const widthElement = directChild(properties, 'tblW');
|
|
3191
|
+
const widthValue = widthElement ? importedTablePreferredWidth(widthElement) : null;
|
|
3192
|
+
if (widthValue) width = widthValue;
|
|
3193
|
+
const alignmentElement = directChild(properties, 'jc');
|
|
3194
|
+
const alignmentValue = alignmentElement ? importedTableAlignment(attribute(alignmentElement, 'val')) : null;
|
|
3195
|
+
if (alignmentValue) alignment = alignmentValue;
|
|
3196
|
+
const indentElement = directChild(properties, 'tblInd');
|
|
3197
|
+
const indentValue = indentElement ? tableWidthPixels(indentElement, true) : null;
|
|
3198
|
+
if (null !== indentValue) indent = indentValue;
|
|
3199
|
+
const marginElement = directChild(properties, 'tblCellMar');
|
|
3200
|
+
if (marginElement) cellMargins = {
|
|
3201
|
+
...cellMargins,
|
|
3202
|
+
...importedCellMargins(marginElement)
|
|
3203
|
+
};
|
|
3204
|
+
}
|
|
3205
|
+
return {
|
|
3206
|
+
layout,
|
|
3207
|
+
width,
|
|
3208
|
+
alignment,
|
|
3209
|
+
indent,
|
|
3210
|
+
cellMargins
|
|
3211
|
+
};
|
|
3212
|
+
}
|
|
3213
|
+
function importedTableLayout(value) {
|
|
3214
|
+
if ('fixed' === value) return 'fixed';
|
|
3215
|
+
return 'autofit' === value ? 'autofit' : null;
|
|
3216
|
+
}
|
|
3217
|
+
function importedTablePreferredWidth(width) {
|
|
3218
|
+
const type = attribute(width, 'type');
|
|
3219
|
+
if ('auto' === type || 'nil' === type) return {
|
|
3220
|
+
type: 'auto',
|
|
3221
|
+
value: null
|
|
3222
|
+
};
|
|
3223
|
+
if ('pct' === type) {
|
|
3224
|
+
const value = percentageValue(attribute(width, 'w'));
|
|
3225
|
+
return null === value ? null : {
|
|
3226
|
+
type: 'percent',
|
|
3227
|
+
value
|
|
3228
|
+
};
|
|
3229
|
+
}
|
|
3230
|
+
if ('dxa' === type) {
|
|
3231
|
+
const value = tableWidthPixels(width, false);
|
|
3232
|
+
return null === value ? null : {
|
|
3233
|
+
type: 'pixels',
|
|
3234
|
+
value
|
|
3235
|
+
};
|
|
3236
|
+
}
|
|
3237
|
+
return null;
|
|
3238
|
+
}
|
|
3239
|
+
function importedTableAlignment(value) {
|
|
3240
|
+
if ('center' === value) return 'center';
|
|
3241
|
+
if ('right' === value || 'end' === value) return 'right';
|
|
3242
|
+
if ('left' === value || 'start' === value) return 'left';
|
|
3243
|
+
return null;
|
|
3244
|
+
}
|
|
3245
|
+
function importedCellMargins(margins) {
|
|
3246
|
+
const children = new Map(directChildren(margins).map((margin)=>[
|
|
3247
|
+
margin.localName,
|
|
3248
|
+
margin
|
|
3249
|
+
]));
|
|
3250
|
+
const result = {};
|
|
3251
|
+
assignMargin(result, 'top', children.get('top'));
|
|
3252
|
+
assignMargin(result, 'right', children.get('right') ?? children.get('end'));
|
|
3253
|
+
assignMargin(result, 'bottom', children.get('bottom'));
|
|
3254
|
+
assignMargin(result, 'left', children.get('left') ?? children.get('start'));
|
|
3255
|
+
return result;
|
|
3256
|
+
}
|
|
3257
|
+
function assignMargin(target, side, element) {
|
|
3258
|
+
if (!element) return;
|
|
3259
|
+
const value = tableWidthPixels(element, true);
|
|
3260
|
+
if (null !== value) target[side] = value;
|
|
3261
|
+
}
|
|
3262
|
+
function tableWidthPixels(element, allowZero) {
|
|
3263
|
+
const type = attribute(element, 'type');
|
|
3264
|
+
if (type && 'dxa' !== type) return null;
|
|
3265
|
+
return work_docx_table_sizing_import_twipsToPixels(Number(attribute(element, 'w')), allowZero);
|
|
3266
|
+
}
|
|
3267
|
+
function percentageValue(value) {
|
|
3268
|
+
const normalized = value?.trim();
|
|
3269
|
+
if (!normalized) return null;
|
|
3270
|
+
const percentage = normalized.endsWith('%') ? Number(normalized.slice(0, -1)) : Number(normalized) / 50;
|
|
3271
|
+
if (!Number.isFinite(percentage) || percentage <= 0) return null;
|
|
3272
|
+
return Math.round(100 * percentage) / 100;
|
|
2700
3273
|
}
|
|
2701
3274
|
function applyColumnWidths(table, columnWidths) {
|
|
2702
3275
|
const occupiedUntilRow = [];
|
|
@@ -2729,8 +3302,8 @@ function insertMarker(document, paragraph, marker) {
|
|
|
2729
3302
|
const properties = directChild(paragraph, 'pPr');
|
|
2730
3303
|
paragraph.insertBefore(run, properties?.nextSibling ?? paragraph.firstChild);
|
|
2731
3304
|
}
|
|
2732
|
-
function work_docx_table_sizing_import_twipsToPixels(value) {
|
|
2733
|
-
if (!Number.isFinite(value) || value
|
|
3305
|
+
function work_docx_table_sizing_import_twipsToPixels(value, allowZero) {
|
|
3306
|
+
if (!Number.isFinite(value) || value < 0 || !allowZero && 0 === value) return null;
|
|
2734
3307
|
return Math.round(value * work_docx_table_sizing_import_PIXELS_PER_TWIP * 100) / 100;
|
|
2735
3308
|
}
|
|
2736
3309
|
function work_docx_table_sizing_import_closestAncestor(element, localName) {
|
|
@@ -2838,18 +3411,19 @@ async function prepareDocxImport(buffer) {
|
|
|
2838
3411
|
const imageLayoutMarkers = markDocxImageLayouts(document);
|
|
2839
3412
|
const paragraphStylesDocument = archive.has('word/styles.xml') ? await archive.xml('word/styles.xml') : null;
|
|
2840
3413
|
const paragraphStyles = createDocxParagraphStyleResolver(paragraphStylesDocument);
|
|
2841
|
-
const
|
|
2842
|
-
const
|
|
2843
|
-
const
|
|
2844
|
-
const
|
|
2845
|
-
const
|
|
3414
|
+
const tableStyles = createDocxTableStyleResolver(paragraphStylesDocument);
|
|
3415
|
+
const paragraphDirectionMarkers = markDocxParagraphDirections(document, paragraphStyles, tableStyles);
|
|
3416
|
+
const paragraphAlignmentMarkers = markDocxParagraphAlignments(document, paragraphStyles, tableStyles);
|
|
3417
|
+
const paragraphIndentMarkers = markDocxParagraphIndents(document, paragraphStyles, tableStyles);
|
|
3418
|
+
const paragraphSpacingMarkers = markDocxParagraphSpacing(document, paragraphStyles, tableStyles);
|
|
3419
|
+
const paragraphPaginationMarkers = markDocxParagraphPagination(document, paragraphStyles, tableStyles);
|
|
2846
3420
|
const themePath = archive.paths('word/theme/').find((path)=>/\/theme\d*\.xml$/i.test(path));
|
|
2847
3421
|
const themeDocument = themePath ? await archive.xml(themePath) : null;
|
|
2848
|
-
const runFormattingMarkers = markDocxRunFormatting(document, paragraphStyles, themeDocument);
|
|
2849
|
-
const tabStopMarkers = markDocxParagraphTabStops(document, paragraphStyles);
|
|
2850
|
-
const tableCellMarkers = markDocxTableCells(document);
|
|
3422
|
+
const runFormattingMarkers = markDocxRunFormatting(document, paragraphStyles, themeDocument, tableStyles);
|
|
3423
|
+
const tabStopMarkers = markDocxParagraphTabStops(document, paragraphStyles, tableStyles);
|
|
3424
|
+
const tableCellMarkers = markDocxTableCells(document, themeDocument, tableStyles);
|
|
2851
3425
|
const tableRowMarkers = markDocxTableRows(document);
|
|
2852
|
-
const tableSizingMarkers = markDocxTableSizing(document);
|
|
3426
|
+
const tableSizingMarkers = markDocxTableSizing(document, tableStyles);
|
|
2853
3427
|
const settings = archive.has('word/settings.xml') ? await archive.xml('word/settings.xml') : null;
|
|
2854
3428
|
const trackChanges = Boolean(settings && firstDescendant(settings, 'trackRevisions')) || changeMarkers.changes.length > 0;
|
|
2855
3429
|
const sectionElements = effectiveSectionProperties(document);
|
|
@@ -3021,6 +3595,7 @@ async function parseSectionLayout(section, archive, relationships, previous, odd
|
|
|
3021
3595
|
const size = pageSize ? Math.abs(shortEdge - 12240) < Math.abs(shortEdge - 11906) ? 'letter' : 'a4' : previous.pageSize;
|
|
3022
3596
|
const marginsElement = firstDescendant(section, 'pgMar');
|
|
3023
3597
|
const columnsElement = firstDescendant(section, 'cols');
|
|
3598
|
+
const documentGridElement = directChild(section, 'docGrid');
|
|
3024
3599
|
const pageChrome = await importSectionPageChrome(section, archive, relationships, previous, oddEvenPageChrome);
|
|
3025
3600
|
const pageNumberStart = work_docx_import_numberAttribute(firstDescendant(section, 'pgNumType'), 'start');
|
|
3026
3601
|
return {
|
|
@@ -3032,11 +3607,27 @@ async function parseSectionLayout(section, archive, relationships, previous, odd
|
|
|
3032
3607
|
columns: columnsElement ? importDocxColumns(columnsElement, previous.columns) : {
|
|
3033
3608
|
...previous.columns
|
|
3034
3609
|
},
|
|
3610
|
+
...documentGridElement ? {
|
|
3611
|
+
documentGrid: parseDocumentGrid(documentGridElement)
|
|
3612
|
+
} : previous.documentGrid ? {
|
|
3613
|
+
documentGrid: {
|
|
3614
|
+
...previous.documentGrid
|
|
3615
|
+
}
|
|
3616
|
+
} : {},
|
|
3035
3617
|
breakAfter: parseSectionBreak(firstDescendant(section, 'type')),
|
|
3036
3618
|
...pageChrome,
|
|
3037
3619
|
pageNumberStart: pageNumberStart > 0 ? pageNumberStart : void 0
|
|
3038
3620
|
};
|
|
3039
3621
|
}
|
|
3622
|
+
function parseDocumentGrid(element) {
|
|
3623
|
+
const sourceType = attribute(element, 'type');
|
|
3624
|
+
const type = 'lines' === sourceType || 'linesAndChars' === sourceType || 'snapToChars' === sourceType ? sourceType : 'default';
|
|
3625
|
+
const sourceLinePitch = work_docx_import_numberAttribute(element, 'linePitch');
|
|
3626
|
+
return {
|
|
3627
|
+
type,
|
|
3628
|
+
linePitch: sourceLinePitch > 0 ? Number((sourceLinePitch / 20).toFixed(2)) : 18
|
|
3629
|
+
};
|
|
3630
|
+
}
|
|
3040
3631
|
function addSectionMarkers(document, sectionElements) {
|
|
3041
3632
|
for(let index = 0; index < sectionElements.length - 1; index += 1){
|
|
3042
3633
|
const paragraph = work_docx_import_closestAncestor(sectionElements[index], 'p');
|