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.
Files changed (35) hide show
  1. package/README.md +3 -0
  2. package/lib/domToModel/processors/linkProcessor.js +6 -2
  3. package/lib/domToModel/processors/linkProcessor.js.map +1 -1
  4. package/lib/domToModel/processors/tableProcessor.js +18 -15
  5. package/lib/domToModel/processors/tableProcessor.js.map +1 -1
  6. package/lib/domUtils/readFile.js +14 -9
  7. package/lib/domUtils/readFile.js.map +1 -1
  8. package/lib/modelApi/editing/retrieveModelFormatState.d.ts +2 -2
  9. package/lib/modelApi/editing/retrieveModelFormatState.js +28 -11
  10. package/lib/modelApi/editing/retrieveModelFormatState.js.map +1 -1
  11. package/lib/modelToDom/handlers/handleList.js +6 -3
  12. package/lib/modelToDom/handlers/handleList.js.map +1 -1
  13. package/lib-amd/domToModel/processors/linkProcessor.js +6 -2
  14. package/lib-amd/domToModel/processors/linkProcessor.js.map +1 -1
  15. package/lib-amd/domToModel/processors/tableProcessor.js +18 -15
  16. package/lib-amd/domToModel/processors/tableProcessor.js.map +1 -1
  17. package/lib-amd/domUtils/readFile.js +14 -9
  18. package/lib-amd/domUtils/readFile.js.map +1 -1
  19. package/lib-amd/modelApi/editing/retrieveModelFormatState.d.ts +2 -2
  20. package/lib-amd/modelApi/editing/retrieveModelFormatState.js +28 -11
  21. package/lib-amd/modelApi/editing/retrieveModelFormatState.js.map +1 -1
  22. package/lib-amd/modelToDom/handlers/handleList.js +6 -3
  23. package/lib-amd/modelToDom/handlers/handleList.js.map +1 -1
  24. package/lib-mjs/domToModel/processors/linkProcessor.js +6 -2
  25. package/lib-mjs/domToModel/processors/linkProcessor.js.map +1 -1
  26. package/lib-mjs/domToModel/processors/tableProcessor.js +18 -15
  27. package/lib-mjs/domToModel/processors/tableProcessor.js.map +1 -1
  28. package/lib-mjs/domUtils/readFile.js +14 -9
  29. package/lib-mjs/domUtils/readFile.js.map +1 -1
  30. package/lib-mjs/modelApi/editing/retrieveModelFormatState.d.ts +2 -2
  31. package/lib-mjs/modelApi/editing/retrieveModelFormatState.js +28 -11
  32. package/lib-mjs/modelApi/editing/retrieveModelFormatState.js.map +1 -1
  33. package/lib-mjs/modelToDom/handlers/handleList.js +6 -3
  34. package/lib-mjs/modelToDom/handlers/handleList.js.map +1 -1
  35. package/package.json +2 -2
