roosterjs-content-model-plugins 9.44.0 → 9.45.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/lib/announce/tableSelectionUtils.js +6 -9
  2. package/lib/announce/tableSelectionUtils.js.map +1 -1
  3. package/lib/autoFormat/AutoFormatPlugin.js +4 -4
  4. package/lib/autoFormat/AutoFormatPlugin.js.map +1 -1
  5. package/lib/autoFormat/numbers/transformOrdinals.js +3 -2
  6. package/lib/autoFormat/numbers/transformOrdinals.js.map +1 -1
  7. package/lib/edit/deleteSteps/deleteList.js +39 -9
  8. package/lib/edit/deleteSteps/deleteList.js.map +1 -1
  9. package/lib/findReplace/FindReplacePlugin.js +5 -4
  10. package/lib/findReplace/FindReplacePlugin.js.map +1 -1
  11. package/lib/imageEdit/utils/generateDataURL.js +4 -2
  12. package/lib/imageEdit/utils/generateDataURL.js.map +1 -1
  13. package/lib/tableEdit/TableEditPlugin.js +4 -4
  14. package/lib/tableEdit/TableEditPlugin.js.map +1 -1
  15. package/lib/tableEdit/editors/TableEditor.d.ts +4 -0
  16. package/lib/tableEdit/editors/TableEditor.js +38 -1
  17. package/lib/tableEdit/editors/TableEditor.js.map +1 -1
  18. package/lib/tableEdit/editors/features/CellResizer.d.ts +1 -0
  19. package/lib/tableEdit/editors/features/CellResizer.js +83 -47
  20. package/lib/tableEdit/editors/features/CellResizer.js.map +1 -1
  21. package/lib/tableEdit/editors/features/TableEditFeatureName.d.ts +1 -1
  22. package/lib/tableEdit/editors/features/TableEditFeatureName.js.map +1 -1
  23. package/lib/tableEdit/editors/features/TableMover.js +2 -2
  24. package/lib/tableEdit/editors/features/TableMover.js.map +1 -1
  25. package/lib/tableEdit/editors/features/TableRowColumnSelector.d.ts +42 -0
  26. package/lib/tableEdit/editors/features/TableRowColumnSelector.js +223 -0
  27. package/lib/tableEdit/editors/features/TableRowColumnSelector.js.map +1 -0
  28. package/lib/tableEdit/editors/utils/getTableFromContentModel.js +1 -0
  29. package/lib/tableEdit/editors/utils/getTableFromContentModel.js.map +1 -1
  30. package/lib/touch/TouchPlugin.js +54 -52
  31. package/lib/touch/TouchPlugin.js.map +1 -1
  32. package/lib-amd/announce/tableSelectionUtils.js +6 -9
  33. package/lib-amd/announce/tableSelectionUtils.js.map +1 -1
  34. package/lib-amd/autoFormat/AutoFormatPlugin.js +4 -4
  35. package/lib-amd/autoFormat/AutoFormatPlugin.js.map +1 -1
  36. package/lib-amd/autoFormat/numbers/transformOrdinals.js +3 -2
  37. package/lib-amd/autoFormat/numbers/transformOrdinals.js.map +1 -1
  38. package/lib-amd/edit/deleteSteps/deleteList.js +39 -10
  39. package/lib-amd/edit/deleteSteps/deleteList.js.map +1 -1
  40. package/lib-amd/findReplace/FindReplacePlugin.js +5 -4
  41. package/lib-amd/findReplace/FindReplacePlugin.js.map +1 -1
  42. package/lib-amd/imageEdit/utils/generateDataURL.js +4 -2
  43. package/lib-amd/imageEdit/utils/generateDataURL.js.map +1 -1
  44. package/lib-amd/tableEdit/TableEditPlugin.js +4 -4
  45. package/lib-amd/tableEdit/TableEditPlugin.js.map +1 -1
  46. package/lib-amd/tableEdit/editors/TableEditor.d.ts +4 -0
  47. package/lib-amd/tableEdit/editors/TableEditor.js +38 -2
  48. package/lib-amd/tableEdit/editors/TableEditor.js.map +1 -1
  49. package/lib-amd/tableEdit/editors/features/CellResizer.d.ts +1 -0
  50. package/lib-amd/tableEdit/editors/features/CellResizer.js +83 -47
  51. package/lib-amd/tableEdit/editors/features/CellResizer.js.map +1 -1
  52. package/lib-amd/tableEdit/editors/features/TableEditFeatureName.d.ts +1 -1
  53. package/lib-amd/tableEdit/editors/features/TableEditFeatureName.js.map +1 -1
  54. package/lib-amd/tableEdit/editors/features/TableMover.js +2 -2
  55. package/lib-amd/tableEdit/editors/features/TableMover.js.map +1 -1
  56. package/lib-amd/tableEdit/editors/features/TableRowColumnSelector.d.ts +42 -0
  57. package/lib-amd/tableEdit/editors/features/TableRowColumnSelector.js +221 -0
  58. package/lib-amd/tableEdit/editors/features/TableRowColumnSelector.js.map +1 -0
  59. package/lib-amd/tableEdit/editors/utils/getTableFromContentModel.js +1 -0
  60. package/lib-amd/tableEdit/editors/utils/getTableFromContentModel.js.map +1 -1
  61. package/lib-amd/touch/TouchPlugin.js +54 -52
  62. package/lib-amd/touch/TouchPlugin.js.map +1 -1
  63. package/lib-mjs/announce/tableSelectionUtils.js +6 -9
  64. package/lib-mjs/announce/tableSelectionUtils.js.map +1 -1
  65. package/lib-mjs/autoFormat/AutoFormatPlugin.js +4 -4
  66. package/lib-mjs/autoFormat/AutoFormatPlugin.js.map +1 -1
  67. package/lib-mjs/autoFormat/numbers/transformOrdinals.js +3 -2
  68. package/lib-mjs/autoFormat/numbers/transformOrdinals.js.map +1 -1
  69. package/lib-mjs/edit/deleteSteps/deleteList.js +40 -10
  70. package/lib-mjs/edit/deleteSteps/deleteList.js.map +1 -1
  71. package/lib-mjs/findReplace/FindReplacePlugin.js +5 -4
  72. package/lib-mjs/findReplace/FindReplacePlugin.js.map +1 -1
  73. package/lib-mjs/imageEdit/utils/generateDataURL.js +4 -2
  74. package/lib-mjs/imageEdit/utils/generateDataURL.js.map +1 -1
  75. package/lib-mjs/tableEdit/TableEditPlugin.js +4 -4
  76. package/lib-mjs/tableEdit/TableEditPlugin.js.map +1 -1
  77. package/lib-mjs/tableEdit/editors/TableEditor.d.ts +4 -0
  78. package/lib-mjs/tableEdit/editors/TableEditor.js +38 -1
  79. package/lib-mjs/tableEdit/editors/TableEditor.js.map +1 -1
  80. package/lib-mjs/tableEdit/editors/features/CellResizer.d.ts +1 -0
  81. package/lib-mjs/tableEdit/editors/features/CellResizer.js +84 -48
  82. package/lib-mjs/tableEdit/editors/features/CellResizer.js.map +1 -1
  83. package/lib-mjs/tableEdit/editors/features/TableEditFeatureName.d.ts +1 -1
  84. package/lib-mjs/tableEdit/editors/features/TableEditFeatureName.js.map +1 -1
  85. package/lib-mjs/tableEdit/editors/features/TableMover.js +2 -2
  86. package/lib-mjs/tableEdit/editors/features/TableMover.js.map +1 -1
  87. package/lib-mjs/tableEdit/editors/features/TableRowColumnSelector.d.ts +42 -0
  88. package/lib-mjs/tableEdit/editors/features/TableRowColumnSelector.js +216 -0
  89. package/lib-mjs/tableEdit/editors/features/TableRowColumnSelector.js.map +1 -0
  90. package/lib-mjs/tableEdit/editors/utils/getTableFromContentModel.js +1 -0
  91. package/lib-mjs/tableEdit/editors/utils/getTableFromContentModel.js.map +1 -1
  92. package/lib-mjs/touch/TouchPlugin.js +54 -52
  93. package/lib-mjs/touch/TouchPlugin.js.map +1 -1
  94. package/package.json +6 -6
