roosterjs-content-model-dom 9.23.0 → 9.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/lib/domToModel/processors/linkProcessor.js +6 -2
- package/lib/domToModel/processors/linkProcessor.js.map +1 -1
- package/lib/domToModel/processors/tableProcessor.js +18 -15
- package/lib/domToModel/processors/tableProcessor.js.map +1 -1
- package/lib/domUtils/readFile.js +14 -9
- package/lib/domUtils/readFile.js.map +1 -1
- package/lib/modelApi/editing/retrieveModelFormatState.d.ts +2 -2
- package/lib/modelApi/editing/retrieveModelFormatState.js +28 -11
- package/lib/modelApi/editing/retrieveModelFormatState.js.map +1 -1
- package/lib/modelToDom/handlers/handleList.js +6 -3
- package/lib/modelToDom/handlers/handleList.js.map +1 -1
- package/lib-amd/domToModel/processors/linkProcessor.js +6 -2
- package/lib-amd/domToModel/processors/linkProcessor.js.map +1 -1
- package/lib-amd/domToModel/processors/tableProcessor.js +18 -15
- package/lib-amd/domToModel/processors/tableProcessor.js.map +1 -1
- package/lib-amd/domUtils/readFile.js +14 -9
- package/lib-amd/domUtils/readFile.js.map +1 -1
- package/lib-amd/modelApi/editing/retrieveModelFormatState.d.ts +2 -2
- package/lib-amd/modelApi/editing/retrieveModelFormatState.js +28 -11
- package/lib-amd/modelApi/editing/retrieveModelFormatState.js.map +1 -1
- package/lib-amd/modelToDom/handlers/handleList.js +6 -3
- package/lib-amd/modelToDom/handlers/handleList.js.map +1 -1
- package/lib-mjs/domToModel/processors/linkProcessor.js +6 -2
- package/lib-mjs/domToModel/processors/linkProcessor.js.map +1 -1
- package/lib-mjs/domToModel/processors/tableProcessor.js +18 -15
- package/lib-mjs/domToModel/processors/tableProcessor.js.map +1 -1
- package/lib-mjs/domUtils/readFile.js +14 -9
- package/lib-mjs/domUtils/readFile.js.map +1 -1
- package/lib-mjs/modelApi/editing/retrieveModelFormatState.d.ts +2 -2
- package/lib-mjs/modelApi/editing/retrieveModelFormatState.js +28 -11
- package/lib-mjs/modelApi/editing/retrieveModelFormatState.js.map +1 -1
- package/lib-mjs/modelToDom/handlers/handleList.js +6 -3
- package/lib-mjs/modelToDom/handlers/handleList.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -51,6 +51,9 @@ There are also some extension packages to provide additional functionalities.
|
|
|
51
51
|
1. [roosterjs-color-utils](https://microsoft.github.io/roosterjs/docs/modules/roosterjs_color_utils.html):
|
|
52
52
|
Provide color transformation utility to make editor work under dark mode.
|
|
53
53
|
|
|
54
|
+
2. [roosterjs-content-model-markdown](https://microsoft.github.io/roosterjs/docs/modules/roosterjs_content_model_types.html):
|
|
55
|
+
Defines public APIs to enable conversions between Markdown and ContentModel
|
|
56
|
+
|
|
54
57
|
To be compatible with old (8.\*) versions, you can use `EditorAdapter` class from the following package which can act as a 8.\* Editor:
|
|
55
58
|
|
|
56
59
|
1. [roosterjs-editor-adapter](https://microsoft.github.io/roosterjs/docs/modules/roosterjs_editor_adapter.html):
|
|
@@ -24,10 +24,14 @@ var linkProcessor = function (group, element, context) {
|
|
|
24
24
|
(0, parseFormat_1.parseFormat)(element, context.formatParsers.dataset, context.link.dataset, context);
|
|
25
25
|
if (isAnchor_1 && !element.firstChild) {
|
|
26
26
|
// Empty anchor, need to make sure it has some child in model
|
|
27
|
-
|
|
27
|
+
var emptyText = (0, createText_1.createText)('', context.segmentFormat, {
|
|
28
28
|
dataset: context.link.dataset,
|
|
29
29
|
format: context.link.format,
|
|
30
|
-
})
|
|
30
|
+
});
|
|
31
|
+
if (context.isInSelection) {
|
|
32
|
+
emptyText.isSelected = true;
|
|
33
|
+
}
|
|
34
|
+
(0, addSegment_1.addSegment)(group, emptyText);
|
|
31
35
|
}
|
|
32
36
|
else {
|
|
33
37
|
(0, knownElementProcessor_1.knownElementProcessor)(group, element, context);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"linkProcessor.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/domToModel/processors/linkProcessor.ts"],"names":[],"mappings":";;;AAAA,+DAA8D;AAC9D,iEAAgE;AAChE,iEAAgE;AAChE,oDAAmD;AACnD,oDAAmD;AAInD;;GAEG;AACI,IAAM,aAAa,GAAkC,UAAC,KAAK,EAAE,OAAO,EAAE,OAAO;IAChF,IAAM,IAAI,GAAG,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;IAC1C,IAAM,IAAI,GAAG,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;IAE1C,IAAI,IAAI,IAAI,IAAI,EAAE;QACd,IAAM,UAAQ,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC;QACjC,IAAM,MAAM,GAAuB;YAC/B,6DAA6D;YAC7D,kDAAkD;YAClD,IAAI,EAAE,UAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa;SAC3C,CAAC;QAEF,IAAA,yBAAW,EAAC,OAAO,EAAE,MAAM,EAAE;YACzB,IAAA,yBAAW,EAAC,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAC/E,IAAA,yBAAW,EAAC,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAEnF,IAAI,UAAQ,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE;gBACjC,6DAA6D;gBAC7D,
|
|
1
|
+
{"version":3,"file":"linkProcessor.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/domToModel/processors/linkProcessor.ts"],"names":[],"mappings":";;;AAAA,+DAA8D;AAC9D,iEAAgE;AAChE,iEAAgE;AAChE,oDAAmD;AACnD,oDAAmD;AAInD;;GAEG;AACI,IAAM,aAAa,GAAkC,UAAC,KAAK,EAAE,OAAO,EAAE,OAAO;IAChF,IAAM,IAAI,GAAG,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;IAC1C,IAAM,IAAI,GAAG,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;IAE1C,IAAI,IAAI,IAAI,IAAI,EAAE;QACd,IAAM,UAAQ,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC;QACjC,IAAM,MAAM,GAAuB;YAC/B,6DAA6D;YAC7D,kDAAkD;YAClD,IAAI,EAAE,UAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa;SAC3C,CAAC;QAEF,IAAA,yBAAW,EAAC,OAAO,EAAE,MAAM,EAAE;YACzB,IAAA,yBAAW,EAAC,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAC/E,IAAA,yBAAW,EAAC,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAEnF,IAAI,UAAQ,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE;gBACjC,6DAA6D;gBAC7D,IAAM,SAAS,GAAG,IAAA,uBAAU,EAAC,EAAE,EAAE,OAAO,CAAC,aAAa,EAAE;oBACpD,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,OAAO;oBAC7B,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,MAAM;iBAC9B,CAAC,CAAC;gBAEH,IAAI,OAAO,CAAC,aAAa,EAAE;oBACvB,SAAS,CAAC,UAAU,GAAG,IAAI,CAAC;iBAC/B;gBAED,IAAA,uBAAU,EAAC,KAAK,EAAE,SAAS,CAAC,CAAC;aAChC;iBAAM;gBACH,IAAA,6CAAqB,EAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;aAClD;QACL,CAAC,CAAC,CAAC;KACN;SAAM;QACH,gEAAgE;QAChE,IAAA,6CAAqB,EAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;KAClD;AACL,CAAC,CAAC;AApCW,QAAA,aAAa,iBAoCxB","sourcesContent":["import { addSegment } from '../../modelApi/common/addSegment';\nimport { createText } from '../../modelApi/creators/createText';\nimport { knownElementProcessor } from './knownElementProcessor';\nimport { parseFormat } from '../utils/parseFormat';\nimport { stackFormat } from '../utils/stackFormat';\nimport type { StackFormatOptions } from '../utils/stackFormat';\nimport type { ElementProcessor } from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\nexport const linkProcessor: ElementProcessor<HTMLElement> = (group, element, context) => {\n const name = element.getAttribute('name');\n const href = element.getAttribute('href');\n\n if (name || href) {\n const isAnchor = !!name && !href;\n const option: StackFormatOptions = {\n // For anchor (name without ref), no need to add other styles\n // For link (href exists), add default link styles\n link: isAnchor ? 'empty' : 'linkDefault',\n };\n\n stackFormat(context, option, () => {\n parseFormat(element, context.formatParsers.link, context.link.format, context);\n parseFormat(element, context.formatParsers.dataset, context.link.dataset, context);\n\n if (isAnchor && !element.firstChild) {\n // Empty anchor, need to make sure it has some child in model\n const emptyText = createText('', context.segmentFormat, {\n dataset: context.link.dataset,\n format: context.link.format,\n });\n\n if (context.isInSelection) {\n emptyText.isSelected = true;\n }\n\n addSegment(group, emptyText);\n } else {\n knownElementProcessor(group, element, context);\n }\n });\n } else {\n // A tag without name or href, can be treated as normal SPAN tag\n knownElementProcessor(group, element, context);\n }\n};\n"]}
|
|
@@ -78,21 +78,24 @@ var tableProcessor = function (group, tableElement, context) {
|
|
|
78
78
|
for (; tableRow.cells[targetCol]; targetCol++) { }
|
|
79
79
|
var td = tr.cells[sourceCol];
|
|
80
80
|
var hasSelectionBeforeCell = context.isInSelection;
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
if (
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
81
|
+
if (context.recalculateTableSize) {
|
|
82
|
+
var colEnd = targetCol + td.colSpan;
|
|
83
|
+
var rowEnd = row + td.rowSpan;
|
|
84
|
+
var needCalcWidth = columnPositions[colEnd] === undefined;
|
|
85
|
+
var needCalcHeight = rowPositions[rowEnd] === undefined;
|
|
86
|
+
if (needCalcWidth || needCalcHeight) {
|
|
87
|
+
var rect = (0, getBoundingClientRect_1.getBoundingClientRect)(td);
|
|
88
|
+
if (rect.width > 0 || rect.height > 0) {
|
|
89
|
+
if (needCalcWidth) {
|
|
90
|
+
var pos = columnPositions[targetCol];
|
|
91
|
+
columnPositions[colEnd] =
|
|
92
|
+
(typeof pos == 'number' ? pos : 0) +
|
|
93
|
+
rect.width / zoomScale;
|
|
94
|
+
}
|
|
95
|
+
if (needCalcHeight) {
|
|
96
|
+
rowPositions[rowEnd] =
|
|
97
|
+
rowPositions[row] + rect.height / zoomScale;
|
|
98
|
+
}
|
|
96
99
|
}
|
|
97
100
|
}
|
|
98
101
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tableProcessor.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/domToModel/processors/tableProcessor.ts"],"names":[],"mappings":"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","sourcesContent":["import { addBlock } from '../../modelApi/common/addBlock';\nimport { createTable } from '../../modelApi/creators/createTable';\nimport { createTableCell } from '../../modelApi/creators/createTableCell';\nimport { getBoundingClientRect } from '../utils/getBoundingClientRect';\nimport { isElementOfType } from '../../domUtils/isElementOfType';\nimport { isNodeOfType } from '../../domUtils/isNodeOfType';\nimport { parseFormat } from '../utils/parseFormat';\nimport { parseValueWithUnit } from '../../formatHandlers/utils/parseValueWithUnit';\nimport { stackFormat } from '../utils/stackFormat';\nimport type {\n ContentModelTableCellFormat,\n DatasetFormat,\n DomToModelContext,\n ElementProcessor,\n SizeFormat,\n} from 'roosterjs-content-model-types';\n\n/**\n * Content Model Element Processor for table\n *\n * For Table with merged/splitted cells, HTML uses colSpan and rowSpan attributes to specify how it should be rendered.\n * To make it easier to edit a table, we will use a different way to describe table.\n *\n * 1. For a m * n table (m rows, n columns), we always create a m * n array for the cells.\n * 2. For a regular table cell, it is mapped to one item of this array\n * 3. For a merged/splitted table cell, it will has colSpan/rowSpan value. We also created TableCell model for those spanned\n * cells, and use \"spanLeft\" and \"spanAbove\" to mark its state\n * 4. When edit table, we always edit on this mapped m * n array because it always has an item for each cell\n * 5. When write back to DOM, we create TD/TH elements for those non-spanned cells, and mark its colSpan/rowSpan value according\n * its neighbour cell's spanLeft/spanAbove attribute\n * @param group The parent block group\n * @param parent Parent DOM node to process\n * @param context DOM to Content Model context\n */\nexport const tableProcessor: ElementProcessor<HTMLTableElement> = (\n group,\n tableElement,\n context\n) => {\n stackFormat(\n context,\n { segment: 'shallowCloneForBlock', paragraph: 'shallowCloneForGroup' },\n () => {\n parseFormat(tableElement, context.formatParsers.block, context.blockFormat, context);\n\n const table = createTable(tableElement.rows.length, context.blockFormat);\n const tableSelection = context.selection?.type == 'table' ? context.selection : null;\n const selectedTable = tableSelection?.table;\n const hasTableSelection = selectedTable == tableElement;\n\n if (context.allowCacheElement) {\n table.cachedElement = tableElement;\n }\n\n context.domIndexer?.onTable(tableElement, table);\n\n parseFormat(tableElement, context.formatParsers.table, table.format, context);\n parseFormat(tableElement, context.formatParsers.tableBorder, table.format, context);\n parseFormat(\n tableElement,\n context.formatParsers.segmentOnBlock,\n context.segmentFormat,\n context\n );\n parseFormat(tableElement, context.formatParsers.dataset, table.dataset, context);\n addBlock(group, table);\n\n const columnPositions: (number | undefined)[] = [0];\n const hasColGroup = processColGroup(tableElement, context, columnPositions);\n const rowPositions: number[] = [0];\n const zoomScale = context.zoomScale || 1;\n\n for (let row = 0; row < tableElement.rows.length; row++) {\n const tr = tableElement.rows[row];\n const tableRow = table.rows[row];\n\n const tbody = tr.parentNode;\n\n if (\n isNodeOfType(tbody, 'ELEMENT_NODE') &&\n (isElementOfType(tbody, 'tbody') ||\n isElementOfType(tbody, 'thead') ||\n isElementOfType(tbody, 'tfoot'))\n ) {\n parseFormat(tbody, context.formatParsers.tableRow, tableRow.format, context);\n } else if (context.allowCacheElement) {\n tableRow.cachedElement = tr;\n }\n\n parseFormat(tr, context.formatParsers.tableRow, tableRow.format, context);\n\n stackFormat(context, { paragraph: 'shallowClone', segment: 'shallowClone' }, () => {\n const parent = tr.parentElement;\n const parentTag = parent?.tagName;\n\n if (\n parent &&\n (parentTag == 'TBODY' || parentTag == 'THEAD' || parentTag == 'TFOOT')\n ) {\n // If there is TBODY around TR, retrieve format from TBODY first, in case some format are declared there\n parseFormat(\n parent,\n context.formatParsers.block,\n context.blockFormat,\n context\n );\n parseFormat(\n parent,\n context.formatParsers.segmentOnBlock,\n context.segmentFormat,\n context\n );\n }\n\n parseFormat(tr, context.formatParsers.block, context.blockFormat, context);\n parseFormat(\n tr,\n context.formatParsers.segmentOnBlock,\n context.segmentFormat,\n context\n );\n\n for (\n let sourceCol = 0, targetCol = 0;\n sourceCol < tr.cells.length;\n sourceCol++\n ) {\n for (; tableRow.cells[targetCol]; targetCol++) {}\n\n const td = tr.cells[sourceCol];\n const hasSelectionBeforeCell = context.isInSelection;\n const colEnd = targetCol + td.colSpan;\n const rowEnd = row + td.rowSpan;\n const needCalcWidth = columnPositions[colEnd] === undefined;\n const needCalcHeight = rowPositions[rowEnd] === undefined;\n\n if (needCalcWidth || needCalcHeight) {\n const rect = getBoundingClientRect(td);\n\n if (rect.width > 0 || rect.height > 0) {\n if (needCalcWidth) {\n const pos = columnPositions[targetCol];\n\n columnPositions[colEnd] =\n (typeof pos == 'number' ? pos : 0) + rect.width / zoomScale;\n }\n\n if (needCalcHeight) {\n rowPositions[rowEnd] =\n rowPositions[row] + rect.height / zoomScale;\n }\n }\n }\n\n stackFormat(\n context,\n { paragraph: 'shallowClone', segment: 'shallowClone' },\n () => {\n parseFormat(\n td,\n context.formatParsers.block,\n context.blockFormat,\n context\n );\n parseFormat(\n td,\n context.formatParsers.segmentOnTableCell,\n context.segmentFormat,\n context\n );\n\n const cellFormat: ContentModelTableCellFormat = {\n ...context.blockFormat,\n };\n const dataset: DatasetFormat = {};\n\n parseFormat(\n td,\n context.formatParsers.tableCell,\n cellFormat,\n context\n );\n parseFormat(\n td,\n context.formatParsers.tableBorder,\n cellFormat,\n context\n );\n parseFormat(td, context.formatParsers.dataset, dataset, context);\n\n for (\n let colSpan = 1;\n colSpan <= td.colSpan;\n colSpan++, targetCol++\n ) {\n for (let rowSpan = 1; rowSpan <= td.rowSpan; rowSpan++) {\n const hasTd = colSpan == 1 && rowSpan == 1;\n const cell = createTableCell(\n colSpan > 1,\n rowSpan > 1,\n td.tagName == 'TH',\n cellFormat\n );\n\n cell.dataset = { ...dataset };\n\n const spannedRow = table.rows[row + rowSpan - 1];\n\n if (spannedRow) {\n spannedRow.cells[targetCol] = cell;\n }\n\n if (hasTd) {\n // When there is COLGROUP, width on table cell should be ignored, so we should not cache the table cell,\n // and always recreate it when write back using the table formats\n if (context.allowCacheElement && !hasColGroup) {\n cell.cachedElement = td;\n }\n\n const { listParent, levels } = context.listFormat;\n\n context.listFormat.listParent = undefined;\n context.listFormat.levels = [];\n\n try {\n context.elementProcessors.child(cell, td, context);\n } finally {\n context.listFormat.listParent = listParent;\n context.listFormat.levels = levels;\n }\n }\n\n const hasSelectionAfterCell = context.isInSelection;\n\n if (\n (hasSelectionBeforeCell && hasSelectionAfterCell) ||\n (hasTableSelection &&\n tableSelection &&\n row >= tableSelection.firstRow &&\n row <= tableSelection.lastRow &&\n targetCol >= tableSelection.firstColumn &&\n targetCol <= tableSelection.lastColumn)\n ) {\n cell.isSelected = true;\n }\n }\n }\n }\n );\n }\n });\n\n for (let col = 0; col < tableRow.cells.length; col++) {\n if (!tableRow.cells[col]) {\n tableRow.cells[col] = createTableCell(\n false,\n false,\n false,\n context.blockFormat\n );\n }\n }\n }\n\n table.widths = calcSizes(columnPositions);\n\n const heights = calcSizes(rowPositions);\n\n table.rows.forEach((row, i) => {\n if (heights[i] > 0) {\n row.height = heights[i];\n }\n });\n }\n );\n};\n\nfunction calcSizes(positions: (number | undefined)[]): number[] {\n const result: number[] = [];\n let lastPos = 0;\n\n for (let i = positions.length - 1; i >= 0; i--) {\n const pos = positions[i];\n\n if (typeof pos == 'number') {\n lastPos = pos;\n break;\n }\n }\n\n for (let i = positions.length - 2; i >= 0; i--) {\n const pos = positions[i];\n if (pos === undefined) {\n result[i] = 0;\n } else {\n result[i] = lastPos - pos;\n lastPos = pos;\n }\n }\n\n return result;\n}\n\nfunction processColGroup(\n table: HTMLElement,\n context: DomToModelContext,\n result: (number | undefined)[]\n): boolean {\n let lastPos = 0;\n let hasColGroup = false;\n\n for (let child = table.firstChild; child; child = child.nextSibling) {\n if (isNodeOfType(child, 'ELEMENT_NODE') && child.tagName == 'COLGROUP') {\n hasColGroup = true;\n\n for (let col = child.firstChild; col; col = col.nextSibling) {\n if (isNodeOfType(col, 'ELEMENT_NODE') && col.tagName == 'COL') {\n const colFormat: SizeFormat = {};\n\n parseFormat(col, context.formatParsers.tableColumn, colFormat, context);\n\n for (let i = 0; i < parseInt(col.getAttribute('span') ?? '1'); i++) {\n if (colFormat.width === undefined) {\n result.push(undefined);\n } else {\n const width = parseValueWithUnit(\n colFormat.width ?? '',\n undefined /*element*/,\n 'px'\n );\n\n result.push(width + lastPos);\n lastPos += width;\n }\n }\n }\n }\n }\n }\n\n return hasColGroup;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"tableProcessor.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/domToModel/processors/tableProcessor.ts"],"names":[],"mappings":";;;;AAAA,2DAA0D;AAC1D,mEAAkE;AAClE,2EAA0E;AAC1E,wEAAuE;AACvE,kEAAiE;AACjE,4DAA2D;AAC3D,oDAAmD;AACnD,oFAAmF;AACnF,oDAAmD;AASnD;;;;;;;;;;;;;;;;GAgBG;AACI,IAAM,cAAc,GAAuC,UAC9D,KAAK,EACL,YAAY,EACZ,OAAO;IAEP,IAAA,yBAAW,EACP,OAAO,EACP,EAAE,OAAO,EAAE,sBAAsB,EAAE,SAAS,EAAE,sBAAsB,EAAE,EACtE;;QACI,IAAA,yBAAW,EAAC,YAAY,EAAE,OAAO,CAAC,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QAErF,IAAM,KAAK,GAAG,IAAA,yBAAW,EAAC,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;QACzE,IAAM,cAAc,GAAG,CAAA,MAAA,OAAO,CAAC,SAAS,0CAAE,IAAI,KAAI,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;QACrF,IAAM,aAAa,GAAG,cAAc,aAAd,cAAc,uBAAd,cAAc,CAAE,KAAK,CAAC;QAC5C,IAAM,iBAAiB,GAAG,aAAa,IAAI,YAAY,CAAC;QAExD,IAAI,OAAO,CAAC,iBAAiB,EAAE;YAC3B,KAAK,CAAC,aAAa,GAAG,YAAY,CAAC;SACtC;QAED,MAAA,OAAO,CAAC,UAAU,0CAAE,OAAO,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;QAEjD,IAAA,yBAAW,EAAC,YAAY,EAAE,OAAO,CAAC,aAAa,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC9E,IAAA,yBAAW,EAAC,YAAY,EAAE,OAAO,CAAC,aAAa,CAAC,WAAW,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACpF,IAAA,yBAAW,EACP,YAAY,EACZ,OAAO,CAAC,aAAa,CAAC,cAAc,EACpC,OAAO,CAAC,aAAa,EACrB,OAAO,CACV,CAAC;QACF,IAAA,yBAAW,EAAC,YAAY,EAAE,OAAO,CAAC,aAAa,CAAC,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACjF,IAAA,mBAAQ,EAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAEvB,IAAM,eAAe,GAA2B,CAAC,CAAC,CAAC,CAAC;QACpD,IAAM,WAAW,GAAG,eAAe,CAAC,YAAY,EAAE,OAAO,EAAE,eAAe,CAAC,CAAC;QAC5E,IAAM,YAAY,GAAa,CAAC,CAAC,CAAC,CAAC;QACnC,IAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,CAAC,CAAC;gCAEhC,GAAG;YACR,IAAM,EAAE,GAAG,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAClC,IAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAEjC,IAAM,KAAK,GAAG,EAAE,CAAC,UAAU,CAAC;YAE5B,IACI,IAAA,2BAAY,EAAC,KAAK,EAAE,cAAc,CAAC;gBACnC,CAAC,IAAA,iCAAe,EAAC,KAAK,EAAE,OAAO,CAAC;oBAC5B,IAAA,iCAAe,EAAC,KAAK,EAAE,OAAO,CAAC;oBAC/B,IAAA,iCAAe,EAAC,KAAK,EAAE,OAAO,CAAC,CAAC,EACtC;gBACE,IAAA,yBAAW,EAAC,KAAK,EAAE,OAAO,CAAC,aAAa,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;aAChF;iBAAM,IAAI,OAAO,CAAC,iBAAiB,EAAE;gBAClC,QAAQ,CAAC,aAAa,GAAG,EAAE,CAAC;aAC/B;YAED,IAAA,yBAAW,EAAC,EAAE,EAAE,OAAO,CAAC,aAAa,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAE1E,IAAA,yBAAW,EAAC,OAAO,EAAE,EAAE,SAAS,EAAE,cAAc,EAAE,OAAO,EAAE,cAAc,EAAE,EAAE;gBACzE,IAAM,MAAM,GAAG,EAAE,CAAC,aAAa,CAAC;gBAChC,IAAM,SAAS,GAAG,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,OAAO,CAAC;gBAElC,IACI,MAAM;oBACN,CAAC,SAAS,IAAI,OAAO,IAAI,SAAS,IAAI,OAAO,IAAI,SAAS,IAAI,OAAO,CAAC,EACxE;oBACE,wGAAwG;oBACxG,IAAA,yBAAW,EACP,MAAM,EACN,OAAO,CAAC,aAAa,CAAC,KAAK,EAC3B,OAAO,CAAC,WAAW,EACnB,OAAO,CACV,CAAC;oBACF,IAAA,yBAAW,EACP,MAAM,EACN,OAAO,CAAC,aAAa,CAAC,cAAc,EACpC,OAAO,CAAC,aAAa,EACrB,OAAO,CACV,CAAC;iBACL;gBAED,IAAA,yBAAW,EAAC,EAAE,EAAE,OAAO,CAAC,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;gBAC3E,IAAA,yBAAW,EACP,EAAE,EACF,OAAO,CAAC,aAAa,CAAC,cAAc,EACpC,OAAO,CAAC,aAAa,EACrB,OAAO,CACV,CAAC;wCAGM,SAAS,EAAM,SAAS;oBAI5B,OAAO,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,EAAE,GAAE;oBAEjD,IAAM,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;oBAC/B,IAAM,sBAAsB,GAAG,OAAO,CAAC,aAAa,CAAC;oBAErD,IAAI,OAAO,CAAC,oBAAoB,EAAE;wBAC9B,IAAM,MAAM,GAAG,SAAS,GAAG,EAAE,CAAC,OAAO,CAAC;wBACtC,IAAM,MAAM,GAAG,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC;wBAChC,IAAM,aAAa,GAAG,eAAe,CAAC,MAAM,CAAC,KAAK,SAAS,CAAC;wBAC5D,IAAM,cAAc,GAAG,YAAY,CAAC,MAAM,CAAC,KAAK,SAAS,CAAC;wBAE1D,IAAI,aAAa,IAAI,cAAc,EAAE;4BACjC,IAAM,IAAI,GAAG,IAAA,6CAAqB,EAAC,EAAE,CAAC,CAAC;4BAEvC,IAAI,IAAI,CAAC,KAAK,GAAG,CAAC,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE;gCACnC,IAAI,aAAa,EAAE;oCACf,IAAM,GAAG,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC;oCAEvC,eAAe,CAAC,MAAM,CAAC;wCACnB,CAAC,OAAO,GAAG,IAAI,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;4CAClC,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;iCAC9B;gCAED,IAAI,cAAc,EAAE;oCAChB,YAAY,CAAC,MAAM,CAAC;wCAChB,YAAY,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC;iCACnD;6BACJ;yBACJ;qBACJ;oBAED,IAAA,yBAAW,EACP,OAAO,EACP,EAAE,SAAS,EAAE,cAAc,EAAE,OAAO,EAAE,cAAc,EAAE,EACtD;wBACI,IAAA,yBAAW,EACP,EAAE,EACF,OAAO,CAAC,aAAa,CAAC,KAAK,EAC3B,OAAO,CAAC,WAAW,EACnB,OAAO,CACV,CAAC;wBACF,IAAA,yBAAW,EACP,EAAE,EACF,OAAO,CAAC,aAAa,CAAC,kBAAkB,EACxC,OAAO,CAAC,aAAa,EACrB,OAAO,CACV,CAAC;wBAEF,IAAM,UAAU,6BACT,OAAO,CAAC,WAAW,CACzB,CAAC;wBACF,IAAM,OAAO,GAAkB,EAAE,CAAC;wBAElC,IAAA,yBAAW,EACP,EAAE,EACF,OAAO,CAAC,aAAa,CAAC,SAAS,EAC/B,UAAU,EACV,OAAO,CACV,CAAC;wBACF,IAAA,yBAAW,EACP,EAAE,EACF,OAAO,CAAC,aAAa,CAAC,WAAW,EACjC,UAAU,EACV,OAAO,CACV,CAAC;wBACF,IAAA,yBAAW,EAAC,EAAE,EAAE,OAAO,CAAC,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;wBAEjE,KACI,IAAI,OAAO,GAAG,CAAC,EACf,OAAO,IAAI,EAAE,CAAC,OAAO,EACrB,OAAO,EAAE,EAAE,SAAS,EAAE,EACxB;4BACE,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE;gCACpD,IAAM,KAAK,GAAG,OAAO,IAAI,CAAC,IAAI,OAAO,IAAI,CAAC,CAAC;gCAC3C,IAAM,IAAI,GAAG,IAAA,iCAAe,EACxB,OAAO,GAAG,CAAC,EACX,OAAO,GAAG,CAAC,EACX,EAAE,CAAC,OAAO,IAAI,IAAI,EAClB,UAAU,CACb,CAAC;gCAEF,IAAI,CAAC,OAAO,6BAAQ,OAAO,CAAE,CAAC;gCAE9B,IAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,GAAG,OAAO,GAAG,CAAC,CAAC,CAAC;gCAEjD,IAAI,UAAU,EAAE;oCACZ,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC;iCACtC;gCAED,IAAI,KAAK,EAAE;oCACP,wGAAwG;oCACxG,iEAAiE;oCACjE,IAAI,OAAO,CAAC,iBAAiB,IAAI,CAAC,WAAW,EAAE;wCAC3C,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;qCAC3B;oCAEK,IAAA,KAAyB,OAAO,CAAC,UAAU,EAAzC,UAAU,gBAAA,EAAE,MAAM,YAAuB,CAAC;oCAElD,OAAO,CAAC,UAAU,CAAC,UAAU,GAAG,SAAS,CAAC;oCAC1C,OAAO,CAAC,UAAU,CAAC,MAAM,GAAG,EAAE,CAAC;oCAE/B,IAAI;wCACA,OAAO,CAAC,iBAAiB,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;qCACtD;4CAAS;wCACN,OAAO,CAAC,UAAU,CAAC,UAAU,GAAG,UAAU,CAAC;wCAC3C,OAAO,CAAC,UAAU,CAAC,MAAM,GAAG,MAAM,CAAC;qCACtC;iCACJ;gCAED,IAAM,qBAAqB,GAAG,OAAO,CAAC,aAAa,CAAC;gCAEpD,IACI,CAAC,sBAAsB,IAAI,qBAAqB,CAAC;oCACjD,CAAC,iBAAiB;wCACd,cAAc;wCACd,GAAG,IAAI,cAAc,CAAC,QAAQ;wCAC9B,GAAG,IAAI,cAAc,CAAC,OAAO;wCAC7B,SAAS,IAAI,cAAc,CAAC,WAAW;wCACvC,SAAS,IAAI,cAAc,CAAC,UAAU,CAAC,EAC7C;oCACE,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;iCAC1B;6BACJ;yBACJ;oBACL,CAAC,CACJ,CAAC;sCAjIiB,SAAS;;;gBADhC,KACI,IAAI,SAAS,GAAG,CAAC,EAAE,SAAS,GAAG,CAAC,EAChC,SAAS,GAAG,EAAE,CAAC,KAAK,CAAC,MAAM,EAC3B,SAAS,EAAE;4BAFP,SAAS,EAAM,SAAS;oBAAT,SAAS;iBAkI/B;YACL,CAAC,CAAC,CAAC;YAEH,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE;gBAClD,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;oBACtB,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,IAAA,iCAAe,EACjC,KAAK,EACL,KAAK,EACL,KAAK,EACL,OAAO,CAAC,WAAW,CACtB,CAAC;iBACL;aACJ;;QAjML,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE;oBAA9C,GAAG;SAkMX;QAED,KAAK,CAAC,MAAM,GAAG,SAAS,CAAC,eAAe,CAAC,CAAC;QAE1C,IAAM,OAAO,GAAG,SAAS,CAAC,YAAY,CAAC,CAAC;QAExC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,UAAC,GAAG,EAAE,CAAC;YACtB,IAAI,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;gBAChB,GAAG,CAAC,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;aAC3B;QACL,CAAC,CAAC,CAAC;IACP,CAAC,CACJ,CAAC;AACN,CAAC,CAAC;AArPW,QAAA,cAAc,kBAqPzB;AAEF,SAAS,SAAS,CAAC,SAAiC;IAChD,IAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,OAAO,GAAG,CAAC,CAAC;IAEhB,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE;QAC5C,IAAM,GAAG,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;QAEzB,IAAI,OAAO,GAAG,IAAI,QAAQ,EAAE;YACxB,OAAO,GAAG,GAAG,CAAC;YACd,MAAM;SACT;KACJ;IAED,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE;QAC5C,IAAM,GAAG,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;QACzB,IAAI,GAAG,KAAK,SAAS,EAAE;YACnB,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;SACjB;aAAM;YACH,MAAM,CAAC,CAAC,CAAC,GAAG,OAAO,GAAG,GAAG,CAAC;YAC1B,OAAO,GAAG,GAAG,CAAC;SACjB;KACJ;IAED,OAAO,MAAM,CAAC;AAClB,CAAC;AAED,SAAS,eAAe,CACpB,KAAkB,EAClB,OAA0B,EAC1B,MAA8B;;IAE9B,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,WAAW,GAAG,KAAK,CAAC;IAExB,KAAK,IAAI,KAAK,GAAG,KAAK,CAAC,UAAU,EAAE,KAAK,EAAE,KAAK,GAAG,KAAK,CAAC,WAAW,EAAE;QACjE,IAAI,IAAA,2BAAY,EAAC,KAAK,EAAE,cAAc,CAAC,IAAI,KAAK,CAAC,OAAO,IAAI,UAAU,EAAE;YACpE,WAAW,GAAG,IAAI,CAAC;YAEnB,KAAK,IAAI,GAAG,GAAG,KAAK,CAAC,UAAU,EAAE,GAAG,EAAE,GAAG,GAAG,GAAG,CAAC,WAAW,EAAE;gBACzD,IAAI,IAAA,2BAAY,EAAC,GAAG,EAAE,cAAc,CAAC,IAAI,GAAG,CAAC,OAAO,IAAI,KAAK,EAAE;oBAC3D,IAAM,SAAS,GAAe,EAAE,CAAC;oBAEjC,IAAA,yBAAW,EAAC,GAAG,EAAE,OAAO,CAAC,aAAa,CAAC,WAAW,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;oBAExE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAA,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,mCAAI,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE;wBAChE,IAAI,SAAS,CAAC,KAAK,KAAK,SAAS,EAAE;4BAC/B,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;yBAC1B;6BAAM;4BACH,IAAM,KAAK,GAAG,IAAA,uCAAkB,EAC5B,MAAA,SAAS,CAAC,KAAK,mCAAI,EAAE,EACrB,SAAS,CAAC,WAAW,EACrB,IAAI,CACP,CAAC;4BAEF,MAAM,CAAC,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,CAAC;4BAC7B,OAAO,IAAI,KAAK,CAAC;yBACpB;qBACJ;iBACJ;aACJ;SACJ;KACJ;IAED,OAAO,WAAW,CAAC;AACvB,CAAC","sourcesContent":["import { addBlock } from '../../modelApi/common/addBlock';\nimport { createTable } from '../../modelApi/creators/createTable';\nimport { createTableCell } from '../../modelApi/creators/createTableCell';\nimport { getBoundingClientRect } from '../utils/getBoundingClientRect';\nimport { isElementOfType } from '../../domUtils/isElementOfType';\nimport { isNodeOfType } from '../../domUtils/isNodeOfType';\nimport { parseFormat } from '../utils/parseFormat';\nimport { parseValueWithUnit } from '../../formatHandlers/utils/parseValueWithUnit';\nimport { stackFormat } from '../utils/stackFormat';\nimport type {\n ContentModelTableCellFormat,\n DatasetFormat,\n DomToModelContext,\n ElementProcessor,\n SizeFormat,\n} from 'roosterjs-content-model-types';\n\n/**\n * Content Model Element Processor for table\n *\n * For Table with merged/splitted cells, HTML uses colSpan and rowSpan attributes to specify how it should be rendered.\n * To make it easier to edit a table, we will use a different way to describe table.\n *\n * 1. For a m * n table (m rows, n columns), we always create a m * n array for the cells.\n * 2. For a regular table cell, it is mapped to one item of this array\n * 3. For a merged/splitted table cell, it will has colSpan/rowSpan value. We also created TableCell model for those spanned\n * cells, and use \"spanLeft\" and \"spanAbove\" to mark its state\n * 4. When edit table, we always edit on this mapped m * n array because it always has an item for each cell\n * 5. When write back to DOM, we create TD/TH elements for those non-spanned cells, and mark its colSpan/rowSpan value according\n * its neighbour cell's spanLeft/spanAbove attribute\n * @param group The parent block group\n * @param parent Parent DOM node to process\n * @param context DOM to Content Model context\n */\nexport const tableProcessor: ElementProcessor<HTMLTableElement> = (\n group,\n tableElement,\n context\n) => {\n stackFormat(\n context,\n { segment: 'shallowCloneForBlock', paragraph: 'shallowCloneForGroup' },\n () => {\n parseFormat(tableElement, context.formatParsers.block, context.blockFormat, context);\n\n const table = createTable(tableElement.rows.length, context.blockFormat);\n const tableSelection = context.selection?.type == 'table' ? context.selection : null;\n const selectedTable = tableSelection?.table;\n const hasTableSelection = selectedTable == tableElement;\n\n if (context.allowCacheElement) {\n table.cachedElement = tableElement;\n }\n\n context.domIndexer?.onTable(tableElement, table);\n\n parseFormat(tableElement, context.formatParsers.table, table.format, context);\n parseFormat(tableElement, context.formatParsers.tableBorder, table.format, context);\n parseFormat(\n tableElement,\n context.formatParsers.segmentOnBlock,\n context.segmentFormat,\n context\n );\n parseFormat(tableElement, context.formatParsers.dataset, table.dataset, context);\n addBlock(group, table);\n\n const columnPositions: (number | undefined)[] = [0];\n const hasColGroup = processColGroup(tableElement, context, columnPositions);\n const rowPositions: number[] = [0];\n const zoomScale = context.zoomScale || 1;\n\n for (let row = 0; row < tableElement.rows.length; row++) {\n const tr = tableElement.rows[row];\n const tableRow = table.rows[row];\n\n const tbody = tr.parentNode;\n\n if (\n isNodeOfType(tbody, 'ELEMENT_NODE') &&\n (isElementOfType(tbody, 'tbody') ||\n isElementOfType(tbody, 'thead') ||\n isElementOfType(tbody, 'tfoot'))\n ) {\n parseFormat(tbody, context.formatParsers.tableRow, tableRow.format, context);\n } else if (context.allowCacheElement) {\n tableRow.cachedElement = tr;\n }\n\n parseFormat(tr, context.formatParsers.tableRow, tableRow.format, context);\n\n stackFormat(context, { paragraph: 'shallowClone', segment: 'shallowClone' }, () => {\n const parent = tr.parentElement;\n const parentTag = parent?.tagName;\n\n if (\n parent &&\n (parentTag == 'TBODY' || parentTag == 'THEAD' || parentTag == 'TFOOT')\n ) {\n // If there is TBODY around TR, retrieve format from TBODY first, in case some format are declared there\n parseFormat(\n parent,\n context.formatParsers.block,\n context.blockFormat,\n context\n );\n parseFormat(\n parent,\n context.formatParsers.segmentOnBlock,\n context.segmentFormat,\n context\n );\n }\n\n parseFormat(tr, context.formatParsers.block, context.blockFormat, context);\n parseFormat(\n tr,\n context.formatParsers.segmentOnBlock,\n context.segmentFormat,\n context\n );\n\n for (\n let sourceCol = 0, targetCol = 0;\n sourceCol < tr.cells.length;\n sourceCol++\n ) {\n for (; tableRow.cells[targetCol]; targetCol++) {}\n\n const td = tr.cells[sourceCol];\n const hasSelectionBeforeCell = context.isInSelection;\n\n if (context.recalculateTableSize) {\n const colEnd = targetCol + td.colSpan;\n const rowEnd = row + td.rowSpan;\n const needCalcWidth = columnPositions[colEnd] === undefined;\n const needCalcHeight = rowPositions[rowEnd] === undefined;\n\n if (needCalcWidth || needCalcHeight) {\n const rect = getBoundingClientRect(td);\n\n if (rect.width > 0 || rect.height > 0) {\n if (needCalcWidth) {\n const pos = columnPositions[targetCol];\n\n columnPositions[colEnd] =\n (typeof pos == 'number' ? pos : 0) +\n rect.width / zoomScale;\n }\n\n if (needCalcHeight) {\n rowPositions[rowEnd] =\n rowPositions[row] + rect.height / zoomScale;\n }\n }\n }\n }\n\n stackFormat(\n context,\n { paragraph: 'shallowClone', segment: 'shallowClone' },\n () => {\n parseFormat(\n td,\n context.formatParsers.block,\n context.blockFormat,\n context\n );\n parseFormat(\n td,\n context.formatParsers.segmentOnTableCell,\n context.segmentFormat,\n context\n );\n\n const cellFormat: ContentModelTableCellFormat = {\n ...context.blockFormat,\n };\n const dataset: DatasetFormat = {};\n\n parseFormat(\n td,\n context.formatParsers.tableCell,\n cellFormat,\n context\n );\n parseFormat(\n td,\n context.formatParsers.tableBorder,\n cellFormat,\n context\n );\n parseFormat(td, context.formatParsers.dataset, dataset, context);\n\n for (\n let colSpan = 1;\n colSpan <= td.colSpan;\n colSpan++, targetCol++\n ) {\n for (let rowSpan = 1; rowSpan <= td.rowSpan; rowSpan++) {\n const hasTd = colSpan == 1 && rowSpan == 1;\n const cell = createTableCell(\n colSpan > 1,\n rowSpan > 1,\n td.tagName == 'TH',\n cellFormat\n );\n\n cell.dataset = { ...dataset };\n\n const spannedRow = table.rows[row + rowSpan - 1];\n\n if (spannedRow) {\n spannedRow.cells[targetCol] = cell;\n }\n\n if (hasTd) {\n // When there is COLGROUP, width on table cell should be ignored, so we should not cache the table cell,\n // and always recreate it when write back using the table formats\n if (context.allowCacheElement && !hasColGroup) {\n cell.cachedElement = td;\n }\n\n const { listParent, levels } = context.listFormat;\n\n context.listFormat.listParent = undefined;\n context.listFormat.levels = [];\n\n try {\n context.elementProcessors.child(cell, td, context);\n } finally {\n context.listFormat.listParent = listParent;\n context.listFormat.levels = levels;\n }\n }\n\n const hasSelectionAfterCell = context.isInSelection;\n\n if (\n (hasSelectionBeforeCell && hasSelectionAfterCell) ||\n (hasTableSelection &&\n tableSelection &&\n row >= tableSelection.firstRow &&\n row <= tableSelection.lastRow &&\n targetCol >= tableSelection.firstColumn &&\n targetCol <= tableSelection.lastColumn)\n ) {\n cell.isSelected = true;\n }\n }\n }\n }\n );\n }\n });\n\n for (let col = 0; col < tableRow.cells.length; col++) {\n if (!tableRow.cells[col]) {\n tableRow.cells[col] = createTableCell(\n false,\n false,\n false,\n context.blockFormat\n );\n }\n }\n }\n\n table.widths = calcSizes(columnPositions);\n\n const heights = calcSizes(rowPositions);\n\n table.rows.forEach((row, i) => {\n if (heights[i] > 0) {\n row.height = heights[i];\n }\n });\n }\n );\n};\n\nfunction calcSizes(positions: (number | undefined)[]): number[] {\n const result: number[] = [];\n let lastPos = 0;\n\n for (let i = positions.length - 1; i >= 0; i--) {\n const pos = positions[i];\n\n if (typeof pos == 'number') {\n lastPos = pos;\n break;\n }\n }\n\n for (let i = positions.length - 2; i >= 0; i--) {\n const pos = positions[i];\n if (pos === undefined) {\n result[i] = 0;\n } else {\n result[i] = lastPos - pos;\n lastPos = pos;\n }\n }\n\n return result;\n}\n\nfunction processColGroup(\n table: HTMLElement,\n context: DomToModelContext,\n result: (number | undefined)[]\n): boolean {\n let lastPos = 0;\n let hasColGroup = false;\n\n for (let child = table.firstChild; child; child = child.nextSibling) {\n if (isNodeOfType(child, 'ELEMENT_NODE') && child.tagName == 'COLGROUP') {\n hasColGroup = true;\n\n for (let col = child.firstChild; col; col = col.nextSibling) {\n if (isNodeOfType(col, 'ELEMENT_NODE') && col.tagName == 'COL') {\n const colFormat: SizeFormat = {};\n\n parseFormat(col, context.formatParsers.tableColumn, colFormat, context);\n\n for (let i = 0; i < parseInt(col.getAttribute('span') ?? '1'); i++) {\n if (colFormat.width === undefined) {\n result.push(undefined);\n } else {\n const width = parseValueWithUnit(\n colFormat.width ?? '',\n undefined /*element*/,\n 'px'\n );\n\n result.push(width + lastPos);\n lastPos += width;\n }\n }\n }\n }\n }\n }\n\n return hasColGroup;\n}\n"]}
|
package/lib/domUtils/readFile.js
CHANGED
|
@@ -8,15 +8,20 @@ exports.readFile = void 0;
|
|
|
8
8
|
* If fail to read, dataUrl will be null
|
|
9
9
|
*/
|
|
10
10
|
function readFile(file, callback) {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
11
|
+
try {
|
|
12
|
+
if (file) {
|
|
13
|
+
var reader_1 = new FileReader();
|
|
14
|
+
reader_1.onload = function () {
|
|
15
|
+
callback(reader_1.result);
|
|
16
|
+
};
|
|
17
|
+
reader_1.onerror = function () {
|
|
18
|
+
callback(null);
|
|
19
|
+
};
|
|
20
|
+
reader_1.readAsDataURL(file);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
catch (_a) {
|
|
24
|
+
callback(null);
|
|
20
25
|
}
|
|
21
26
|
}
|
|
22
27
|
exports.readFile = readFile;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"readFile.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-dom/lib/domUtils/readFile.ts"],"names":[],"mappings":";;;AAAA;;;;;GAKG;AACH,SAAgB,QAAQ,CAAC,IAAU,EAAE,QAA0C;IAC3E,IAAI,IAAI,EAAE;
|
|
1
|
+
{"version":3,"file":"readFile.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-dom/lib/domUtils/readFile.ts"],"names":[],"mappings":";;;AAAA;;;;;GAKG;AACH,SAAgB,QAAQ,CAAC,IAAU,EAAE,QAA0C;IAC3E,IAAI;QACA,IAAI,IAAI,EAAE;YACN,IAAM,QAAM,GAAG,IAAI,UAAU,EAAE,CAAC;YAChC,QAAM,CAAC,MAAM,GAAG;gBACZ,QAAQ,CAAC,QAAM,CAAC,MAAgB,CAAC,CAAC;YACtC,CAAC,CAAC;YACF,QAAM,CAAC,OAAO,GAAG;gBACb,QAAQ,CAAC,IAAI,CAAC,CAAC;YACnB,CAAC,CAAC;YACF,QAAM,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;SAC9B;KACJ;IAAC,WAAM;QACJ,QAAQ,CAAC,IAAI,CAAC,CAAC;KAClB;AACL,CAAC;AAfD,4BAeC","sourcesContent":["/**\n * Read a file object and invoke a callback function with the data url of this file\n * @param file The file to read\n * @param callback the callback to invoke with data url of the file.\n * If fail to read, dataUrl will be null\n */\nexport function readFile(file: File, callback: (dataUrl: string | null) => void) {\n try {\n if (file) {\n const reader = new FileReader();\n reader.onload = () => {\n callback(reader.result as string);\n };\n reader.onerror = () => {\n callback(null);\n };\n reader.readAsDataURL(file);\n }\n } catch {\n callback(null);\n }\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ConflictFormatSolution, ContentModelFormatState, ContentModelSegmentFormat, ReadonlyContentModelDocument } from 'roosterjs-content-model-types';
|
|
1
|
+
import type { ConflictFormatSolution, ContentModelFormatState, ContentModelSegmentFormat, ReadonlyContentModelDocument, DOMHelper } from 'roosterjs-content-model-types';
|
|
2
2
|
/**
|
|
3
3
|
* Retrieve format state from the given Content Model
|
|
4
4
|
* @param model The Content Model to retrieve format state from
|
|
@@ -6,4 +6,4 @@ import type { ConflictFormatSolution, ContentModelFormatState, ContentModelSegme
|
|
|
6
6
|
* @param formatState Existing format state object, used for receiving the result
|
|
7
7
|
* @param conflictSolution The strategy for handling format conflicts
|
|
8
8
|
*/
|
|
9
|
-
export declare function retrieveModelFormatState(model: ReadonlyContentModelDocument, pendingFormat: ContentModelSegmentFormat | null, formatState: ContentModelFormatState, conflictSolution?: ConflictFormatSolution): void;
|
|
9
|
+
export declare function retrieveModelFormatState(model: ReadonlyContentModelDocument, pendingFormat: ContentModelSegmentFormat | null, formatState: ContentModelFormatState, conflictSolution?: ConflictFormatSolution, domHelper?: DOMHelper): void;
|
|
@@ -15,13 +15,18 @@ var parseValueWithUnit_1 = require("../../formatHandlers/utils/parseValueWithUni
|
|
|
15
15
|
* @param formatState Existing format state object, used for receiving the result
|
|
16
16
|
* @param conflictSolution The strategy for handling format conflicts
|
|
17
17
|
*/
|
|
18
|
-
function retrieveModelFormatState(model, pendingFormat, formatState, conflictSolution) {
|
|
18
|
+
function retrieveModelFormatState(model, pendingFormat, formatState, conflictSolution, domHelper) {
|
|
19
19
|
if (conflictSolution === void 0) { conflictSolution = 'remove'; }
|
|
20
20
|
var firstTableContext;
|
|
21
21
|
var firstBlock;
|
|
22
22
|
var isFirst = true;
|
|
23
23
|
var isFirstImage = true;
|
|
24
24
|
var isFirstSegment = true;
|
|
25
|
+
var containerFormat = undefined;
|
|
26
|
+
var modelFormat = (0, tslib_1.__assign)({}, model.format);
|
|
27
|
+
delete modelFormat.italic;
|
|
28
|
+
delete modelFormat.underline;
|
|
29
|
+
delete modelFormat.fontWeight;
|
|
25
30
|
(0, iterateSelections_1.iterateSelections)(model, function (path, tableContext, block, segments) {
|
|
26
31
|
// Structure formats
|
|
27
32
|
retrieveStructureFormat(formatState, path, isFirst, conflictSolution);
|
|
@@ -39,13 +44,19 @@ function retrieveModelFormatState(model, pendingFormat, formatState, conflictSol
|
|
|
39
44
|
retrieveParagraphFormat(formatState, block, isFirst, conflictSolution);
|
|
40
45
|
// Segment formats
|
|
41
46
|
segments === null || segments === void 0 ? void 0 : segments.forEach(function (segment) {
|
|
42
|
-
var _a, _b, _c;
|
|
47
|
+
var _a, _b, _c, _d;
|
|
43
48
|
if (isFirstSegment || segment.segmentType != 'SelectionMarker') {
|
|
44
|
-
var
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
+
var currentFormat = Object.assign({}, block.format, (_a = block.decorator) === null || _a === void 0 ? void 0 : _a.format, segment.format, (_b = segment.code) === null || _b === void 0 ? void 0 : _b.format, (_c = segment.link) === null || _c === void 0 ? void 0 : _c.format, pendingFormat);
|
|
50
|
+
// Sometimes the content may not specify all required format but just leverage the container format to do so.
|
|
51
|
+
// In this case, we need to merge the container format into the current format
|
|
52
|
+
// to make sure the current format contains all required format.
|
|
53
|
+
if (!hasAllRequiredFormat(currentFormat)) {
|
|
54
|
+
if (!containerFormat) {
|
|
55
|
+
containerFormat = (_d = domHelper === null || domHelper === void 0 ? void 0 : domHelper.getContainerFormat()) !== null && _d !== void 0 ? _d : modelFormat;
|
|
56
|
+
}
|
|
57
|
+
currentFormat = Object.assign({}, containerFormat, currentFormat);
|
|
58
|
+
}
|
|
59
|
+
retrieveSegmentFormat(formatState, isFirst, currentFormat, conflictSolution);
|
|
49
60
|
mergeValue(formatState, 'isCodeInline', !!(segment === null || segment === void 0 ? void 0 : segment.code), isFirst, conflictSolution);
|
|
50
61
|
}
|
|
51
62
|
// We only care the format of selection marker when it is the first selected segment. This is because when selection marker
|
|
@@ -189,11 +200,17 @@ function mergeValue(format, key, newValue, isFirst, conflictSolution, parseFn) {
|
|
|
189
200
|
}
|
|
190
201
|
}
|
|
191
202
|
function px2Pt(px) {
|
|
192
|
-
if (px
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
203
|
+
if (px) {
|
|
204
|
+
var index = px.indexOf('px');
|
|
205
|
+
if (index !== -1 && index === px.length - 2) {
|
|
206
|
+
// Edge may not handle the floating computing well which causes the calculated value to be a little less than the actual value
|
|
207
|
+
// So add 0.05 to fix it
|
|
208
|
+
return Math.round(parseFloat(px) * 75 + 0.05) / 100 + 'pt';
|
|
209
|
+
}
|
|
196
210
|
}
|
|
197
211
|
return px;
|
|
198
212
|
}
|
|
213
|
+
function hasAllRequiredFormat(format) {
|
|
214
|
+
return !!format.fontFamily && !!format.fontSize && !!format.textColor;
|
|
215
|
+
}
|
|
199
216
|
//# sourceMappingURL=retrieveModelFormatState.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"retrieveModelFormatState.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/modelApi/editing/retrieveModelFormatState.ts"],"names":[],"mappings":";;;;AAAA,kEAAwE;AACxE,yFAAwF;AACxF,uEAAmE;AACnE,sDAAqD;AACrD,oEAAmE;AACnE,oFAAmF;AAenF;;;;;;GAMG;AACH,SAAgB,wBAAwB,CACpC,KAAmC,EACnC,aAA+C,EAC/C,WAAoC,EACpC,gBAAmD;IAAnD,iCAAA,EAAA,2BAAmD;IAEnD,IAAI,iBAA4D,CAAC;IACjE,IAAI,UAAiD,CAAC;IACtD,IAAI,OAAO,GAAG,IAAI,CAAC;IACnB,IAAI,YAAY,GAAG,IAAI,CAAC;IACxB,IAAI,cAAc,GAAG,IAAI,CAAC;IAE1B,IAAA,qCAAiB,EACb,KAAK,EACL,UAAC,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,QAAQ;QAChC,oBAAoB;QACpB,uBAAuB,CAAC,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;QAEtE,uBAAuB;QACvB,IAAI,KAAK,EAAE;YACP,IAAI,UAAU,EAAE;gBACZ,WAAW,CAAC,oBAAoB,GAAG,IAAI,CAAC;aAC3C;iBAAM;gBACH,UAAU,GAAG,KAAK,CAAC;aACtB;SACJ;QAED,IAAI,CAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,SAAS,KAAI,WAAW,EAAE;YACjC,oBAAoB;YACpB,uBAAuB,CAAC,WAAW,EAAE,KAAK,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;YAEvE,kBAAkB;YAClB,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,OAAO,CAAC,UAAA,OAAO;;gBACrB,IAAI,cAAc,IAAI,OAAO,CAAC,WAAW,IAAI,iBAAiB,EAAE;oBAC5D,IAAM,WAAW,6BAAQ,KAAK,CAAC,MAAM,CAAE,CAAC;oBAExC,OAAO,WAAW,CAAC,MAAM,CAAC;oBAC1B,OAAO,WAAW,CAAC,SAAS,CAAC;oBAC7B,OAAO,WAAW,CAAC,UAAU,CAAC;oBAE9B,qBAAqB,CACjB,WAAW,EACX,OAAO,EACP,MAAM,CAAC,MAAM,CACT,EAAE,EACF,WAAW,EACX,KAAK,CAAC,MAAM,EACZ,MAAA,KAAK,CAAC,SAAS,0CAAE,MAAM,EACvB,OAAO,CAAC,MAAM,EACd,MAAA,OAAO,CAAC,IAAI,0CAAE,MAAM,EACpB,MAAA,OAAO,CAAC,IAAI,0CAAE,MAAM,EACpB,aAAa,CAChB,EACD,gBAAgB,CACnB,CAAC;oBAEF,UAAU,CAAC,WAAW,EAAE,cAAc,EAAE,CAAC,CAAC,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,IAAI,CAAA,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;iBACvF;gBAED,2HAA2H;gBAC3H,6HAA6H;gBAC7H,6HAA6H;gBAC7H,YAAY;gBACZ,cAAc,GAAG,KAAK,CAAC;gBAEvB,WAAW,CAAC,SAAS,GAAG,WAAW,CAAC,SAAS,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC;gBAChE,WAAW,CAAC,kBAAkB;oBAC1B,WAAW,CAAC,kBAAkB;wBAC9B,QAAQ,CAAC,IAAI,CAAC,UAAA,OAAO,IAAI,OAAA,OAAO,CAAC,WAAW,IAAI,OAAO,EAA9B,CAA8B,CAAC,CAAC;gBAE7D,OAAO,GAAG,KAAK,CAAC;gBAEhB,IAAI,OAAO,CAAC,WAAW,KAAK,OAAO,EAAE;oBACjC,IAAI,YAAY,EAAE;wBACd,mBAAmB,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;wBAC1C,YAAY,GAAG,KAAK,CAAC;qBACxB;yBAAM;wBACH,WAAW,CAAC,WAAW,GAAG,SAAS,CAAC;qBACvC;iBACJ;YACL,CAAC,CAAC,CAAC;YAEH,OAAO,GAAG,KAAK,CAAC;SACnB;QAED,IAAI,YAAY,EAAE;YACd,IAAI,iBAAiB,EAAE;gBACX,IAAA,KAAK,GAAyB,iBAAiB,MAA1C,EAAE,QAAQ,GAAe,iBAAiB,SAAhC,EAAE,QAAQ,GAAK,iBAAiB,SAAtB,CAAuB;gBAExD,qBAAqB;gBACrB,IACI,YAAY,CAAC,KAAK,IAAI,KAAK;oBAC3B,CAAC,YAAY,CAAC,QAAQ,IAAI,QAAQ,IAAI,YAAY,CAAC,QAAQ,IAAI,QAAQ,CAAC,EAC1E;oBACE,WAAW,CAAC,iBAAiB,GAAG,IAAI,CAAC;oBACrC,WAAW,CAAC,oBAAoB,GAAG,IAAI,CAAC;iBAC3C;aACJ;iBAAM;gBACH,gBAAgB;gBAChB,mBAAmB,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;gBAC/C,iBAAiB,GAAG,YAAY,CAAC;aACpC;SACJ;IACL,CAAC,EACD;QACI,uBAAuB,EAAE,OAAO;KACnC,CACJ,CAAC;IAEF,IAAI,WAAW,CAAC,QAAQ,EAAE;QACtB,WAAW,CAAC,QAAQ,GAAG,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;KACtD;AACL,CAAC;AAhHD,4DAgHC;AAED,SAAS,qBAAqB,CAC1B,MAA+B,EAC/B,OAAgB,EAChB,YAAuC,EACvC,gBAAmD;;IAAnD,iCAAA,EAAA,2BAAmD;IAEnD,IAAM,gBAAgB,GAAG,MAAA,MAAA,YAAY,CAAC,wBAAwB,0CAAE,KAAK,CAAC,GAAG,CAAC,0CAAE,GAAG,EAAE,CAAC;IAElF,UAAU,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAA,eAAM,EAAC,YAAY,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;IACzF,UAAU,CAAC,MAAM,EAAE,UAAU,EAAE,YAAY,CAAC,MAAM,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;IAC/E,UAAU,CAAC,MAAM,EAAE,aAAa,EAAE,YAAY,CAAC,SAAS,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;IACrF,UAAU,CAAC,MAAM,EAAE,iBAAiB,EAAE,YAAY,CAAC,aAAa,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;IAC7F,UAAU,CAAC,MAAM,EAAE,eAAe,EAAE,gBAAgB,IAAI,OAAO,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;IAC5F,UAAU,CAAC,MAAM,EAAE,aAAa,EAAE,gBAAgB,IAAI,KAAK,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;IACxF,UAAU,CAAC,MAAM,EAAE,eAAe,EAAE,YAAY,CAAC,aAAa,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;IAE3F,UAAU,CAAC,MAAM,EAAE,UAAU,EAAE,YAAY,CAAC,UAAU,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;IACnF,UAAU,CACN,MAAM,EACN,UAAU,EACV,YAAY,CAAC,QAAQ,EACrB,OAAO,EACP,gBAAgB,EAChB,UAAA,GAAG,IAAI,OAAA,IAAA,uCAAkB,EAAC,GAAG,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,IAAI,EAA/C,CAA+C,CACzD,CAAC;IACF,UAAU,CAAC,MAAM,EAAE,iBAAiB,EAAE,YAAY,CAAC,eAAe,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;IAC/F,UAAU,CAAC,MAAM,EAAE,WAAW,EAAE,YAAY,CAAC,SAAS,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;IACnF,UAAU,CAAC,MAAM,EAAE,YAAY,EAAE,YAAY,CAAC,UAAU,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;IACrF,UAAU,CAAC,MAAM,EAAE,YAAY,EAAE,YAAY,CAAC,UAAU,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;AACzF,CAAC;AAED,SAAS,uBAAuB,CAC5B,MAA+B,EAC/B,SAAwC,EACxC,OAAgB,EAChB,gBAAmD;;IAAnD,iCAAA,EAAA,2BAAmD;IAEnD,IAAM,YAAY,GAAG,QAAQ,CAAC,CAAC,CAAA,MAAA,SAAS,CAAC,SAAS,0CAAE,OAAO,KAAI,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IACjF,IAAM,iBAAiB,GAAG,YAAY,IAAI,CAAC,IAAI,YAAY,IAAI,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC;IAE5F,UAAU,CAAC,MAAM,EAAE,cAAc,EAAE,SAAS,CAAC,MAAM,CAAC,YAAY,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;IAC7F,UAAU,CAAC,MAAM,EAAE,WAAW,EAAE,SAAS,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;IACvF,UAAU,CAAC,MAAM,EAAE,cAAc,EAAE,iBAAiB,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;IACjF,UAAU,CAAC,MAAM,EAAE,WAAW,EAAE,SAAS,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;IACvF,UAAU,CAAC,MAAM,EAAE,WAAW,EAAE,SAAS,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;AAC3F,CAAC;AAED,SAAS,uBAAuB,CAC5B,MAA+B,EAC/B,IAAsC,EACtC,OAAgB,EAChB,gBAAmD;;IAAnD,iCAAA,EAAA,2BAAmD;IAEnD,IAAM,aAAa,GAAG,IAAA,qEAAiC,EAAC,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC;IAChF,IAAM,cAAc,GAAG,IAAA,qEAAiC,EAAC,IAAI,EAAE,CAAC,iBAAiB,CAAC,EAAE,EAAE,CAAC,CAAC;IAExF,IAAI,aAAa,IAAI,CAAC,EAAE;QACpB,IAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAiC,CAAC;QACrE,IAAM,QAAQ,GAAG,MAAA,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,0CAAE,QAAQ,CAAC;QAExE,UAAU,CAAC,MAAM,EAAE,UAAU,EAAE,QAAQ,IAAI,IAAI,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;QAC5E,UAAU,CAAC,MAAM,EAAE,aAAa,EAAE,QAAQ,IAAI,IAAI,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;KAClF;IAED,UAAU,CACN,MAAM,EACN,cAAc,EACd,cAAc,IAAI,CAAC;QACf,CAAA,MAAC,IAAI,CAAC,cAAc,CAAyC,0CAAE,OAAO,KAAI,YAAY,EAC1F,OAAO,EACP,gBAAgB,CACnB,CAAC;AACN,CAAC;AAED,SAAS,mBAAmB,CACxB,YAA2C,EAC3C,MAA+B;IAE/B,IAAM,WAAW,GAAG,IAAA,sCAAgB,EAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IAEzD,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC;IACxB,MAAM,CAAC,cAAc,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,UAAA,GAAG;QACpD,OAAA,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,UAAA,IAAI,IAAI,OAAA,IAAI,CAAC,QAAQ,EAAb,CAAa,CAAC;IAArC,CAAqC,CACxC,CAAC;IAEF,IAAI,WAAW,EAAE;QACb,MAAM,CAAC,WAAW,GAAG,WAAW,CAAC;KACpC;AACL,CAAC;AAED,SAAS,mBAAmB,CAAC,KAAgC,EAAE,MAA+B;IAClF,IAAA,MAAM,GAAK,KAAK,OAAV,CAAW;IACzB,IAAM,SAAS,GAAG,WAAW,CAAC;IAC9B,IAAM,eAAe,GAAG,IAAA,kCAAmB,EAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;IAC/D,IAAM,WAAW,GAAG,eAAe,CAAC,KAAK,CAAC;IAC1C,IAAM,WAAW,GAAG,eAAe,CAAC,KAAK,CAAC;IAC1C,IAAM,WAAW,GAAG,eAAe,CAAC,KAAK,CAAC;IAC1C,MAAM,CAAC,WAAW,GAAG;QACjB,WAAW,aAAA;QACX,WAAW,aAAA;QACX,WAAW,aAAA;QACX,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,YAAY,EAAE,MAAM,CAAC,YAAY;KACpC,CAAC;AACN,CAAC;AAED,SAAS,UAAU,CACf,MAA+B,EAC/B,GAAM,EACN,QAAgD,EAChD,OAAgB,EAChB,gBAAmD,EACnD,OAAqF;IADrF,iCAAA,EAAA,2BAAmD;IACnD,wBAAA,EAAA,oBAA2E,GAAG,IAAI,OAAA,GAAG,EAAH,CAAG;IAErF,IAAI,OAAO,EAAE;QACT,IAAI,QAAQ,KAAK,SAAS,EAAE;YACxB,MAAM,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC;SAC1B;KACJ;SAAM,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE;QACnD,QAAQ,gBAAgB,EAAE;YACtB,KAAK,QAAQ;gBACT,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;gBACnB,MAAM;YACV,KAAK,WAAW;gBACZ,MAAM;YACV,KAAK,gBAAgB;gBACjB,IAAI,OAAO,MAAM,CAAC,GAAG,CAAC,KAAK,QAAQ,EAAE;oBAChC,MAAM,CAAC,GAAG,CAAY,GAAG,UAAU,CAAC;iBACxC;qBAAM;oBACH,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;iBACtB;gBACD,MAAM;SACb;KACJ;AACL,CAAC;AAED,SAAS,KAAK,CAAC,EAAU;IACrB,IAAI,EAAE,IAAI,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE;QACzC,uHAAuH;QACvH,wBAAwB;QACxB,OAAO,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,IAAI,CAAC;KAC9D;IACD,OAAO,EAAE,CAAC;AACd,CAAC","sourcesContent":["import { extractBorderValues } from '../../domUtils/style/borderValues';\nimport { getClosestAncestorBlockGroupIndex } from './getClosestAncestorBlockGroupIndex';\nimport { getTableMetadata } from '../metadata/updateTableMetadata';\nimport { isBold } from '../../domUtils/style/isBold';\nimport { iterateSelections } from '../selection/iterateSelections';\nimport { parseValueWithUnit } from '../../formatHandlers/utils/parseValueWithUnit';\nimport type {\n ConflictFormatSolution,\n ContentModelFormatState,\n ContentModelSegmentFormat,\n ReadonlyContentModelBlockGroup,\n ReadonlyContentModelBlock,\n ReadonlyContentModelImage,\n ReadonlyTableSelectionContext,\n ReadonlyContentModelParagraph,\n ReadonlyContentModelFormatContainer,\n ReadonlyContentModelListItem,\n ReadonlyContentModelDocument,\n} from 'roosterjs-content-model-types';\n\n/**\n * Retrieve format state from the given Content Model\n * @param model The Content Model to retrieve format state from\n * @param pendingFormat Existing pending format, if any\n * @param formatState Existing format state object, used for receiving the result\n * @param conflictSolution The strategy for handling format conflicts\n */\nexport function retrieveModelFormatState(\n model: ReadonlyContentModelDocument,\n pendingFormat: ContentModelSegmentFormat | null,\n formatState: ContentModelFormatState,\n conflictSolution: ConflictFormatSolution = 'remove'\n) {\n let firstTableContext: ReadonlyTableSelectionContext | undefined;\n let firstBlock: ReadonlyContentModelBlock | undefined;\n let isFirst = true;\n let isFirstImage = true;\n let isFirstSegment = true;\n\n iterateSelections(\n model,\n (path, tableContext, block, segments) => {\n // Structure formats\n retrieveStructureFormat(formatState, path, isFirst, conflictSolution);\n\n // Multiple line format\n if (block) {\n if (firstBlock) {\n formatState.isMultilineSelection = true;\n } else {\n firstBlock = block;\n }\n }\n\n if (block?.blockType == 'Paragraph') {\n // Paragraph formats\n retrieveParagraphFormat(formatState, block, isFirst, conflictSolution);\n\n // Segment formats\n segments?.forEach(segment => {\n if (isFirstSegment || segment.segmentType != 'SelectionMarker') {\n const modelFormat = { ...model.format };\n\n delete modelFormat.italic;\n delete modelFormat.underline;\n delete modelFormat.fontWeight;\n\n retrieveSegmentFormat(\n formatState,\n isFirst,\n Object.assign(\n {},\n modelFormat,\n block.format,\n block.decorator?.format,\n segment.format,\n segment.code?.format,\n segment.link?.format,\n pendingFormat\n ),\n conflictSolution\n );\n\n mergeValue(formatState, 'isCodeInline', !!segment?.code, isFirst, conflictSolution);\n }\n\n // We only care the format of selection marker when it is the first selected segment. This is because when selection marker\n // is after some other selected segments, it mostly like appears at the beginning of a seconde line when the whole first line\n // is selected (e.g. triple-click on a line) then the second selection marker doesn't contain a correct format, so we need to\n // ignore it\n isFirstSegment = false;\n\n formatState.canUnlink = formatState.canUnlink || !!segment.link;\n formatState.canAddImageAltText =\n formatState.canAddImageAltText ||\n segments.some(segment => segment.segmentType == 'Image');\n\n isFirst = false;\n\n if (segment.segmentType === 'Image') {\n if (isFirstImage) {\n retrieveImageFormat(segment, formatState);\n isFirstImage = false;\n } else {\n formatState.imageFormat = undefined;\n }\n }\n });\n\n isFirst = false;\n }\n\n if (tableContext) {\n if (firstTableContext) {\n const { table, colIndex, rowIndex } = firstTableContext;\n\n // Merge table format\n if (\n tableContext.table == table &&\n (tableContext.colIndex != colIndex || tableContext.rowIndex != rowIndex)\n ) {\n formatState.canMergeTableCell = true;\n formatState.isMultilineSelection = true;\n }\n } else {\n // Table formats\n retrieveTableFormat(tableContext, formatState);\n firstTableContext = tableContext;\n }\n }\n },\n {\n includeListFormatHolder: 'never',\n }\n );\n\n if (formatState.fontSize) {\n formatState.fontSize = px2Pt(formatState.fontSize);\n }\n}\n\nfunction retrieveSegmentFormat(\n result: ContentModelFormatState,\n isFirst: boolean,\n mergedFormat: ContentModelSegmentFormat,\n conflictSolution: ConflictFormatSolution = 'remove'\n) {\n const superOrSubscript = mergedFormat.superOrSubScriptSequence?.split(' ')?.pop();\n\n mergeValue(result, 'isBold', isBold(mergedFormat.fontWeight), isFirst, conflictSolution);\n mergeValue(result, 'isItalic', mergedFormat.italic, isFirst, conflictSolution);\n mergeValue(result, 'isUnderline', mergedFormat.underline, isFirst, conflictSolution);\n mergeValue(result, 'isStrikeThrough', mergedFormat.strikethrough, isFirst, conflictSolution);\n mergeValue(result, 'isSuperscript', superOrSubscript == 'super', isFirst, conflictSolution);\n mergeValue(result, 'isSubscript', superOrSubscript == 'sub', isFirst, conflictSolution);\n mergeValue(result, 'letterSpacing', mergedFormat.letterSpacing, isFirst, conflictSolution);\n\n mergeValue(result, 'fontName', mergedFormat.fontFamily, isFirst, conflictSolution);\n mergeValue(\n result,\n 'fontSize',\n mergedFormat.fontSize,\n isFirst,\n conflictSolution,\n val => parseValueWithUnit(val, undefined, 'pt') + 'pt'\n );\n mergeValue(result, 'backgroundColor', mergedFormat.backgroundColor, isFirst, conflictSolution);\n mergeValue(result, 'textColor', mergedFormat.textColor, isFirst, conflictSolution);\n mergeValue(result, 'fontWeight', mergedFormat.fontWeight, isFirst, conflictSolution);\n mergeValue(result, 'lineHeight', mergedFormat.lineHeight, isFirst, conflictSolution);\n}\n\nfunction retrieveParagraphFormat(\n result: ContentModelFormatState,\n paragraph: ReadonlyContentModelParagraph,\n isFirst: boolean,\n conflictSolution: ConflictFormatSolution = 'remove'\n) {\n const headingLevel = parseInt((paragraph.decorator?.tagName || '').substring(1));\n const validHeadingLevel = headingLevel >= 1 && headingLevel <= 6 ? headingLevel : undefined;\n\n mergeValue(result, 'marginBottom', paragraph.format.marginBottom, isFirst, conflictSolution);\n mergeValue(result, 'marginTop', paragraph.format.marginTop, isFirst, conflictSolution);\n mergeValue(result, 'headingLevel', validHeadingLevel, isFirst, conflictSolution);\n mergeValue(result, 'textAlign', paragraph.format.textAlign, isFirst, conflictSolution);\n mergeValue(result, 'direction', paragraph.format.direction, isFirst, conflictSolution);\n}\n\nfunction retrieveStructureFormat(\n result: ContentModelFormatState,\n path: ReadonlyContentModelBlockGroup[],\n isFirst: boolean,\n conflictSolution: ConflictFormatSolution = 'remove'\n) {\n const listItemIndex = getClosestAncestorBlockGroupIndex(path, ['ListItem'], []);\n const containerIndex = getClosestAncestorBlockGroupIndex(path, ['FormatContainer'], []);\n\n if (listItemIndex >= 0) {\n const listItem = path[listItemIndex] as ReadonlyContentModelListItem;\n const listType = listItem?.levels[listItem.levels.length - 1]?.listType;\n\n mergeValue(result, 'isBullet', listType == 'UL', isFirst, conflictSolution);\n mergeValue(result, 'isNumbering', listType == 'OL', isFirst, conflictSolution);\n }\n\n mergeValue(\n result,\n 'isBlockQuote',\n containerIndex >= 0 &&\n (path[containerIndex] as ReadonlyContentModelFormatContainer)?.tagName == 'blockquote',\n isFirst,\n conflictSolution\n );\n}\n\nfunction retrieveTableFormat(\n tableContext: ReadonlyTableSelectionContext,\n result: ContentModelFormatState\n) {\n const tableFormat = getTableMetadata(tableContext.table);\n\n result.isInTable = true;\n result.tableHasHeader = tableContext.table.rows.some(row =>\n row.cells.some(cell => cell.isHeader)\n );\n\n if (tableFormat) {\n result.tableFormat = tableFormat;\n }\n}\n\nfunction retrieveImageFormat(image: ReadonlyContentModelImage, result: ContentModelFormatState) {\n const { format } = image;\n const borderKey = 'borderTop';\n const extractedBorder = extractBorderValues(format[borderKey]);\n const borderColor = extractedBorder.color;\n const borderWidth = extractedBorder.width;\n const borderStyle = extractedBorder.style;\n result.imageFormat = {\n borderColor,\n borderWidth,\n borderStyle,\n boxShadow: format.boxShadow,\n borderRadius: format.borderRadius,\n };\n}\n\nfunction mergeValue<K extends keyof ContentModelFormatState>(\n format: ContentModelFormatState,\n key: K,\n newValue: ContentModelFormatState[K] | undefined,\n isFirst: boolean,\n conflictSolution: ConflictFormatSolution = 'remove',\n parseFn: (val: ContentModelFormatState[K]) => ContentModelFormatState[K] = val => val,\n) {\n if (isFirst) {\n if (newValue !== undefined) {\n format[key] = newValue;\n }\n } else if (parseFn(newValue) !== parseFn(format[key])) {\n switch (conflictSolution) {\n case 'remove':\n delete format[key];\n break;\n case 'keepFirst':\n break;\n case 'returnMultiple':\n if (typeof format[key] === 'string') {\n (format[key] as string) = 'Multiple';\n } else {\n delete format[key];\n }\n break;\n }\n }\n}\n\nfunction px2Pt(px: string) {\n if (px && px.indexOf('px') == px.length - 2) {\n // Edge may not handle the floating computing well which causes the calculated value is a little less than actual value\n // So add 0.05 to fix it\n return Math.round(parseFloat(px) * 75 + 0.05) / 100 + 'pt';\n }\n return px;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"retrieveModelFormatState.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/modelApi/editing/retrieveModelFormatState.ts"],"names":[],"mappings":"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","sourcesContent":["import { extractBorderValues } from '../../domUtils/style/borderValues';\nimport { getClosestAncestorBlockGroupIndex } from './getClosestAncestorBlockGroupIndex';\nimport { getTableMetadata } from '../metadata/updateTableMetadata';\nimport { isBold } from '../../domUtils/style/isBold';\nimport { iterateSelections } from '../selection/iterateSelections';\nimport { parseValueWithUnit } from '../../formatHandlers/utils/parseValueWithUnit';\nimport type {\n ConflictFormatSolution,\n ContentModelFormatState,\n ContentModelSegmentFormat,\n ReadonlyContentModelBlockGroup,\n ReadonlyContentModelBlock,\n ReadonlyContentModelImage,\n ReadonlyTableSelectionContext,\n ReadonlyContentModelParagraph,\n ReadonlyContentModelFormatContainer,\n ReadonlyContentModelListItem,\n ReadonlyContentModelDocument,\n DOMHelper,\n} from 'roosterjs-content-model-types';\n\n/**\n * Retrieve format state from the given Content Model\n * @param model The Content Model to retrieve format state from\n * @param pendingFormat Existing pending format, if any\n * @param formatState Existing format state object, used for receiving the result\n * @param conflictSolution The strategy for handling format conflicts\n */\nexport function retrieveModelFormatState(\n model: ReadonlyContentModelDocument,\n pendingFormat: ContentModelSegmentFormat | null,\n formatState: ContentModelFormatState,\n conflictSolution: ConflictFormatSolution = 'remove',\n domHelper?: DOMHelper\n) {\n let firstTableContext: ReadonlyTableSelectionContext | undefined;\n let firstBlock: ReadonlyContentModelBlock | undefined;\n let isFirst = true;\n let isFirstImage = true;\n let isFirstSegment = true;\n let containerFormat: ContentModelSegmentFormat | undefined = undefined;\n\n const modelFormat = { ...model.format };\n\n delete modelFormat.italic;\n delete modelFormat.underline;\n delete modelFormat.fontWeight;\n\n iterateSelections(\n model,\n (path, tableContext, block, segments) => {\n // Structure formats\n retrieveStructureFormat(formatState, path, isFirst, conflictSolution);\n\n // Multiple line format\n if (block) {\n if (firstBlock) {\n formatState.isMultilineSelection = true;\n } else {\n firstBlock = block;\n }\n }\n\n if (block?.blockType == 'Paragraph') {\n // Paragraph formats\n retrieveParagraphFormat(formatState, block, isFirst, conflictSolution);\n\n // Segment formats\n segments?.forEach(segment => {\n if (isFirstSegment || segment.segmentType != 'SelectionMarker') {\n let currentFormat = Object.assign(\n {},\n block.format,\n block.decorator?.format,\n segment.format,\n segment.code?.format,\n segment.link?.format,\n pendingFormat\n );\n\n // Sometimes the content may not specify all required format but just leverage the container format to do so.\n // In this case, we need to merge the container format into the current format\n // to make sure the current format contains all required format.\n if (!hasAllRequiredFormat(currentFormat)) {\n if (!containerFormat) {\n containerFormat = domHelper?.getContainerFormat() ?? modelFormat;\n }\n\n currentFormat = Object.assign({}, containerFormat, currentFormat);\n }\n\n retrieveSegmentFormat(\n formatState,\n isFirst,\n currentFormat,\n conflictSolution\n );\n\n mergeValue(\n formatState,\n 'isCodeInline',\n !!segment?.code,\n isFirst,\n conflictSolution\n );\n }\n\n // We only care the format of selection marker when it is the first selected segment. This is because when selection marker\n // is after some other selected segments, it mostly like appears at the beginning of a seconde line when the whole first line\n // is selected (e.g. triple-click on a line) then the second selection marker doesn't contain a correct format, so we need to\n // ignore it\n isFirstSegment = false;\n\n formatState.canUnlink = formatState.canUnlink || !!segment.link;\n formatState.canAddImageAltText =\n formatState.canAddImageAltText ||\n segments.some(segment => segment.segmentType == 'Image');\n\n isFirst = false;\n\n if (segment.segmentType === 'Image') {\n if (isFirstImage) {\n retrieveImageFormat(segment, formatState);\n isFirstImage = false;\n } else {\n formatState.imageFormat = undefined;\n }\n }\n });\n\n isFirst = false;\n }\n\n if (tableContext) {\n if (firstTableContext) {\n const { table, colIndex, rowIndex } = firstTableContext;\n\n // Merge table format\n if (\n tableContext.table == table &&\n (tableContext.colIndex != colIndex || tableContext.rowIndex != rowIndex)\n ) {\n formatState.canMergeTableCell = true;\n formatState.isMultilineSelection = true;\n }\n } else {\n // Table formats\n retrieveTableFormat(tableContext, formatState);\n firstTableContext = tableContext;\n }\n }\n },\n {\n includeListFormatHolder: 'never',\n }\n );\n\n if (formatState.fontSize) {\n formatState.fontSize = px2Pt(formatState.fontSize);\n }\n}\n\nfunction retrieveSegmentFormat(\n result: ContentModelFormatState,\n isFirst: boolean,\n mergedFormat: ContentModelSegmentFormat,\n conflictSolution: ConflictFormatSolution = 'remove'\n) {\n const superOrSubscript = mergedFormat.superOrSubScriptSequence?.split(' ')?.pop();\n\n mergeValue(result, 'isBold', isBold(mergedFormat.fontWeight), isFirst, conflictSolution);\n mergeValue(result, 'isItalic', mergedFormat.italic, isFirst, conflictSolution);\n mergeValue(result, 'isUnderline', mergedFormat.underline, isFirst, conflictSolution);\n mergeValue(result, 'isStrikeThrough', mergedFormat.strikethrough, isFirst, conflictSolution);\n mergeValue(result, 'isSuperscript', superOrSubscript == 'super', isFirst, conflictSolution);\n mergeValue(result, 'isSubscript', superOrSubscript == 'sub', isFirst, conflictSolution);\n mergeValue(result, 'letterSpacing', mergedFormat.letterSpacing, isFirst, conflictSolution);\n\n mergeValue(result, 'fontName', mergedFormat.fontFamily, isFirst, conflictSolution);\n mergeValue(\n result,\n 'fontSize',\n mergedFormat.fontSize,\n isFirst,\n conflictSolution,\n val => parseValueWithUnit(val, undefined, 'pt') + 'pt'\n );\n mergeValue(result, 'backgroundColor', mergedFormat.backgroundColor, isFirst, conflictSolution);\n mergeValue(result, 'textColor', mergedFormat.textColor, isFirst, conflictSolution);\n mergeValue(result, 'fontWeight', mergedFormat.fontWeight, isFirst, conflictSolution);\n mergeValue(result, 'lineHeight', mergedFormat.lineHeight, isFirst, conflictSolution);\n}\n\nfunction retrieveParagraphFormat(\n result: ContentModelFormatState,\n paragraph: ReadonlyContentModelParagraph,\n isFirst: boolean,\n conflictSolution: ConflictFormatSolution = 'remove'\n) {\n const headingLevel = parseInt((paragraph.decorator?.tagName || '').substring(1));\n const validHeadingLevel = headingLevel >= 1 && headingLevel <= 6 ? headingLevel : undefined;\n\n mergeValue(result, 'marginBottom', paragraph.format.marginBottom, isFirst, conflictSolution);\n mergeValue(result, 'marginTop', paragraph.format.marginTop, isFirst, conflictSolution);\n mergeValue(result, 'headingLevel', validHeadingLevel, isFirst, conflictSolution);\n mergeValue(result, 'textAlign', paragraph.format.textAlign, isFirst, conflictSolution);\n mergeValue(result, 'direction', paragraph.format.direction, isFirst, conflictSolution);\n}\n\nfunction retrieveStructureFormat(\n result: ContentModelFormatState,\n path: ReadonlyContentModelBlockGroup[],\n isFirst: boolean,\n conflictSolution: ConflictFormatSolution = 'remove'\n) {\n const listItemIndex = getClosestAncestorBlockGroupIndex(path, ['ListItem'], []);\n const containerIndex = getClosestAncestorBlockGroupIndex(path, ['FormatContainer'], []);\n\n if (listItemIndex >= 0) {\n const listItem = path[listItemIndex] as ReadonlyContentModelListItem;\n const listType = listItem?.levels[listItem.levels.length - 1]?.listType;\n\n mergeValue(result, 'isBullet', listType == 'UL', isFirst, conflictSolution);\n mergeValue(result, 'isNumbering', listType == 'OL', isFirst, conflictSolution);\n }\n\n mergeValue(\n result,\n 'isBlockQuote',\n containerIndex >= 0 &&\n (path[containerIndex] as ReadonlyContentModelFormatContainer)?.tagName == 'blockquote',\n isFirst,\n conflictSolution\n );\n}\n\nfunction retrieveTableFormat(\n tableContext: ReadonlyTableSelectionContext,\n result: ContentModelFormatState\n) {\n const tableFormat = getTableMetadata(tableContext.table);\n\n result.isInTable = true;\n result.tableHasHeader = tableContext.table.rows.some(row =>\n row.cells.some(cell => cell.isHeader)\n );\n\n if (tableFormat) {\n result.tableFormat = tableFormat;\n }\n}\n\nfunction retrieveImageFormat(image: ReadonlyContentModelImage, result: ContentModelFormatState) {\n const { format } = image;\n const borderKey = 'borderTop';\n const extractedBorder = extractBorderValues(format[borderKey]);\n const borderColor = extractedBorder.color;\n const borderWidth = extractedBorder.width;\n const borderStyle = extractedBorder.style;\n result.imageFormat = {\n borderColor,\n borderWidth,\n borderStyle,\n boxShadow: format.boxShadow,\n borderRadius: format.borderRadius,\n };\n}\n\nfunction mergeValue<K extends keyof ContentModelFormatState>(\n format: ContentModelFormatState,\n key: K,\n newValue: ContentModelFormatState[K] | undefined,\n isFirst: boolean,\n conflictSolution: ConflictFormatSolution = 'remove',\n parseFn: (val: ContentModelFormatState[K]) => ContentModelFormatState[K] = val => val\n) {\n if (isFirst) {\n if (newValue !== undefined) {\n format[key] = newValue;\n }\n } else if (parseFn(newValue) !== parseFn(format[key])) {\n switch (conflictSolution) {\n case 'remove':\n delete format[key];\n break;\n case 'keepFirst':\n break;\n case 'returnMultiple':\n if (typeof format[key] === 'string') {\n (format[key] as string) = 'Multiple';\n } else {\n delete format[key];\n }\n break;\n }\n }\n}\n\nfunction px2Pt(px: string) {\n if (px) {\n const index = px.indexOf('px');\n if (index !== -1 && index === px.length - 2) {\n // Edge may not handle the floating computing well which causes the calculated value to be a little less than the actual value\n // So add 0.05 to fix it\n return Math.round(parseFloat(px) * 75 + 0.05) / 100 + 'pt';\n }\n }\n return px;\n}\n\nfunction hasAllRequiredFormat(format: ContentModelSegmentFormat) {\n return !!format.fontFamily && !!format.fontSize && !!format.textColor;\n}\n"]}
|
|
@@ -8,7 +8,7 @@ var applyMetadata_1 = require("../utils/applyMetadata");
|
|
|
8
8
|
* @internal
|
|
9
9
|
*/
|
|
10
10
|
var handleList = function (doc, parent, listItem, context, refNode) {
|
|
11
|
-
var _a, _b;
|
|
11
|
+
var _a, _b, _c;
|
|
12
12
|
var layer = 0;
|
|
13
13
|
var nodeStack = context.listFormat.nodeStack;
|
|
14
14
|
if (nodeStack.length == 0) {
|
|
@@ -22,7 +22,10 @@ var handleList = function (doc, parent, listItem, context, refNode) {
|
|
|
22
22
|
var itemLevel = listItem.levels[layer];
|
|
23
23
|
if (stackLevel.listType != itemLevel.listType ||
|
|
24
24
|
((_a = stackLevel.dataset) === null || _a === void 0 ? void 0 : _a.editingInfo) != itemLevel.dataset.editingInfo ||
|
|
25
|
-
(itemLevel.listType == 'OL' &&
|
|
25
|
+
(itemLevel.listType == 'OL' &&
|
|
26
|
+
typeof itemLevel.format.startNumberOverride === 'number') ||
|
|
27
|
+
(itemLevel.listType == 'UL' &&
|
|
28
|
+
itemLevel.format.listStyleType != ((_b = stackLevel.format) === null || _b === void 0 ? void 0 : _b.listStyleType))) {
|
|
26
29
|
break;
|
|
27
30
|
}
|
|
28
31
|
}
|
|
@@ -41,7 +44,7 @@ var handleList = function (doc, parent, listItem, context, refNode) {
|
|
|
41
44
|
// Need to apply listItemElement formats after applying metadata since the list numbers value relies on the result of metadata handling
|
|
42
45
|
(0, applyFormat_1.applyFormat)(newList, context.formatAppliers.listLevel, level.format, context);
|
|
43
46
|
(0, applyFormat_1.applyFormat)(newList, context.formatAppliers.dataset, level.dataset, context);
|
|
44
|
-
(
|
|
47
|
+
(_c = context.onNodeCreated) === null || _c === void 0 ? void 0 : _c.call(context, level, newList);
|
|
45
48
|
}
|
|
46
49
|
return refNode;
|
|
47
50
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handleList.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/modelToDom/handlers/handleList.ts"],"names":[],"mappings":";;;;AAAA,oDAAmD;AACnD,wDAAuD;AAOvD;;GAEG;AACI,IAAM,UAAU,GAAmD,UACtE,GAAa,EACb,MAAY,EACZ,QAA8B,EAC9B,OAA0B,EAC1B,OAAoB;;IAEpB,IAAI,KAAK,GAAG,CAAC,CAAC;IACN,IAAA,SAAS,GAAK,OAAO,CAAC,UAAU,UAAvB,CAAwB;IAEzC,IAAI,SAAS,CAAC,MAAM,IAAI,CAAC,EAAE;QACvB,SAAS,CAAC,IAAI,CAAC;YACX,IAAI,EAAE,MAAM;SACf,CAAC,CAAC;KACN;IAED,0EAA0E;IAC1E,OAAO,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,IAAI,KAAK,GAAG,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;QAC5E,IAAM,UAAU,GAAG,SAAS,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;QACxC,IAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAEzC,IACI,UAAU,CAAC,QAAQ,IAAI,SAAS,CAAC,QAAQ;YACzC,CAAA,MAAA,UAAU,CAAC,OAAO,0CAAE,WAAW,KAAI,SAAS,CAAC,OAAO,CAAC,WAAW;YAChE,CAAC,SAAS,CAAC,QAAQ,IAAI,IAAI,
|
|
1
|
+
{"version":3,"file":"handleList.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/modelToDom/handlers/handleList.ts"],"names":[],"mappings":";;;;AAAA,oDAAmD;AACnD,wDAAuD;AAOvD;;GAEG;AACI,IAAM,UAAU,GAAmD,UACtE,GAAa,EACb,MAAY,EACZ,QAA8B,EAC9B,OAA0B,EAC1B,OAAoB;;IAEpB,IAAI,KAAK,GAAG,CAAC,CAAC;IACN,IAAA,SAAS,GAAK,OAAO,CAAC,UAAU,UAAvB,CAAwB;IAEzC,IAAI,SAAS,CAAC,MAAM,IAAI,CAAC,EAAE;QACvB,SAAS,CAAC,IAAI,CAAC;YACX,IAAI,EAAE,MAAM;SACf,CAAC,CAAC;KACN;IAED,0EAA0E;IAC1E,OAAO,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,IAAI,KAAK,GAAG,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;QAC5E,IAAM,UAAU,GAAG,SAAS,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;QACxC,IAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAEzC,IACI,UAAU,CAAC,QAAQ,IAAI,SAAS,CAAC,QAAQ;YACzC,CAAA,MAAA,UAAU,CAAC,OAAO,0CAAE,WAAW,KAAI,SAAS,CAAC,OAAO,CAAC,WAAW;YAChE,CAAC,SAAS,CAAC,QAAQ,IAAI,IAAI;gBACvB,OAAO,SAAS,CAAC,MAAM,CAAC,mBAAmB,KAAK,QAAQ,CAAC;YAC7D,CAAC,SAAS,CAAC,QAAQ,IAAI,IAAI;gBACvB,SAAS,CAAC,MAAM,CAAC,aAAa,KAAI,MAAA,UAAU,CAAC,MAAM,0CAAE,aAAa,CAAA,CAAC,EACzE;YACE,MAAM;SACT;KACJ;IAED,mDAAmD;IACnD,SAAS,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;IAE5B,oDAAoD;IACpD,OAAO,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;QAC5C,IAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACrC,IAAM,OAAO,GAAG,GAAG,CAAC,aAAa,CAAC,KAAK,CAAC,QAAQ,IAAI,IAAI,CAAC,CAAC;QAC1D,IAAM,UAAU,GAAG,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;QAExD,UAAU,CAAC,YAAY,CAAC,OAAO,EAAE,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC9D,SAAS,CAAC,IAAI,yBAAG,IAAI,EAAE,OAAO,IAAK,KAAK,EAAG,CAAC;QAE5C,IAAA,yBAAW,EAAC,OAAO,EAAE,OAAO,CAAC,cAAc,CAAC,eAAe,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAEpF,oIAAoI;QACpI,IAAA,6BAAa,EAAC,KAAK,EAAE,OAAO,CAAC,gBAAgB,CAAC,SAAS,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAEhF,uIAAuI;QACvI,IAAA,yBAAW,EAAC,OAAO,EAAE,OAAO,CAAC,cAAc,CAAC,SAAS,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC9E,IAAA,yBAAW,EAAC,OAAO,EAAE,OAAO,CAAC,cAAc,CAAC,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAE7E,MAAA,OAAO,CAAC,aAAa,+CAArB,OAAO,EAAiB,KAAK,EAAE,OAAO,CAAC,CAAC;KAC3C;IAED,OAAO,OAAO,CAAC;AACnB,CAAC,CAAC;AA1DW,QAAA,UAAU,cA0DrB","sourcesContent":["import { applyFormat } from '../utils/applyFormat';\nimport { applyMetadata } from '../utils/applyMetadata';\nimport type {\n ContentModelBlockHandler,\n ContentModelListItem,\n ModelToDomContext,\n} from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\nexport const handleList: ContentModelBlockHandler<ContentModelListItem> = (\n doc: Document,\n parent: Node,\n listItem: ContentModelListItem,\n context: ModelToDomContext,\n refNode: Node | null\n) => {\n let layer = 0;\n const { nodeStack } = context.listFormat;\n\n if (nodeStack.length == 0) {\n nodeStack.push({\n node: parent,\n });\n }\n\n // Skip existing list levels that has same properties so we can reuse them\n for (; layer < listItem.levels.length && layer + 1 < nodeStack.length; layer++) {\n const stackLevel = nodeStack[layer + 1];\n const itemLevel = listItem.levels[layer];\n\n if (\n stackLevel.listType != itemLevel.listType ||\n stackLevel.dataset?.editingInfo != itemLevel.dataset.editingInfo ||\n (itemLevel.listType == 'OL' &&\n typeof itemLevel.format.startNumberOverride === 'number') ||\n (itemLevel.listType == 'UL' &&\n itemLevel.format.listStyleType != stackLevel.format?.listStyleType)\n ) {\n break;\n }\n }\n\n // Cut off remained list levels that we can't reuse\n nodeStack.splice(layer + 1);\n\n // Create new list levels that are after reused ones\n for (; layer < listItem.levels.length; layer++) {\n const level = listItem.levels[layer];\n const newList = doc.createElement(level.listType || 'UL');\n const lastParent = nodeStack[nodeStack.length - 1].node;\n\n lastParent.insertBefore(newList, layer == 0 ? refNode : null);\n nodeStack.push({ node: newList, ...level });\n\n applyFormat(newList, context.formatAppliers.listLevelThread, level.format, context);\n\n // Need to apply metadata after applying list level format since the list numbers value relies on the result of list thread handling\n applyMetadata(level, context.metadataAppliers.listLevel, level.format, context);\n\n // Need to apply listItemElement formats after applying metadata since the list numbers value relies on the result of metadata handling\n applyFormat(newList, context.formatAppliers.listLevel, level.format, context);\n applyFormat(newList, context.formatAppliers.dataset, level.dataset, context);\n\n context.onNodeCreated?.(level, newList);\n }\n\n return refNode;\n};\n"]}
|
|
@@ -20,10 +20,14 @@ define(["require", "exports", "../../modelApi/common/addSegment", "../../modelAp
|
|
|
20
20
|
(0, parseFormat_1.parseFormat)(element, context.formatParsers.dataset, context.link.dataset, context);
|
|
21
21
|
if (isAnchor_1 && !element.firstChild) {
|
|
22
22
|
// Empty anchor, need to make sure it has some child in model
|
|
23
|
-
|
|
23
|
+
var emptyText = (0, createText_1.createText)('', context.segmentFormat, {
|
|
24
24
|
dataset: context.link.dataset,
|
|
25
25
|
format: context.link.format,
|
|
26
|
-
})
|
|
26
|
+
});
|
|
27
|
+
if (context.isInSelection) {
|
|
28
|
+
emptyText.isSelected = true;
|
|
29
|
+
}
|
|
30
|
+
(0, addSegment_1.addSegment)(group, emptyText);
|
|
27
31
|
}
|
|
28
32
|
else {
|
|
29
33
|
(0, knownElementProcessor_1.knownElementProcessor)(group, element, context);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"linkProcessor.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/domToModel/processors/linkProcessor.ts"],"names":[],"mappings":";;;;IAQA;;OAEG;IACI,IAAM,aAAa,GAAkC,UAAC,KAAK,EAAE,OAAO,EAAE,OAAO;QAChF,IAAM,IAAI,GAAG,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QAC1C,IAAM,IAAI,GAAG,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QAE1C,IAAI,IAAI,IAAI,IAAI,EAAE;YACd,IAAM,UAAQ,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC;YACjC,IAAM,MAAM,GAAuB;gBAC/B,6DAA6D;gBAC7D,kDAAkD;gBAClD,IAAI,EAAE,UAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa;aAC3C,CAAC;YAEF,IAAA,yBAAW,EAAC,OAAO,EAAE,MAAM,EAAE;gBACzB,IAAA,yBAAW,EAAC,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAC/E,IAAA,yBAAW,EAAC,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;gBAEnF,IAAI,UAAQ,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE;oBACjC,6DAA6D;oBAC7D,
|
|
1
|
+
{"version":3,"file":"linkProcessor.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/domToModel/processors/linkProcessor.ts"],"names":[],"mappings":";;;;IAQA;;OAEG;IACI,IAAM,aAAa,GAAkC,UAAC,KAAK,EAAE,OAAO,EAAE,OAAO;QAChF,IAAM,IAAI,GAAG,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QAC1C,IAAM,IAAI,GAAG,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QAE1C,IAAI,IAAI,IAAI,IAAI,EAAE;YACd,IAAM,UAAQ,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC;YACjC,IAAM,MAAM,GAAuB;gBAC/B,6DAA6D;gBAC7D,kDAAkD;gBAClD,IAAI,EAAE,UAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa;aAC3C,CAAC;YAEF,IAAA,yBAAW,EAAC,OAAO,EAAE,MAAM,EAAE;gBACzB,IAAA,yBAAW,EAAC,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAC/E,IAAA,yBAAW,EAAC,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;gBAEnF,IAAI,UAAQ,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE;oBACjC,6DAA6D;oBAC7D,IAAM,SAAS,GAAG,IAAA,uBAAU,EAAC,EAAE,EAAE,OAAO,CAAC,aAAa,EAAE;wBACpD,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,OAAO;wBAC7B,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,MAAM;qBAC9B,CAAC,CAAC;oBAEH,IAAI,OAAO,CAAC,aAAa,EAAE;wBACvB,SAAS,CAAC,UAAU,GAAG,IAAI,CAAC;qBAC/B;oBAED,IAAA,uBAAU,EAAC,KAAK,EAAE,SAAS,CAAC,CAAC;iBAChC;qBAAM;oBACH,IAAA,6CAAqB,EAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;iBAClD;YACL,CAAC,CAAC,CAAC;SACN;aAAM;YACH,gEAAgE;YAChE,IAAA,6CAAqB,EAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;SAClD;IACL,CAAC,CAAC;IApCW,QAAA,aAAa,iBAoCxB","sourcesContent":["import { addSegment } from '../../modelApi/common/addSegment';\nimport { createText } from '../../modelApi/creators/createText';\nimport { knownElementProcessor } from './knownElementProcessor';\nimport { parseFormat } from '../utils/parseFormat';\nimport { stackFormat } from '../utils/stackFormat';\nimport type { StackFormatOptions } from '../utils/stackFormat';\nimport type { ElementProcessor } from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\nexport const linkProcessor: ElementProcessor<HTMLElement> = (group, element, context) => {\n const name = element.getAttribute('name');\n const href = element.getAttribute('href');\n\n if (name || href) {\n const isAnchor = !!name && !href;\n const option: StackFormatOptions = {\n // For anchor (name without ref), no need to add other styles\n // For link (href exists), add default link styles\n link: isAnchor ? 'empty' : 'linkDefault',\n };\n\n stackFormat(context, option, () => {\n parseFormat(element, context.formatParsers.link, context.link.format, context);\n parseFormat(element, context.formatParsers.dataset, context.link.dataset, context);\n\n if (isAnchor && !element.firstChild) {\n // Empty anchor, need to make sure it has some child in model\n const emptyText = createText('', context.segmentFormat, {\n dataset: context.link.dataset,\n format: context.link.format,\n });\n\n if (context.isInSelection) {\n emptyText.isSelected = true;\n }\n\n addSegment(group, emptyText);\n } else {\n knownElementProcessor(group, element, context);\n }\n });\n } else {\n // A tag without name or href, can be treated as normal SPAN tag\n knownElementProcessor(group, element, context);\n }\n};\n"]}
|
|
@@ -69,21 +69,24 @@ define(["require", "exports", "tslib", "../../modelApi/common/addBlock", "../../
|
|
|
69
69
|
for (; tableRow.cells[targetCol]; targetCol++) { }
|
|
70
70
|
var td = tr.cells[sourceCol];
|
|
71
71
|
var hasSelectionBeforeCell = context.isInSelection;
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
if (
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
72
|
+
if (context.recalculateTableSize) {
|
|
73
|
+
var colEnd = targetCol + td.colSpan;
|
|
74
|
+
var rowEnd = row + td.rowSpan;
|
|
75
|
+
var needCalcWidth = columnPositions[colEnd] === undefined;
|
|
76
|
+
var needCalcHeight = rowPositions[rowEnd] === undefined;
|
|
77
|
+
if (needCalcWidth || needCalcHeight) {
|
|
78
|
+
var rect = (0, getBoundingClientRect_1.getBoundingClientRect)(td);
|
|
79
|
+
if (rect.width > 0 || rect.height > 0) {
|
|
80
|
+
if (needCalcWidth) {
|
|
81
|
+
var pos = columnPositions[targetCol];
|
|
82
|
+
columnPositions[colEnd] =
|
|
83
|
+
(typeof pos == 'number' ? pos : 0) +
|
|
84
|
+
rect.width / zoomScale;
|
|
85
|
+
}
|
|
86
|
+
if (needCalcHeight) {
|
|
87
|
+
rowPositions[rowEnd] =
|
|
88
|
+
rowPositions[row] + rect.height / zoomScale;
|
|
89
|
+
}
|
|
87
90
|
}
|
|
88
91
|
}
|
|
89
92
|
}
|