@@ -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":"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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\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"]}
@@ -9,15 +9,20 @@ define(["require", "exports"], function (require, exports) {
9
9
  * If fail to read, dataUrl will be null
10
10
  */
11
11
  function readFile(file, callback) {
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);
12
+ try {
13
+ if (file) {
14
+ var reader_1 = new FileReader();
15
+ reader_1.onload = function () {
16
+ callback(reader_1.result);
17
+ };
18
+ reader_1.onerror = function () {
19
+ callback(null);
20
+ };
21
+ reader_1.readAsDataURL(file);
22
+ }
23
+ }
24
+ catch (_a) {
25
+ callback(null);
21
26
  }
22
27
  }
23
28
  exports.readFile = readFile;
@@ -1 +1 @@
1
- {"version":3,"file":"readFile.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-dom/lib/domUtils/readFile.ts"],"names":[],"mappings":";;;;IAAA;;;;;OAKG;IACH,SAAgB,QAAQ,CAAC,IAAU,EAAE,QAA0C;QAC3E,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;IACL,CAAC;IAXD,4BAWC","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 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}\n"]}
1
+ {"version":3,"file":"readFile.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-dom/lib/domUtils/readFile.ts"],"names":[],"mappings":";;;;IAAA;;;;;OAKG;IACH,SAAgB,QAAQ,CAAC,IAAU,EAAE,QAA0C;QAC3E,IAAI;YACA,IAAI,IAAI,EAAE;gBACN,IAAM,QAAM,GAAG,IAAI,UAAU,EAAE,CAAC;gBAChC,QAAM,CAAC,MAAM,GAAG;oBACZ,QAAQ,CAAC,QAAM,CAAC,MAAgB,CAAC,CAAC;gBACtC,CAAC,CAAC;gBACF,QAAM,CAAC,OAAO,GAAG;oBACb,QAAQ,CAAC,IAAI,CAAC,CAAC;gBACnB,CAAC,CAAC;gBACF,QAAM,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;aAC9B;SACJ;QAAC,WAAM;YACJ,QAAQ,CAAC,IAAI,CAAC,CAAC;SAClB;IACL,CAAC;IAfD,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;
@@ -9,13 +9,18 @@ define(["require", "exports", "tslib", "../../domUtils/style/borderValues", "./g
9
9
  * @param formatState Existing format state object, used for receiving the result
10
10
  * @param conflictSolution The strategy for handling format conflicts
11
11
  */
12
- function retrieveModelFormatState(model, pendingFormat, formatState, conflictSolution) {
12
+ function retrieveModelFormatState(model, pendingFormat, formatState, conflictSolution, domHelper) {
13
13
  if (conflictSolution === void 0) { conflictSolution = 'remove'; }
14
14
  var firstTableContext;
15
15
  var firstBlock;
16
16
  var isFirst = true;
17
17
  var isFirstImage = true;
18
18
  var isFirstSegment = true;
19
+ var containerFormat = undefined;
20
+ var modelFormat = (0, tslib_1.__assign)({}, model.format);
21
+ delete modelFormat.italic;
22
+ delete modelFormat.underline;
23
+ delete modelFormat.fontWeight;
19
24
  (0, iterateSelections_1.iterateSelections)(model, function (path, tableContext, block, segments) {
20
25
  // Structure formats
21
26
  retrieveStructureFormat(formatState, path, isFirst, conflictSolution);
@@ -33,13 +38,19 @@ define(["require", "exports", "tslib", "../../domUtils/style/borderValues", "./g
33
38
  retrieveParagraphFormat(formatState, block, isFirst, conflictSolution);
34
39
  // Segment formats
35
40
  segments === null || segments === void 0 ? void 0 : segments.forEach(function (segment) {
36
- var _a, _b, _c;
41
+ var _a, _b, _c, _d;
37
42
  if (isFirstSegment || segment.segmentType != 'SelectionMarker') {
38
- var modelFormat = (0, tslib_1.__assign)({}, model.format);
39
- delete modelFormat.italic;
40
- delete modelFormat.underline;
41
- delete modelFormat.fontWeight;
42
- retrieveSegmentFormat(formatState, isFirst, Object.assign({}, modelFormat, 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), conflictSolution);
43
+ 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);
44
+ // Sometimes the content may not specify all required format but just leverage the container format to do so.
45
+ // In this case, we need to merge the container format into the current format
46
+ // to make sure the current format contains all required format.
47
+ if (!hasAllRequiredFormat(currentFormat)) {
48
+ if (!containerFormat) {
49
+ containerFormat = (_d = domHelper === null || domHelper === void 0 ? void 0 : domHelper.getContainerFormat()) !== null && _d !== void 0 ? _d : modelFormat;
50
+ }
51
+ currentFormat = Object.assign({}, containerFormat, currentFormat);
52
+ }
53
+ retrieveSegmentFormat(formatState, isFirst, currentFormat, conflictSolution);
43
54
  mergeValue(formatState, 'isCodeInline', !!(segment === null || segment === void 0 ? void 0 : segment.code), isFirst, conflictSolution);
44
55
  }
45
56
  // We only care the format of selection marker when it is the first selected segment. This is because when selection marker
@@ -183,12 +194,18 @@ define(["require", "exports", "tslib", "../../domUtils/style/borderValues", "./g
183
194
  }
184
195
  }
185
196
  function px2Pt(px) {
186
- if (px && px.indexOf('px') == px.length - 2) {
187
- // Edge may not handle the floating computing well which causes the calculated value is a little less than actual value
188
- // So add 0.05 to fix it
189
- return Math.round(parseFloat(px) * 75 + 0.05) / 100 + 'pt';
197
+ if (px) {
198
+ var index = px.indexOf('px');
199
+ if (index !== -1 && index === px.length - 2) {
200
+ // Edge may not handle the floating computing well which causes the calculated value to be a little less than the actual value
201
+ // So add 0.05 to fix it
202
+ return Math.round(parseFloat(px) * 75 + 0.05) / 100 + 'pt';
203
+ }
190
204
  }
191
205
  return px;
192
206
  }
207
+ function hasAllRequiredFormat(format) {
208
+ return !!format.fontFamily && !!format.fontSize && !!format.textColor;
209
+ }
193
210
  });
194
211
  //# 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":"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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} 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":";;;;IAqBA;;;;;;OAMG;IACH,SAAgB,wBAAwB,CACpC,KAAmC,EACnC,aAA+C,EAC/C,WAAoC,EACpC,gBAAmD,EACnD,SAAqB;QADrB,iCAAA,EAAA,2BAAmD;QAGnD,IAAI,iBAA4D,CAAC;QACjE,IAAI,UAAiD,CAAC;QACtD,IAAI,OAAO,GAAG,IAAI,CAAC;QACnB,IAAI,YAAY,GAAG,IAAI,CAAC;QACxB,IAAI,cAAc,GAAG,IAAI,CAAC;QAC1B,IAAI,eAAe,GAA0C,SAAS,CAAC;QAEvE,IAAM,WAAW,6BAAQ,KAAK,CAAC,MAAM,CAAE,CAAC;QAExC,OAAO,WAAW,CAAC,MAAM,CAAC;QAC1B,OAAO,WAAW,CAAC,SAAS,CAAC;QAC7B,OAAO,WAAW,CAAC,UAAU,CAAC;QAE9B,IAAA,qCAAiB,EACb,KAAK,EACL,UAAC,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,QAAQ;YAChC,oBAAoB;YACpB,uBAAuB,CAAC,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;YAEtE,uBAAuB;YACvB,IAAI,KAAK,EAAE;gBACP,IAAI,UAAU,EAAE;oBACZ,WAAW,CAAC,oBAAoB,GAAG,IAAI,CAAC;iBAC3C;qBAAM;oBACH,UAAU,GAAG,KAAK,CAAC;iBACtB;aACJ;YAED,IAAI,CAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,SAAS,KAAI,WAAW,EAAE;gBACjC,oBAAoB;gBACpB,uBAAuB,CAAC,WAAW,EAAE,KAAK,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;gBAEvE,kBAAkB;gBAClB,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,OAAO,CAAC,UAAA,OAAO;;oBACrB,IAAI,cAAc,IAAI,OAAO,CAAC,WAAW,IAAI,iBAAiB,EAAE;wBAC5D,IAAI,aAAa,GAAG,MAAM,CAAC,MAAM,CAC7B,EAAE,EACF,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,CAAC;wBAEF,6GAA6G;wBAC7G,8EAA8E;wBAC9E,gEAAgE;wBAChE,IAAI,CAAC,oBAAoB,CAAC,aAAa,CAAC,EAAE;4BACtC,IAAI,CAAC,eAAe,EAAE;gCAClB,eAAe,GAAG,MAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,kBAAkB,EAAE,mCAAI,WAAW,CAAC;6BACpE;4BAED,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,eAAe,EAAE,aAAa,CAAC,CAAC;yBACrE;wBAED,qBAAqB,CACjB,WAAW,EACX,OAAO,EACP,aAAa,EACb,gBAAgB,CACnB,CAAC;wBAEF,UAAU,CACN,WAAW,EACX,cAAc,EACd,CAAC,CAAC,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,IAAI,CAAA,EACf,OAAO,EACP,gBAAgB,CACnB,CAAC;qBACL;oBAED,2HAA2H;oBAC3H,6HAA6H;oBAC7H,6HAA6H;oBAC7H,YAAY;oBACZ,cAAc,GAAG,KAAK,CAAC;oBAEvB,WAAW,CAAC,SAAS,GAAG,WAAW,CAAC,SAAS,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC;oBAChE,WAAW,CAAC,kBAAkB;wBAC1B,WAAW,CAAC,kBAAkB;4BAC9B,QAAQ,CAAC,IAAI,CAAC,UAAA,OAAO,IAAI,OAAA,OAAO,CAAC,WAAW,IAAI,OAAO,EAA9B,CAA8B,CAAC,CAAC;oBAE7D,OAAO,GAAG,KAAK,CAAC;oBAEhB,IAAI,OAAO,CAAC,WAAW,KAAK,OAAO,EAAE;wBACjC,IAAI,YAAY,EAAE;4BACd,mBAAmB,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;4BAC1C,YAAY,GAAG,KAAK,CAAC;yBACxB;6BAAM;4BACH,WAAW,CAAC,WAAW,GAAG,SAAS,CAAC;yBACvC;qBACJ;gBACL,CAAC,CAAC,CAAC;gBAEH,OAAO,GAAG,KAAK,CAAC;aACnB;YAED,IAAI,YAAY,EAAE;gBACd,IAAI,iBAAiB,EAAE;oBACX,IAAA,KAAK,GAAyB,iBAAiB,MAA1C,EAAE,QAAQ,GAAe,iBAAiB,SAAhC,EAAE,QAAQ,GAAK,iBAAiB,SAAtB,CAAuB;oBAExD,qBAAqB;oBACrB,IACI,YAAY,CAAC,KAAK,IAAI,KAAK;wBAC3B,CAAC,YAAY,CAAC,QAAQ,IAAI,QAAQ,IAAI,YAAY,CAAC,QAAQ,IAAI,QAAQ,CAAC,EAC1E;wBACE,WAAW,CAAC,iBAAiB,GAAG,IAAI,CAAC;wBACrC,WAAW,CAAC,oBAAoB,GAAG,IAAI,CAAC;qBAC3C;iBACJ;qBAAM;oBACH,gBAAgB;oBAChB,mBAAmB,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;oBAC/C,iBAAiB,GAAG,YAAY,CAAC;iBACpC;aACJ;QACL,CAAC,EACD;YACI,uBAAuB,EAAE,OAAO;SACnC,CACJ,CAAC;QAEF,IAAI,WAAW,CAAC,QAAQ,EAAE;YACtB,WAAW,CAAC,QAAQ,GAAG,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;SACtD;IACL,CAAC;IApID,4DAoIC;IAED,SAAS,qBAAqB,CAC1B,MAA+B,EAC/B,OAAgB,EAChB,YAAuC,EACvC,gBAAmD;;QAAnD,iCAAA,EAAA,2BAAmD;QAEnD,IAAM,gBAAgB,GAAG,MAAA,MAAA,YAAY,CAAC,wBAAwB,0CAAE,KAAK,CAAC,GAAG,CAAC,0CAAE,GAAG,EAAE,CAAC;QAElF,UAAU,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAA,eAAM,EAAC,YAAY,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;QACzF,UAAU,CAAC,MAAM,EAAE,UAAU,EAAE,YAAY,CAAC,MAAM,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;QAC/E,UAAU,CAAC,MAAM,EAAE,aAAa,EAAE,YAAY,CAAC,SAAS,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;QACrF,UAAU,CAAC,MAAM,EAAE,iBAAiB,EAAE,YAAY,CAAC,aAAa,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;QAC7F,UAAU,CAAC,MAAM,EAAE,eAAe,EAAE,gBAAgB,IAAI,OAAO,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;QAC5F,UAAU,CAAC,MAAM,EAAE,aAAa,EAAE,gBAAgB,IAAI,KAAK,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;QACxF,UAAU,CAAC,MAAM,EAAE,eAAe,EAAE,YAAY,CAAC,aAAa,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;QAE3F,UAAU,CAAC,MAAM,EAAE,UAAU,EAAE,YAAY,CAAC,UAAU,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;QACnF,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;QACF,UAAU,CAAC,MAAM,EAAE,iBAAiB,EAAE,YAAY,CAAC,eAAe,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;QAC/F,UAAU,CAAC,MAAM,EAAE,WAAW,EAAE,YAAY,CAAC,SAAS,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;QACnF,UAAU,CAAC,MAAM,EAAE,YAAY,EAAE,YAAY,CAAC,UAAU,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;QACrF,UAAU,CAAC,MAAM,EAAE,YAAY,EAAE,YAAY,CAAC,UAAU,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;IACzF,CAAC;IAED,SAAS,uBAAuB,CAC5B,MAA+B,EAC/B,SAAwC,EACxC,OAAgB,EAChB,gBAAmD;;QAAnD,iCAAA,EAAA,2BAAmD;QAEnD,IAAM,YAAY,GAAG,QAAQ,CAAC,CAAC,CAAA,MAAA,SAAS,CAAC,SAAS,0CAAE,OAAO,KAAI,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;QACjF,IAAM,iBAAiB,GAAG,YAAY,IAAI,CAAC,IAAI,YAAY,IAAI,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC;QAE5F,UAAU,CAAC,MAAM,EAAE,cAAc,EAAE,SAAS,CAAC,MAAM,CAAC,YAAY,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;QAC7F,UAAU,CAAC,MAAM,EAAE,WAAW,EAAE,SAAS,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;QACvF,UAAU,CAAC,MAAM,EAAE,cAAc,EAAE,iBAAiB,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;QACjF,UAAU,CAAC,MAAM,EAAE,WAAW,EAAE,SAAS,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;QACvF,UAAU,CAAC,MAAM,EAAE,WAAW,EAAE,SAAS,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;IAC3F,CAAC;IAED,SAAS,uBAAuB,CAC5B,MAA+B,EAC/B,IAAsC,EACtC,OAAgB,EAChB,gBAAmD;;QAAnD,iCAAA,EAAA,2BAAmD;QAEnD,IAAM,aAAa,GAAG,IAAA,qEAAiC,EAAC,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC;QAChF,IAAM,cAAc,GAAG,IAAA,qEAAiC,EAAC,IAAI,EAAE,CAAC,iBAAiB,CAAC,EAAE,EAAE,CAAC,CAAC;QAExF,IAAI,aAAa,IAAI,CAAC,EAAE;YACpB,IAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAiC,CAAC;YACrE,IAAM,QAAQ,GAAG,MAAA,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,0CAAE,QAAQ,CAAC;YAExE,UAAU,CAAC,MAAM,EAAE,UAAU,EAAE,QAAQ,IAAI,IAAI,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;YAC5E,UAAU,CAAC,MAAM,EAAE,aAAa,EAAE,QAAQ,IAAI,IAAI,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;SAClF;QAED,UAAU,CACN,MAAM,EACN,cAAc,EACd,cAAc,IAAI,CAAC;YACf,CAAA,MAAC,IAAI,CAAC,cAAc,CAAyC,0CAAE,OAAO,KAAI,YAAY,EAC1F,OAAO,EACP,gBAAgB,CACnB,CAAC;IACN,CAAC;IAED,SAAS,mBAAmB,CACxB,YAA2C,EAC3C,MAA+B;QAE/B,IAAM,WAAW,GAAG,IAAA,sCAAgB,EAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QAEzD,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC;QACxB,MAAM,CAAC,cAAc,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,UAAA,GAAG;YACpD,OAAA,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,UAAA,IAAI,IAAI,OAAA,IAAI,CAAC,QAAQ,EAAb,CAAa,CAAC;QAArC,CAAqC,CACxC,CAAC;QAEF,IAAI,WAAW,EAAE;YACb,MAAM,CAAC,WAAW,GAAG,WAAW,CAAC;SACpC;IACL,CAAC;IAED,SAAS,mBAAmB,CAAC,KAAgC,EAAE,MAA+B;QAClF,IAAA,MAAM,GAAK,KAAK,OAAV,CAAW;QACzB,IAAM,SAAS,GAAG,WAAW,CAAC;QAC9B,IAAM,eAAe,GAAG,IAAA,kCAAmB,EAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;QAC/D,IAAM,WAAW,GAAG,eAAe,CAAC,KAAK,CAAC;QAC1C,IAAM,WAAW,GAAG,eAAe,CAAC,KAAK,CAAC;QAC1C,IAAM,WAAW,GAAG,eAAe,CAAC,KAAK,CAAC;QAC1C,MAAM,CAAC,WAAW,GAAG;YACjB,WAAW,aAAA;YACX,WAAW,aAAA;YACX,WAAW,aAAA;YACX,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,YAAY,EAAE,MAAM,CAAC,YAAY;SACpC,CAAC;IACN,CAAC;IAED,SAAS,UAAU,CACf,MAA+B,EAC/B,GAAM,EACN,QAAgD,EAChD,OAAgB,EAChB,gBAAmD,EACnD,OAAqF;QADrF,iCAAA,EAAA,2BAAmD;QACnD,wBAAA,EAAA,oBAA2E,GAAG,IAAI,OAAA,GAAG,EAAH,CAAG;QAErF,IAAI,OAAO,EAAE;YACT,IAAI,QAAQ,KAAK,SAAS,EAAE;gBACxB,MAAM,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC;aAC1B;SACJ;aAAM,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE;YACnD,QAAQ,gBAAgB,EAAE;gBACtB,KAAK,QAAQ;oBACT,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;oBACnB,MAAM;gBACV,KAAK,WAAW;oBACZ,MAAM;gBACV,KAAK,gBAAgB;oBACjB,IAAI,OAAO,MAAM,CAAC,GAAG,CAAC,KAAK,QAAQ,EAAE;wBAChC,MAAM,CAAC,GAAG,CAAY,GAAG,UAAU,CAAC;qBACxC;yBAAM;wBACH,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;qBACtB;oBACD,MAAM;aACb;SACJ;IACL,CAAC;IAED,SAAS,KAAK,CAAC,EAAU;QACrB,IAAI,EAAE,EAAE;YACJ,IAAM,KAAK,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAC/B,IAAI,KAAK,KAAK,CAAC,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE;gBACzC,8HAA8H;gBAC9H,wBAAwB;gBACxB,OAAO,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,IAAI,CAAC;aAC9D;SACJ;QACD,OAAO,EAAE,CAAC;IACd,CAAC;IAED,SAAS,oBAAoB,CAAC,MAAiC;QAC3D,OAAO,CAAC,CAAC,MAAM,CAAC,UAAU,IAAI,CAAC,CAAC,MAAM,CAAC,QAAQ,IAAI,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC;IAC1E,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 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"]}
@@ -6,7 +6,7 @@ define(["require", "exports", "tslib", "../utils/applyFormat", "../utils/applyMe
6
6
  * @internal
7
7
  */
8
8
  var handleList = function (doc, parent, listItem, context, refNode) {
9
- var _a, _b;
9
+ var _a, _b, _c;
10
10
  var layer = 0;
11
11
  var nodeStack = context.listFormat.nodeStack;
12
12
  if (nodeStack.length == 0) {
@@ -20,7 +20,10 @@ define(["require", "exports", "tslib", "../utils/applyFormat", "../utils/applyMe
20
20
  var itemLevel = listItem.levels[layer];
21
21
  if (stackLevel.listType != itemLevel.listType ||
22
22
  ((_a = stackLevel.dataset) === null || _a === void 0 ? void 0 : _a.editingInfo) != itemLevel.dataset.editingInfo ||
23
- (itemLevel.listType == 'OL' && typeof itemLevel.format.startNumberOverride === 'number')) {
23
+ (itemLevel.listType == 'OL' &&
24
+ typeof itemLevel.format.startNumberOverride === 'number') ||
25
+ (itemLevel.listType == 'UL' &&
26
+ itemLevel.format.listStyleType != ((_b = stackLevel.format) === null || _b === void 0 ? void 0 : _b.listStyleType))) {
24
27
  break;
25
28
  }
26
29
  }
@@ -39,7 +42,7 @@ define(["require", "exports", "tslib", "../utils/applyFormat", "../utils/applyMe
39
42
  // Need to apply listItemElement formats after applying metadata since the list numbers value relies on the result of metadata handling
40
43
  (0, applyFormat_1.applyFormat)(newList, context.formatAppliers.listLevel, level.format, context);
41
44
  (0, applyFormat_1.applyFormat)(newList, context.formatAppliers.dataset, level.dataset, context);
42
- (_b = context.onNodeCreated) === null || _b === void 0 ? void 0 : _b.call(context, level, newList);
45
+ (_c = context.onNodeCreated) === null || _c === void 0 ? void 0 : _c.call(context, level, newList);
43
46
  }
44
47
  return refNode;
45
48
  };
@@ -1 +1 @@
1
- {"version":3,"file":"handleList.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/modelToDom/handlers/handleList.ts"],"names":[],"mappings":";;;;IAQA;;OAEG;IACI,IAAM,UAAU,GAAmD,UACtE,GAAa,EACb,MAAY,EACZ,QAA8B,EAC9B,OAA0B,EAC1B,OAAoB;;QAEpB,IAAI,KAAK,GAAG,CAAC,CAAC;QACN,IAAA,SAAS,GAAK,OAAO,CAAC,UAAU,UAAvB,CAAwB;QAEzC,IAAI,SAAS,CAAC,MAAM,IAAI,CAAC,EAAE;YACvB,SAAS,CAAC,IAAI,CAAC;gBACX,IAAI,EAAE,MAAM;aACf,CAAC,CAAC;SACN;QAED,0EAA0E;QAC1E,OAAO,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,IAAI,KAAK,GAAG,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;YAC5E,IAAM,UAAU,GAAG,SAAS,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;YACxC,IAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAEzC,IACI,UAAU,CAAC,QAAQ,IAAI,SAAS,CAAC,QAAQ;gBACzC,CAAA,MAAA,UAAU,CAAC,OAAO,0CAAE,WAAW,KAAI,SAAS,CAAC,OAAO,CAAC,WAAW;gBAChE,CAAC,SAAS,CAAC,QAAQ,IAAI,IAAI,IAAI,OAAO,SAAS,CAAC,MAAM,CAAC,mBAAmB,KAAK,QAAQ,CAAC,EAC1F;gBACE,MAAM;aACT;SACJ;QAED,mDAAmD;QACnD,SAAS,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;QAE5B,oDAAoD;QACpD,OAAO,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;YAC5C,IAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACrC,IAAM,OAAO,GAAG,GAAG,CAAC,aAAa,CAAC,KAAK,CAAC,QAAQ,IAAI,IAAI,CAAC,CAAC;YAC1D,IAAM,UAAU,GAAG,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;YAExD,UAAU,CAAC,YAAY,CAAC,OAAO,EAAE,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YAC9D,SAAS,CAAC,IAAI,yBAAG,IAAI,EAAE,OAAO,IAAK,KAAK,EAAG,CAAC;YAE5C,IAAA,yBAAW,EAAC,OAAO,EAAE,OAAO,CAAC,cAAc,CAAC,eAAe,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAEpF,oIAAoI;YACpI,IAAA,6BAAa,EAAC,KAAK,EAAE,OAAO,CAAC,gBAAgB,CAAC,SAAS,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAEhF,uIAAuI;YACvI,IAAA,yBAAW,EAAC,OAAO,EAAE,OAAO,CAAC,cAAc,CAAC,SAAS,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAC9E,IAAA,yBAAW,EAAC,OAAO,EAAE,OAAO,CAAC,cAAc,CAAC,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAE7E,MAAA,OAAO,CAAC,aAAa,+CAArB,OAAO,EAAiB,KAAK,EAAE,OAAO,CAAC,CAAC;SAC3C;QAED,OAAO,OAAO,CAAC;IACnB,CAAC,CAAC;IAvDW,QAAA,UAAU,cAuDrB","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' && typeof itemLevel.format.startNumberOverride === 'number')\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"]}
1
+ {"version":3,"file":"handleList.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/modelToDom/handlers/handleList.ts"],"names":[],"mappings":";;;;IAQA;;OAEG;IACI,IAAM,UAAU,GAAmD,UACtE,GAAa,EACb,MAAY,EACZ,QAA8B,EAC9B,OAA0B,EAC1B,OAAoB;;QAEpB,IAAI,KAAK,GAAG,CAAC,CAAC;QACN,IAAA,SAAS,GAAK,OAAO,CAAC,UAAU,UAAvB,CAAwB;QAEzC,IAAI,SAAS,CAAC,MAAM,IAAI,CAAC,EAAE;YACvB,SAAS,CAAC,IAAI,CAAC;gBACX,IAAI,EAAE,MAAM;aACf,CAAC,CAAC;SACN;QAED,0EAA0E;QAC1E,OAAO,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,IAAI,KAAK,GAAG,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;YAC5E,IAAM,UAAU,GAAG,SAAS,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;YACxC,IAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAEzC,IACI,UAAU,CAAC,QAAQ,IAAI,SAAS,CAAC,QAAQ;gBACzC,CAAA,MAAA,UAAU,CAAC,OAAO,0CAAE,WAAW,KAAI,SAAS,CAAC,OAAO,CAAC,WAAW;gBAChE,CAAC,SAAS,CAAC,QAAQ,IAAI,IAAI;oBACvB,OAAO,SAAS,CAAC,MAAM,CAAC,mBAAmB,KAAK,QAAQ,CAAC;gBAC7D,CAAC,SAAS,CAAC,QAAQ,IAAI,IAAI;oBACvB,SAAS,CAAC,MAAM,CAAC,aAAa,KAAI,MAAA,UAAU,CAAC,MAAM,0CAAE,aAAa,CAAA,CAAC,EACzE;gBACE,MAAM;aACT;SACJ;QAED,mDAAmD;QACnD,SAAS,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;QAE5B,oDAAoD;QACpD,OAAO,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;YAC5C,IAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACrC,IAAM,OAAO,GAAG,GAAG,CAAC,aAAa,CAAC,KAAK,CAAC,QAAQ,IAAI,IAAI,CAAC,CAAC;YAC1D,IAAM,UAAU,GAAG,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;YAExD,UAAU,CAAC,YAAY,CAAC,OAAO,EAAE,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YAC9D,SAAS,CAAC,IAAI,yBAAG,IAAI,EAAE,OAAO,IAAK,KAAK,EAAG,CAAC;YAE5C,IAAA,yBAAW,EAAC,OAAO,EAAE,OAAO,CAAC,cAAc,CAAC,eAAe,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAEpF,oIAAoI;YACpI,IAAA,6BAAa,EAAC,KAAK,EAAE,OAAO,CAAC,gBAAgB,CAAC,SAAS,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAEhF,uIAAuI;YACvI,IAAA,yBAAW,EAAC,OAAO,EAAE,OAAO,CAAC,cAAc,CAAC,SAAS,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAC9E,IAAA,yBAAW,EAAC,OAAO,EAAE,OAAO,CAAC,cAAc,CAAC,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAE7E,MAAA,OAAO,CAAC,aAAa,+CAArB,OAAO,EAAiB,KAAK,EAAE,OAAO,CAAC,CAAC;SAC3C;QAED,OAAO,OAAO,CAAC;IACnB,CAAC,CAAC;IA1DW,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"]}
@@ -21,10 +21,14 @@ export var linkProcessor = function (group, element, context) {
21
21
  parseFormat(element, context.formatParsers.dataset, context.link.dataset, context);
22
22
  if (isAnchor_1 && !element.firstChild) {
23
23
  // Empty anchor, need to make sure it has some child in model
24
- addSegment(group, createText('', context.segmentFormat, {
24
+ var emptyText = createText('', context.segmentFormat, {
25
25
  dataset: context.link.dataset,
26
26
  format: context.link.format,
27
- }));
27
+ });
28
+ if (context.isInSelection) {
29
+ emptyText.isSelected = true;
30
+ }
31
+ addSegment(group, emptyText);
28
32
  }
29
33
  else {
30
34
  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,OAAO,EAAE,UAAU,EAAE,MAAM,kCAAkC,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,oCAAoC,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAInD;;GAEG;AACH,MAAM,CAAC,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,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE;YACzB,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAC/E,WAAW,CAAC,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,UAAU,CACN,KAAK,EACL,UAAU,CAAC,EAAE,EAAE,OAAO,CAAC,aAAa,EAAE;oBAClC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,OAAO;oBAC7B,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,MAAM;iBAC9B,CAAC,CACL,CAAC;aACL;iBAAM;gBACH,qBAAqB,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;aAClD;QACL,CAAC,CAAC,CAAC;KACN;SAAM;QACH,gEAAgE;QAChE,qBAAqB,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;KAClD;AACL,CAAC,CAAC","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 addSegment(\n group,\n createText('', context.segmentFormat, {\n dataset: context.link.dataset,\n format: context.link.format,\n })\n );\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"]}
1
+ {"version":3,"file":"linkProcessor.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/domToModel/processors/linkProcessor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kCAAkC,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,oCAAoC,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAInD;;GAEG;AACH,MAAM,CAAC,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,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE;YACzB,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAC/E,WAAW,CAAC,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,UAAU,CAAC,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,UAAU,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;aAChC;iBAAM;gBACH,qBAAqB,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;aAClD;QACL,CAAC,CAAC,CAAC;KACN;SAAM;QACH,gEAAgE;QAChE,qBAAqB,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;KAClD;AACL,CAAC,CAAC","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"]}
@@ -75,21 +75,24 @@ export var tableProcessor = function (group, tableElement, context) {
75
75
  for (; tableRow.cells[targetCol]; targetCol++) { }
76
76
  var td = tr.cells[sourceCol];
77
77
  var hasSelectionBeforeCell = context.isInSelection;
78
- var colEnd = targetCol + td.colSpan;
79
- var rowEnd = row + td.rowSpan;
80
- var needCalcWidth = columnPositions[colEnd] === undefined;
81
- var needCalcHeight = rowPositions[rowEnd] === undefined;
82
- if (needCalcWidth || needCalcHeight) {
83
- var rect = getBoundingClientRect(td);
84
- if (rect.width > 0 || rect.height > 0) {
85
- if (needCalcWidth) {
86
- var pos = columnPositions[targetCol];
87
- columnPositions[colEnd] =
88
- (typeof pos == 'number' ? pos : 0) + rect.width / zoomScale;
89
- }
90
- if (needCalcHeight) {
91
- rowPositions[rowEnd] =
92
- rowPositions[row] + rect.height / zoomScale;
78
+ if (context.recalculateTableSize) {
79
+ var colEnd = targetCol + td.colSpan;
80
+ var rowEnd = row + td.rowSpan;
81
+ var needCalcWidth = columnPositions[colEnd] === undefined;
82
+ var needCalcHeight = rowPositions[rowEnd] === undefined;
83
+ if (needCalcWidth || needCalcHeight) {
84
+ var rect = getBoundingClientRect(td);
85
+ if (rect.width > 0 || rect.height > 0) {
86
+ if (needCalcWidth) {
87
+ var pos = columnPositions[targetCol];
88
+ columnPositions[colEnd] =
89
+ (typeof pos == 'number' ? pos : 0) +
90
+ rect.width / zoomScale;
91
+ }
92
+ if (needCalcHeight) {
93
+ rowPositions[rowEnd] =
94
+ rowPositions[row] + rect.height / zoomScale;
95
+ }
93
96
  }
94
97
  }
95
98
  }
@@ -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":"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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\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"]}