@@ -11,8 +11,12 @@ function retrieveStringFromParsedTable(tsInfo) {
11
11
  var parsedTable = tsInfo.parsedTable, firstCo = tsInfo.firstCo, lastCo = tsInfo.lastCo;
12
12
  var result = '';
13
13
  if (lastCo) {
14
- for (var r = firstCo.row; r <= lastCo.row; r++) {
15
- for (var c = firstCo.col; c <= lastCo.col; c++) {
14
+ var firstCol = Math.min(firstCo.col, lastCo.col);
15
+ var lastCol = Math.max(firstCo.col, lastCo.col);
16
+ var firstRow = Math.min(firstCo.row, lastCo.row);
17
+ var lastRow = Math.max(firstCo.row, lastCo.row);
18
+ for (var r = firstRow; r <= lastRow; r++) {
19
+ for (var c = firstCol; c <= lastCol; c++) {
16
20
  var cell = parsedTable[r] && parsedTable[r][c];
17
21
  if (cell && typeof cell != 'string') {
18
22
  result += ' ' + cell.innerText + ',';
@@ -60,13 +64,6 @@ function getIsSelectingOrUnselecting(prevTableSelection, newTableSelection) {
60
64
  // Same area but different positions
61
65
  return 'selecting';
62
66
  }
63
- if (prevFirstColumn !== newFirstColumn ||
64
- prevFirstRow !== newFirstRow ||
65
- prevLastColumn !== newLastColumn ||
66
- prevLastRow !== newLastRow) {
67
- return 'selecting';
68
- }
69
- return null;
70
67
  }
71
68
  exports.getIsSelectingOrUnselecting = getIsSelectingOrUnselecting;
72
69
  //# sourceMappingURL=tableSelectionUtils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tableSelectionUtils.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-plugins/lib/announce/tableSelectionUtils.ts"],"names":[],"mappings":";;;AAEA;;;;;GAKG;AACH,SAAgB,6BAA6B,CAAC,MAA0B;IAC5D,IAAA,WAAW,GAAsB,MAAM,YAA5B,EAAE,OAAO,GAAa,MAAM,QAAnB,EAAE,MAAM,GAAK,MAAM,OAAX,CAAY;IAChD,IAAI,MAAM,GAAG,EAAE,CAAC;IAEhB,IAAI,MAAM,EAAE;QACR,KAAK,IAAI,CAAC,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,MAAM,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE;YAC5C,KAAK,IAAI,CAAC,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,MAAM,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE;gBAC5C,IAAM,IAAI,GAAG,WAAW,CAAC,CAAC,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBACjD,IAAI,IAAI,IAAI,OAAO,IAAI,IAAI,QAAQ,EAAE;oBACjC,MAAM,IAAI,GAAG,GAAG,IAAI,CAAC,SAAS,GAAG,GAAG,CAAC;iBACxC;aACJ;SACJ;KACJ;IAED,OAAO,MAAM,CAAC;AAClB,CAAC;AAhBD,sEAgBC;AAED;;;;;;;GAOG;AACH,SAAgB,2BAA2B,CACvC,kBAAyC,EACzC,iBAAiC;IAEjC,IAAI,CAAC,kBAAkB,EAAE;QACrB,OAAO,WAAW,CAAC;KACtB;IAGG,IAAU,YAAY,GAItB,kBAAkB,SAJI,EACb,WAAW,GAGpB,kBAAkB,QAHE,EACP,eAAe,GAE5B,kBAAkB,YAFU,EAChB,cAAc,GAC1B,kBAAkB,WADQ,CACP;IAGnB,IAAU,WAAW,GAIrB,iBAAiB,SAJI,EACZ,UAAU,GAGnB,iBAAiB,QAHE,EACN,cAAc,GAE3B,iBAAiB,YAFU,EACf,aAAa,GACzB,iBAAiB,WADQ,CACP;IAEtB,IAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;IAC7D,IAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,cAAc,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;IACnE,IAAM,QAAQ,GAAG,WAAW,GAAG,WAAW,CAAC;IAE3C,IAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAC1D,IAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IAChE,IAAM,OAAO,GAAG,UAAU,GAAG,UAAU,CAAC;IAExC,oCAAoC;IACpC,IACI,YAAY,KAAK,WAAW;QAC5B,WAAW,KAAK,UAAU;QAC1B,eAAe,KAAK,cAAc;QAClC,cAAc,KAAK,aAAa,EAClC;QACE,OAAO,IAAI,CAAC;KACf;IAED,IAAI,OAAO,GAAG,QAAQ,EAAE;QACpB,OAAO,WAAW,CAAC;KACtB;SAAM,IAAI,OAAO,GAAG,QAAQ,EAAE;QAC3B,OAAO,aAAa,CAAC;KACxB;SAAM;QACH,oCAAoC;QACpC,OAAO,WAAW,CAAC;KACtB;IAED,IACI,eAAe,KAAK,cAAc;QAClC,YAAY,KAAK,WAAW;QAC5B,cAAc,KAAK,aAAa;QAChC,WAAW,KAAK,UAAU,EAC5B;QACE,OAAO,WAAW,CAAC;KACtB;IAED,OAAO,IAAI,CAAC;AAChB,CAAC;AA3DD,kEA2DC","sourcesContent":["import type { TableSelectionInfo, TableSelection } from 'roosterjs-content-model-types';\n\n/**\n * @internal\n * Retrieves text content from selected table cells in a parsed table structure\n * @param tsInfo Table selection information containing the parsed table and coordinates\n * @returns Combined text content from all selected cells, separated by spaces\n */\nexport function retrieveStringFromParsedTable(tsInfo: TableSelectionInfo): string {\n const { parsedTable, firstCo, lastCo } = tsInfo;\n let result = '';\n\n if (lastCo) {\n for (let r = firstCo.row; r <= lastCo.row; r++) {\n for (let c = firstCo.col; c <= lastCo.col; c++) {\n const cell = parsedTable[r] && parsedTable[r][c];\n if (cell && typeof cell != 'string') {\n result += ' ' + cell.innerText + ',';\n }\n }\n }\n }\n\n return result;\n}\n\n/**\n * @internal\n * Determines whether the table selection is expanding (selecting more) or contracting (selecting less)\n * @param prevTableSelection Previous table selection object containing firstRow, lastRow, firstColumn, and lastColumn properties\n * @param firstCo Current first coordinate of the selection (with row, col properties)\n * @param lastCo Current last coordinate of the selection (with row, col properties)\n * @returns 'selecting' if expanding selection, 'unselecting' if contracting, or null if no change\n */\nexport function getIsSelectingOrUnselecting(\n prevTableSelection: TableSelection | null,\n newTableSelection: TableSelection\n): 'selecting' | 'unselecting' | null {\n if (!prevTableSelection) {\n return 'selecting';\n }\n\n const {\n firstRow: prevFirstRow,\n lastRow: prevLastRow,\n firstColumn: prevFirstColumn,\n lastColumn: prevLastColumn,\n } = prevTableSelection;\n\n const {\n firstRow: newFirstRow,\n lastRow: newLastRow,\n firstColumn: newFirstColumn,\n lastColumn: newLastColumn,\n } = newTableSelection;\n\n const prevRowSpan = Math.abs(prevLastRow - prevFirstRow) + 1;\n const prevColSpan = Math.abs(prevLastColumn - prevFirstColumn) + 1;\n const prevArea = prevRowSpan * prevColSpan;\n\n const newRowSpan = Math.abs(newLastRow - newFirstRow) + 1;\n const newColSpan = Math.abs(newLastColumn - newFirstColumn) + 1;\n const newArea = newRowSpan * newColSpan;\n\n // Check if selections are identical\n if (\n prevFirstRow === newFirstRow &&\n prevLastRow === newLastRow &&\n prevFirstColumn === newFirstColumn &&\n prevLastColumn === newLastColumn\n ) {\n return null;\n }\n\n if (newArea > prevArea) {\n return 'selecting';\n } else if (newArea < prevArea) {\n return 'unselecting';\n } else {\n // Same area but different positions\n return 'selecting';\n }\n\n if (\n prevFirstColumn !== newFirstColumn ||\n prevFirstRow !== newFirstRow ||\n prevLastColumn !== newLastColumn ||\n prevLastRow !== newLastRow\n ) {\n return 'selecting';\n }\n\n return null;\n}\n"]}
1
+ {"version":3,"file":"tableSelectionUtils.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-plugins/lib/announce/tableSelectionUtils.ts"],"names":[],"mappings":";;;AAEA;;;;;GAKG;AACH,SAAgB,6BAA6B,CAAC,MAA0B;IAC5D,IAAA,WAAW,GAAsB,MAAM,YAA5B,EAAE,OAAO,GAAa,MAAM,QAAnB,EAAE,MAAM,GAAK,MAAM,OAAX,CAAY;IAChD,IAAI,MAAM,GAAG,EAAE,CAAC;IAEhB,IAAI,MAAM,EAAE;QACR,IAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;QACnD,IAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;QAClD,IAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;QACnD,IAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;QAElD,KAAK,IAAI,CAAC,GAAG,QAAQ,EAAE,CAAC,IAAI,OAAO,EAAE,CAAC,EAAE,EAAE;YACtC,KAAK,IAAI,CAAC,GAAG,QAAQ,EAAE,CAAC,IAAI,OAAO,EAAE,CAAC,EAAE,EAAE;gBACtC,IAAM,IAAI,GAAG,WAAW,CAAC,CAAC,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBACjD,IAAI,IAAI,IAAI,OAAO,IAAI,IAAI,QAAQ,EAAE;oBACjC,MAAM,IAAI,GAAG,GAAG,IAAI,CAAC,SAAS,GAAG,GAAG,CAAC;iBACxC;aACJ;SACJ;KACJ;IAED,OAAO,MAAM,CAAC;AAClB,CAAC;AArBD,sEAqBC;AAED;;;;;;;GAOG;AACH,SAAgB,2BAA2B,CACvC,kBAAyC,EACzC,iBAAiC;IAEjC,IAAI,CAAC,kBAAkB,EAAE;QACrB,OAAO,WAAW,CAAC;KACtB;IAGG,IAAU,YAAY,GAItB,kBAAkB,SAJI,EACb,WAAW,GAGpB,kBAAkB,QAHE,EACP,eAAe,GAE5B,kBAAkB,YAFU,EAChB,cAAc,GAC1B,kBAAkB,WADQ,CACP;IAGnB,IAAU,WAAW,GAIrB,iBAAiB,SAJI,EACZ,UAAU,GAGnB,iBAAiB,QAHE,EACN,cAAc,GAE3B,iBAAiB,YAFU,EACf,aAAa,GACzB,iBAAiB,WADQ,CACP;IAEtB,IAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;IAC7D,IAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,cAAc,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;IACnE,IAAM,QAAQ,GAAG,WAAW,GAAG,WAAW,CAAC;IAE3C,IAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAC1D,IAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IAChE,IAAM,OAAO,GAAG,UAAU,GAAG,UAAU,CAAC;IAExC,oCAAoC;IACpC,IACI,YAAY,KAAK,WAAW;QAC5B,WAAW,KAAK,UAAU;QAC1B,eAAe,KAAK,cAAc;QAClC,cAAc,KAAK,aAAa,EAClC;QACE,OAAO,IAAI,CAAC;KACf;IAED,IAAI,OAAO,GAAG,QAAQ,EAAE;QACpB,OAAO,WAAW,CAAC;KACtB;SAAM,IAAI,OAAO,GAAG,QAAQ,EAAE;QAC3B,OAAO,aAAa,CAAC;KACxB;SAAM;QACH,oCAAoC;QACpC,OAAO,WAAW,CAAC;KACtB;AACL,CAAC;AAhDD,kEAgDC","sourcesContent":["import type { TableSelectionInfo, TableSelection } from 'roosterjs-content-model-types';\n\n/**\n * @internal\n * Retrieves text content from selected table cells in a parsed table structure\n * @param tsInfo Table selection information containing the parsed table and coordinates\n * @returns Combined text content from all selected cells, separated by spaces\n */\nexport function retrieveStringFromParsedTable(tsInfo: TableSelectionInfo): string {\n const { parsedTable, firstCo, lastCo } = tsInfo;\n let result = '';\n\n if (lastCo) {\n const firstCol = Math.min(firstCo.col, lastCo.col);\n const lastCol = Math.max(firstCo.col, lastCo.col);\n const firstRow = Math.min(firstCo.row, lastCo.row);\n const lastRow = Math.max(firstCo.row, lastCo.row);\n\n for (let r = firstRow; r <= lastRow; r++) {\n for (let c = firstCol; c <= lastCol; c++) {\n const cell = parsedTable[r] && parsedTable[r][c];\n if (cell && typeof cell != 'string') {\n result += ' ' + cell.innerText + ',';\n }\n }\n }\n }\n\n return result;\n}\n\n/**\n * @internal\n * Determines whether the table selection is expanding (selecting more) or contracting (selecting less)\n * @param prevTableSelection Previous table selection object containing firstRow, lastRow, firstColumn, and lastColumn properties\n * @param firstCo Current first coordinate of the selection (with row, col properties)\n * @param lastCo Current last coordinate of the selection (with row, col properties)\n * @returns 'selecting' if expanding selection, 'unselecting' if contracting, or null if no change\n */\nexport function getIsSelectingOrUnselecting(\n prevTableSelection: TableSelection | null,\n newTableSelection: TableSelection\n): 'selecting' | 'unselecting' | null {\n if (!prevTableSelection) {\n return 'selecting';\n }\n\n const {\n firstRow: prevFirstRow,\n lastRow: prevLastRow,\n firstColumn: prevFirstColumn,\n lastColumn: prevLastColumn,\n } = prevTableSelection;\n\n const {\n firstRow: newFirstRow,\n lastRow: newLastRow,\n firstColumn: newFirstColumn,\n lastColumn: newLastColumn,\n } = newTableSelection;\n\n const prevRowSpan = Math.abs(prevLastRow - prevFirstRow) + 1;\n const prevColSpan = Math.abs(prevLastColumn - prevFirstColumn) + 1;\n const prevArea = prevRowSpan * prevColSpan;\n\n const newRowSpan = Math.abs(newLastRow - newFirstRow) + 1;\n const newColSpan = Math.abs(newLastColumn - newFirstColumn) + 1;\n const newArea = newRowSpan * newColSpan;\n\n // Check if selections are identical\n if (\n prevFirstRow === newFirstRow &&\n prevLastRow === newLastRow &&\n prevFirstColumn === newFirstColumn &&\n prevLastColumn === newLastColumn\n ) {\n return null;\n }\n\n if (newArea > prevArea) {\n return 'selecting';\n } else if (newArea < prevArea) {\n return 'unselecting';\n } else {\n // Same area but different positions\n return 'selecting';\n }\n}\n"]}
@@ -60,8 +60,8 @@ var AutoFormatPlugin = /** @class */ (function () {
60
60
  autoTel: autoTel,
61
61
  autoMailto: autoMailto,
62
62
  });
63
- if (linkSegment) {
64
- return createAnchor(((_a = linkSegment.link) === null || _a === void 0 ? void 0 : _a.format.href) || '', linkSegment.text);
63
+ if (linkSegment && _this.editor) {
64
+ return createAnchor(_this.editor.getDocument(), ((_a = linkSegment.link) === null || _a === void 0 ? void 0 : _a.format.href) || '', linkSegment.text);
65
65
  }
66
66
  return false;
67
67
  },
@@ -290,8 +290,8 @@ var AutoFormatPlugin = /** @class */ (function () {
290
290
  return AutoFormatPlugin;
291
291
  }());
292
292
  exports.AutoFormatPlugin = AutoFormatPlugin;
293
- var createAnchor = function (url, text) {
294
- var anchor = document.createElement('a');
293
+ var createAnchor = function (doc, url, text) {
294
+ var anchor = doc.createElement('a');
295
295
  anchor.href = url;
296
296
  anchor.textContent = text;
297
297
  return anchor;
@@ -1 +1 @@
1
- {"version":3,"file":"AutoFormatPlugin.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-plugins/lib/autoFormat/AutoFormatPlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { ChangeSource } from 'roosterjs-content-model-dom';\nimport { checkAndInsertHorizontalLine } from './horizontalLine/checkAndInsertHorizontalLine';\nimport { createLink } from './link/createLink';\nimport { getListTypeStyle } from './list/getListTypeStyle';\nimport { keyboardListTrigger } from './list/keyboardListTrigger';\nimport { transformFraction } from './numbers/transformFraction';\nimport { transformHyphen } from './hyphen/transformHyphen';\nimport { transformOrdinals } from './numbers/transformOrdinals';\nimport { unlink } from './link/unlink';\nimport {\n formatTextSegmentBeforeSelectionMarker,\n promoteLink,\n getPromoteLink,\n} from 'roosterjs-content-model-api';\nimport type { AutoFormatOptions } from './interface/AutoFormatOptions';\nimport type {\n ContentChangedEvent,\n ContentModelText,\n EditorInputEvent,\n EditorPlugin,\n FormatContentModelContext,\n FormatContentModelOptions,\n IEditor,\n KeyDownEvent,\n PluginEvent,\n ReadonlyContentModelDocument,\n ShallowMutableContentModelParagraph,\n} from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\ninterface Feature {\n enabled: boolean;\n transformFunction: (\n model: ReadonlyContentModelDocument,\n previousSegment: ContentModelText,\n paragraph: ShallowMutableContentModelParagraph,\n context: FormatContentModelContext\n ) => boolean | HTMLElement;\n changeSource: string;\n apiName: string;\n}\n\n/**\n * @internal\n */\nconst DefaultOptions: Partial<AutoFormatOptions> = {\n autoBullet: false,\n autoNumbering: false,\n autoUnlink: false,\n autoLink: false,\n autoHyphen: false,\n autoFraction: false,\n autoOrdinals: false,\n removeListMargins: false,\n autoHorizontalLine: false,\n};\n\n/**\n * Auto Format plugin handles auto formatting, such as transforming * characters into a bullet list.\n * It can be customized with options to enable or disable auto list features.\n */\nexport class AutoFormatPlugin implements EditorPlugin {\n private editor: IEditor | null = null;\n /**\n * @param options An optional parameter that takes in an object of type AutoFormatOptions, which includes the following properties:\n * - autoBullet: A boolean that enables or disables automatic bullet list formatting. Defaults to false.\n * - autoNumbering: A boolean that enables or disables automatic numbering formatting. Defaults to false.\n * - removeListMargins: A boolean to remove list margins when it is automatically triggered. Defaults to false.\n * - autoHyphen: A boolean that enables or disables automatic hyphen transformation. Defaults to false.\n * - autoFraction: A boolean that enables or disables automatic fraction transformation. Defaults to false.\n * - autoOrdinals: A boolean that enables or disables automatic ordinal number transformation. Defaults to false.\n * - autoLink: A boolean that enables or disables automatic hyperlink url address creation when pasting or typing content. Defaults to false.\n * - autoUnlink: A boolean that enables or disables automatic hyperlink removal when pressing backspace. Defaults to false.\n * - autoTel: A boolean that enables or disables automatic hyperlink telephone numbers transformation. Defaults to false.\n * - autoMailto: A boolean that enables or disables automatic hyperlink email address transformation. Defaults to false.\n * - autoHorizontalLine: A boolean that enables or disables automatic horizontal line creation. Defaults to false.\n */\n constructor(private options: AutoFormatOptions = DefaultOptions) {}\n\n /**\n * Get name of this plugin\n */\n getName() {\n return 'AutoFormat';\n }\n\n /**\n * The first method that editor will call to a plugin when editor is initializing.\n * It will pass in the editor instance, plugin should take this chance to save the\n * editor reference so that it can call to any editor method or format API later.\n * @param editor The editor object\n */\n initialize(editor: IEditor) {\n this.editor = editor;\n }\n\n /**\n * The last method that editor will call to a plugin before it is disposed.\n * Plugin can take this chance to clear the reference to editor. After this method is\n * called, plugin should not call to any editor method since it will result in error.\n */\n dispose() {\n this.editor = null;\n }\n\n private shouldHandleInputEventExclusively(editor: IEditor, event: EditorInputEvent) {\n const rawEvent = event.rawEvent;\n const selection = editor.getDOMSelection();\n let shouldHandle = false;\n if (\n rawEvent.inputType === 'insertText' &&\n selection &&\n selection.type === 'range' &&\n selection.range.collapsed &&\n rawEvent.data == ' '\n ) {\n const { autoLink, autoTel, autoMailto, autoBullet, autoNumbering } = this.options;\n\n formatTextSegmentBeforeSelectionMarker(\n editor,\n (model, previousSegment, _paragraph, _markerFormat) => {\n const list = getListTypeStyle(model, autoBullet, autoNumbering);\n const promotedLink = getPromoteLink(previousSegment, {\n autoLink,\n autoTel,\n autoMailto,\n });\n shouldHandle = !!promotedLink || !!list;\n\n return false;\n }\n );\n }\n return shouldHandle;\n }\n\n willHandleEventExclusively(event: PluginEvent) {\n if (this.editor) {\n switch (event.eventType) {\n case 'input':\n return this.shouldHandleInputEventExclusively(this.editor, event);\n }\n }\n return false;\n }\n\n /**\n * Core method for a plugin. Once an event happens in editor, editor will call this\n * method of each plugin to handle the event as long as the event is not handled\n * exclusively by another plugin.\n * @param event The event to handle:\n */\n onPluginEvent(event: PluginEvent) {\n if (this.editor) {\n switch (event.eventType) {\n case 'input':\n this.handleEditorInputEvent(this.editor, event);\n break;\n case 'keyDown':\n this.handleKeyDownEvent(this.editor, event);\n break;\n case 'contentChanged':\n this.handleContentChangedEvent(this.editor, event);\n break;\n }\n }\n }\n\n private autoLink: Feature = {\n enabled: !!(this.options.autoLink || this.options.autoTel || this.options.autoMailto),\n transformFunction: (_model, previousSegment, paragraph, context) => {\n const { autoLink, autoTel, autoMailto } = this.options;\n const linkSegment = promoteLink(previousSegment, paragraph, {\n autoLink,\n autoTel,\n autoMailto,\n });\n\n if (linkSegment) {\n return createAnchor(linkSegment.link?.format.href || '', linkSegment.text);\n }\n return false;\n },\n apiName: 'autoLink',\n changeSource: ChangeSource.AutoLink,\n };\n\n private tabFeatures: Feature[] = [\n {\n enabled: !!(this.options.autoBullet || this.options.autoNumbering),\n transformFunction: (model, _previousSegment, paragraph, context) =>\n keyboardListTrigger(\n model,\n paragraph,\n context,\n this.options.autoBullet,\n this.options.autoNumbering,\n this.options.removeListMargins\n ),\n apiName: 'autoToggleList',\n changeSource: ChangeSource.AutoFormat,\n },\n this.autoLink,\n ];\n\n private features: Feature[] = [\n ...this.tabFeatures,\n {\n enabled: !!this.options.autoHyphen,\n apiName: 'autoHyphen',\n changeSource: ChangeSource.Format,\n transformFunction: (_model, previousSegment, paragraph, context) =>\n transformHyphen(previousSegment, paragraph, context),\n },\n {\n enabled: !!this.options.autoFraction,\n apiName: 'autoFraction',\n changeSource: ChangeSource.Format,\n transformFunction: (_model, previousSegment, paragraph, context) =>\n transformFraction(previousSegment, paragraph, context),\n },\n {\n enabled: !!this.options.autoOrdinals,\n apiName: 'autoOrdinal',\n changeSource: ChangeSource.Format,\n transformFunction: (_model, previousSegment, paragraph, context) =>\n transformOrdinals(previousSegment, paragraph, context),\n },\n ];\n\n private enterFeatures: Feature[] = [\n {\n enabled: !!this.options.autoHorizontalLine,\n transformFunction: (model, _previousSegment, paragraph, context) =>\n checkAndInsertHorizontalLine(model, paragraph, context),\n apiName: 'autoHorizontalLine',\n changeSource: ChangeSource.AutoFormat,\n },\n this.autoLink,\n ];\n\n private handleKeyboardEvents(editor: IEditor, features: Feature[]): FormatContentModelOptions {\n const formatOptions: FormatContentModelOptions = {\n changeSource: '',\n apiName: '',\n getChangeData: undefined,\n };\n\n formatTextSegmentBeforeSelectionMarker(\n editor,\n (model, previousSegment, paragraph, _markerFormat, context) => {\n let featureApplied: Feature | undefined = undefined;\n for (const feature of features) {\n if (feature.enabled) {\n const result = feature.transformFunction(\n model,\n previousSegment,\n paragraph,\n context\n );\n\n if (result) {\n if (typeof result !== 'boolean') {\n formatOptions.getChangeData = () => result;\n }\n featureApplied = feature;\n break;\n }\n }\n }\n\n if (featureApplied) {\n formatOptions.changeSource = featureApplied.changeSource;\n formatOptions.apiName = featureApplied.apiName;\n }\n\n return !!featureApplied;\n },\n formatOptions\n );\n return formatOptions;\n }\n\n private handleEditorInputEvent(editor: IEditor, event: EditorInputEvent) {\n const rawEvent = event.rawEvent;\n const selection = editor.getDOMSelection();\n if (\n rawEvent.inputType === 'insertText' &&\n selection &&\n selection.type === 'range' &&\n selection.range.collapsed\n ) {\n switch (rawEvent.data) {\n case ' ':\n this.handleKeyboardEvents(editor, this.features);\n break;\n }\n }\n }\n\n private handleKeyDownEvent(editor: IEditor, event: KeyDownEvent) {\n const rawEvent = event.rawEvent;\n if (!rawEvent.defaultPrevented && !event.handledByEditFeature) {\n switch (rawEvent.key) {\n case 'Backspace':\n if (this.options.autoUnlink) {\n unlink(editor, rawEvent);\n }\n break;\n case 'Tab':\n if (!rawEvent.shiftKey) {\n const eventHandled = this.handleKeyboardEvents(editor, this.tabFeatures);\n if (eventHandled.apiName == 'autoToggleList') {\n event.rawEvent.preventDefault();\n }\n }\n break;\n case 'Enter':\n const eventHandled = this.handleKeyboardEvents(editor, this.enterFeatures);\n if (eventHandled.apiName == 'autoHorizontalLine') {\n event.rawEvent.preventDefault();\n }\n break;\n }\n }\n }\n\n private handleContentChangedEvent(editor: IEditor, event: ContentChangedEvent) {\n const { autoLink, autoTel, autoMailto } = this.options;\n if (event.source == 'Paste' && (autoLink || autoTel || autoMailto)) {\n createLink(editor, {\n autoLink,\n autoTel,\n autoMailto,\n });\n }\n }\n}\n\nconst createAnchor = (url: string, text: string) => {\n const anchor = document.createElement('a');\n anchor.href = url;\n anchor.textContent = text;\n return anchor;\n};\n"]}
1
+ {"version":3,"file":"AutoFormatPlugin.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-plugins/lib/autoFormat/AutoFormatPlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { ChangeSource } from 'roosterjs-content-model-dom';\nimport { checkAndInsertHorizontalLine } from './horizontalLine/checkAndInsertHorizontalLine';\nimport { createLink } from './link/createLink';\nimport { getListTypeStyle } from './list/getListTypeStyle';\nimport { keyboardListTrigger } from './list/keyboardListTrigger';\nimport { transformFraction } from './numbers/transformFraction';\nimport { transformHyphen } from './hyphen/transformHyphen';\nimport { transformOrdinals } from './numbers/transformOrdinals';\nimport { unlink } from './link/unlink';\nimport {\n formatTextSegmentBeforeSelectionMarker,\n promoteLink,\n getPromoteLink,\n} from 'roosterjs-content-model-api';\nimport type { AutoFormatOptions } from './interface/AutoFormatOptions';\nimport type {\n ContentChangedEvent,\n ContentModelText,\n EditorInputEvent,\n EditorPlugin,\n FormatContentModelContext,\n FormatContentModelOptions,\n IEditor,\n KeyDownEvent,\n PluginEvent,\n ReadonlyContentModelDocument,\n ShallowMutableContentModelParagraph,\n} from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\ninterface Feature {\n enabled: boolean;\n transformFunction: (\n model: ReadonlyContentModelDocument,\n previousSegment: ContentModelText,\n paragraph: ShallowMutableContentModelParagraph,\n context: FormatContentModelContext\n ) => boolean | HTMLElement;\n changeSource: string;\n apiName: string;\n}\n\n/**\n * @internal\n */\nconst DefaultOptions: Partial<AutoFormatOptions> = {\n autoBullet: false,\n autoNumbering: false,\n autoUnlink: false,\n autoLink: false,\n autoHyphen: false,\n autoFraction: false,\n autoOrdinals: false,\n removeListMargins: false,\n autoHorizontalLine: false,\n};\n\n/**\n * Auto Format plugin handles auto formatting, such as transforming * characters into a bullet list.\n * It can be customized with options to enable or disable auto list features.\n */\nexport class AutoFormatPlugin implements EditorPlugin {\n private editor: IEditor | null = null;\n /**\n * @param options An optional parameter that takes in an object of type AutoFormatOptions, which includes the following properties:\n * - autoBullet: A boolean that enables or disables automatic bullet list formatting. Defaults to false.\n * - autoNumbering: A boolean that enables or disables automatic numbering formatting. Defaults to false.\n * - removeListMargins: A boolean to remove list margins when it is automatically triggered. Defaults to false.\n * - autoHyphen: A boolean that enables or disables automatic hyphen transformation. Defaults to false.\n * - autoFraction: A boolean that enables or disables automatic fraction transformation. Defaults to false.\n * - autoOrdinals: A boolean that enables or disables automatic ordinal number transformation. Defaults to false.\n * - autoLink: A boolean that enables or disables automatic hyperlink url address creation when pasting or typing content. Defaults to false.\n * - autoUnlink: A boolean that enables or disables automatic hyperlink removal when pressing backspace. Defaults to false.\n * - autoTel: A boolean that enables or disables automatic hyperlink telephone numbers transformation. Defaults to false.\n * - autoMailto: A boolean that enables or disables automatic hyperlink email address transformation. Defaults to false.\n * - autoHorizontalLine: A boolean that enables or disables automatic horizontal line creation. Defaults to false.\n */\n constructor(private options: AutoFormatOptions = DefaultOptions) {}\n\n /**\n * Get name of this plugin\n */\n getName() {\n return 'AutoFormat';\n }\n\n /**\n * The first method that editor will call to a plugin when editor is initializing.\n * It will pass in the editor instance, plugin should take this chance to save the\n * editor reference so that it can call to any editor method or format API later.\n * @param editor The editor object\n */\n initialize(editor: IEditor) {\n this.editor = editor;\n }\n\n /**\n * The last method that editor will call to a plugin before it is disposed.\n * Plugin can take this chance to clear the reference to editor. After this method is\n * called, plugin should not call to any editor method since it will result in error.\n */\n dispose() {\n this.editor = null;\n }\n\n private shouldHandleInputEventExclusively(editor: IEditor, event: EditorInputEvent) {\n const rawEvent = event.rawEvent;\n const selection = editor.getDOMSelection();\n let shouldHandle = false;\n if (\n rawEvent.inputType === 'insertText' &&\n selection &&\n selection.type === 'range' &&\n selection.range.collapsed &&\n rawEvent.data == ' '\n ) {\n const { autoLink, autoTel, autoMailto, autoBullet, autoNumbering } = this.options;\n\n formatTextSegmentBeforeSelectionMarker(\n editor,\n (model, previousSegment, _paragraph, _markerFormat) => {\n const list = getListTypeStyle(model, autoBullet, autoNumbering);\n const promotedLink = getPromoteLink(previousSegment, {\n autoLink,\n autoTel,\n autoMailto,\n });\n shouldHandle = !!promotedLink || !!list;\n\n return false;\n }\n );\n }\n return shouldHandle;\n }\n\n willHandleEventExclusively(event: PluginEvent) {\n if (this.editor) {\n switch (event.eventType) {\n case 'input':\n return this.shouldHandleInputEventExclusively(this.editor, event);\n }\n }\n return false;\n }\n\n /**\n * Core method for a plugin. Once an event happens in editor, editor will call this\n * method of each plugin to handle the event as long as the event is not handled\n * exclusively by another plugin.\n * @param event The event to handle:\n */\n onPluginEvent(event: PluginEvent) {\n if (this.editor) {\n switch (event.eventType) {\n case 'input':\n this.handleEditorInputEvent(this.editor, event);\n break;\n case 'keyDown':\n this.handleKeyDownEvent(this.editor, event);\n break;\n case 'contentChanged':\n this.handleContentChangedEvent(this.editor, event);\n break;\n }\n }\n }\n\n private autoLink: Feature = {\n enabled: !!(this.options.autoLink || this.options.autoTel || this.options.autoMailto),\n transformFunction: (_model, previousSegment, paragraph, context) => {\n const { autoLink, autoTel, autoMailto } = this.options;\n const linkSegment = promoteLink(previousSegment, paragraph, {\n autoLink,\n autoTel,\n autoMailto,\n });\n\n if (linkSegment && this.editor) {\n return createAnchor(\n this.editor.getDocument(),\n linkSegment.link?.format.href || '',\n linkSegment.text\n );\n }\n return false;\n },\n apiName: 'autoLink',\n changeSource: ChangeSource.AutoLink,\n };\n\n private tabFeatures: Feature[] = [\n {\n enabled: !!(this.options.autoBullet || this.options.autoNumbering),\n transformFunction: (model, _previousSegment, paragraph, context) =>\n keyboardListTrigger(\n model,\n paragraph,\n context,\n this.options.autoBullet,\n this.options.autoNumbering,\n this.options.removeListMargins\n ),\n apiName: 'autoToggleList',\n changeSource: ChangeSource.AutoFormat,\n },\n this.autoLink,\n ];\n\n private features: Feature[] = [\n ...this.tabFeatures,\n {\n enabled: !!this.options.autoHyphen,\n apiName: 'autoHyphen',\n changeSource: ChangeSource.Format,\n transformFunction: (_model, previousSegment, paragraph, context) =>\n transformHyphen(previousSegment, paragraph, context),\n },\n {\n enabled: !!this.options.autoFraction,\n apiName: 'autoFraction',\n changeSource: ChangeSource.Format,\n transformFunction: (_model, previousSegment, paragraph, context) =>\n transformFraction(previousSegment, paragraph, context),\n },\n {\n enabled: !!this.options.autoOrdinals,\n apiName: 'autoOrdinal',\n changeSource: ChangeSource.Format,\n transformFunction: (_model, previousSegment, paragraph, context) =>\n transformOrdinals(previousSegment, paragraph, context),\n },\n ];\n\n private enterFeatures: Feature[] = [\n {\n enabled: !!this.options.autoHorizontalLine,\n transformFunction: (model, _previousSegment, paragraph, context) =>\n checkAndInsertHorizontalLine(model, paragraph, context),\n apiName: 'autoHorizontalLine',\n changeSource: ChangeSource.AutoFormat,\n },\n this.autoLink,\n ];\n\n private handleKeyboardEvents(editor: IEditor, features: Feature[]): FormatContentModelOptions {\n const formatOptions: FormatContentModelOptions = {\n changeSource: '',\n apiName: '',\n getChangeData: undefined,\n };\n\n formatTextSegmentBeforeSelectionMarker(\n editor,\n (model, previousSegment, paragraph, _markerFormat, context) => {\n let featureApplied: Feature | undefined = undefined;\n for (const feature of features) {\n if (feature.enabled) {\n const result = feature.transformFunction(\n model,\n previousSegment,\n paragraph,\n context\n );\n\n if (result) {\n if (typeof result !== 'boolean') {\n formatOptions.getChangeData = () => result;\n }\n featureApplied = feature;\n break;\n }\n }\n }\n\n if (featureApplied) {\n formatOptions.changeSource = featureApplied.changeSource;\n formatOptions.apiName = featureApplied.apiName;\n }\n\n return !!featureApplied;\n },\n formatOptions\n );\n return formatOptions;\n }\n\n private handleEditorInputEvent(editor: IEditor, event: EditorInputEvent) {\n const rawEvent = event.rawEvent;\n const selection = editor.getDOMSelection();\n if (\n rawEvent.inputType === 'insertText' &&\n selection &&\n selection.type === 'range' &&\n selection.range.collapsed\n ) {\n switch (rawEvent.data) {\n case ' ':\n this.handleKeyboardEvents(editor, this.features);\n break;\n }\n }\n }\n\n private handleKeyDownEvent(editor: IEditor, event: KeyDownEvent) {\n const rawEvent = event.rawEvent;\n if (!rawEvent.defaultPrevented && !event.handledByEditFeature) {\n switch (rawEvent.key) {\n case 'Backspace':\n if (this.options.autoUnlink) {\n unlink(editor, rawEvent);\n }\n break;\n case 'Tab':\n if (!rawEvent.shiftKey) {\n const eventHandled = this.handleKeyboardEvents(editor, this.tabFeatures);\n if (eventHandled.apiName == 'autoToggleList') {\n event.rawEvent.preventDefault();\n }\n }\n break;\n case 'Enter':\n const eventHandled = this.handleKeyboardEvents(editor, this.enterFeatures);\n if (eventHandled.apiName == 'autoHorizontalLine') {\n event.rawEvent.preventDefault();\n }\n break;\n }\n }\n }\n\n private handleContentChangedEvent(editor: IEditor, event: ContentChangedEvent) {\n const { autoLink, autoTel, autoMailto } = this.options;\n if (event.source == 'Paste' && (autoLink || autoTel || autoMailto)) {\n createLink(editor, {\n autoLink,\n autoTel,\n autoMailto,\n });\n }\n }\n}\n\nconst createAnchor = (doc: Document, url: string, text: string) => {\n const anchor = doc.createElement('a');\n anchor.href = url;\n anchor.textContent = text;\n return anchor;\n};\n"]}
@@ -29,7 +29,8 @@ var ORDINAL_LENGTH = 2;
29
29
  var numericValue = null;
30
30
  if (numberSegment &&
31
31
  numberSegment.segmentType == 'Text' &&
32
- (numericValue = getNumericValue(numberSegment.text, true /* checkFullText */)) &&
32
+ (numericValue = getNumericValue(numberSegment.text, true /* checkFullText */)) !==
33
+ null &&
33
34
  getOrdinal(numericValue) === value) {
34
35
  shouldAddSuperScript = true;
35
36
  }
@@ -37,7 +38,7 @@ var ORDINAL_LENGTH = 2;
37
38
  else {
38
39
  var ordinal = value.substring(value.length - ORDINAL_LENGTH); // This value is equal st, nd, rd, th
39
40
  var numericValue = getNumericValue(value); //This is the numeric part. Ex: 10th, numeric value =
40
- if (numericValue && getOrdinal(numericValue) === ordinal) {
41
+ if (numericValue !== null && getOrdinal(numericValue) === ordinal) {
41
42
  shouldAddSuperScript = true;
42
43
  }
43
44
  }
@@ -1 +1 @@
1
- {"version":3,"file":"transformOrdinals.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/autoFormat/numbers/transformOrdinals.ts"],"names":[],"mappings":"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","sourcesContent":["import { splitTextSegment } from 'roosterjs-content-model-api';\n\nimport type {\n ContentModelText,\n FormatContentModelContext,\n ShallowMutableContentModelParagraph,\n} from 'roosterjs-content-model-types';\n\nconst getOrdinal = (value: number) => {\n const ORDINALS: Record<number, string> = {\n 1: 'st',\n 2: 'nd',\n 3: 'rd',\n };\n return ORDINALS[value] || 'th';\n};\n\nconst ORDINALS = ['st', 'nd', 'rd', 'th'];\n\n/**\n * The two last characters of ordinal number (st, nd, rd, th)\n */\nconst ORDINAL_LENGTH = 2;\n\n/**\n * @internal\n */ export function transformOrdinals(\n previousSegment: ContentModelText,\n paragraph: ShallowMutableContentModelParagraph,\n context: FormatContentModelContext\n): boolean {\n const value = previousSegment.text.split(' ').pop()?.trim();\n let shouldAddSuperScript = false;\n if (value) {\n const isOrdinal = ORDINALS.indexOf(value) > -1;\n if (isOrdinal) {\n const index = paragraph.segments.indexOf(previousSegment);\n const numberSegment = paragraph.segments[index - 1];\n let numericValue: number | null = null;\n if (\n numberSegment &&\n numberSegment.segmentType == 'Text' &&\n (numericValue = getNumericValue(numberSegment.text, true /* checkFullText */)) &&\n getOrdinal(numericValue) === value\n ) {\n shouldAddSuperScript = true;\n }\n } else {\n const ordinal = value.substring(value.length - ORDINAL_LENGTH); // This value is equal st, nd, rd, th\n const numericValue = getNumericValue(value); //This is the numeric part. Ex: 10th, numeric value =\n if (numericValue && getOrdinal(numericValue) === ordinal) {\n shouldAddSuperScript = true;\n }\n }\n\n if (shouldAddSuperScript) {\n const ordinalSegment = splitTextSegment(\n previousSegment,\n paragraph,\n previousSegment.text.length - 3,\n previousSegment.text.length - 1\n );\n\n ordinalSegment.format.superOrSubScriptSequence = 'super';\n context.canUndoByBackspace = true;\n }\n }\n return shouldAddSuperScript;\n}\n\nfunction getNumericValue(text: string, checkFullText: boolean = false): number | null {\n const number = checkFullText ? text : text.substring(0, text.length - ORDINAL_LENGTH);\n const isNumber = /^-?\\d+$/.test(number);\n if (isNumber) {\n const numericValue = parseInt(number);\n return Math.abs(numericValue) < 20\n ? numericValue\n : parseInt(number.substring(number.length - 1));\n }\n return null;\n}\n"]}
1
+ {"version":3,"file":"transformOrdinals.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/autoFormat/numbers/transformOrdinals.ts"],"names":[],"mappings":";;;AAAA,2EAA+D;AAQ/D,IAAM,UAAU,GAAG,UAAC,KAAa;IAC7B,IAAM,QAAQ,GAA2B;QACrC,CAAC,EAAE,IAAI;QACP,CAAC,EAAE,IAAI;QACP,CAAC,EAAE,IAAI;KACV,CAAC;IACF,OAAO,QAAQ,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC;AACnC,CAAC,CAAC;AAEF,IAAM,QAAQ,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAE1C;;GAEG;AACH,IAAM,cAAc,GAAG,CAAC,CAAC;AAEzB;;GAEG,CAAC,SAAgB,iBAAiB,CACjC,eAAiC,EACjC,SAA8C,EAC9C,OAAkC;;IAElC,IAAM,KAAK,GAAG,MAAA,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,0CAAE,IAAI,EAAE,CAAC;IAC5D,IAAI,oBAAoB,GAAG,KAAK,CAAC;IACjC,IAAI,KAAK,EAAE;QACP,IAAM,SAAS,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;QAC/C,IAAI,SAAS,EAAE;YACX,IAAM,KAAK,GAAG,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;YAC1D,IAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;YACpD,IAAI,YAAY,GAAkB,IAAI,CAAC;YACvC,IACI,aAAa;gBACb,aAAa,CAAC,WAAW,IAAI,MAAM;gBACnC,CAAC,YAAY,GAAG,eAAe,CAAC,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,mBAAmB,CAAC,CAAC;oBAC1E,IAAI;gBACR,UAAU,CAAC,YAAY,CAAC,KAAK,KAAK,EACpC;gBACE,oBAAoB,GAAG,IAAI,CAAC;aAC/B;SACJ;aAAM;YACH,IAAM,OAAO,GAAG,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,GAAG,cAAc,CAAC,CAAC,CAAC,sCAAsC;YACtG,IAAM,YAAY,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,qDAAqD;YAClG,IAAI,YAAY,KAAK,IAAI,IAAI,UAAU,CAAC,YAAY,CAAC,KAAK,OAAO,EAAE;gBAC/D,oBAAoB,GAAG,IAAI,CAAC;aAC/B;SACJ;QAED,IAAI,oBAAoB,EAAE;YACtB,IAAM,cAAc,GAAG,IAAA,8CAAgB,EACnC,eAAe,EACf,SAAS,EACT,eAAe,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAC/B,eAAe,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAClC,CAAC;YAEF,cAAc,CAAC,MAAM,CAAC,wBAAwB,GAAG,OAAO,CAAC;YACzD,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;SACrC;KACJ;IACD,OAAO,oBAAoB,CAAC;AAChC,CAAC;AA3CG,8CA2CH;AAED,SAAS,eAAe,CAAC,IAAY,EAAE,aAA8B;IAA9B,8BAAA,EAAA,qBAA8B;IACjE,IAAM,MAAM,GAAG,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,GAAG,cAAc,CAAC,CAAC;IACtF,IAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACxC,IAAI,QAAQ,EAAE;QACV,IAAM,YAAY,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;QACtC,OAAO,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,EAAE;YAC9B,CAAC,CAAC,YAAY;YACd,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;KACvD;IACD,OAAO,IAAI,CAAC;AAChB,CAAC","sourcesContent":["import { splitTextSegment } from 'roosterjs-content-model-api';\n\nimport type {\n ContentModelText,\n FormatContentModelContext,\n ShallowMutableContentModelParagraph,\n} from 'roosterjs-content-model-types';\n\nconst getOrdinal = (value: number) => {\n const ORDINALS: Record<number, string> = {\n 1: 'st',\n 2: 'nd',\n 3: 'rd',\n };\n return ORDINALS[value] || 'th';\n};\n\nconst ORDINALS = ['st', 'nd', 'rd', 'th'];\n\n/**\n * The two last characters of ordinal number (st, nd, rd, th)\n */\nconst ORDINAL_LENGTH = 2;\n\n/**\n * @internal\n */ export function transformOrdinals(\n previousSegment: ContentModelText,\n paragraph: ShallowMutableContentModelParagraph,\n context: FormatContentModelContext\n): boolean {\n const value = previousSegment.text.split(' ').pop()?.trim();\n let shouldAddSuperScript = false;\n if (value) {\n const isOrdinal = ORDINALS.indexOf(value) > -1;\n if (isOrdinal) {\n const index = paragraph.segments.indexOf(previousSegment);\n const numberSegment = paragraph.segments[index - 1];\n let numericValue: number | null = null;\n if (\n numberSegment &&\n numberSegment.segmentType == 'Text' &&\n (numericValue = getNumericValue(numberSegment.text, true /* checkFullText */)) !==\n null &&\n getOrdinal(numericValue) === value\n ) {\n shouldAddSuperScript = true;\n }\n } else {\n const ordinal = value.substring(value.length - ORDINAL_LENGTH); // This value is equal st, nd, rd, th\n const numericValue = getNumericValue(value); //This is the numeric part. Ex: 10th, numeric value =\n if (numericValue !== null && getOrdinal(numericValue) === ordinal) {\n shouldAddSuperScript = true;\n }\n }\n\n if (shouldAddSuperScript) {\n const ordinalSegment = splitTextSegment(\n previousSegment,\n paragraph,\n previousSegment.text.length - 3,\n previousSegment.text.length - 1\n );\n\n ordinalSegment.format.superOrSubScriptSequence = 'super';\n context.canUndoByBackspace = true;\n }\n }\n return shouldAddSuperScript;\n}\n\nfunction getNumericValue(text: string, checkFullText: boolean = false): number | null {\n const number = checkFullText ? text : text.substring(0, text.length - ORDINAL_LENGTH);\n const isNumber = /^-?\\d+$/.test(number);\n if (isNumber) {\n const numericValue = parseInt(number);\n return Math.abs(numericValue) < 20\n ? numericValue\n : parseInt(number.substring(number.length - 1));\n }\n return null;\n}\n"]}
@@ -1,25 +1,55 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.deleteList = void 0;
4
+ var tslib_1 = require("tslib");
4
5
  var roosterjs_content_model_dom_1 = require("roosterjs-content-model-dom");
5
6
  /**
6
7
  * @internal
7
8
  */
8
9
  var deleteList = function (context) {
10
+ var _a, _b;
9
11
  if (context.deleteResult != 'notDeleted') {
10
12
  return;
11
13
  }
12
- var _a = context.insertPoint, paragraph = _a.paragraph, marker = _a.marker, path = _a.path;
13
- if (paragraph.segments[0] == marker) {
14
- var index = (0, roosterjs_content_model_dom_1.getClosestAncestorBlockGroupIndex)(path, ['ListItem'], ['TableCell', 'FormatContainer']);
15
- var item = path[index];
16
- var lastLevel = item === null || item === void 0 ? void 0 : item.levels[item.levels.length - 1];
17
- if (lastLevel && (item === null || item === void 0 ? void 0 : item.blocks[0]) == paragraph) {
18
- if (lastLevel.format.displayForDummyItem == 'block') {
19
- item.levels.pop();
14
+ var _c = context.insertPoint, paragraph = _c.paragraph, marker = _c.marker, path = _c.path;
15
+ var index = (0, roosterjs_content_model_dom_1.getClosestAncestorBlockGroupIndex)(path, ['ListItem'], ['TableCell', 'FormatContainer']);
16
+ var item = path[index];
17
+ var parent = path[index + 1];
18
+ if ((item === null || item === void 0 ? void 0 : item.blockGroupType) == 'ListItem' &&
19
+ item.levels.length > 0 &&
20
+ paragraph.segments[0] == marker &&
21
+ parent) {
22
+ var mutableList = (0, roosterjs_content_model_dom_1.mutateBlock)(item);
23
+ var lastLevel = mutableList.levels[mutableList.levels.length - 1];
24
+ var listItemIndex = parent.blocks.indexOf(item);
25
+ var previousItem = parent.blocks[listItemIndex - 1];
26
+ // 1. If the last level is dummy, just remove it (legacy behavior)
27
+ // 2. If focus is at the beginning of list item and previous block is a list item with the same level count,
28
+ // merge current list item into previous one
29
+ // 3. Otherwise, split the list item. Keep the blocks before the paragraph in the current list item,
30
+ // move the rest to a new list item (if there are multiple levels) or directly to parent (if only one level)
31
+ if (lastLevel.format.displayForDummyItem == 'block') {
32
+ mutableList.levels.pop();
33
+ context.deleteResult = 'range';
34
+ }
35
+ else if (item.blocks[0] == paragraph &&
36
+ (previousItem === null || previousItem === void 0 ? void 0 : previousItem.blockType) == 'BlockGroup' &&
37
+ previousItem.blockGroupType == 'ListItem' &&
38
+ previousItem.levels.length == mutableList.levels.length) {
39
+ var mutablePreviousItem = (0, roosterjs_content_model_dom_1.mutateBlock)(previousItem);
40
+ (_a = mutablePreviousItem.blocks).push.apply(_a, (0, tslib_1.__spreadArray)([], (0, tslib_1.__read)(mutableList.blocks), false));
41
+ (0, roosterjs_content_model_dom_1.mutateBlock)(parent).blocks.splice(listItemIndex, 1);
42
+ context.deleteResult = 'range';
43
+ }
44
+ else {
45
+ var removedBlocks = mutableList.blocks.splice(mutableList.blocks.indexOf(paragraph), mutableList.blocks.length);
46
+ if (mutableList.levels.length > 1) {
47
+ var newListItem = (0, roosterjs_content_model_dom_1.createListItem)(mutableList.levels.slice(0, -1), mutableList.format);
48
+ newListItem.blocks = removedBlocks.map(function (block) { return (0, roosterjs_content_model_dom_1.mutateBlock)(block); });
49
+ (0, roosterjs_content_model_dom_1.mutateBlock)(parent).blocks.splice(listItemIndex + 1, 0, newListItem);
20
50
  }
21
51
  else {
22
- lastLevel.format.displayForDummyItem = 'block';
52
+ (_b = (0, roosterjs_content_model_dom_1.mutateBlock)(parent).blocks).splice.apply(_b, (0, tslib_1.__spreadArray)([listItemIndex + 1, 0], (0, tslib_1.__read)(removedBlocks), false));
23
53
  }
24
54
  context.deleteResult = 'range';
25
55
  }
@@ -1 +1 @@
1
- {"version":3,"file":"deleteList.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/edit/deleteSteps/deleteList.ts"],"names":[],"mappings":";;;AAAA,2EAAgF;AAGhF;;GAEG;AACI,IAAM,UAAU,GAAwB,UAAA,OAAO;IAClD,IAAI,OAAO,CAAC,YAAY,IAAI,YAAY,EAAE;QACtC,OAAO;KACV;IAEK,IAAA,KAA8B,OAAO,CAAC,WAAW,EAA/C,SAAS,eAAA,EAAE,MAAM,YAAA,EAAE,IAAI,UAAwB,CAAC;IAExD,IAAI,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,MAAM,EAAE;QACjC,IAAM,KAAK,GAAG,IAAA,+DAAiC,EAC3C,IAAI,EACJ,CAAC,UAAU,CAAC,EACZ,CAAC,WAAW,EAAE,iBAAiB,CAAC,CACnC,CAAC;QACF,IAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAqC,CAAC;QAC7D,IAAM,SAAS,GAAG,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAEvD,IAAI,SAAS,IAAI,CAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,MAAM,CAAC,CAAC,CAAC,KAAI,SAAS,EAAE;YAC3C,IAAI,SAAS,CAAC,MAAM,CAAC,mBAAmB,IAAI,OAAO,EAAE;gBACjD,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;aACrB;iBAAM;gBACH,SAAS,CAAC,MAAM,CAAC,mBAAmB,GAAG,OAAO,CAAC;aAClD;YAED,OAAO,CAAC,YAAY,GAAG,OAAO,CAAC;SAClC;KACJ;AACL,CAAC,CAAC;AA1BW,QAAA,UAAU,cA0BrB","sourcesContent":["import { getClosestAncestorBlockGroupIndex } from 'roosterjs-content-model-dom';\nimport type { DeleteSelectionStep, ContentModelListItem } from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\nexport const deleteList: DeleteSelectionStep = context => {\n if (context.deleteResult != 'notDeleted') {\n return;\n }\n\n const { paragraph, marker, path } = context.insertPoint;\n\n if (paragraph.segments[0] == marker) {\n const index = getClosestAncestorBlockGroupIndex<ContentModelListItem>(\n path,\n ['ListItem'],\n ['TableCell', 'FormatContainer']\n );\n const item = path[index] as ContentModelListItem | undefined;\n const lastLevel = item?.levels[item.levels.length - 1];\n\n if (lastLevel && item?.blocks[0] == paragraph) {\n if (lastLevel.format.displayForDummyItem == 'block') {\n item.levels.pop();\n } else {\n lastLevel.format.displayForDummyItem = 'block';\n }\n\n context.deleteResult = 'range';\n }\n }\n};\n"]}
1
+ {"version":3,"file":"deleteList.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/edit/deleteSteps/deleteList.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n createListItem,\n getClosestAncestorBlockGroupIndex,\n mutateBlock,\n} from 'roosterjs-content-model-dom';\nimport type {\n DeleteSelectionStep,\n ContentModelListItem,\n ContentModelBlock,\n} from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\nexport const deleteList: DeleteSelectionStep = context => {\n if (context.deleteResult != 'notDeleted') {\n return;\n }\n\n const { paragraph, marker, path } = context.insertPoint;\n const index = getClosestAncestorBlockGroupIndex<ContentModelListItem>(\n path,\n ['ListItem'],\n ['TableCell', 'FormatContainer']\n );\n const item = path[index];\n const parent = path[index + 1];\n\n if (\n item?.blockGroupType == 'ListItem' &&\n item.levels.length > 0 &&\n paragraph.segments[0] == marker &&\n parent\n ) {\n const mutableList = mutateBlock(item);\n const lastLevel = mutableList.levels[mutableList.levels.length - 1];\n const listItemIndex = parent.blocks.indexOf(item);\n const previousItem = parent.blocks[listItemIndex - 1];\n\n // 1. If the last level is dummy, just remove it (legacy behavior)\n // 2. If focus is at the beginning of list item and previous block is a list item with the same level count,\n // merge current list item into previous one\n // 3. Otherwise, split the list item. Keep the blocks before the paragraph in the current list item,\n // move the rest to a new list item (if there are multiple levels) or directly to parent (if only one level)\n if (lastLevel.format.displayForDummyItem == 'block') {\n mutableList.levels.pop();\n\n context.deleteResult = 'range';\n } else if (\n item.blocks[0] == paragraph &&\n previousItem?.blockType == 'BlockGroup' &&\n previousItem.blockGroupType == 'ListItem' &&\n previousItem.levels.length == mutableList.levels.length\n ) {\n const mutablePreviousItem = mutateBlock(previousItem);\n\n mutablePreviousItem.blocks.push(...mutableList.blocks);\n mutateBlock(parent).blocks.splice(listItemIndex, 1);\n\n context.deleteResult = 'range';\n } else {\n const removedBlocks = mutableList.blocks.splice(\n mutableList.blocks.indexOf(paragraph),\n mutableList.blocks.length\n );\n\n if (mutableList.levels.length > 1) {\n const newListItem = createListItem(\n mutableList.levels.slice(0, -1),\n mutableList.format\n );\n\n newListItem.blocks = removedBlocks.map(\n block => mutateBlock(block) as ContentModelBlock\n );\n\n mutateBlock(parent).blocks.splice(listItemIndex + 1, 0, newListItem);\n } else {\n mutateBlock(parent).blocks.splice(listItemIndex + 1, 0, ...removedBlocks);\n }\n\n context.deleteResult = 'range';\n }\n }\n};\n"]}
@@ -35,11 +35,12 @@ var FindReplacePlugin = /** @class */ (function () {
35
35
  * @param editor The editor object
36
36
  */
37
37
  FindReplacePlugin.prototype.initialize = function (editor) {
38
- var _a;
39
38
  this.editor = editor;
40
- var win = (_a = editor.getDocument().defaultView) !== null && _a !== void 0 ? _a : window;
41
- this.context.findHighlight.initialize(win);
42
- this.context.replaceHighlight.initialize(win);
39
+ var win = editor.getDocument().defaultView;
40
+ if (win) {
41
+ this.context.findHighlight.initialize(win);
42
+ this.context.replaceHighlight.initialize(win);
43
+ }
43
44
  this.editor.setEditorStyle(constants_1.FindHighlightRuleKey, this.findHighlightStyle, [
44
45
  constants_1.FindHighlightSelector,
45
46
  ]);
@@ -1 +1 @@
1
- {"version":3,"file":"FindReplacePlugin.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-plugins/lib/findReplace/FindReplacePlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { ChangeSource } from 'roosterjs-content-model-dom';\nimport { updateHighlight } from './utils/updateHighlight';\nimport type { FindReplaceHighlightOptions } from './types/FindReplaceHighlightOptions';\nimport {\n FindHighlightRuleKey,\n FindHighlightSelector,\n ReplaceHighlightRuleKey,\n ReplaceHighlightSelector,\n} from './utils/constants';\nimport type { EditorPlugin, IEditor, PluginEvent } from 'roosterjs-content-model-types';\nimport type { FindReplaceContext } from './types/FindReplaceContext';\n\nconst DefaultFindHighlightStyle = 'background-color: yellow;';\nconst DefaultReplaceHighlightStyle = 'background-color: orange;';\n\n/**\n * Plugin for finding and replacing text in the editor, maintain the highlights for found and replaced text\n */\nexport class FindReplacePlugin implements EditorPlugin {\n private editor: IEditor | null = null;\n private findHighlightStyle: string;\n private replaceHighlightStyle: string;\n\n /**\n * Creates a FindReplacePlugin instance\n * @param context FindReplaceContext to use. It will be disposed when plugin is being disposed.\n * @param options Options for highlighting styles\n */\n constructor(private context: FindReplaceContext, options?: FindReplaceHighlightOptions) {\n this.findHighlightStyle = options?.findHighlightStyle ?? DefaultFindHighlightStyle;\n this.replaceHighlightStyle = options?.replaceHighlightStyle ?? DefaultReplaceHighlightStyle;\n }\n\n /**\n * Get name of this plugin\n */\n getName() {\n return 'FindReplace';\n }\n\n /**\n * The first method that editor will call to a plugin when editor is initializing.\n * It will pass in the editor instance, plugin should take this chance to save the\n * editor reference so that it can call to any editor method or format API later.\n * @param editor The editor object\n */\n initialize(editor: IEditor) {\n this.editor = editor;\n\n const win = editor.getDocument().defaultView ?? window;\n\n this.context.findHighlight.initialize(win);\n this.context.replaceHighlight.initialize(win);\n\n this.editor.setEditorStyle(FindHighlightRuleKey, this.findHighlightStyle, [\n FindHighlightSelector,\n ]);\n this.editor.setEditorStyle(ReplaceHighlightRuleKey, this.replaceHighlightStyle, [\n ReplaceHighlightSelector,\n ]);\n }\n\n /**\n * The last method that editor will call to a plugin before it is disposed.\n * Plugin can take this chance to clear the reference to editor. After this method is\n * called, plugin should not call to any editor method since it will result in error.\n */\n dispose() {\n this.context.findHighlight.dispose();\n this.context.replaceHighlight.dispose();\n\n if (this.editor) {\n this.editor.setEditorStyle(FindHighlightRuleKey, null /*cssRule*/);\n this.editor.setEditorStyle(ReplaceHighlightRuleKey, null /*cssRule*/);\n\n this.editor = null;\n }\n }\n\n /**\n * Core method for a plugin. Once an event happens in editor, editor will call this\n * method of each plugin to handle the event as long as the event is not handled\n * exclusively by another plugin.\n * @param event The event to handle:\n */\n onPluginEvent(event: PluginEvent) {\n if (!this.context.text || !this.editor) {\n return;\n }\n\n switch (event.eventType) {\n case 'input':\n const selection = this.editor.getDOMSelection();\n\n if (selection?.type == 'range') {\n const block = this.editor\n .getDOMHelper()\n .findClosestBlockElement(selection.range.startContainer);\n\n updateHighlight(this.editor, this.context, [block], [block]);\n }\n\n break;\n case 'contentChanged':\n if (!event.contentModel && event.source != ChangeSource.Replace) {\n updateHighlight(this.editor, this.context);\n }\n\n break;\n\n case 'rewriteFromModel':\n updateHighlight(\n this.editor,\n this.context,\n event.addedBlockElements,\n event.removedBlockElements\n );\n\n break;\n }\n }\n}\n"]}
1
+ {"version":3,"file":"FindReplacePlugin.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-plugins/lib/findReplace/FindReplacePlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { ChangeSource } from 'roosterjs-content-model-dom';\nimport { updateHighlight } from './utils/updateHighlight';\nimport type { FindReplaceHighlightOptions } from './types/FindReplaceHighlightOptions';\nimport {\n FindHighlightRuleKey,\n FindHighlightSelector,\n ReplaceHighlightRuleKey,\n ReplaceHighlightSelector,\n} from './utils/constants';\nimport type { EditorPlugin, IEditor, PluginEvent } from 'roosterjs-content-model-types';\nimport type { FindReplaceContext } from './types/FindReplaceContext';\n\nconst DefaultFindHighlightStyle = 'background-color: yellow;';\nconst DefaultReplaceHighlightStyle = 'background-color: orange;';\n\n/**\n * Plugin for finding and replacing text in the editor, maintain the highlights for found and replaced text\n */\nexport class FindReplacePlugin implements EditorPlugin {\n private editor: IEditor | null = null;\n private findHighlightStyle: string;\n private replaceHighlightStyle: string;\n\n /**\n * Creates a FindReplacePlugin instance\n * @param context FindReplaceContext to use. It will be disposed when plugin is being disposed.\n * @param options Options for highlighting styles\n */\n constructor(private context: FindReplaceContext, options?: FindReplaceHighlightOptions) {\n this.findHighlightStyle = options?.findHighlightStyle ?? DefaultFindHighlightStyle;\n this.replaceHighlightStyle = options?.replaceHighlightStyle ?? DefaultReplaceHighlightStyle;\n }\n\n /**\n * Get name of this plugin\n */\n getName() {\n return 'FindReplace';\n }\n\n /**\n * The first method that editor will call to a plugin when editor is initializing.\n * It will pass in the editor instance, plugin should take this chance to save the\n * editor reference so that it can call to any editor method or format API later.\n * @param editor The editor object\n */\n initialize(editor: IEditor) {\n this.editor = editor;\n\n const win = editor.getDocument().defaultView;\n\n if (win) {\n this.context.findHighlight.initialize(win);\n this.context.replaceHighlight.initialize(win);\n }\n\n this.editor.setEditorStyle(FindHighlightRuleKey, this.findHighlightStyle, [\n FindHighlightSelector,\n ]);\n this.editor.setEditorStyle(ReplaceHighlightRuleKey, this.replaceHighlightStyle, [\n ReplaceHighlightSelector,\n ]);\n }\n\n /**\n * The last method that editor will call to a plugin before it is disposed.\n * Plugin can take this chance to clear the reference to editor. After this method is\n * called, plugin should not call to any editor method since it will result in error.\n */\n dispose() {\n this.context.findHighlight.dispose();\n this.context.replaceHighlight.dispose();\n\n if (this.editor) {\n this.editor.setEditorStyle(FindHighlightRuleKey, null /*cssRule*/);\n this.editor.setEditorStyle(ReplaceHighlightRuleKey, null /*cssRule*/);\n\n this.editor = null;\n }\n }\n\n /**\n * Core method for a plugin. Once an event happens in editor, editor will call this\n * method of each plugin to handle the event as long as the event is not handled\n * exclusively by another plugin.\n * @param event The event to handle:\n */\n onPluginEvent(event: PluginEvent) {\n if (!this.context.text || !this.editor) {\n return;\n }\n\n switch (event.eventType) {\n case 'input':\n const selection = this.editor.getDOMSelection();\n\n if (selection?.type == 'range') {\n const block = this.editor\n .getDOMHelper()\n .findClosestBlockElement(selection.range.startContainer);\n\n updateHighlight(this.editor, this.context, [block], [block]);\n }\n\n break;\n case 'contentChanged':\n if (!event.contentModel && event.source != ChangeSource.Replace) {\n updateHighlight(this.editor, this.context);\n }\n\n break;\n\n case 'rewriteFromModel':\n updateHighlight(\n this.editor,\n this.context,\n event.addedBlockElements,\n event.removedBlockElements\n );\n\n break;\n }\n }\n}\n"]}
@@ -30,9 +30,11 @@ function generateDataURL(image, editInfo) {
30
30
  var height = heightPx || image.clientHeight;
31
31
  var imageWidth = nWidth * (1 - left - right);
32
32
  var imageHeight = nHeight * (1 - top - bottom);
33
+ var doc = image.ownerDocument;
34
+ var win = doc.defaultView;
33
35
  // Adjust the canvas size and scaling for high display resolution
34
- var devicePixelRatio = window.devicePixelRatio || 1;
35
- var canvas = document.createElement('canvas');
36
+ var devicePixelRatio = (win === null || win === void 0 ? void 0 : win.devicePixelRatio) || 1;
37
+ var canvas = doc.createElement('canvas');
36
38
  var targetWidth = generatedImageSize.targetWidth, targetHeight = generatedImageSize.targetHeight;
37
39
  canvas.width = targetWidth * devicePixelRatio;
38
40
  canvas.height = targetHeight * devicePixelRatio;
@@ -1 +1 @@
1
- {"version":3,"file":"generateDataURL.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/imageEdit/utils/generateDataURL.ts"],"names":[],"mappings":";;;AAAA,yDAA4D;AAG5D;;;;;;;;;;GAUG;AACH,SAAgB,eAAe,CAAC,KAAuB,EAAE,QAA6B;IAClF,IAAM,kBAAkB,GAAG,IAAA,yCAAqB,EAAC,QAAQ,CAAC,CAAC;IAC3D,IAAI,CAAC,kBAAkB,EAAE;QACrB,OAAO,EAAE,CAAC;KACb;IAGG,IAAA,QAAQ,GASR,QAAQ,SATA,EACR,OAAO,GAQP,QAAQ,QARD,EACP,QAAQ,GAOR,QAAQ,SAPA,EACR,aAAa,GAMb,QAAQ,cANK,EACb,WAAW,GAKX,QAAQ,YALG,EACX,YAAY,GAIZ,QAAQ,aAJI,EACZ,UAAU,GAGV,QAAQ,WAHE,EACV,YAAY,GAEZ,QAAQ,aAFI,EACZ,aAAa,GACb,QAAQ,cADK,CACJ;IACb,IAAM,KAAK,GAAG,QAAQ,IAAI,CAAC,CAAC;IAC5B,IAAM,IAAI,GAAG,WAAW,IAAI,CAAC,CAAC;IAC9B,IAAM,KAAK,GAAG,YAAY,IAAI,CAAC,CAAC;IAChC,IAAM,GAAG,GAAG,UAAU,IAAI,CAAC,CAAC;IAC5B,IAAM,MAAM,GAAG,aAAa,IAAI,CAAC,CAAC;IAClC,IAAM,OAAO,GAAG,aAAa,IAAI,KAAK,CAAC,aAAa,CAAC;IACrD,IAAM,MAAM,GAAG,YAAY,IAAI,KAAK,CAAC,aAAa,CAAC;IACnD,IAAM,KAAK,GAAG,OAAO,IAAI,KAAK,CAAC,WAAW,CAAC;IAC3C,IAAM,MAAM,GAAG,QAAQ,IAAI,KAAK,CAAC,YAAY,CAAC;IAE9C,IAAM,UAAU,GAAG,MAAM,GAAG,CAAC,CAAC,GAAG,IAAI,GAAG,KAAK,CAAC,CAAC;IAC/C,IAAM,WAAW,GAAG,OAAO,GAAG,CAAC,CAAC,GAAG,GAAG,GAAG,MAAM,CAAC,CAAC;IAEjD,iEAAiE;IACjE,IAAM,gBAAgB,GAAG,MAAM,CAAC,gBAAgB,IAAI,CAAC,CAAC;IACtD,IAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IACxC,IAAA,WAAW,GAAmB,kBAAkB,YAArC,EAAE,YAAY,GAAK,kBAAkB,aAAvB,CAAwB;IACzD,MAAM,CAAC,KAAK,GAAG,WAAW,GAAG,gBAAgB,CAAC;IAC9C,MAAM,CAAC,MAAM,GAAG,YAAY,GAAG,gBAAgB,CAAC;IAEhD,IAAM,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IAExC,IAAI;QACA,IAAI,OAAO,EAAE;YACT,OAAO,CAAC,KAAK,CAAC,gBAAgB,EAAE,gBAAgB,CAAC,CAAC;YAClD,OAAO,CAAC,SAAS,CAAC,WAAW,GAAG,CAAC,EAAE,YAAY,GAAG,CAAC,CAAC,CAAC;YACrD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACtB,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACtF,OAAO,CAAC,SAAS,CACb,KAAK,EACL,MAAM,GAAG,IAAI,EACb,OAAO,GAAG,GAAG,EACb,UAAU,EACV,WAAW,EACX,CAAC,KAAK,GAAG,CAAC,EACV,CAAC,MAAM,GAAG,CAAC,EACX,KAAK,EACL,MAAM,CACT,CAAC;SACL;QACD,OAAO,MAAM,CAAC,SAAS,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;KAC7C;IAAC,WAAM;QACJ,OAAO,KAAK,CAAC,GAAG,CAAC;KACpB;AACL,CAAC;AA7DD,0CA6DC","sourcesContent":["import { getGeneratedImageSize } from './generateImageSize';\nimport type { ImageMetadataFormat } from 'roosterjs-content-model-types';\n\n/**\n * @internal\n * Generate new dataURL from an image and edit info\n * @param image The image to generate data URL from. It is supposed to have original src loaded\n * @param editInfo Edit info of the image\n * @returns A BASE64 encoded string with image prefix that represents the content of the generated image.\n * If there are rotate/crop/resize info in the edit info, the generated image will also reflect the result.\n * It is possible to throw exception since the original image may not be able to read its content from\n * the code, so better check canRegenerateImage() of the image first.\n * @throws Exception when fail to generate dataURL from canvas\n */\nexport function generateDataURL(image: HTMLImageElement, editInfo: ImageMetadataFormat): string {\n const generatedImageSize = getGeneratedImageSize(editInfo);\n if (!generatedImageSize) {\n return '';\n }\n\n const {\n angleRad,\n widthPx,\n heightPx,\n bottomPercent,\n leftPercent,\n rightPercent,\n topPercent,\n naturalWidth,\n naturalHeight,\n } = editInfo;\n const angle = angleRad || 0;\n const left = leftPercent || 0;\n const right = rightPercent || 0;\n const top = topPercent || 0;\n const bottom = bottomPercent || 0;\n const nHeight = naturalHeight || image.naturalHeight;\n const nWidth = naturalWidth || image.naturalHeight;\n const width = widthPx || image.clientWidth;\n const height = heightPx || image.clientHeight;\n\n const imageWidth = nWidth * (1 - left - right);\n const imageHeight = nHeight * (1 - top - bottom);\n\n // Adjust the canvas size and scaling for high display resolution\n const devicePixelRatio = window.devicePixelRatio || 1;\n const canvas = document.createElement('canvas');\n const { targetWidth, targetHeight } = generatedImageSize;\n canvas.width = targetWidth * devicePixelRatio;\n canvas.height = targetHeight * devicePixelRatio;\n\n const context = canvas.getContext('2d');\n\n try {\n if (context) {\n context.scale(devicePixelRatio, devicePixelRatio);\n context.translate(targetWidth / 2, targetHeight / 2);\n context.rotate(angle);\n context.scale(editInfo.flippedHorizontal ? -1 : 1, editInfo.flippedVertical ? -1 : 1);\n context.drawImage(\n image,\n nWidth * left,\n nHeight * top,\n imageWidth,\n imageHeight,\n -width / 2,\n -height / 2,\n width,\n height\n );\n }\n return canvas.toDataURL('image/png', 1.0);\n } catch {\n return image.src;\n }\n}\n"]}
1
+ {"version":3,"file":"generateDataURL.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/imageEdit/utils/generateDataURL.ts"],"names":[],"mappings":"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","sourcesContent":["import { getGeneratedImageSize } from './generateImageSize';\nimport type { ImageMetadataFormat } from 'roosterjs-content-model-types';\n\n/**\n * @internal\n * Generate new dataURL from an image and edit info\n * @param image The image to generate data URL from. It is supposed to have original src loaded\n * @param editInfo Edit info of the image\n * @returns A BASE64 encoded string with image prefix that represents the content of the generated image.\n * If there are rotate/crop/resize info in the edit info, the generated image will also reflect the result.\n * It is possible to throw exception since the original image may not be able to read its content from\n * the code, so better check canRegenerateImage() of the image first.\n * @throws Exception when fail to generate dataURL from canvas\n */\nexport function generateDataURL(image: HTMLImageElement, editInfo: ImageMetadataFormat): string {\n const generatedImageSize = getGeneratedImageSize(editInfo);\n if (!generatedImageSize) {\n return '';\n }\n\n const {\n angleRad,\n widthPx,\n heightPx,\n bottomPercent,\n leftPercent,\n rightPercent,\n topPercent,\n naturalWidth,\n naturalHeight,\n } = editInfo;\n const angle = angleRad || 0;\n const left = leftPercent || 0;\n const right = rightPercent || 0;\n const top = topPercent || 0;\n const bottom = bottomPercent || 0;\n const nHeight = naturalHeight || image.naturalHeight;\n const nWidth = naturalWidth || image.naturalHeight;\n const width = widthPx || image.clientWidth;\n const height = heightPx || image.clientHeight;\n\n const imageWidth = nWidth * (1 - left - right);\n const imageHeight = nHeight * (1 - top - bottom);\n const doc = image.ownerDocument;\n const win = doc.defaultView;\n\n // Adjust the canvas size and scaling for high display resolution\n const devicePixelRatio = win?.devicePixelRatio || 1;\n const canvas = doc.createElement('canvas');\n const { targetWidth, targetHeight } = generatedImageSize;\n canvas.width = targetWidth * devicePixelRatio;\n canvas.height = targetHeight * devicePixelRatio;\n\n const context = canvas.getContext('2d');\n\n try {\n if (context) {\n context.scale(devicePixelRatio, devicePixelRatio);\n context.translate(targetWidth / 2, targetHeight / 2);\n context.rotate(angle);\n context.scale(editInfo.flippedHorizontal ? -1 : 1, editInfo.flippedVertical ? -1 : 1);\n context.drawImage(\n image,\n nWidth * left,\n nHeight * top,\n imageWidth,\n imageHeight,\n -width / 2,\n -height / 2,\n width,\n height\n );\n }\n return canvas.toDataURL('image/png', 1.0);\n } catch {\n return image.src;\n }\n}\n"]}
@@ -42,13 +42,13 @@ var TableEditPlugin = /** @class */ (function () {
42
42
  }
43
43
  };
44
44
  this.onMouseMove = function (event) {
45
- var _a;
45
+ var _a, _b;
46
46
  var e = event;
47
- if (e.buttons > 0 || !_this.editor) {
47
+ var editorWindow = (_a = _this.editor) === null || _a === void 0 ? void 0 : _a.getDocument().defaultView;
48
+ if (e.buttons > 0 || !editorWindow) {
48
49
  return;
49
50
  }
50
51
  _this.ensureTableRects();
51
- var editorWindow = _this.editor.getDocument().defaultView || window;
52
52
  var x = e.pageX - editorWindow.scrollX;
53
53
  var y = e.pageY - editorWindow.scrollY;
54
54
  var currentTable = null;
@@ -67,7 +67,7 @@ var TableEditPlugin = /** @class */ (function () {
67
67
  }
68
68
  }
69
69
  _this.setTableEditor(currentTable, e);
70
- (_a = _this.tableEditor) === null || _a === void 0 ? void 0 : _a.onMouseMove(x, y);
70
+ (_b = _this.tableEditor) === null || _b === void 0 ? void 0 : _b.onMouseMove(x, y);
71
71
  };
72
72
  this.invalidateTableRects = function () {
73
73
  _this.tableRectMap = null;
@@ -1 +1 @@
1
- {"version":3,"file":"TableEditPlugin.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-plugins/lib/tableEdit/TableEditPlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { isNodeOfType, normalizeRect } from 'roosterjs-content-model-dom';\nimport { TableEditor } from './editors/TableEditor';\nimport type { TableWithRoot } from './TableWithRoot';\nimport type { TableEditFeatureName } from './editors/features/TableEditFeatureName';\nimport type { OnTableEditorCreatedCallback } from './OnTableEditorCreatedCallback';\nimport type {\n DOMHelper,\n EditorPlugin,\n IEditor,\n PluginEvent,\n Rect,\n} from 'roosterjs-content-model-types';\n\nconst TABLE_RESIZER_LENGTH = 12;\n\n/**\n * TableEdit plugin, provides the ability to resize a table by drag-and-drop\n */\nexport class TableEditPlugin implements EditorPlugin {\n private editor: IEditor | null = null;\n private onMouseMoveDisposer: (() => void) | null = null;\n private tableRectMap: (TableWithRoot & { rect: Rect })[] | null = null;\n private tableEditor: TableEditor | null = null;\n\n /**\n * Construct a new instance of TableResize plugin\n * @param anchorContainerSelector An optional selector string to specify the container to host the plugin.\n * The container must not be affected by transform: scale(), otherwise the position calculation will be wrong.\n * If not specified, the plugin will be inserted in document.body\n * @param onTableEditorCreated An optional callback to customize the Table Editors elements when created.\n * @param disableFeatures An optional array of TableEditFeatures to disable\n * @param tableSelector A function to select the tables to be edited. By default, it selects all contentEditable tables.\n */\n constructor(\n private anchorContainerSelector?: string,\n private onTableEditorCreated?: OnTableEditorCreatedCallback,\n private disableFeatures?: TableEditFeatureName[],\n private tableSelector: (domHelper: DOMHelper) => TableWithRoot[] = defaultTableSelector\n ) {}\n\n /**\n * Get a friendly name of this plugin\n */\n getName() {\n return 'TableEdit';\n }\n\n /**\n * Initialize this plugin. This should only be called from Editor\n * @param editor Editor instance\n */\n initialize(editor: IEditor) {\n this.editor = editor;\n this.onMouseMoveDisposer = this.editor.attachDomEvent({\n mousemove: { beforeDispatch: this.onMouseMove },\n });\n const scrollContainer = this.editor.getScrollContainer();\n scrollContainer.addEventListener('mouseout', this.onMouseOut);\n }\n\n private onMouseOut = ({ relatedTarget, currentTarget }: MouseEvent) => {\n const relatedTargetNode = relatedTarget as Node;\n const currentTargetNode = currentTarget as Node;\n if (\n isNodeOfType(relatedTargetNode, 'ELEMENT_NODE') &&\n isNodeOfType(currentTargetNode, 'ELEMENT_NODE') &&\n this.tableEditor &&\n !this.tableEditor.isOwnedElement(relatedTargetNode) &&\n !currentTargetNode.contains(relatedTargetNode)\n ) {\n this.setTableEditor(null);\n }\n };\n\n /**\n * Dispose this plugin\n */\n dispose() {\n const scrollContainer = this.editor?.getScrollContainer();\n scrollContainer?.removeEventListener('mouseout', this.onMouseOut);\n this.onMouseMoveDisposer?.();\n this.invalidateTableRects();\n this.disposeTableEditor();\n this.editor = null;\n this.onMouseMoveDisposer = null;\n this.onTableEditorCreated = undefined;\n }\n\n /**\n * Handle events triggered from editor\n * @param event PluginEvent object\n */\n onPluginEvent(e: PluginEvent) {\n switch (e.eventType) {\n case 'input':\n case 'contentChanged':\n case 'scroll':\n case 'zoomChanged':\n this.setTableEditor(null);\n this.invalidateTableRects();\n break;\n }\n }\n\n private onMouseMove = (event: Event) => {\n const e = event as MouseEvent;\n\n if (e.buttons > 0 || !this.editor) {\n return;\n }\n\n this.ensureTableRects();\n\n const editorWindow = this.editor.getDocument().defaultView || window;\n const x = e.pageX - editorWindow.scrollX;\n const y = e.pageY - editorWindow.scrollY;\n let currentTable: TableWithRoot | null = null;\n\n //Find table in range of mouse\n if (this.tableRectMap) {\n for (let i = this.tableRectMap.length - 1; i >= 0; i--) {\n const entry = this.tableRectMap[i];\n const { rect } = entry;\n\n if (\n x >= rect.left - TABLE_RESIZER_LENGTH &&\n x <= rect.right + TABLE_RESIZER_LENGTH &&\n y >= rect.top - TABLE_RESIZER_LENGTH &&\n y <= rect.bottom + TABLE_RESIZER_LENGTH\n ) {\n currentTable = entry;\n break;\n }\n }\n }\n\n this.setTableEditor(currentTable, e);\n this.tableEditor?.onMouseMove(x, y);\n };\n\n /**\n * @internal Public only for unit test\n * @param entry Table to use when setting the Editors\n * @param event (Optional) Mouse event\n */\n public setTableEditor(entry: TableWithRoot | null, event?: MouseEvent) {\n if (\n this.tableEditor &&\n !this.tableEditor.isEditing() &&\n entry?.table != this.tableEditor.table\n ) {\n this.disposeTableEditor();\n }\n\n if (!this.tableEditor && entry && this.editor && entry.table.rows.length > 0) {\n // anchorContainerSelector is used to specify the container to host the plugin, which can be outside of the editor's div\n const container = this.anchorContainerSelector\n ? this.editor.getDocument().querySelector(this.anchorContainerSelector)\n : undefined;\n\n this.tableEditor = new TableEditor(\n this.editor,\n entry.table,\n entry.logicalRoot,\n this.invalidateTableRects,\n isNodeOfType(container, 'ELEMENT_NODE') ? container : undefined,\n event?.currentTarget,\n this.onTableEditorCreated,\n this.disableFeatures\n );\n }\n }\n\n private invalidateTableRects = () => {\n this.tableRectMap = null;\n };\n\n private disposeTableEditor() {\n this.tableEditor?.dispose();\n this.tableEditor = null;\n }\n\n private ensureTableRects() {\n if (!this.tableRectMap && this.editor) {\n this.tableRectMap = [];\n\n const tables = this.tableSelector(this.editor.getDOMHelper());\n tables.forEach(table => {\n const rect = normalizeRect(table.table.getBoundingClientRect());\n\n if (rect && this.tableRectMap) {\n this.tableRectMap.push({\n ...table,\n rect,\n });\n }\n });\n }\n }\n}\n\nfunction defaultTableSelector(domHelper: DOMHelper): TableWithRoot[] {\n return domHelper\n .queryElements('table')\n .filter(table => table.isContentEditable)\n .map(table => ({\n table,\n logicalRoot: null,\n }));\n}\n"]}
1
+ {"version":3,"file":"TableEditPlugin.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-plugins/lib/tableEdit/TableEditPlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { isNodeOfType, normalizeRect } from 'roosterjs-content-model-dom';\nimport { TableEditor } from './editors/TableEditor';\nimport type { TableWithRoot } from './TableWithRoot';\nimport type { TableEditFeatureName } from './editors/features/TableEditFeatureName';\nimport type { OnTableEditorCreatedCallback } from './OnTableEditorCreatedCallback';\nimport type {\n DOMHelper,\n EditorPlugin,\n IEditor,\n PluginEvent,\n Rect,\n} from 'roosterjs-content-model-types';\n\nconst TABLE_RESIZER_LENGTH = 12;\n\n/**\n * TableEdit plugin, provides the ability to resize a table by drag-and-drop\n */\nexport class TableEditPlugin implements EditorPlugin {\n private editor: IEditor | null = null;\n private onMouseMoveDisposer: (() => void) | null = null;\n private tableRectMap: (TableWithRoot & { rect: Rect })[] | null = null;\n private tableEditor: TableEditor | null = null;\n\n /**\n * Construct a new instance of TableResize plugin\n * @param anchorContainerSelector An optional selector string to specify the container to host the plugin.\n * The container must not be affected by transform: scale(), otherwise the position calculation will be wrong.\n * If not specified, the plugin will be inserted in document.body\n * @param onTableEditorCreated An optional callback to customize the Table Editors elements when created.\n * @param disableFeatures An optional array of TableEditFeatures to disable\n * @param tableSelector A function to select the tables to be edited. By default, it selects all contentEditable tables.\n */\n constructor(\n private anchorContainerSelector?: string,\n private onTableEditorCreated?: OnTableEditorCreatedCallback,\n private disableFeatures?: TableEditFeatureName[],\n private tableSelector: (domHelper: DOMHelper) => TableWithRoot[] = defaultTableSelector\n ) {}\n\n /**\n * Get a friendly name of this plugin\n */\n getName() {\n return 'TableEdit';\n }\n\n /**\n * Initialize this plugin. This should only be called from Editor\n * @param editor Editor instance\n */\n initialize(editor: IEditor) {\n this.editor = editor;\n this.onMouseMoveDisposer = this.editor.attachDomEvent({\n mousemove: { beforeDispatch: this.onMouseMove },\n });\n const scrollContainer = this.editor.getScrollContainer();\n scrollContainer.addEventListener('mouseout', this.onMouseOut);\n }\n\n private onMouseOut = ({ relatedTarget, currentTarget }: MouseEvent) => {\n const relatedTargetNode = relatedTarget as Node;\n const currentTargetNode = currentTarget as Node;\n if (\n isNodeOfType(relatedTargetNode, 'ELEMENT_NODE') &&\n isNodeOfType(currentTargetNode, 'ELEMENT_NODE') &&\n this.tableEditor &&\n !this.tableEditor.isOwnedElement(relatedTargetNode) &&\n !currentTargetNode.contains(relatedTargetNode)\n ) {\n this.setTableEditor(null);\n }\n };\n\n /**\n * Dispose this plugin\n */\n dispose() {\n const scrollContainer = this.editor?.getScrollContainer();\n scrollContainer?.removeEventListener('mouseout', this.onMouseOut);\n this.onMouseMoveDisposer?.();\n this.invalidateTableRects();\n this.disposeTableEditor();\n this.editor = null;\n this.onMouseMoveDisposer = null;\n this.onTableEditorCreated = undefined;\n }\n\n /**\n * Handle events triggered from editor\n * @param event PluginEvent object\n */\n onPluginEvent(e: PluginEvent) {\n switch (e.eventType) {\n case 'input':\n case 'contentChanged':\n case 'scroll':\n case 'zoomChanged':\n this.setTableEditor(null);\n this.invalidateTableRects();\n break;\n }\n }\n\n private onMouseMove = (event: Event) => {\n const e = event as MouseEvent;\n const editorWindow = this.editor?.getDocument().defaultView;\n\n if (e.buttons > 0 || !editorWindow) {\n return;\n }\n\n this.ensureTableRects();\n\n const x = e.pageX - editorWindow.scrollX;\n const y = e.pageY - editorWindow.scrollY;\n let currentTable: TableWithRoot | null = null;\n\n //Find table in range of mouse\n if (this.tableRectMap) {\n for (let i = this.tableRectMap.length - 1; i >= 0; i--) {\n const entry = this.tableRectMap[i];\n const { rect } = entry;\n\n if (\n x >= rect.left - TABLE_RESIZER_LENGTH &&\n x <= rect.right + TABLE_RESIZER_LENGTH &&\n y >= rect.top - TABLE_RESIZER_LENGTH &&\n y <= rect.bottom + TABLE_RESIZER_LENGTH\n ) {\n currentTable = entry;\n break;\n }\n }\n }\n\n this.setTableEditor(currentTable, e);\n this.tableEditor?.onMouseMove(x, y);\n };\n\n /**\n * @internal Public only for unit test\n * @param entry Table to use when setting the Editors\n * @param event (Optional) Mouse event\n */\n public setTableEditor(entry: TableWithRoot | null, event?: MouseEvent) {\n if (\n this.tableEditor &&\n !this.tableEditor.isEditing() &&\n entry?.table != this.tableEditor.table\n ) {\n this.disposeTableEditor();\n }\n\n if (!this.tableEditor && entry && this.editor && entry.table.rows.length > 0) {\n // anchorContainerSelector is used to specify the container to host the plugin, which can be outside of the editor's div\n const container = this.anchorContainerSelector\n ? this.editor.getDocument().querySelector(this.anchorContainerSelector)\n : undefined;\n\n this.tableEditor = new TableEditor(\n this.editor,\n entry.table,\n entry.logicalRoot,\n this.invalidateTableRects,\n isNodeOfType(container, 'ELEMENT_NODE') ? container : undefined,\n event?.currentTarget,\n this.onTableEditorCreated,\n this.disableFeatures\n );\n }\n }\n\n private invalidateTableRects = () => {\n this.tableRectMap = null;\n };\n\n private disposeTableEditor() {\n this.tableEditor?.dispose();\n this.tableEditor = null;\n }\n\n private ensureTableRects() {\n if (!this.tableRectMap && this.editor) {\n this.tableRectMap = [];\n\n const tables = this.tableSelector(this.editor.getDOMHelper());\n tables.forEach(table => {\n const rect = normalizeRect(table.table.getBoundingClientRect());\n\n if (rect && this.tableRectMap) {\n this.tableRectMap.push({\n ...table,\n rect,\n });\n }\n });\n }\n }\n}\n\nfunction defaultTableSelector(domHelper: DOMHelper): TableWithRoot[] {\n return domHelper\n .queryElements('table')\n .filter(table => table.isContentEditable)\n .map(table => ({\n table,\n logicalRoot: null,\n }));\n}\n"]}
@@ -45,6 +45,8 @@ export declare class TableEditor {
45
45
  private verticalResizer;
46
46
  private tableResizer;
47
47
  private tableMover;
48
+ private tableColumnSelector;
49
+ private tableRowSelector;
48
50
  private isRTL;
49
51
  private range;
50
52
  private isCurrentlyEditing;
@@ -64,8 +66,10 @@ export declare class TableEditor {
64
66
  * @param td td to attach to, set this to null to remove inserters (both horizontal and vertical)
65
67
  */
66
68
  private setInserterTd;
69
+ private setSelectorRowColumn;
67
70
  private disposeTableResizer;
68
71
  private disposeTableInserter;
72
+ private disposeTableSelector;
69
73
  private disposeCellResizers;
70
74
  private disposeTableMover;
71
75
  private onFinishEditing;