@a3s-lab/office 0.1.0 → 0.2.2
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 +101 -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 +766 -107
- 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, runText);
|
|
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,22 +2316,45 @@ 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
|
}
|
|
2058
2325
|
function hasImportedDocxRunFormattingMarkers(markers) {
|
|
2059
2326
|
return markers.runs.length > 0;
|
|
2060
2327
|
}
|
|
2061
|
-
function resolvedRunFormatting(propertySources, theme) {
|
|
2328
|
+
function resolvedRunFormatting(propertySources, theme, runText) {
|
|
2062
2329
|
const fonts = {};
|
|
2063
2330
|
let fontSize;
|
|
2331
|
+
let complexFontSize;
|
|
2064
2332
|
let color;
|
|
2065
2333
|
let backgroundColor;
|
|
2334
|
+
let bold;
|
|
2335
|
+
let complexBold;
|
|
2336
|
+
let italic;
|
|
2337
|
+
let complexItalic;
|
|
2338
|
+
let underline;
|
|
2339
|
+
let strike;
|
|
2340
|
+
let snapToGrid;
|
|
2341
|
+
let complexScriptFormatting;
|
|
2342
|
+
let rightToLeft;
|
|
2343
|
+
let fontHint;
|
|
2066
2344
|
for (const properties of propertySources){
|
|
2345
|
+
bold = overriddenBoolean(bold, onOffProperty(properties, 'b'));
|
|
2346
|
+
complexBold = overriddenBoolean(complexBold, onOffProperty(properties, 'bCs'));
|
|
2347
|
+
italic = overriddenBoolean(italic, onOffProperty(properties, 'i'));
|
|
2348
|
+
complexItalic = overriddenBoolean(complexItalic, onOffProperty(properties, 'iCs'));
|
|
2349
|
+
underline = overriddenBoolean(underline, underlineProperty(properties));
|
|
2350
|
+
strike = overriddenBoolean(strike, onOffProperty(properties, 'strike'));
|
|
2351
|
+
strike = overriddenBoolean(strike, onOffProperty(properties, 'dstrike'));
|
|
2352
|
+
snapToGrid = overriddenBoolean(snapToGrid, onOffProperty(properties, 'snapToGrid'));
|
|
2353
|
+
complexScriptFormatting = overriddenBoolean(complexScriptFormatting, onOffProperty(properties, 'cs'));
|
|
2354
|
+
rightToLeft = overriddenBoolean(rightToLeft, onOffProperty(properties, 'rtl'));
|
|
2067
2355
|
const runFonts = directChild(properties, 'rFonts');
|
|
2068
2356
|
if (runFonts) {
|
|
2357
|
+
fontHint = resolvedFontHint(runFonts) ?? fontHint;
|
|
2069
2358
|
assignFont(fonts, 'ascii', resolvedFont(runFonts, 'ascii', 'asciiTheme', theme));
|
|
2070
2359
|
assignFont(fonts, 'hAnsi', resolvedFont(runFonts, 'hAnsi', 'hAnsiTheme', theme));
|
|
2071
2360
|
assignFont(fonts, 'eastAsia', resolvedFont(runFonts, 'eastAsia', 'eastAsiaTheme', theme));
|
|
@@ -2073,6 +2362,8 @@ function resolvedRunFormatting(propertySources, theme) {
|
|
|
2073
2362
|
}
|
|
2074
2363
|
const size = work_docx_run_formatting_import_numericAttribute(directChild(properties, 'sz'), 'val');
|
|
2075
2364
|
if (void 0 !== size && size > 0) fontSize = Math.min(512, size / 2);
|
|
2365
|
+
const complexSize = work_docx_run_formatting_import_numericAttribute(directChild(properties, 'szCs'), 'val');
|
|
2366
|
+
if (void 0 !== complexSize && complexSize > 0) complexFontSize = Math.min(512, complexSize / 2);
|
|
2076
2367
|
const colorElement = directChild(properties, 'color');
|
|
2077
2368
|
if (colorElement) {
|
|
2078
2369
|
const value = work_docx_run_formatting_import_wordAttribute(colorElement, 'val')?.trim();
|
|
@@ -2094,18 +2385,41 @@ function resolvedRunFormatting(propertySources, theme) {
|
|
|
2094
2385
|
else if (fill && /^[0-9a-f]{6}$/i.test(fill)) backgroundColor = `#${fill.toLowerCase()}`;
|
|
2095
2386
|
}
|
|
2096
2387
|
}
|
|
2097
|
-
const
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2388
|
+
const fontSlot = true === complexScriptFormatting || true === rightToLeft ? 'complex' : docxFontSlotForText(runText, fontHint);
|
|
2389
|
+
const usesComplexFormatting = 'complex' === fontSlot;
|
|
2390
|
+
const resolvedBold = usesComplexFormatting ? complexBold ?? bold : bold;
|
|
2391
|
+
const resolvedItalic = usesComplexFormatting ? complexItalic ?? italic : italic;
|
|
2392
|
+
const resolvedFontSize = usesComplexFormatting ? complexFontSize ?? fontSize : fontSize;
|
|
2393
|
+
let fontFamily = uniqueFonts(orderedFonts(fonts, fontSlot));
|
|
2394
|
+
if (!fontFamily) fontFamily = uniqueFonts(orderedFonts({
|
|
2395
|
+
ascii: docxThemeFont(theme, 'minorAscii'),
|
|
2396
|
+
hAnsi: docxThemeFont(theme, 'minorHAnsi'),
|
|
2397
|
+
eastAsia: docxThemeFont(theme, 'minorEastAsia'),
|
|
2398
|
+
complex: docxThemeFont(theme, 'minorBidi')
|
|
2399
|
+
}, fontSlot));
|
|
2400
|
+
const hasRunPropertySource = propertySources.length > 0;
|
|
2103
2401
|
return {
|
|
2402
|
+
...void 0 !== resolvedBold || hasRunPropertySource ? {
|
|
2403
|
+
bold: resolvedBold ?? false
|
|
2404
|
+
} : {},
|
|
2405
|
+
...void 0 !== resolvedItalic || hasRunPropertySource ? {
|
|
2406
|
+
italic: resolvedItalic ?? false
|
|
2407
|
+
} : {},
|
|
2408
|
+
...void 0 !== underline || hasRunPropertySource ? {
|
|
2409
|
+
underline: underline ?? false
|
|
2410
|
+
} : {},
|
|
2411
|
+
...void 0 !== strike || hasRunPropertySource ? {
|
|
2412
|
+
strike: strike ?? false
|
|
2413
|
+
} : {},
|
|
2104
2414
|
...fontFamily ? {
|
|
2105
|
-
fontFamily
|
|
2415
|
+
fontFamily,
|
|
2416
|
+
wordLineHeightFactor: documentWordLineHeightFactor(fontFamily)
|
|
2106
2417
|
} : {},
|
|
2107
|
-
...void 0 !==
|
|
2108
|
-
fontSize
|
|
2418
|
+
...void 0 !== resolvedFontSize ? {
|
|
2419
|
+
fontSize: resolvedFontSize
|
|
2420
|
+
} : {},
|
|
2421
|
+
...void 0 !== snapToGrid ? {
|
|
2422
|
+
wordSnapToGrid: snapToGrid
|
|
2109
2423
|
} : {},
|
|
2110
2424
|
...color ? {
|
|
2111
2425
|
color
|
|
@@ -2127,14 +2441,57 @@ function work_docx_run_formatting_import_markerText(document, marker) {
|
|
|
2127
2441
|
text.textContent = marker;
|
|
2128
2442
|
return text;
|
|
2129
2443
|
}
|
|
2130
|
-
function
|
|
2444
|
+
function formattingMarkup(document, formatting) {
|
|
2131
2445
|
const span = document.createElement('span');
|
|
2446
|
+
if (false === formatting.bold) span.style.fontWeight = 'normal';
|
|
2447
|
+
if (false === formatting.italic) span.style.fontStyle = 'normal';
|
|
2448
|
+
if ((false === formatting.underline || false === formatting.strike) && !formatting.underline && !formatting.strike) span.style.textDecorationLine = 'none';
|
|
2132
2449
|
if (formatting.fontFamily) span.style.fontFamily = formatting.fontFamily;
|
|
2450
|
+
if (void 0 !== formatting.wordLineHeightFactor) {
|
|
2451
|
+
const factor = formatLineHeightFactor(formatting.wordLineHeightFactor);
|
|
2452
|
+
span.dataset.officeWordLineHeightFactor = factor;
|
|
2453
|
+
span.style.setProperty('--work-document-word-line-height-factor', factor);
|
|
2454
|
+
}
|
|
2455
|
+
if (void 0 !== formatting.wordSnapToGrid) span.dataset.officeWordSnapToGrid = String(formatting.wordSnapToGrid);
|
|
2133
2456
|
if (void 0 !== formatting.fontSize) span.style.fontSize = `${work_docx_run_formatting_import_formatNumber(formatting.fontSize)}pt`;
|
|
2134
2457
|
if (formatting.color) span.style.color = formatting.color;
|
|
2135
2458
|
if (formatting.backgroundColor) span.style.backgroundColor = formatting.backgroundColor;
|
|
2136
2459
|
const html = span.outerHTML;
|
|
2137
|
-
|
|
2460
|
+
const tags = [
|
|
2461
|
+
...formatting.bold ? [
|
|
2462
|
+
'strong'
|
|
2463
|
+
] : [],
|
|
2464
|
+
...formatting.italic ? [
|
|
2465
|
+
'em'
|
|
2466
|
+
] : [],
|
|
2467
|
+
...formatting.underline ? [
|
|
2468
|
+
'u'
|
|
2469
|
+
] : [],
|
|
2470
|
+
...formatting.strike ? [
|
|
2471
|
+
's'
|
|
2472
|
+
] : []
|
|
2473
|
+
];
|
|
2474
|
+
return {
|
|
2475
|
+
start: `${html.slice(0, html.indexOf('>') + 1)}${tags.map((tag)=>`<${tag}>`).join('')}`,
|
|
2476
|
+
end: `${[
|
|
2477
|
+
...tags
|
|
2478
|
+
].reverse().map((tag)=>`</${tag}>`).join('')}</span>`
|
|
2479
|
+
};
|
|
2480
|
+
}
|
|
2481
|
+
function overriddenBoolean(current, next) {
|
|
2482
|
+
return void 0 === next ? current : next;
|
|
2483
|
+
}
|
|
2484
|
+
function onOffProperty(properties, propertyName) {
|
|
2485
|
+
const element = directChild(properties, propertyName);
|
|
2486
|
+
if (!element) return;
|
|
2487
|
+
const value = work_docx_run_formatting_import_wordAttribute(element, 'val')?.trim().toLowerCase();
|
|
2488
|
+
return '0' !== value && 'false' !== value && 'off' !== value;
|
|
2489
|
+
}
|
|
2490
|
+
function underlineProperty(properties) {
|
|
2491
|
+
const element = directChild(properties, 'u');
|
|
2492
|
+
if (!element) return;
|
|
2493
|
+
const value = work_docx_run_formatting_import_wordAttribute(element, 'val')?.trim().toLowerCase();
|
|
2494
|
+
return '0' !== value && 'false' !== value && 'off' !== value && 'none' !== value;
|
|
2138
2495
|
}
|
|
2139
2496
|
function directRunText(run) {
|
|
2140
2497
|
return Array.from(run.children).filter((child)=>'t' === child.localName || 'delText' === child.localName).map((child)=>child.textContent ?? '').join('');
|
|
@@ -2151,6 +2508,61 @@ function assignFont(fonts, key, value) {
|
|
|
2151
2508
|
const normalized = value?.trim();
|
|
2152
2509
|
if (normalized) fonts[key] = normalized;
|
|
2153
2510
|
}
|
|
2511
|
+
function resolvedFontHint(element) {
|
|
2512
|
+
const hint = work_docx_run_formatting_import_wordAttribute(element, 'hint')?.trim().toLowerCase();
|
|
2513
|
+
if ('eastasia' === hint) return 'eastAsia';
|
|
2514
|
+
if ('cs' === hint) return 'complex';
|
|
2515
|
+
if ('default' === hint) return 'ascii';
|
|
2516
|
+
}
|
|
2517
|
+
function orderedFonts(fonts, preferred) {
|
|
2518
|
+
const order = {
|
|
2519
|
+
ascii: [
|
|
2520
|
+
'ascii',
|
|
2521
|
+
'hAnsi',
|
|
2522
|
+
'eastAsia',
|
|
2523
|
+
'complex'
|
|
2524
|
+
],
|
|
2525
|
+
hAnsi: [
|
|
2526
|
+
'hAnsi',
|
|
2527
|
+
'ascii',
|
|
2528
|
+
'eastAsia',
|
|
2529
|
+
'complex'
|
|
2530
|
+
],
|
|
2531
|
+
eastAsia: [
|
|
2532
|
+
'eastAsia',
|
|
2533
|
+
'hAnsi',
|
|
2534
|
+
'ascii',
|
|
2535
|
+
'complex'
|
|
2536
|
+
],
|
|
2537
|
+
complex: [
|
|
2538
|
+
'complex',
|
|
2539
|
+
'hAnsi',
|
|
2540
|
+
'ascii',
|
|
2541
|
+
'eastAsia'
|
|
2542
|
+
]
|
|
2543
|
+
};
|
|
2544
|
+
return order[preferred].map((slot)=>fonts[slot]);
|
|
2545
|
+
}
|
|
2546
|
+
function docxFontSlotForText(text, hint) {
|
|
2547
|
+
for (const character of text){
|
|
2548
|
+
const codePoint = character.codePointAt(0);
|
|
2549
|
+
if (!(void 0 === codePoint || isNeutralCodePoint(codePoint))) {
|
|
2550
|
+
if (isComplexScriptCodePoint(codePoint)) return 'complex';
|
|
2551
|
+
if (isEastAsianCodePoint(codePoint)) return 'eastAsia';
|
|
2552
|
+
return codePoint <= 0x7f ? 'ascii' : 'hAnsi';
|
|
2553
|
+
}
|
|
2554
|
+
}
|
|
2555
|
+
return hint ?? 'ascii';
|
|
2556
|
+
}
|
|
2557
|
+
function isNeutralCodePoint(codePoint) {
|
|
2558
|
+
return codePoint <= 0x20 || codePoint <= 0x7f && !(codePoint >= 0x41 && codePoint <= 0x5a || codePoint >= 0x61 && codePoint <= 0x7a) || codePoint >= 0x300 && codePoint <= 0x36f || codePoint >= 0x2000 && codePoint <= 0x206f;
|
|
2559
|
+
}
|
|
2560
|
+
function isComplexScriptCodePoint(codePoint) {
|
|
2561
|
+
return codePoint >= 0x0590 && codePoint <= 0x08ff || codePoint >= 0xfb1d && codePoint <= 0xfdff || codePoint >= 0xfe70 && codePoint <= 0xfeff || codePoint >= 0x1ee00 && codePoint <= 0x1eeff;
|
|
2562
|
+
}
|
|
2563
|
+
function isEastAsianCodePoint(codePoint) {
|
|
2564
|
+
return codePoint >= 0x1100 && codePoint <= 0x11ff || codePoint >= 0x2e80 && codePoint <= 0xa4cf || codePoint >= 0xac00 && codePoint <= 0xd7af || codePoint >= 0xf900 && codePoint <= 0xfaff || codePoint >= 0xfe10 && codePoint <= 0xfe6f || codePoint >= 0xff00 && codePoint <= 0xffef || codePoint >= 0x20000 && codePoint <= 0x323af;
|
|
2565
|
+
}
|
|
2154
2566
|
function resolvedFont(element, explicitName, themeName, theme) {
|
|
2155
2567
|
const explicit = work_docx_run_formatting_import_wordAttribute(element, explicitName);
|
|
2156
2568
|
if (explicit?.trim()) return explicit;
|
|
@@ -2200,18 +2612,22 @@ function wordHighlightColor(value) {
|
|
|
2200
2612
|
function work_docx_run_formatting_import_formatNumber(value) {
|
|
2201
2613
|
return Number(value.toFixed(2)).toString();
|
|
2202
2614
|
}
|
|
2615
|
+
function formatLineHeightFactor(value) {
|
|
2616
|
+
return Number(value.toFixed(4)).toString();
|
|
2617
|
+
}
|
|
2203
2618
|
const work_docx_tab_stop_import_WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
|
|
2204
2619
|
const work_docx_tab_stop_import_XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
|
|
2205
2620
|
const work_docx_tab_stop_import_TWIPS_PER_CSS_PIXEL = 15;
|
|
2206
2621
|
const PARAGRAPH_TAB_STOP_MARKER_PATTERN = /__A3S_WORK_PARAGRAPH_TAB_STOPS_\d+__/g;
|
|
2207
2622
|
const INLINE_TAB_MARKER_PATTERN = /__A3S_WORK_INLINE_TAB_\d+__/g;
|
|
2208
|
-
function markDocxParagraphTabStops(document, styleSource) {
|
|
2623
|
+
function markDocxParagraphTabStops(document, styleSource, tableStyleSource) {
|
|
2209
2624
|
const paragraphs = [];
|
|
2210
2625
|
const inlineTabs = [];
|
|
2211
2626
|
const styles = resolveDocxParagraphStyleResolver(styleSource);
|
|
2627
|
+
const tableStyles = resolveDocxTableStyleResolver(tableStyleSource);
|
|
2212
2628
|
for (const paragraph of descendants(document, 'p')){
|
|
2213
2629
|
let properties = directChild(paragraph, 'pPr');
|
|
2214
|
-
const tabStops = resolvedParagraphTabStops(docxParagraphPropertySources(properties, styles));
|
|
2630
|
+
const tabStops = resolvedParagraphTabStops(docxParagraphPropertySources(properties, styles, docxTableParagraphPropertySources(paragraph, tableStyles)));
|
|
2215
2631
|
if (tabStops.length) {
|
|
2216
2632
|
properties ??= work_docx_tab_stop_import_insertParagraphProperties(document, paragraph);
|
|
2217
2633
|
const marker = `__A3S_WORK_PARAGRAPH_TAB_STOPS_${paragraphs.length + 1}__`;
|
|
@@ -2357,20 +2773,42 @@ function work_docx_tab_stop_import_textNodes(root) {
|
|
|
2357
2773
|
while(walker.nextNode())nodes.push(walker.currentNode);
|
|
2358
2774
|
return nodes;
|
|
2359
2775
|
}
|
|
2776
|
+
const TABLE_BORDER_EDGES = [
|
|
2777
|
+
'top',
|
|
2778
|
+
'right',
|
|
2779
|
+
'bottom',
|
|
2780
|
+
'left'
|
|
2781
|
+
];
|
|
2360
2782
|
const work_docx_table_cell_import_WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
|
|
2361
2783
|
const work_docx_table_cell_import_XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
|
|
2362
2784
|
const TABLE_CELL_MARKER_PATTERN = /__A3S_WORK_TABLE_CELL_\d+__/g;
|
|
2363
|
-
|
|
2785
|
+
const PIXELS_PER_TWIP = 96 / 1440;
|
|
2786
|
+
function markDocxTableCells(document, themeSource, tableStyleSource) {
|
|
2364
2787
|
const cells = [];
|
|
2788
|
+
const theme = resolveDocxThemeResolver(themeSource);
|
|
2789
|
+
const tableStyles = resolveDocxTableStyleResolver(tableStyleSource);
|
|
2365
2790
|
for (const cell of descendants(document, 'tc')){
|
|
2366
2791
|
const properties = directChild(cell, 'tcPr');
|
|
2367
|
-
const
|
|
2368
|
-
const
|
|
2369
|
-
const
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2792
|
+
const table = work_docx_table_cell_import_closestAncestor(cell, 'tbl');
|
|
2793
|
+
const directTableProperties = table ? directChild(table, 'tblPr') : void 0;
|
|
2794
|
+
const layers = [
|
|
2795
|
+
...docxTableCellStyleLayers(cell, tableStyles),
|
|
2796
|
+
...directTableProperties ? [
|
|
2797
|
+
{
|
|
2798
|
+
tableProperties: directTableProperties
|
|
2799
|
+
}
|
|
2800
|
+
] : [],
|
|
2801
|
+
...properties ? [
|
|
2802
|
+
{
|
|
2803
|
+
cellProperties: properties
|
|
2804
|
+
}
|
|
2805
|
+
] : []
|
|
2806
|
+
];
|
|
2807
|
+
const borders = importedTableCellBorders(cell, layers, theme);
|
|
2808
|
+
const backgroundColor = importedTableCellBackgroundColor(layers, theme);
|
|
2809
|
+
const verticalAlign = importedTableCellVerticalAlign(layers);
|
|
2810
|
+
const margins = importedTableCellMargins(layers);
|
|
2811
|
+
if (!backgroundColor && !verticalAlign && !borders && !margins) continue;
|
|
2374
2812
|
const paragraph = firstTableCellParagraph(document, cell);
|
|
2375
2813
|
if (!paragraph) continue;
|
|
2376
2814
|
const marker = `__A3S_WORK_TABLE_CELL_${cells.length + 1}__`;
|
|
@@ -2383,10 +2821,11 @@ function markDocxTableCells(document) {
|
|
|
2383
2821
|
...verticalAlign ? {
|
|
2384
2822
|
verticalAlign
|
|
2385
2823
|
} : {},
|
|
2386
|
-
...
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2824
|
+
...borders ? {
|
|
2825
|
+
borders
|
|
2826
|
+
} : {},
|
|
2827
|
+
...margins ? {
|
|
2828
|
+
margins
|
|
2390
2829
|
} : {}
|
|
2391
2830
|
});
|
|
2392
2831
|
}
|
|
@@ -2422,44 +2861,130 @@ function applyCellFormat(cell, format) {
|
|
|
2422
2861
|
cell.dataset.officeCellVerticalAlign = format.verticalAlign;
|
|
2423
2862
|
cell.style.verticalAlign = format.verticalAlign;
|
|
2424
2863
|
}
|
|
2425
|
-
if (format.
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2864
|
+
if (format.borders) {
|
|
2865
|
+
const borders = documentTableBordersFromElement(cell, {
|
|
2866
|
+
color: '#cfd5df',
|
|
2867
|
+
style: 'solid',
|
|
2868
|
+
width: 1
|
|
2869
|
+
});
|
|
2870
|
+
for (const edge of TABLE_BORDER_EDGES){
|
|
2871
|
+
const border = format.borders[edge];
|
|
2872
|
+
if (border) borders[edge] = {
|
|
2873
|
+
...border
|
|
2874
|
+
};
|
|
2875
|
+
}
|
|
2876
|
+
const rendered = renderDocumentTableBorders(borders);
|
|
2877
|
+
for (const [name, value] of Object.entries(rendered))if ('style' !== name) cell.setAttribute(name, value);
|
|
2878
|
+
cell.style.cssText = `${cell.style.cssText}; ${rendered.style}`;
|
|
2879
|
+
}
|
|
2880
|
+
if (format.margins) {
|
|
2881
|
+
const rendered = renderDocumentTableCellMarginOverrides(format.margins);
|
|
2882
|
+
for (const [name, value] of Object.entries(rendered))if ('style' !== name) cell.setAttribute(name, value);
|
|
2883
|
+
if (rendered.style) cell.style.cssText = `${cell.style.cssText}; ${rendered.style}`;
|
|
2884
|
+
}
|
|
2885
|
+
}
|
|
2886
|
+
function importedTableCellMargins(layers) {
|
|
2887
|
+
const margins = {};
|
|
2888
|
+
for (const layer of layers){
|
|
2889
|
+
const marginElement = layer.cellProperties ? directChild(layer.cellProperties, 'tcMar') : void 0;
|
|
2890
|
+
if (!marginElement) continue;
|
|
2891
|
+
const children = new Map(directChildren(marginElement).map((margin)=>[
|
|
2892
|
+
margin.localName,
|
|
2893
|
+
margin
|
|
2894
|
+
]));
|
|
2895
|
+
assignCellMargin(margins, 'top', children.get('top'));
|
|
2896
|
+
assignCellMargin(margins, 'right', children.get('right') ?? children.get('end'));
|
|
2897
|
+
assignCellMargin(margins, 'bottom', children.get('bottom'));
|
|
2898
|
+
assignCellMargin(margins, 'left', children.get('left') ?? children.get('start'));
|
|
2899
|
+
}
|
|
2900
|
+
return Object.keys(margins).length ? margins : null;
|
|
2901
|
+
}
|
|
2902
|
+
function assignCellMargin(target, side, element) {
|
|
2903
|
+
if (!element) return;
|
|
2904
|
+
const type = attribute(element, 'type');
|
|
2905
|
+
if (type && 'dxa' !== type) return;
|
|
2906
|
+
const twips = Number(attribute(element, 'w'));
|
|
2907
|
+
if (!Number.isFinite(twips) || twips < 0) return;
|
|
2908
|
+
target[side] = Math.round(twips * PIXELS_PER_TWIP * 100) / 100;
|
|
2909
|
+
}
|
|
2910
|
+
function importedTableCellBorders(cell, layers, theme) {
|
|
2911
|
+
const borders = {};
|
|
2912
|
+
for (const layer of layers){
|
|
2913
|
+
if (layer.tableProperties) mergeBorders(borders, tableBordersForCell(cell, layer.tableProperties, theme));
|
|
2914
|
+
if (layer.cellProperties) mergeBorders(borders, borderEdges(directChild(layer.cellProperties, 'tcBorders'), theme));
|
|
2430
2915
|
}
|
|
2916
|
+
return Object.keys(borders).length ? borders : null;
|
|
2431
2917
|
}
|
|
2432
|
-
function
|
|
2918
|
+
function tableBordersForCell(cell, properties, theme) {
|
|
2433
2919
|
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
|
-
|
|
2920
|
+
const borders = borderElementMap(directChild(properties, 'tblBorders'));
|
|
2921
|
+
if (!table || !borders.size) return {};
|
|
2922
|
+
const row = work_docx_table_cell_import_closestAncestor(cell, 'tr');
|
|
2923
|
+
if (!row) return {};
|
|
2924
|
+
const rows = descendants(table, 'tr').filter((candidate)=>work_docx_table_cell_import_closestAncestor(candidate, 'tbl') === table);
|
|
2925
|
+
const cells = descendants(row, 'tc').filter((candidate)=>work_docx_table_cell_import_closestAncestor(candidate, 'tr') === row);
|
|
2926
|
+
const rowIndex = rows.indexOf(row);
|
|
2927
|
+
const cellIndex = cells.indexOf(cell);
|
|
2928
|
+
if (rowIndex < 0 || cellIndex < 0) return {};
|
|
2929
|
+
return compactBorders({
|
|
2930
|
+
top: parseBorder(borders.get(0 === rowIndex ? 'top' : 'insideH'), theme),
|
|
2931
|
+
right: parseBorder(borderElement(borders, cellIndex === cells.length - 1 ? [
|
|
2932
|
+
'right',
|
|
2933
|
+
'end'
|
|
2934
|
+
] : [
|
|
2935
|
+
'insideV'
|
|
2936
|
+
]), theme),
|
|
2937
|
+
bottom: parseBorder(borders.get(rowIndex === rows.length - 1 ? 'bottom' : 'insideH'), theme),
|
|
2938
|
+
left: parseBorder(borderElement(borders, 0 === cellIndex ? [
|
|
2939
|
+
'left',
|
|
2940
|
+
'start'
|
|
2941
|
+
] : [
|
|
2942
|
+
'insideV'
|
|
2943
|
+
]), theme)
|
|
2944
|
+
});
|
|
2945
|
+
}
|
|
2946
|
+
function mergeBorders(target, source) {
|
|
2947
|
+
for (const edge of TABLE_BORDER_EDGES){
|
|
2948
|
+
const border = source[edge];
|
|
2949
|
+
if (border) target[edge] = border;
|
|
2950
|
+
}
|
|
2951
|
+
}
|
|
2952
|
+
function borderEdges(borders, theme) {
|
|
2953
|
+
const edges = borderElementMap(borders);
|
|
2954
|
+
return compactBorders({
|
|
2955
|
+
top: parseBorder(edges.get('top'), theme),
|
|
2956
|
+
right: parseBorder(borderElement(edges, [
|
|
2957
|
+
'right',
|
|
2958
|
+
'end'
|
|
2959
|
+
]), theme),
|
|
2960
|
+
bottom: parseBorder(edges.get('bottom'), theme),
|
|
2961
|
+
left: parseBorder(borderElement(edges, [
|
|
2962
|
+
'left',
|
|
2963
|
+
'start'
|
|
2964
|
+
]), theme)
|
|
2965
|
+
});
|
|
2966
|
+
}
|
|
2967
|
+
function borderElementMap(borders) {
|
|
2968
|
+
return new Map(borders ? directChildren(borders).map((edge)=>[
|
|
2453
2969
|
edge.localName,
|
|
2454
2970
|
edge
|
|
2455
|
-
]));
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
const
|
|
2459
|
-
|
|
2460
|
-
|
|
2971
|
+
]) : []);
|
|
2972
|
+
}
|
|
2973
|
+
function borderElement(borders, names) {
|
|
2974
|
+
for (const name of names){
|
|
2975
|
+
const edge = borders.get(name);
|
|
2976
|
+
if (edge) return edge;
|
|
2977
|
+
}
|
|
2461
2978
|
}
|
|
2462
|
-
function
|
|
2979
|
+
function compactBorders(borders) {
|
|
2980
|
+
const result = {};
|
|
2981
|
+
for (const edge of TABLE_BORDER_EDGES){
|
|
2982
|
+
const border = borders[edge];
|
|
2983
|
+
if (border) result[edge] = border;
|
|
2984
|
+
}
|
|
2985
|
+
return result;
|
|
2986
|
+
}
|
|
2987
|
+
function parseBorder(edge, theme) {
|
|
2463
2988
|
if (!edge) return null;
|
|
2464
2989
|
const style = tableBorderStyle(attribute(edge, 'val'));
|
|
2465
2990
|
if (!style) return null;
|
|
@@ -2468,7 +2993,8 @@ function parseBorder(edge) {
|
|
|
2468
2993
|
style,
|
|
2469
2994
|
width: 0
|
|
2470
2995
|
};
|
|
2471
|
-
const
|
|
2996
|
+
const themed = docxThemeColor(theme, attribute(edge, 'themeColor'), attribute(edge, 'themeTint'), attribute(edge, 'themeShade'));
|
|
2997
|
+
const color = themed ? `#${themed}` : ooxmlColor(attribute(edge, 'color')) ?? '#000000';
|
|
2472
2998
|
const size = Number(attribute(edge, 'sz'));
|
|
2473
2999
|
const width = Number.isFinite(size) && size > 0 ? size / 6 : 1;
|
|
2474
3000
|
return {
|
|
@@ -2477,6 +3003,30 @@ function parseBorder(edge) {
|
|
|
2477
3003
|
width: Math.max(0.5, Math.min(6, Math.round(2 * width) / 2))
|
|
2478
3004
|
};
|
|
2479
3005
|
}
|
|
3006
|
+
function importedTableCellBackgroundColor(layers, theme) {
|
|
3007
|
+
let color = null;
|
|
3008
|
+
for (const layer of layers){
|
|
3009
|
+
const tableShading = layer.tableProperties ? directChild(layer.tableProperties, 'shd') : void 0;
|
|
3010
|
+
const cellShading = layer.cellProperties ? directChild(layer.cellProperties, 'shd') : void 0;
|
|
3011
|
+
if (tableShading) color = tableCellBackgroundColor(tableShading, theme);
|
|
3012
|
+
if (cellShading) color = tableCellBackgroundColor(cellShading, theme);
|
|
3013
|
+
}
|
|
3014
|
+
return color;
|
|
3015
|
+
}
|
|
3016
|
+
function tableCellBackgroundColor(shading, theme) {
|
|
3017
|
+
const themed = docxThemeColor(theme, attribute(shading, 'themeFill'), attribute(shading, 'themeFillTint'), attribute(shading, 'themeFillShade'));
|
|
3018
|
+
return themed ? `#${themed}` : ooxmlColor(attribute(shading, 'fill'));
|
|
3019
|
+
}
|
|
3020
|
+
function importedTableCellVerticalAlign(layers) {
|
|
3021
|
+
let alignment = null;
|
|
3022
|
+
for (const layer of layers){
|
|
3023
|
+
const element = layer.cellProperties ? directChild(layer.cellProperties, 'vAlign') : void 0;
|
|
3024
|
+
if (!element) continue;
|
|
3025
|
+
const value = tableVerticalAlign(attribute(element, 'val'));
|
|
3026
|
+
if (value) alignment = value;
|
|
3027
|
+
}
|
|
3028
|
+
return alignment;
|
|
3029
|
+
}
|
|
2480
3030
|
function tableBorderStyle(value) {
|
|
2481
3031
|
const normalized = value?.trim();
|
|
2482
3032
|
if (!normalized) return null;
|
|
@@ -2532,7 +3082,7 @@ function work_docx_table_cell_import_textNodes(root) {
|
|
|
2532
3082
|
const work_docx_table_row_import_WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
|
|
2533
3083
|
const work_docx_table_row_import_XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
|
|
2534
3084
|
const TABLE_ROW_MARKER_PATTERN = /__A3S_WORK_TABLE_ROW_\d+__/g;
|
|
2535
|
-
const
|
|
3085
|
+
const work_docx_table_row_import_PIXELS_PER_TWIP = 96 / 1440;
|
|
2536
3086
|
function markDocxTableRows(document) {
|
|
2537
3087
|
const rows = [];
|
|
2538
3088
|
for (const row of descendants(document, 'tr')){
|
|
@@ -2625,7 +3175,7 @@ function tableRowHeightRule(value) {
|
|
|
2625
3175
|
}
|
|
2626
3176
|
function work_docx_table_row_import_twipsToPixels(value) {
|
|
2627
3177
|
if (!Number.isFinite(value) || value <= 0) return null;
|
|
2628
|
-
return Math.round(value *
|
|
3178
|
+
return Math.round(value * work_docx_table_row_import_PIXELS_PER_TWIP * 100) / 100;
|
|
2629
3179
|
}
|
|
2630
3180
|
function work_docx_table_row_import_closestAncestor(element, localName) {
|
|
2631
3181
|
let current = element;
|
|
@@ -2647,21 +3197,19 @@ const work_docx_table_sizing_import_WORD_NAMESPACE = 'http://schemas.openxmlform
|
|
|
2647
3197
|
const work_docx_table_sizing_import_XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
|
|
2648
3198
|
const TABLE_SIZING_MARKER_PATTERN = /__A3S_WORK_TABLE_SIZING_\d+__/g;
|
|
2649
3199
|
const work_docx_table_sizing_import_PIXELS_PER_TWIP = 96 / 1440;
|
|
2650
|
-
function markDocxTableSizing(document) {
|
|
3200
|
+
function markDocxTableSizing(document, tableStyleSource) {
|
|
2651
3201
|
const tables = [];
|
|
3202
|
+
const tableStyles = resolveDocxTableStyleResolver(tableStyleSource);
|
|
2652
3203
|
for (const table of descendants(document, 'tbl')){
|
|
2653
3204
|
const paragraph = firstTableParagraph(document, table);
|
|
2654
3205
|
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
3206
|
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) : [];
|
|
3207
|
+
const columnWidths = grid ? directChildren(grid, 'gridCol').map((column)=>work_docx_table_sizing_import_twipsToPixels(Number(attribute(column, 'w')), false)).filter((width)=>null !== width) : [];
|
|
2660
3208
|
const marker = `__A3S_WORK_TABLE_SIZING_${tables.length + 1}__`;
|
|
2661
3209
|
insertMarker(document, paragraph, marker);
|
|
2662
3210
|
tables.push({
|
|
2663
3211
|
marker,
|
|
2664
|
-
|
|
3212
|
+
geometry: importedTableGeometry(docxTablePropertySources(table, tableStyles)),
|
|
2665
3213
|
columnWidths
|
|
2666
3214
|
});
|
|
2667
3215
|
}
|
|
@@ -2680,8 +3228,9 @@ function applyImportedDocxTableSizingMarkers(document, markers) {
|
|
|
2680
3228
|
node.data = node.data.replace(TABLE_SIZING_MARKER_PATTERN, (marker)=>{
|
|
2681
3229
|
const sizing = tableByMarker.get(marker);
|
|
2682
3230
|
if (table instanceof HTMLTableElement && sizing) {
|
|
2683
|
-
table.dataset.
|
|
2684
|
-
|
|
3231
|
+
table.dataset.officeTableImported = 'true';
|
|
3232
|
+
applyDocumentTableGeometryToElement(table, sizing.geometry);
|
|
3233
|
+
if (sizing.columnWidths.length) applyColumnWidths(table, sizing.columnWidths);
|
|
2685
3234
|
}
|
|
2686
3235
|
return '';
|
|
2687
3236
|
});
|
|
@@ -2691,12 +3240,104 @@ function applyImportedDocxTableSizingMarkers(document, markers) {
|
|
|
2691
3240
|
function hasImportedDocxTableSizingMarkers(markers) {
|
|
2692
3241
|
return markers.tables.length > 0;
|
|
2693
3242
|
}
|
|
2694
|
-
function
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
3243
|
+
function importedTableGeometry(propertySources) {
|
|
3244
|
+
let layout = DEFAULT_DOCUMENT_TABLE_GEOMETRY.layout;
|
|
3245
|
+
let width = {
|
|
3246
|
+
type: 'auto',
|
|
3247
|
+
value: null
|
|
3248
|
+
};
|
|
3249
|
+
let alignment = DEFAULT_DOCUMENT_TABLE_GEOMETRY.alignment;
|
|
3250
|
+
let indent = DEFAULT_DOCUMENT_TABLE_GEOMETRY.indent;
|
|
3251
|
+
let cellMargins = {
|
|
3252
|
+
...DEFAULT_DOCUMENT_TABLE_CELL_MARGINS
|
|
3253
|
+
};
|
|
3254
|
+
for (const properties of propertySources){
|
|
3255
|
+
const layoutElement = directChild(properties, 'tblLayout');
|
|
3256
|
+
const layoutValue = layoutElement ? importedTableLayout(attribute(layoutElement, 'type')) : null;
|
|
3257
|
+
if (layoutValue) layout = layoutValue;
|
|
3258
|
+
const widthElement = directChild(properties, 'tblW');
|
|
3259
|
+
const widthValue = widthElement ? importedTablePreferredWidth(widthElement) : null;
|
|
3260
|
+
if (widthValue) width = widthValue;
|
|
3261
|
+
const alignmentElement = directChild(properties, 'jc');
|
|
3262
|
+
const alignmentValue = alignmentElement ? importedTableAlignment(attribute(alignmentElement, 'val')) : null;
|
|
3263
|
+
if (alignmentValue) alignment = alignmentValue;
|
|
3264
|
+
const indentElement = directChild(properties, 'tblInd');
|
|
3265
|
+
const indentValue = indentElement ? tableWidthPixels(indentElement, true) : null;
|
|
3266
|
+
if (null !== indentValue) indent = indentValue;
|
|
3267
|
+
const marginElement = directChild(properties, 'tblCellMar');
|
|
3268
|
+
if (marginElement) cellMargins = {
|
|
3269
|
+
...cellMargins,
|
|
3270
|
+
...importedCellMargins(marginElement)
|
|
3271
|
+
};
|
|
3272
|
+
}
|
|
3273
|
+
return {
|
|
3274
|
+
layout,
|
|
3275
|
+
width,
|
|
3276
|
+
alignment,
|
|
3277
|
+
indent,
|
|
3278
|
+
cellMargins
|
|
3279
|
+
};
|
|
3280
|
+
}
|
|
3281
|
+
function importedTableLayout(value) {
|
|
3282
|
+
if ('fixed' === value) return 'fixed';
|
|
3283
|
+
return 'autofit' === value ? 'autofit' : null;
|
|
3284
|
+
}
|
|
3285
|
+
function importedTablePreferredWidth(width) {
|
|
3286
|
+
const type = attribute(width, 'type');
|
|
3287
|
+
if ('auto' === type || 'nil' === type) return {
|
|
3288
|
+
type: 'auto',
|
|
3289
|
+
value: null
|
|
3290
|
+
};
|
|
3291
|
+
if ('pct' === type) {
|
|
3292
|
+
const value = percentageValue(attribute(width, 'w'));
|
|
3293
|
+
return null === value ? null : {
|
|
3294
|
+
type: 'percent',
|
|
3295
|
+
value
|
|
3296
|
+
};
|
|
3297
|
+
}
|
|
3298
|
+
if ('dxa' === type) {
|
|
3299
|
+
const value = tableWidthPixels(width, false);
|
|
3300
|
+
return null === value ? null : {
|
|
3301
|
+
type: 'pixels',
|
|
3302
|
+
value
|
|
3303
|
+
};
|
|
3304
|
+
}
|
|
3305
|
+
return null;
|
|
3306
|
+
}
|
|
3307
|
+
function importedTableAlignment(value) {
|
|
3308
|
+
if ('center' === value) return 'center';
|
|
3309
|
+
if ('right' === value || 'end' === value) return 'right';
|
|
3310
|
+
if ('left' === value || 'start' === value) return 'left';
|
|
3311
|
+
return null;
|
|
3312
|
+
}
|
|
3313
|
+
function importedCellMargins(margins) {
|
|
3314
|
+
const children = new Map(directChildren(margins).map((margin)=>[
|
|
3315
|
+
margin.localName,
|
|
3316
|
+
margin
|
|
3317
|
+
]));
|
|
3318
|
+
const result = {};
|
|
3319
|
+
assignMargin(result, 'top', children.get('top'));
|
|
3320
|
+
assignMargin(result, 'right', children.get('right') ?? children.get('end'));
|
|
3321
|
+
assignMargin(result, 'bottom', children.get('bottom'));
|
|
3322
|
+
assignMargin(result, 'left', children.get('left') ?? children.get('start'));
|
|
3323
|
+
return result;
|
|
3324
|
+
}
|
|
3325
|
+
function assignMargin(target, side, element) {
|
|
3326
|
+
if (!element) return;
|
|
3327
|
+
const value = tableWidthPixels(element, true);
|
|
3328
|
+
if (null !== value) target[side] = value;
|
|
3329
|
+
}
|
|
3330
|
+
function tableWidthPixels(element, allowZero) {
|
|
3331
|
+
const type = attribute(element, 'type');
|
|
3332
|
+
if (type && 'dxa' !== type) return null;
|
|
3333
|
+
return work_docx_table_sizing_import_twipsToPixels(Number(attribute(element, 'w')), allowZero);
|
|
3334
|
+
}
|
|
3335
|
+
function percentageValue(value) {
|
|
3336
|
+
const normalized = value?.trim();
|
|
3337
|
+
if (!normalized) return null;
|
|
3338
|
+
const percentage = normalized.endsWith('%') ? Number(normalized.slice(0, -1)) : Number(normalized) / 50;
|
|
3339
|
+
if (!Number.isFinite(percentage) || percentage <= 0) return null;
|
|
3340
|
+
return Math.round(100 * percentage) / 100;
|
|
2700
3341
|
}
|
|
2701
3342
|
function applyColumnWidths(table, columnWidths) {
|
|
2702
3343
|
const occupiedUntilRow = [];
|
|
@@ -2729,8 +3370,8 @@ function insertMarker(document, paragraph, marker) {
|
|
|
2729
3370
|
const properties = directChild(paragraph, 'pPr');
|
|
2730
3371
|
paragraph.insertBefore(run, properties?.nextSibling ?? paragraph.firstChild);
|
|
2731
3372
|
}
|
|
2732
|
-
function work_docx_table_sizing_import_twipsToPixels(value) {
|
|
2733
|
-
if (!Number.isFinite(value) || value
|
|
3373
|
+
function work_docx_table_sizing_import_twipsToPixels(value, allowZero) {
|
|
3374
|
+
if (!Number.isFinite(value) || value < 0 || !allowZero && 0 === value) return null;
|
|
2734
3375
|
return Math.round(value * work_docx_table_sizing_import_PIXELS_PER_TWIP * 100) / 100;
|
|
2735
3376
|
}
|
|
2736
3377
|
function work_docx_table_sizing_import_closestAncestor(element, localName) {
|
|
@@ -2838,18 +3479,19 @@ async function prepareDocxImport(buffer) {
|
|
|
2838
3479
|
const imageLayoutMarkers = markDocxImageLayouts(document);
|
|
2839
3480
|
const paragraphStylesDocument = archive.has('word/styles.xml') ? await archive.xml('word/styles.xml') : null;
|
|
2840
3481
|
const paragraphStyles = createDocxParagraphStyleResolver(paragraphStylesDocument);
|
|
2841
|
-
const
|
|
2842
|
-
const
|
|
2843
|
-
const
|
|
2844
|
-
const
|
|
2845
|
-
const
|
|
3482
|
+
const tableStyles = createDocxTableStyleResolver(paragraphStylesDocument);
|
|
3483
|
+
const paragraphDirectionMarkers = markDocxParagraphDirections(document, paragraphStyles, tableStyles);
|
|
3484
|
+
const paragraphAlignmentMarkers = markDocxParagraphAlignments(document, paragraphStyles, tableStyles);
|
|
3485
|
+
const paragraphIndentMarkers = markDocxParagraphIndents(document, paragraphStyles, tableStyles);
|
|
3486
|
+
const paragraphSpacingMarkers = markDocxParagraphSpacing(document, paragraphStyles, tableStyles);
|
|
3487
|
+
const paragraphPaginationMarkers = markDocxParagraphPagination(document, paragraphStyles, tableStyles);
|
|
2846
3488
|
const themePath = archive.paths('word/theme/').find((path)=>/\/theme\d*\.xml$/i.test(path));
|
|
2847
3489
|
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);
|
|
3490
|
+
const runFormattingMarkers = markDocxRunFormatting(document, paragraphStyles, themeDocument, tableStyles);
|
|
3491
|
+
const tabStopMarkers = markDocxParagraphTabStops(document, paragraphStyles, tableStyles);
|
|
3492
|
+
const tableCellMarkers = markDocxTableCells(document, themeDocument, tableStyles);
|
|
2851
3493
|
const tableRowMarkers = markDocxTableRows(document);
|
|
2852
|
-
const tableSizingMarkers = markDocxTableSizing(document);
|
|
3494
|
+
const tableSizingMarkers = markDocxTableSizing(document, tableStyles);
|
|
2853
3495
|
const settings = archive.has('word/settings.xml') ? await archive.xml('word/settings.xml') : null;
|
|
2854
3496
|
const trackChanges = Boolean(settings && firstDescendant(settings, 'trackRevisions')) || changeMarkers.changes.length > 0;
|
|
2855
3497
|
const sectionElements = effectiveSectionProperties(document);
|
|
@@ -3021,6 +3663,7 @@ async function parseSectionLayout(section, archive, relationships, previous, odd
|
|
|
3021
3663
|
const size = pageSize ? Math.abs(shortEdge - 12240) < Math.abs(shortEdge - 11906) ? 'letter' : 'a4' : previous.pageSize;
|
|
3022
3664
|
const marginsElement = firstDescendant(section, 'pgMar');
|
|
3023
3665
|
const columnsElement = firstDescendant(section, 'cols');
|
|
3666
|
+
const documentGridElement = directChild(section, 'docGrid');
|
|
3024
3667
|
const pageChrome = await importSectionPageChrome(section, archive, relationships, previous, oddEvenPageChrome);
|
|
3025
3668
|
const pageNumberStart = work_docx_import_numberAttribute(firstDescendant(section, 'pgNumType'), 'start');
|
|
3026
3669
|
return {
|
|
@@ -3032,11 +3675,27 @@ async function parseSectionLayout(section, archive, relationships, previous, odd
|
|
|
3032
3675
|
columns: columnsElement ? importDocxColumns(columnsElement, previous.columns) : {
|
|
3033
3676
|
...previous.columns
|
|
3034
3677
|
},
|
|
3678
|
+
...documentGridElement ? {
|
|
3679
|
+
documentGrid: parseDocumentGrid(documentGridElement)
|
|
3680
|
+
} : previous.documentGrid ? {
|
|
3681
|
+
documentGrid: {
|
|
3682
|
+
...previous.documentGrid
|
|
3683
|
+
}
|
|
3684
|
+
} : {},
|
|
3035
3685
|
breakAfter: parseSectionBreak(firstDescendant(section, 'type')),
|
|
3036
3686
|
...pageChrome,
|
|
3037
3687
|
pageNumberStart: pageNumberStart > 0 ? pageNumberStart : void 0
|
|
3038
3688
|
};
|
|
3039
3689
|
}
|
|
3690
|
+
function parseDocumentGrid(element) {
|
|
3691
|
+
const sourceType = attribute(element, 'type');
|
|
3692
|
+
const type = 'lines' === sourceType || 'linesAndChars' === sourceType || 'snapToChars' === sourceType ? sourceType : 'default';
|
|
3693
|
+
const sourceLinePitch = work_docx_import_numberAttribute(element, 'linePitch');
|
|
3694
|
+
return {
|
|
3695
|
+
type,
|
|
3696
|
+
linePitch: sourceLinePitch > 0 ? Number((sourceLinePitch / 20).toFixed(2)) : 18
|
|
3697
|
+
};
|
|
3698
|
+
}
|
|
3040
3699
|
function addSectionMarkers(document, sectionElements) {
|
|
3041
3700
|
for(let index = 0; index < sectionElements.length - 1; index += 1){
|
|
3042
3701
|
const paragraph = work_docx_import_closestAncestor(sectionElements[index], 'p');
|