roosterjs-content-model-plugins 0.26.3 → 0.27.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 (190) hide show
  1. package/lib/autoFormat/AutoFormatPlugin.d.ts +2 -2
  2. package/lib/autoFormat/AutoFormatPlugin.js.map +1 -1
  3. package/lib/autoFormat/keyboardListTrigger.d.ts +2 -2
  4. package/lib/autoFormat/keyboardListTrigger.js.map +1 -1
  5. package/lib/edit/EditPlugin.d.ts +3 -3
  6. package/lib/edit/EditPlugin.js +1 -1
  7. package/lib/edit/EditPlugin.js.map +1 -1
  8. package/lib/edit/deleteSteps/deleteCollapsedSelection.js +20 -1
  9. package/lib/edit/deleteSteps/deleteCollapsedSelection.js.map +1 -1
  10. package/lib/edit/handleKeyboardEventCommon.d.ts +2 -2
  11. package/lib/edit/handleKeyboardEventCommon.js.map +1 -1
  12. package/lib/edit/inputSteps/handleEnterOnList.js +40 -10
  13. package/lib/edit/inputSteps/handleEnterOnList.js.map +1 -1
  14. package/lib/edit/keyboardDelete.d.ts +3 -3
  15. package/lib/edit/keyboardDelete.js +1 -1
  16. package/lib/edit/keyboardDelete.js.map +1 -1
  17. package/lib/edit/keyboardInput.d.ts +2 -2
  18. package/lib/edit/keyboardInput.js.map +1 -1
  19. package/lib/edit/keyboardTab.d.ts +2 -2
  20. package/lib/edit/keyboardTab.js +19 -11
  21. package/lib/edit/keyboardTab.js.map +1 -1
  22. package/lib/edit/tabUtils/handleTabOnList.d.ts +7 -0
  23. package/lib/edit/tabUtils/handleTabOnList.js +34 -0
  24. package/lib/edit/tabUtils/handleTabOnList.js.map +1 -0
  25. package/lib/edit/tabUtils/handleTabOnParagraph.d.ts +17 -0
  26. package/lib/edit/tabUtils/handleTabOnParagraph.js +81 -0
  27. package/lib/edit/tabUtils/handleTabOnParagraph.js.map +1 -0
  28. package/lib/index.d.ts +4 -0
  29. package/lib/index.js +18 -1
  30. package/lib/index.js.map +1 -1
  31. package/lib/paste/PastePlugin.d.ts +2 -3
  32. package/lib/paste/PastePlugin.js +0 -1
  33. package/lib/paste/PastePlugin.js.map +1 -1
  34. package/lib/shortcut/ShortcutCommand.d.ts +44 -0
  35. package/lib/shortcut/ShortcutCommand.js +3 -0
  36. package/lib/shortcut/ShortcutCommand.js.map +1 -0
  37. package/lib/shortcut/ShortcutPlugin.d.ts +51 -0
  38. package/lib/shortcut/ShortcutPlugin.js +118 -0
  39. package/lib/shortcut/ShortcutPlugin.js.map +1 -0
  40. package/lib/shortcut/shortcuts.d.ts +73 -0
  41. package/lib/shortcut/shortcuts.js +178 -0
  42. package/lib/shortcut/shortcuts.js.map +1 -0
  43. package/lib/tableEdit/TableEditPlugin.d.ts +47 -0
  44. package/lib/tableEdit/TableEditPlugin.js +156 -0
  45. package/lib/tableEdit/TableEditPlugin.js.map +1 -0
  46. package/lib/tableEdit/editors/TableEditor.d.ts +73 -0
  47. package/lib/tableEdit/editors/TableEditor.js +294 -0
  48. package/lib/tableEdit/editors/TableEditor.js.map +1 -0
  49. package/lib/tableEdit/editors/features/CellResizer.d.ts +6 -0
  50. package/lib/tableEdit/editors/features/CellResizer.js +169 -0
  51. package/lib/tableEdit/editors/features/CellResizer.js.map +1 -0
  52. package/lib/tableEdit/editors/features/TableEditorFeature.d.ts +13 -0
  53. package/lib/tableEdit/editors/features/TableEditorFeature.js +17 -0
  54. package/lib/tableEdit/editors/features/TableEditorFeature.js.map +1 -0
  55. package/lib/tableEdit/editors/features/TableInserter.d.ts +6 -0
  56. package/lib/tableEdit/editors/features/TableInserter.js +113 -0
  57. package/lib/tableEdit/editors/features/TableInserter.js.map +1 -0
  58. package/lib/tableEdit/editors/features/TableMover.d.ts +8 -0
  59. package/lib/tableEdit/editors/features/TableMover.js +83 -0
  60. package/lib/tableEdit/editors/features/TableMover.js.map +1 -0
  61. package/lib/tableEdit/editors/features/TableResizer.d.ts +6 -0
  62. package/lib/tableEdit/editors/features/TableResizer.js +163 -0
  63. package/lib/tableEdit/editors/features/TableResizer.js.map +1 -0
  64. package/lib-amd/autoFormat/AutoFormatPlugin.d.ts +2 -2
  65. package/lib-amd/autoFormat/AutoFormatPlugin.js.map +1 -1
  66. package/lib-amd/autoFormat/keyboardListTrigger.d.ts +2 -2
  67. package/lib-amd/autoFormat/keyboardListTrigger.js.map +1 -1
  68. package/lib-amd/edit/EditPlugin.d.ts +3 -3
  69. package/lib-amd/edit/EditPlugin.js +1 -1
  70. package/lib-amd/edit/EditPlugin.js.map +1 -1
  71. package/lib-amd/edit/deleteSteps/deleteCollapsedSelection.js +19 -1
  72. package/lib-amd/edit/deleteSteps/deleteCollapsedSelection.js.map +1 -1
  73. package/lib-amd/edit/handleKeyboardEventCommon.d.ts +2 -2
  74. package/lib-amd/edit/handleKeyboardEventCommon.js.map +1 -1
  75. package/lib-amd/edit/inputSteps/handleEnterOnList.js +40 -10
  76. package/lib-amd/edit/inputSteps/handleEnterOnList.js.map +1 -1
  77. package/lib-amd/edit/keyboardDelete.d.ts +3 -3
  78. package/lib-amd/edit/keyboardDelete.js +1 -1
  79. package/lib-amd/edit/keyboardDelete.js.map +1 -1
  80. package/lib-amd/edit/keyboardInput.d.ts +2 -2
  81. package/lib-amd/edit/keyboardInput.js.map +1 -1
  82. package/lib-amd/edit/keyboardTab.d.ts +2 -2
  83. package/lib-amd/edit/keyboardTab.js +18 -12
  84. package/lib-amd/edit/keyboardTab.js.map +1 -1
  85. package/lib-amd/edit/tabUtils/handleTabOnList.d.ts +7 -0
  86. package/lib-amd/edit/tabUtils/handleTabOnList.js +34 -0
  87. package/lib-amd/edit/tabUtils/handleTabOnList.js.map +1 -0
  88. package/lib-amd/edit/tabUtils/handleTabOnParagraph.d.ts +17 -0
  89. package/lib-amd/edit/tabUtils/handleTabOnParagraph.js +81 -0
  90. package/lib-amd/edit/tabUtils/handleTabOnParagraph.js.map +1 -0
  91. package/lib-amd/index.d.ts +4 -0
  92. package/lib-amd/index.js +16 -2
  93. package/lib-amd/index.js.map +1 -1
  94. package/lib-amd/paste/PastePlugin.d.ts +2 -3
  95. package/lib-amd/paste/PastePlugin.js +0 -1
  96. package/lib-amd/paste/PastePlugin.js.map +1 -1
  97. package/lib-amd/shortcut/ShortcutCommand.d.ts +44 -0
  98. package/lib-amd/shortcut/ShortcutCommand.js +5 -0
  99. package/lib-amd/shortcut/ShortcutCommand.js.map +1 -0
  100. package/lib-amd/shortcut/ShortcutPlugin.d.ts +51 -0
  101. package/lib-amd/shortcut/ShortcutPlugin.js +118 -0
  102. package/lib-amd/shortcut/ShortcutPlugin.js.map +1 -0
  103. package/lib-amd/shortcut/shortcuts.d.ts +73 -0
  104. package/lib-amd/shortcut/shortcuts.js +178 -0
  105. package/lib-amd/shortcut/shortcuts.js.map +1 -0
  106. package/lib-amd/tableEdit/TableEditPlugin.d.ts +47 -0
  107. package/lib-amd/tableEdit/TableEditPlugin.js +155 -0
  108. package/lib-amd/tableEdit/TableEditPlugin.js.map +1 -0
  109. package/lib-amd/tableEdit/editors/TableEditor.d.ts +73 -0
  110. package/lib-amd/tableEdit/editors/TableEditor.js +289 -0
  111. package/lib-amd/tableEdit/editors/TableEditor.js.map +1 -0
  112. package/lib-amd/tableEdit/editors/features/CellResizer.d.ts +6 -0
  113. package/lib-amd/tableEdit/editors/features/CellResizer.js +165 -0
  114. package/lib-amd/tableEdit/editors/features/CellResizer.js.map +1 -0
  115. package/lib-amd/tableEdit/editors/features/TableEditorFeature.d.ts +13 -0
  116. package/lib-amd/tableEdit/editors/features/TableEditorFeature.js +19 -0
  117. package/lib-amd/tableEdit/editors/features/TableEditorFeature.js.map +1 -0
  118. package/lib-amd/tableEdit/editors/features/TableInserter.d.ts +6 -0
  119. package/lib-amd/tableEdit/editors/features/TableInserter.js +110 -0
  120. package/lib-amd/tableEdit/editors/features/TableInserter.js.map +1 -0
  121. package/lib-amd/tableEdit/editors/features/TableMover.d.ts +8 -0
  122. package/lib-amd/tableEdit/editors/features/TableMover.js +80 -0
  123. package/lib-amd/tableEdit/editors/features/TableMover.js.map +1 -0
  124. package/lib-amd/tableEdit/editors/features/TableResizer.d.ts +6 -0
  125. package/lib-amd/tableEdit/editors/features/TableResizer.js +160 -0
  126. package/lib-amd/tableEdit/editors/features/TableResizer.js.map +1 -0
  127. package/lib-mjs/autoFormat/AutoFormatPlugin.d.ts +2 -2
  128. package/lib-mjs/autoFormat/AutoFormatPlugin.js.map +1 -1
  129. package/lib-mjs/autoFormat/keyboardListTrigger.d.ts +2 -2
  130. package/lib-mjs/autoFormat/keyboardListTrigger.js.map +1 -1
  131. package/lib-mjs/edit/EditPlugin.d.ts +3 -3
  132. package/lib-mjs/edit/EditPlugin.js +1 -1
  133. package/lib-mjs/edit/EditPlugin.js.map +1 -1
  134. package/lib-mjs/edit/deleteSteps/deleteCollapsedSelection.js +20 -1
  135. package/lib-mjs/edit/deleteSteps/deleteCollapsedSelection.js.map +1 -1
  136. package/lib-mjs/edit/handleKeyboardEventCommon.d.ts +2 -2
  137. package/lib-mjs/edit/handleKeyboardEventCommon.js.map +1 -1
  138. package/lib-mjs/edit/inputSteps/handleEnterOnList.js +42 -12
  139. package/lib-mjs/edit/inputSteps/handleEnterOnList.js.map +1 -1
  140. package/lib-mjs/edit/keyboardDelete.d.ts +3 -3
  141. package/lib-mjs/edit/keyboardDelete.js +1 -1
  142. package/lib-mjs/edit/keyboardDelete.js.map +1 -1
  143. package/lib-mjs/edit/keyboardInput.d.ts +2 -2
  144. package/lib-mjs/edit/keyboardInput.js.map +1 -1
  145. package/lib-mjs/edit/keyboardTab.d.ts +2 -2
  146. package/lib-mjs/edit/keyboardTab.js +19 -11
  147. package/lib-mjs/edit/keyboardTab.js.map +1 -1
  148. package/lib-mjs/edit/tabUtils/handleTabOnList.d.ts +7 -0
  149. package/lib-mjs/edit/tabUtils/handleTabOnList.js +30 -0
  150. package/lib-mjs/edit/tabUtils/handleTabOnList.js.map +1 -0
  151. package/lib-mjs/edit/tabUtils/handleTabOnParagraph.d.ts +17 -0
  152. package/lib-mjs/edit/tabUtils/handleTabOnParagraph.js +77 -0
  153. package/lib-mjs/edit/tabUtils/handleTabOnParagraph.js.map +1 -0
  154. package/lib-mjs/index.d.ts +4 -0
  155. package/lib-mjs/index.js +3 -0
  156. package/lib-mjs/index.js.map +1 -1
  157. package/lib-mjs/paste/PastePlugin.d.ts +2 -3
  158. package/lib-mjs/paste/PastePlugin.js +0 -1
  159. package/lib-mjs/paste/PastePlugin.js.map +1 -1
  160. package/lib-mjs/shortcut/ShortcutCommand.d.ts +44 -0
  161. package/lib-mjs/shortcut/ShortcutCommand.js +2 -0
  162. package/lib-mjs/shortcut/ShortcutCommand.js.map +1 -0
  163. package/lib-mjs/shortcut/ShortcutPlugin.d.ts +51 -0
  164. package/lib-mjs/shortcut/ShortcutPlugin.js +115 -0
  165. package/lib-mjs/shortcut/ShortcutPlugin.js.map +1 -0
  166. package/lib-mjs/shortcut/shortcuts.d.ts +73 -0
  167. package/lib-mjs/shortcut/shortcuts.js +175 -0
  168. package/lib-mjs/shortcut/shortcuts.js.map +1 -0
  169. package/lib-mjs/tableEdit/TableEditPlugin.d.ts +47 -0
  170. package/lib-mjs/tableEdit/TableEditPlugin.js +153 -0
  171. package/lib-mjs/tableEdit/TableEditPlugin.js.map +1 -0
  172. package/lib-mjs/tableEdit/editors/TableEditor.d.ts +73 -0
  173. package/lib-mjs/tableEdit/editors/TableEditor.js +292 -0
  174. package/lib-mjs/tableEdit/editors/TableEditor.js.map +1 -0
  175. package/lib-mjs/tableEdit/editors/features/CellResizer.d.ts +6 -0
  176. package/lib-mjs/tableEdit/editors/features/CellResizer.js +166 -0
  177. package/lib-mjs/tableEdit/editors/features/CellResizer.js.map +1 -0
  178. package/lib-mjs/tableEdit/editors/features/TableEditorFeature.d.ts +13 -0
  179. package/lib-mjs/tableEdit/editors/features/TableEditorFeature.js +13 -0
  180. package/lib-mjs/tableEdit/editors/features/TableEditorFeature.js.map +1 -0
  181. package/lib-mjs/tableEdit/editors/features/TableInserter.d.ts +6 -0
  182. package/lib-mjs/tableEdit/editors/features/TableInserter.js +110 -0
  183. package/lib-mjs/tableEdit/editors/features/TableInserter.js.map +1 -0
  184. package/lib-mjs/tableEdit/editors/features/TableMover.d.ts +8 -0
  185. package/lib-mjs/tableEdit/editors/features/TableMover.js +80 -0
  186. package/lib-mjs/tableEdit/editors/features/TableMover.js.map +1 -0
  187. package/lib-mjs/tableEdit/editors/features/TableResizer.d.ts +6 -0
  188. package/lib-mjs/tableEdit/editors/features/TableResizer.js +160 -0
  189. package/lib-mjs/tableEdit/editors/features/TableResizer.js.map +1 -0
  190. package/package.json +5 -5
@@ -1 +1 @@
1
- {"version":3,"file":"keyboardDelete.js","sourceRoot":"","sources":["../../../../packages-content-model/roosterjs-content-model-plugins/lib/edit/keyboardDelete.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC5F,OAAO,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AAC9E,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EACH,yBAAyB,EACzB,6BAA6B,EAC7B,gBAAgB,GACnB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACH,2BAA2B,EAC3B,0BAA0B,GAC7B,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EACH,gCAAgC,EAChC,+BAA+B,GAClC,MAAM,wCAAwC,CAAC;AAOhD;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,MAAyB,EAAE,QAAuB;IAC7E,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,IAAM,SAAS,GAAG,MAAM,CAAC,eAAe,EAAE,CAAC;IAE3C,IAAI,4BAA4B,CAAC,SAAS,EAAE,QAAQ,CAAC,EAAE;QACnD,MAAM,CAAC,kBAAkB,CACrB,UAAC,KAAK,EAAE,OAAO;YACX,IAAM,MAAM,GAAG,eAAe,CAC1B,KAAK,EACL,cAAc,CAAC,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC,KAAK,CAAC,EACzD,OAAO,CACV,CAAC,YAAY,CAAC;YAEf,OAAO,GAAG,yBAAyB,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;YAC9E,OAAO,OAAO,CAAC;QACnB,CAAC,EACD;YACI,QAAQ,UAAA;YACR,YAAY,EAAE,YAAY,CAAC,QAAQ;YACnC,aAAa,EAAE,cAAM,OAAA,QAAQ,CAAC,KAAK,EAAd,CAAc;YACnC,OAAO,EAAE,QAAQ,CAAC,GAAG,IAAI,QAAQ,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,oBAAoB;SAC/E,CACJ,CAAC;KACL;IAED,OAAO,OAAO,CAAC;AACnB,CAAC;AAED,SAAS,cAAc,CAAC,QAAuB,EAAE,KAAc;IAC3D,IAAM,SAAS,GAAG,QAAQ,CAAC,GAAG,IAAI,QAAQ,CAAC;IAC3C,IAAM,0BAA0B,GAC5B,6BAA6B,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,IAAI,CAAC;IAC1F,IAAM,mBAAmB,GAAG,gBAAgB,CAAC,QAAQ,EAAE,KAAK,CAAC;QACzD,CAAC,CAAC,SAAS;YACP,CAAC,CAAC,0BAA0B;YAC5B,CAAC,CAAC,2BAA2B;QACjC,CAAC,CAAC,IAAI,CAAC;IACX,IAAM,wBAAwB,GAAG,SAAS;QACtC,CAAC,CAAC,+BAA+B;QACjC,CAAC,CAAC,gCAAgC,CAAC;IACvC,OAAO,CAAC,0BAA0B,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,UAAU,CAAC,CAAC;AACnG,CAAC;AAED,SAAS,4BAA4B,CAAC,SAA8B,EAAE,QAAuB;IACzF,IAAI,CAAC,SAAS,EAAE;QACZ,OAAO,KAAK,CAAC,CAAC,oBAAoB;KACrC;SAAM,IAAI,SAAS,CAAC,IAAI,IAAI,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,SAAS,EAAE;QAChE,OAAO,IAAI,CAAC,CAAC,4DAA4D;KAC5E;SAAM;QACH,IAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC;QAE9B,oGAAoG;QACpG,OAAO,CAAC,CACJ,YAAY,CAAC,KAAK,CAAC,cAAc,EAAE,WAAW,CAAC;YAC/C,CAAC,aAAa,CAAC,QAAQ,CAAC;YACxB,CAAC,eAAe,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,cAAc,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CACxE,CAAC;KACL;AACL,CAAC;AAED,SAAS,eAAe,CAAC,QAAuB,EAAE,KAAY;IAC1D,OAAO,QAAQ,CAAC,GAAG,IAAI,WAAW,IAAI,KAAK,CAAC,WAAW,GAAG,CAAC,CAAC;AAChE,CAAC;AAED,SAAS,cAAc,CAAC,QAAuB,EAAE,KAAY;;IACzD,OAAO,CACH,QAAQ,CAAC,GAAG,IAAI,QAAQ;QACxB,KAAK,CAAC,WAAW,GAAG,CAAC,MAAA,MAAA,KAAK,CAAC,cAAc,CAAC,SAAS,0CAAE,MAAM,mCAAI,CAAC,CAAC,GAAG,CAAC,CACxE,CAAC;AACN,CAAC","sourcesContent":["import { ChangeSource, deleteSelection, isModifierKey } from 'roosterjs-content-model-core';\nimport { deleteAllSegmentBefore } from './deleteSteps/deleteAllSegmentBefore';\nimport { deleteList } from './deleteSteps/deleteList';\nimport { isNodeOfType } from 'roosterjs-content-model-dom';\nimport {\n handleKeyboardEventResult,\n shouldDeleteAllSegmentsBefore,\n shouldDeleteWord,\n} from './handleKeyboardEventCommon';\nimport {\n backwardDeleteWordSelection,\n forwardDeleteWordSelection,\n} from './deleteSteps/deleteWordSelection';\nimport {\n backwardDeleteCollapsedSelection,\n forwardDeleteCollapsedSelection,\n} from './deleteSteps/deleteCollapsedSelection';\nimport type {\n DOMSelection,\n DeleteSelectionStep,\n IStandaloneEditor,\n} from 'roosterjs-content-model-types';\n\n/**\n * @internal\n * Do keyboard event handling for DELETE/BACKSPACE key\n * @param editor The Content Model Editor\n * @param rawEvent DOM keyboard event\n * @returns True if the event is handled by content model, otherwise false\n */\nexport function keyboardDelete(editor: IStandaloneEditor, rawEvent: KeyboardEvent) {\n let handled = false;\n const selection = editor.getDOMSelection();\n\n if (shouldDeleteWithContentModel(selection, rawEvent)) {\n editor.formatContentModel(\n (model, context) => {\n const result = deleteSelection(\n model,\n getDeleteSteps(rawEvent, !!editor.getEnvironment().isMac),\n context\n ).deleteResult;\n\n handled = handleKeyboardEventResult(editor, model, rawEvent, result, context);\n return handled;\n },\n {\n rawEvent,\n changeSource: ChangeSource.Keyboard,\n getChangeData: () => rawEvent.which,\n apiName: rawEvent.key == 'Delete' ? 'handleDeleteKey' : 'handleBackspaceKey',\n }\n );\n }\n\n return handled;\n}\n\nfunction getDeleteSteps(rawEvent: KeyboardEvent, isMac: boolean): (DeleteSelectionStep | null)[] {\n const isForward = rawEvent.key == 'Delete';\n const deleteAllSegmentBeforeStep =\n shouldDeleteAllSegmentsBefore(rawEvent) && !isForward ? deleteAllSegmentBefore : null;\n const deleteWordSelection = shouldDeleteWord(rawEvent, isMac)\n ? isForward\n ? forwardDeleteWordSelection\n : backwardDeleteWordSelection\n : null;\n const deleteCollapsedSelection = isForward\n ? forwardDeleteCollapsedSelection\n : backwardDeleteCollapsedSelection;\n return [deleteAllSegmentBeforeStep, deleteWordSelection, deleteCollapsedSelection, deleteList];\n}\n\nfunction shouldDeleteWithContentModel(selection: DOMSelection | null, rawEvent: KeyboardEvent) {\n if (!selection) {\n return false; // Nothing to delete\n } else if (selection.type != 'range' || !selection.range.collapsed) {\n return true; // Selection is not collapsed, need to delete all selections\n } else {\n const range = selection.range;\n\n // When selection is collapsed and is in middle of text node, no need to use Content Model to delete\n return !(\n isNodeOfType(range.startContainer, 'TEXT_NODE') &&\n !isModifierKey(rawEvent) &&\n (canDeleteBefore(rawEvent, range) || canDeleteAfter(rawEvent, range))\n );\n }\n}\n\nfunction canDeleteBefore(rawEvent: KeyboardEvent, range: Range) {\n return rawEvent.key == 'Backspace' && range.startOffset > 1;\n}\n\nfunction canDeleteAfter(rawEvent: KeyboardEvent, range: Range) {\n return (\n rawEvent.key == 'Delete' &&\n range.startOffset < (range.startContainer.nodeValue?.length ?? 0) - 1\n );\n}\n"]}
1
+ {"version":3,"file":"keyboardDelete.js","sourceRoot":"","sources":["../../../../packages-content-model/roosterjs-content-model-plugins/lib/edit/keyboardDelete.ts"],"names":[],"mappings":"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","sourcesContent":["import { ChangeSource, deleteSelection, isModifierKey } from 'roosterjs-content-model-core';\nimport { deleteAllSegmentBefore } from './deleteSteps/deleteAllSegmentBefore';\nimport { deleteList } from './deleteSteps/deleteList';\nimport { isNodeOfType } from 'roosterjs-content-model-dom';\nimport {\n handleKeyboardEventResult,\n shouldDeleteAllSegmentsBefore,\n shouldDeleteWord,\n} from './handleKeyboardEventCommon';\nimport {\n backwardDeleteWordSelection,\n forwardDeleteWordSelection,\n} from './deleteSteps/deleteWordSelection';\nimport {\n backwardDeleteCollapsedSelection,\n forwardDeleteCollapsedSelection,\n} from './deleteSteps/deleteCollapsedSelection';\nimport type { DOMSelection, DeleteSelectionStep, IEditor } from 'roosterjs-content-model-types';\n\n/**\n * @internal\n * Do keyboard event handling for DELETE/BACKSPACE key\n * @param editor The editor object\n * @param rawEvent DOM keyboard event\n * @returns True if the event is handled by content model, otherwise false\n */\nexport function keyboardDelete(editor: IEditor, rawEvent: KeyboardEvent) {\n let handled = false;\n const selection = editor.getDOMSelection();\n\n if (shouldDeleteWithContentModel(selection, rawEvent)) {\n editor.formatContentModel(\n (model, context) => {\n const result = deleteSelection(\n model,\n getDeleteSteps(rawEvent, !!editor.getEnvironment().isMac),\n context\n ).deleteResult;\n\n handled = handleKeyboardEventResult(editor, model, rawEvent, result, context);\n return handled;\n },\n {\n rawEvent,\n changeSource: ChangeSource.Keyboard,\n getChangeData: () => rawEvent.which,\n apiName: rawEvent.key == 'Delete' ? 'handleDeleteKey' : 'handleBackspaceKey',\n }\n );\n }\n\n return handled;\n}\n\nfunction getDeleteSteps(rawEvent: KeyboardEvent, isMac: boolean): (DeleteSelectionStep | null)[] {\n const isForward = rawEvent.key == 'Delete';\n const deleteAllSegmentBeforeStep =\n shouldDeleteAllSegmentsBefore(rawEvent) && !isForward ? deleteAllSegmentBefore : null;\n const deleteWordSelection = shouldDeleteWord(rawEvent, isMac)\n ? isForward\n ? forwardDeleteWordSelection\n : backwardDeleteWordSelection\n : null;\n const deleteCollapsedSelection = isForward\n ? forwardDeleteCollapsedSelection\n : backwardDeleteCollapsedSelection;\n return [deleteAllSegmentBeforeStep, deleteWordSelection, deleteCollapsedSelection, deleteList];\n}\n\nfunction shouldDeleteWithContentModel(selection: DOMSelection | null, rawEvent: KeyboardEvent) {\n if (!selection) {\n return false; // Nothing to delete\n } else if (selection.type != 'range' || !selection.range.collapsed) {\n return true; // Selection is not collapsed, need to delete all selections\n } else {\n const range = selection.range;\n\n // When selection is collapsed and is in middle of text node, no need to use Content Model to delete\n return !(\n isNodeOfType(range.startContainer, 'TEXT_NODE') &&\n !isModifierKey(rawEvent) &&\n (canDeleteBefore(rawEvent, range) || canDeleteAfter(rawEvent, range))\n );\n }\n}\n\nfunction canDeleteBefore(rawEvent: KeyboardEvent, range: Range) {\n return rawEvent.key == 'Backspace' && range.startOffset > 1;\n}\n\nfunction canDeleteAfter(rawEvent: KeyboardEvent, range: Range) {\n return (\n rawEvent.key == 'Delete' &&\n range.startOffset < (range.startContainer.nodeValue?.length ?? 0) - 1\n );\n}\n"]}
@@ -1,5 +1,5 @@
1
- import type { IStandaloneEditor } from 'roosterjs-content-model-types';
1
+ import type { IEditor } from 'roosterjs-content-model-types';
2
2
  /**
3
3
  * @internal
4
4
  */
5
- export declare function keyboardInput(editor: IStandaloneEditor, rawEvent: KeyboardEvent): true | undefined;
5
+ export declare function keyboardInput(editor: IEditor, rawEvent: KeyboardEvent): true | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"keyboardInput.js","sourceRoot":"","sources":["../../../../packages-content-model/roosterjs-content-model-plugins/lib/edit/keyboardInput.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC9E,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AAGpE;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,MAAyB,EAAE,QAAuB;IAC5E,IAAM,SAAS,GAAG,MAAM,CAAC,eAAe,EAAE,CAAC;IAE3C,IAAI,2BAA2B,CAAC,SAAS,EAAE,QAAQ,CAAC,EAAE;QAClD,MAAM,CAAC,YAAY,EAAE,CAAC;QAEtB,MAAM,CAAC,kBAAkB,CACrB,UAAC,KAAK,EAAE,OAAO;;YACX,IAAM,MAAM,GAAG,eAAe,CAAC,KAAK,EAAE,aAAa,CAAC,SAAS,EAAE,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC;YAEnF,0EAA0E;YAC1E,qFAAqF;YACrF,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;YAE/B,oJAAoJ;YACpJ,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;YAEhC,IAAI,MAAM,CAAC,YAAY,IAAI,OAAO,EAAE;gBAChC,2HAA2H;gBAC3H,OAAO,CAAC,gBAAgB,GAAG,MAAA,MAAM,CAAC,WAAW,0CAAE,MAAM,CAAC,MAAM,CAAC;gBAE7D,qBAAqB,CAAC,KAAK,CAAC,CAAC;gBAE7B,sFAAsF;gBACtF,OAAO,IAAI,CAAC;aACf;iBAAM;gBACH,OAAO,KAAK,CAAC;aAChB;QACL,CAAC,EACD;YACI,QAAQ,UAAA;SACX,CACJ,CAAC;QAEF,OAAO,IAAI,CAAC;KACf;AACL,CAAC;AAED,SAAS,aAAa,CAAC,SAA8B,EAAE,QAAuB;IAC1E,OAAO,oBAAoB,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAChF,CAAC;AAED,SAAS,2BAA2B,CAAC,SAA8B,EAAE,QAAuB;IACxF,IAAI,CAAC,SAAS,EAAE;QACZ,OAAO,KAAK,CAAC,CAAC,oBAAoB;KACrC;SAAM,IACH,CAAC,aAAa,CAAC,QAAQ,CAAC;QACxB,CAAC,QAAQ,CAAC,GAAG,IAAI,OAAO,IAAI,QAAQ,CAAC,GAAG,IAAI,OAAO,IAAI,QAAQ,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC,EAClF;QACE,OAAO,CACH,SAAS,CAAC,IAAI,IAAI,OAAO;YACzB,CAAC,SAAS,CAAC,KAAK,CAAC,SAAS;YAC1B,oBAAoB,CAAC,SAAS,EAAE,QAAQ,CAAC,CAC5C,CAAC;KACL;SAAM;QACH,OAAO,KAAK,CAAC;KAChB;AACL,CAAC;AAED,IAAM,oBAAoB,GAAG,UAAC,SAA8B,EAAE,QAAuB;IACjF,OAAO,SAAS,IAAI,SAAS,CAAC,IAAI,IAAI,OAAO,IAAI,QAAQ,CAAC,GAAG,IAAI,OAAO,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;AACnG,CAAC,CAAC","sourcesContent":["import { deleteSelection, isModifierKey } from 'roosterjs-content-model-core';\nimport { handleEnterOnList } from './inputSteps/handleEnterOnList';\nimport { normalizeContentModel } from 'roosterjs-content-model-dom';\nimport type { DOMSelection, IStandaloneEditor } from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\nexport function keyboardInput(editor: IStandaloneEditor, rawEvent: KeyboardEvent) {\n const selection = editor.getDOMSelection();\n\n if (shouldInputWithContentModel(selection, rawEvent)) {\n editor.takeSnapshot();\n\n editor.formatContentModel(\n (model, context) => {\n const result = deleteSelection(model, getInputSteps(selection, rawEvent), context);\n\n // We have deleted selection then we will let browser to handle the input.\n // With this combined operation, we don't wan to mass up the cached model so clear it\n context.clearModelCache = true;\n\n // Skip undo snapshot here and add undo snapshot before the operation so that we don't add another undo snapshot in middle of this replace operation\n context.skipUndoSnapshot = true;\n\n if (result.deleteResult == 'range') {\n // We have deleted something, next input should inherit the segment format from deleted content, so set pending format here\n context.newPendingFormat = result.insertPoint?.marker.format;\n\n normalizeContentModel(model);\n\n // Do not preventDefault since we still want browser to handle the final input for now\n return true;\n } else {\n return false;\n }\n },\n {\n rawEvent,\n }\n );\n\n return true;\n }\n}\n\nfunction getInputSteps(selection: DOMSelection | null, rawEvent: KeyboardEvent) {\n return shouldHandleEnterKey(selection, rawEvent) ? [handleEnterOnList] : [];\n}\n\nfunction shouldInputWithContentModel(selection: DOMSelection | null, rawEvent: KeyboardEvent) {\n if (!selection) {\n return false; // Nothing to delete\n } else if (\n !isModifierKey(rawEvent) &&\n (rawEvent.key == 'Enter' || rawEvent.key == 'Space' || rawEvent.key.length == 1)\n ) {\n return (\n selection.type != 'range' ||\n !selection.range.collapsed ||\n shouldHandleEnterKey(selection, rawEvent)\n );\n } else {\n return false;\n }\n}\n\nconst shouldHandleEnterKey = (selection: DOMSelection | null, rawEvent: KeyboardEvent) => {\n return selection && selection.type == 'range' && rawEvent.key == 'Enter' && !rawEvent.shiftKey;\n};\n"]}
1
+ {"version":3,"file":"keyboardInput.js","sourceRoot":"","sources":["../../../../packages-content-model/roosterjs-content-model-plugins/lib/edit/keyboardInput.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC9E,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AAGpE;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,MAAe,EAAE,QAAuB;IAClE,IAAM,SAAS,GAAG,MAAM,CAAC,eAAe,EAAE,CAAC;IAE3C,IAAI,2BAA2B,CAAC,SAAS,EAAE,QAAQ,CAAC,EAAE;QAClD,MAAM,CAAC,YAAY,EAAE,CAAC;QAEtB,MAAM,CAAC,kBAAkB,CACrB,UAAC,KAAK,EAAE,OAAO;;YACX,IAAM,MAAM,GAAG,eAAe,CAAC,KAAK,EAAE,aAAa,CAAC,SAAS,EAAE,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC;YAEnF,0EAA0E;YAC1E,qFAAqF;YACrF,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;YAE/B,oJAAoJ;YACpJ,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;YAEhC,IAAI,MAAM,CAAC,YAAY,IAAI,OAAO,EAAE;gBAChC,2HAA2H;gBAC3H,OAAO,CAAC,gBAAgB,GAAG,MAAA,MAAM,CAAC,WAAW,0CAAE,MAAM,CAAC,MAAM,CAAC;gBAE7D,qBAAqB,CAAC,KAAK,CAAC,CAAC;gBAE7B,sFAAsF;gBACtF,OAAO,IAAI,CAAC;aACf;iBAAM;gBACH,OAAO,KAAK,CAAC;aAChB;QACL,CAAC,EACD;YACI,QAAQ,UAAA;SACX,CACJ,CAAC;QAEF,OAAO,IAAI,CAAC;KACf;AACL,CAAC;AAED,SAAS,aAAa,CAAC,SAA8B,EAAE,QAAuB;IAC1E,OAAO,oBAAoB,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAChF,CAAC;AAED,SAAS,2BAA2B,CAAC,SAA8B,EAAE,QAAuB;IACxF,IAAI,CAAC,SAAS,EAAE;QACZ,OAAO,KAAK,CAAC,CAAC,oBAAoB;KACrC;SAAM,IACH,CAAC,aAAa,CAAC,QAAQ,CAAC;QACxB,CAAC,QAAQ,CAAC,GAAG,IAAI,OAAO,IAAI,QAAQ,CAAC,GAAG,IAAI,OAAO,IAAI,QAAQ,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC,EAClF;QACE,OAAO,CACH,SAAS,CAAC,IAAI,IAAI,OAAO;YACzB,CAAC,SAAS,CAAC,KAAK,CAAC,SAAS;YAC1B,oBAAoB,CAAC,SAAS,EAAE,QAAQ,CAAC,CAC5C,CAAC;KACL;SAAM;QACH,OAAO,KAAK,CAAC;KAChB;AACL,CAAC;AAED,IAAM,oBAAoB,GAAG,UAAC,SAA8B,EAAE,QAAuB;IACjF,OAAO,SAAS,IAAI,SAAS,CAAC,IAAI,IAAI,OAAO,IAAI,QAAQ,CAAC,GAAG,IAAI,OAAO,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;AACnG,CAAC,CAAC","sourcesContent":["import { deleteSelection, isModifierKey } from 'roosterjs-content-model-core';\nimport { handleEnterOnList } from './inputSteps/handleEnterOnList';\nimport { normalizeContentModel } from 'roosterjs-content-model-dom';\nimport type { DOMSelection, IEditor } from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\nexport function keyboardInput(editor: IEditor, rawEvent: KeyboardEvent) {\n const selection = editor.getDOMSelection();\n\n if (shouldInputWithContentModel(selection, rawEvent)) {\n editor.takeSnapshot();\n\n editor.formatContentModel(\n (model, context) => {\n const result = deleteSelection(model, getInputSteps(selection, rawEvent), context);\n\n // We have deleted selection then we will let browser to handle the input.\n // With this combined operation, we don't wan to mass up the cached model so clear it\n context.clearModelCache = true;\n\n // Skip undo snapshot here and add undo snapshot before the operation so that we don't add another undo snapshot in middle of this replace operation\n context.skipUndoSnapshot = true;\n\n if (result.deleteResult == 'range') {\n // We have deleted something, next input should inherit the segment format from deleted content, so set pending format here\n context.newPendingFormat = result.insertPoint?.marker.format;\n\n normalizeContentModel(model);\n\n // Do not preventDefault since we still want browser to handle the final input for now\n return true;\n } else {\n return false;\n }\n },\n {\n rawEvent,\n }\n );\n\n return true;\n }\n}\n\nfunction getInputSteps(selection: DOMSelection | null, rawEvent: KeyboardEvent) {\n return shouldHandleEnterKey(selection, rawEvent) ? [handleEnterOnList] : [];\n}\n\nfunction shouldInputWithContentModel(selection: DOMSelection | null, rawEvent: KeyboardEvent) {\n if (!selection) {\n return false; // Nothing to delete\n } else if (\n !isModifierKey(rawEvent) &&\n (rawEvent.key == 'Enter' || rawEvent.key == 'Space' || rawEvent.key.length == 1)\n ) {\n return (\n selection.type != 'range' ||\n !selection.range.collapsed ||\n shouldHandleEnterKey(selection, rawEvent)\n );\n } else {\n return false;\n }\n}\n\nconst shouldHandleEnterKey = (selection: DOMSelection | null, rawEvent: KeyboardEvent) => {\n return selection && selection.type == 'range' && rawEvent.key == 'Enter' && !rawEvent.shiftKey;\n};\n"]}
@@ -1,5 +1,5 @@
1
- import type { IStandaloneEditor } from 'roosterjs-content-model-types';
1
+ import type { IEditor } from 'roosterjs-content-model-types';
2
2
  /**
3
3
  * @internal
4
4
  */
5
- export declare function keyboardTab(editor: IStandaloneEditor, rawEvent: KeyboardEvent): true | undefined;
5
+ export declare function keyboardTab(editor: IEditor, rawEvent: KeyboardEvent): true | undefined;
@@ -1,4 +1,6 @@
1
1
  import { getOperationalBlocks, isBlockGroupOfType } from 'roosterjs-content-model-core';
2
+ import { handleTabOnList } from './tabUtils/handleTabOnList';
3
+ import { handleTabOnParagraph } from './tabUtils/handleTabOnParagraph';
2
4
  import { setModelIndentation } from 'roosterjs-content-model-api';
3
5
  /**
4
6
  * @internal
@@ -6,26 +8,32 @@ import { setModelIndentation } from 'roosterjs-content-model-api';
6
8
  export function keyboardTab(editor, rawEvent) {
7
9
  var selection = editor.getDOMSelection();
8
10
  if ((selection === null || selection === void 0 ? void 0 : selection.type) == 'range') {
9
- editor.takeSnapshot();
10
- editor.formatContentModel(function (model, _context) {
11
- return handleTabOnList(model, rawEvent);
11
+ editor.formatContentModel(function (model) {
12
+ return handleTab(model, rawEvent);
13
+ }, {
14
+ apiName: 'handleTabKey',
12
15
  });
13
16
  return true;
14
17
  }
15
18
  }
16
- function isMarkerAtStartOfBlock(listItem) {
17
- return (listItem.blocks[0].blockType == 'Paragraph' &&
18
- listItem.blocks[0].segments[0].segmentType == 'SelectionMarker');
19
- }
20
- function handleTabOnList(model, rawEvent) {
19
+ /**
20
+ * If multiple blocks are selected, indent or outdent the selected blocks with setModelIndentation.
21
+ * If only one block is selected, call handleTabOnParagraph or handleTabOnList to handle the tab key.
22
+ */
23
+ function handleTab(model, rawEvent) {
21
24
  var blocks = getOperationalBlocks(model, ['ListItem'], ['TableCell']);
22
- var listItem = blocks[0].block;
23
- if (isBlockGroupOfType(listItem, 'ListItem') &&
24
- isMarkerAtStartOfBlock(listItem)) {
25
+ var block = blocks.length > 0 ? blocks[0].block : undefined;
26
+ if (blocks.length > 1) {
25
27
  setModelIndentation(model, rawEvent.shiftKey ? 'outdent' : 'indent');
26
28
  rawEvent.preventDefault();
27
29
  return true;
28
30
  }
31
+ else if ((block === null || block === void 0 ? void 0 : block.blockType) === 'Paragraph') {
32
+ return handleTabOnParagraph(model, block, rawEvent);
33
+ }
34
+ else if (isBlockGroupOfType(block, 'ListItem')) {
35
+ return handleTabOnList(model, block, rawEvent);
36
+ }
29
37
  return false;
30
38
  }
31
39
  //# sourceMappingURL=keyboardTab.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"keyboardTab.js","sourceRoot":"","sources":["../../../../packages-content-model/roosterjs-content-model-plugins/lib/edit/keyboardTab.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AACxF,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAOlE;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,MAAyB,EAAE,QAAuB;IAC1E,IAAM,SAAS,GAAG,MAAM,CAAC,eAAe,EAAE,CAAC;IAE3C,IAAI,CAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,IAAI,KAAI,OAAO,EAAE;QAC5B,MAAM,CAAC,YAAY,EAAE,CAAC;QAEtB,MAAM,CAAC,kBAAkB,CAAC,UAAC,KAAK,EAAE,QAAQ;YACtC,OAAO,eAAe,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC;KACf;AACL,CAAC;AAED,SAAS,sBAAsB,CAAC,QAA8B;IAC1D,OAAO,CACH,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,IAAI,WAAW;QAC3C,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,WAAW,IAAI,iBAAiB,CAClE,CAAC;AACN,CAAC;AAED,SAAS,eAAe,CAAC,KAA2B,EAAE,QAAuB;IACzE,IAAM,MAAM,GAAG,oBAAoB,CAAuB,KAAK,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;IAC9F,IAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAEjC,IACI,kBAAkB,CAAuB,QAAQ,EAAE,UAAU,CAAC;QAC9D,sBAAsB,CAAC,QAAQ,CAAC,EAClC;QACE,mBAAmB,CAAC,KAAK,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QACrE,QAAQ,CAAC,cAAc,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC;KACf;IACD,OAAO,KAAK,CAAC;AACjB,CAAC","sourcesContent":["import { getOperationalBlocks, isBlockGroupOfType } from 'roosterjs-content-model-core';\nimport { setModelIndentation } from 'roosterjs-content-model-api';\nimport type {\n ContentModelDocument,\n ContentModelListItem,\n IStandaloneEditor,\n} from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\nexport function keyboardTab(editor: IStandaloneEditor, rawEvent: KeyboardEvent) {\n const selection = editor.getDOMSelection();\n\n if (selection?.type == 'range') {\n editor.takeSnapshot();\n\n editor.formatContentModel((model, _context) => {\n return handleTabOnList(model, rawEvent);\n });\n\n return true;\n }\n}\n\nfunction isMarkerAtStartOfBlock(listItem: ContentModelListItem) {\n return (\n listItem.blocks[0].blockType == 'Paragraph' &&\n listItem.blocks[0].segments[0].segmentType == 'SelectionMarker'\n );\n}\n\nfunction handleTabOnList(model: ContentModelDocument, rawEvent: KeyboardEvent) {\n const blocks = getOperationalBlocks<ContentModelListItem>(model, ['ListItem'], ['TableCell']);\n const listItem = blocks[0].block;\n\n if (\n isBlockGroupOfType<ContentModelListItem>(listItem, 'ListItem') &&\n isMarkerAtStartOfBlock(listItem)\n ) {\n setModelIndentation(model, rawEvent.shiftKey ? 'outdent' : 'indent');\n rawEvent.preventDefault();\n return true;\n }\n return false;\n}\n"]}
1
+ {"version":3,"file":"keyboardTab.js","sourceRoot":"","sources":["../../../../packages-content-model/roosterjs-content-model-plugins/lib/edit/keyboardTab.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AACxF,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAOlE;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,MAAe,EAAE,QAAuB;IAChE,IAAM,SAAS,GAAG,MAAM,CAAC,eAAe,EAAE,CAAC;IAE3C,IAAI,CAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,IAAI,KAAI,OAAO,EAAE;QAC5B,MAAM,CAAC,kBAAkB,CACrB,UAAA,KAAK;YACD,OAAO,SAAS,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QACtC,CAAC,EACD;YACI,OAAO,EAAE,cAAc;SAC1B,CACJ,CAAC;QAEF,OAAO,IAAI,CAAC;KACf;AACL,CAAC;AAED;;;GAGG;AACH,SAAS,SAAS,CAAC,KAA2B,EAAE,QAAuB;IACnE,IAAM,MAAM,GAAG,oBAAoB,CAAuB,KAAK,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;IAC9F,IAAM,KAAK,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IAC9D,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE;QACnB,mBAAmB,CAAC,KAAK,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QACrE,QAAQ,CAAC,cAAc,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC;KACf;SAAM,IAAI,CAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,SAAS,MAAK,WAAW,EAAE;QACzC,OAAO,oBAAoB,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;KACvD;SAAM,IAAI,kBAAkB,CAAuB,KAAK,EAAE,UAAU,CAAC,EAAE;QACpE,OAAO,eAAe,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;KAClD;IACD,OAAO,KAAK,CAAC;AACjB,CAAC","sourcesContent":["import { getOperationalBlocks, isBlockGroupOfType } from 'roosterjs-content-model-core';\nimport { handleTabOnList } from './tabUtils/handleTabOnList';\nimport { handleTabOnParagraph } from './tabUtils/handleTabOnParagraph';\nimport { setModelIndentation } from 'roosterjs-content-model-api';\nimport type {\n ContentModelDocument,\n ContentModelListItem,\n IEditor,\n} from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\nexport function keyboardTab(editor: IEditor, rawEvent: KeyboardEvent) {\n const selection = editor.getDOMSelection();\n\n if (selection?.type == 'range') {\n editor.formatContentModel(\n model => {\n return handleTab(model, rawEvent);\n },\n {\n apiName: 'handleTabKey',\n }\n );\n\n return true;\n }\n}\n\n/**\n * If multiple blocks are selected, indent or outdent the selected blocks with setModelIndentation.\n * If only one block is selected, call handleTabOnParagraph or handleTabOnList to handle the tab key.\n */\nfunction handleTab(model: ContentModelDocument, rawEvent: KeyboardEvent) {\n const blocks = getOperationalBlocks<ContentModelListItem>(model, ['ListItem'], ['TableCell']);\n const block = blocks.length > 0 ? blocks[0].block : undefined;\n if (blocks.length > 1) {\n setModelIndentation(model, rawEvent.shiftKey ? 'outdent' : 'indent');\n rawEvent.preventDefault();\n return true;\n } else if (block?.blockType === 'Paragraph') {\n return handleTabOnParagraph(model, block, rawEvent);\n } else if (isBlockGroupOfType<ContentModelListItem>(block, 'ListItem')) {\n return handleTabOnList(model, block, rawEvent);\n }\n return false;\n}\n"]}
@@ -0,0 +1,7 @@
1
+ import type { ContentModelDocument, ContentModelListItem } from 'roosterjs-content-model-types';
2
+ /**
3
+ * 1. When the selection is collapsed and the cursor is at start of a list item, call setModelIndentation.
4
+ * 2. Otherwise call handleTabOnParagraph.
5
+ * @internal
6
+ */
7
+ export declare function handleTabOnList(model: ContentModelDocument, listItem: ContentModelListItem, rawEvent: KeyboardEvent): boolean;
@@ -0,0 +1,30 @@
1
+ import { handleTabOnParagraph } from './handleTabOnParagraph';
2
+ import { setModelIndentation } from 'roosterjs-content-model-api';
3
+ /**
4
+ * 1. When the selection is collapsed and the cursor is at start of a list item, call setModelIndentation.
5
+ * 2. Otherwise call handleTabOnParagraph.
6
+ * @internal
7
+ */
8
+ export function handleTabOnList(model, listItem, rawEvent) {
9
+ var selectedParagraph = findSelectedParagraph(listItem);
10
+ if (!isMarkerAtStartOfBlock(listItem) &&
11
+ selectedParagraph.length == 1 &&
12
+ selectedParagraph[0].blockType === 'Paragraph') {
13
+ return handleTabOnParagraph(model, selectedParagraph[0], rawEvent);
14
+ }
15
+ else {
16
+ setModelIndentation(model, rawEvent.shiftKey ? 'outdent' : 'indent');
17
+ rawEvent.preventDefault();
18
+ return true;
19
+ }
20
+ }
21
+ function isMarkerAtStartOfBlock(listItem) {
22
+ return (listItem.blocks[0].blockType == 'Paragraph' &&
23
+ listItem.blocks[0].segments[0].segmentType == 'SelectionMarker');
24
+ }
25
+ function findSelectedParagraph(listItem) {
26
+ return listItem.blocks.filter(function (block) {
27
+ return block.blockType == 'Paragraph' && block.segments.some(function (segment) { return segment.isSelected; });
28
+ });
29
+ }
30
+ //# sourceMappingURL=handleTabOnList.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handleTabOnList.js","sourceRoot":"","sources":["../../../../../packages-content-model/roosterjs-content-model-plugins/lib/edit/tabUtils/handleTabOnList.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAGlE;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAC3B,KAA2B,EAC3B,QAA8B,EAC9B,QAAuB;IAEvB,IAAM,iBAAiB,GAAG,qBAAqB,CAAC,QAAQ,CAAC,CAAC;IAC1D,IACI,CAAC,sBAAsB,CAAC,QAAQ,CAAC;QACjC,iBAAiB,CAAC,MAAM,IAAI,CAAC;QAC7B,iBAAiB,CAAC,CAAC,CAAC,CAAC,SAAS,KAAK,WAAW,EAChD;QACE,OAAO,oBAAoB,CAAC,KAAK,EAAE,iBAAiB,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;KACtE;SAAM;QACH,mBAAmB,CAAC,KAAK,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QACrE,QAAQ,CAAC,cAAc,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC;KACf;AACL,CAAC;AAED,SAAS,sBAAsB,CAAC,QAA8B;IAC1D,OAAO,CACH,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,IAAI,WAAW;QAC3C,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,WAAW,IAAI,iBAAiB,CAClE,CAAC;AACN,CAAC;AAED,SAAS,qBAAqB,CAAC,QAA8B;IACzD,OAAO,QAAQ,CAAC,MAAM,CAAC,MAAM,CACzB,UAAA,KAAK;QACD,OAAA,KAAK,CAAC,SAAS,IAAI,WAAW,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAA,OAAO,IAAI,OAAA,OAAO,CAAC,UAAU,EAAlB,CAAkB,CAAC;IAApF,CAAoF,CAC3F,CAAC;AACN,CAAC","sourcesContent":["import { handleTabOnParagraph } from './handleTabOnParagraph';\nimport { setModelIndentation } from 'roosterjs-content-model-api';\nimport type { ContentModelDocument, ContentModelListItem } from 'roosterjs-content-model-types';\n\n/**\n * 1. When the selection is collapsed and the cursor is at start of a list item, call setModelIndentation.\n * 2. Otherwise call handleTabOnParagraph.\n * @internal\n */\nexport function handleTabOnList(\n model: ContentModelDocument,\n listItem: ContentModelListItem,\n rawEvent: KeyboardEvent\n) {\n const selectedParagraph = findSelectedParagraph(listItem);\n if (\n !isMarkerAtStartOfBlock(listItem) &&\n selectedParagraph.length == 1 &&\n selectedParagraph[0].blockType === 'Paragraph'\n ) {\n return handleTabOnParagraph(model, selectedParagraph[0], rawEvent);\n } else {\n setModelIndentation(model, rawEvent.shiftKey ? 'outdent' : 'indent');\n rawEvent.preventDefault();\n return true;\n }\n}\n\nfunction isMarkerAtStartOfBlock(listItem: ContentModelListItem) {\n return (\n listItem.blocks[0].blockType == 'Paragraph' &&\n listItem.blocks[0].segments[0].segmentType == 'SelectionMarker'\n );\n}\n\nfunction findSelectedParagraph(listItem: ContentModelListItem) {\n return listItem.blocks.filter(\n block =>\n block.blockType == 'Paragraph' && block.segments.some(segment => segment.isSelected)\n );\n}\n"]}
@@ -0,0 +1,17 @@
1
+ import type { ContentModelDocument, ContentModelParagraph } from 'roosterjs-content-model-types';
2
+ /**
3
+ * @internal
4
+ The handleTabOnParagraph function will handle the tab key in following scenarios:
5
+ * 1. When the selection is collapsed and the cursor is at the end of a paragraph, add 4 spaces.
6
+ * 2. When the selection is collapsed and the cursor is at the start of a paragraph, call setModelIndention function to indent the whole paragraph
7
+ * 3. When the selection is collapsed and the cursor is at the middle of a paragraph, add 4 spaces.
8
+ * 4. When the selection is not collapsed, replace the selected range with a single space.
9
+ * 5. When the selection is not collapsed, but all segments are selected, call setModelIndention function to indent the whole paragraph
10
+ The handleTabOnParagraph function will handle the shift + tab key in a indented paragraph in following scenarios:
11
+ * 1. When the selection is collapsed and the cursor is at the end of a paragraph, remove 4 spaces.
12
+ * 2. When the selection is collapsed and the cursor is at the start of a paragraph, call setModelIndention function to outdent the whole paragraph
13
+ * 3. When the selection is collapsed and the cursor is at the middle of a paragraph, remove 4 spaces.
14
+ * 4. When the selection is not collapsed, replace the selected range with a 4 space.
15
+ * 5. When the selection is not collapsed, but all segments are selected, call setModelIndention function to outdent the whole paragraph
16
+ */
17
+ export declare function handleTabOnParagraph(model: ContentModelDocument, paragraph: ContentModelParagraph, rawEvent: KeyboardEvent): boolean;
@@ -0,0 +1,77 @@
1
+ import { createSelectionMarker, createText } from 'roosterjs-content-model-dom';
2
+ import { setModelIndentation } from 'roosterjs-content-model-api';
3
+ var tabSpaces = '    ';
4
+ var space = ' ';
5
+ /**
6
+ * @internal
7
+ The handleTabOnParagraph function will handle the tab key in following scenarios:
8
+ * 1. When the selection is collapsed and the cursor is at the end of a paragraph, add 4 spaces.
9
+ * 2. When the selection is collapsed and the cursor is at the start of a paragraph, call setModelIndention function to indent the whole paragraph
10
+ * 3. When the selection is collapsed and the cursor is at the middle of a paragraph, add 4 spaces.
11
+ * 4. When the selection is not collapsed, replace the selected range with a single space.
12
+ * 5. When the selection is not collapsed, but all segments are selected, call setModelIndention function to indent the whole paragraph
13
+ The handleTabOnParagraph function will handle the shift + tab key in a indented paragraph in following scenarios:
14
+ * 1. When the selection is collapsed and the cursor is at the end of a paragraph, remove 4 spaces.
15
+ * 2. When the selection is collapsed and the cursor is at the start of a paragraph, call setModelIndention function to outdent the whole paragraph
16
+ * 3. When the selection is collapsed and the cursor is at the middle of a paragraph, remove 4 spaces.
17
+ * 4. When the selection is not collapsed, replace the selected range with a 4 space.
18
+ * 5. When the selection is not collapsed, but all segments are selected, call setModelIndention function to outdent the whole paragraph
19
+ */
20
+ export function handleTabOnParagraph(model, paragraph, rawEvent) {
21
+ var selectedSegments = paragraph.segments.filter(function (segment) { return segment.isSelected; });
22
+ var isCollapsed = selectedSegments.length === 1 && selectedSegments[0].segmentType === 'SelectionMarker';
23
+ var isAllSelected = paragraph.segments.every(function (segment) { return segment.isSelected; });
24
+ if ((paragraph.segments[0].segmentType === 'SelectionMarker' && isCollapsed) || isAllSelected) {
25
+ setModelIndentation(model, rawEvent.shiftKey ? 'outdent' : 'indent');
26
+ }
27
+ else {
28
+ if (!isCollapsed) {
29
+ var firstSelectedSegmentIndex_1 = undefined;
30
+ var lastSelectedSegmentIndex_1 = undefined;
31
+ paragraph.segments.forEach(function (segment, index) {
32
+ if (segment.isSelected) {
33
+ if (!firstSelectedSegmentIndex_1) {
34
+ firstSelectedSegmentIndex_1 = index;
35
+ }
36
+ lastSelectedSegmentIndex_1 = index;
37
+ }
38
+ });
39
+ if (firstSelectedSegmentIndex_1 && lastSelectedSegmentIndex_1) {
40
+ var firstSelectedSegment = paragraph.segments[firstSelectedSegmentIndex_1];
41
+ var spaceText = createText(rawEvent.shiftKey ? tabSpaces : space, firstSelectedSegment.format);
42
+ var marker = createSelectionMarker(firstSelectedSegment.format);
43
+ paragraph.segments.splice(firstSelectedSegmentIndex_1, lastSelectedSegmentIndex_1 - firstSelectedSegmentIndex_1 + 1, spaceText, marker);
44
+ }
45
+ else {
46
+ return false;
47
+ }
48
+ }
49
+ else {
50
+ var markerIndex = paragraph.segments.findIndex(function (segment) { return segment.segmentType === 'SelectionMarker'; });
51
+ if (!rawEvent.shiftKey) {
52
+ var markerFormat = paragraph.segments[markerIndex].format;
53
+ var tabText = createText(tabSpaces, markerFormat);
54
+ paragraph.segments.splice(markerIndex, 0, tabText);
55
+ }
56
+ else {
57
+ var tabText = paragraph.segments[markerIndex - 1];
58
+ var tabSpacesLength = tabSpaces.length;
59
+ if (tabText.segmentType == 'Text') {
60
+ var tabSpaceTextLength = tabText.text.length - tabSpacesLength;
61
+ if (tabText.text === tabSpaces) {
62
+ paragraph.segments.splice(markerIndex - 1, 1);
63
+ }
64
+ else if (tabText.text.substring(tabSpaceTextLength) === tabSpaces) {
65
+ tabText.text = tabText.text.substring(0, tabSpaceTextLength);
66
+ }
67
+ else {
68
+ return false;
69
+ }
70
+ }
71
+ }
72
+ }
73
+ }
74
+ rawEvent.preventDefault();
75
+ return true;
76
+ }
77
+ //# sourceMappingURL=handleTabOnParagraph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handleTabOnParagraph.js","sourceRoot":"","sources":["../../../../../packages-content-model/roosterjs-content-model-plugins/lib/edit/tabUtils/handleTabOnParagraph.ts"],"names":[],"mappings":"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","sourcesContent":["import { createSelectionMarker, createText } from 'roosterjs-content-model-dom';\nimport { setModelIndentation } from 'roosterjs-content-model-api';\nimport type { ContentModelDocument, ContentModelParagraph } from 'roosterjs-content-model-types';\n\nconst tabSpaces = '    ';\nconst space = ' ';\n\n/**\n * @internal\n The handleTabOnParagraph function will handle the tab key in following scenarios:\n * 1. When the selection is collapsed and the cursor is at the end of a paragraph, add 4 spaces.\n * 2. When the selection is collapsed and the cursor is at the start of a paragraph, call setModelIndention function to indent the whole paragraph\n * 3. When the selection is collapsed and the cursor is at the middle of a paragraph, add 4 spaces.\n * 4. When the selection is not collapsed, replace the selected range with a single space.\n * 5. When the selection is not collapsed, but all segments are selected, call setModelIndention function to indent the whole paragraph\n The handleTabOnParagraph function will handle the shift + tab key in a indented paragraph in following scenarios:\n * 1. When the selection is collapsed and the cursor is at the end of a paragraph, remove 4 spaces.\n * 2. When the selection is collapsed and the cursor is at the start of a paragraph, call setModelIndention function to outdent the whole paragraph\n * 3. When the selection is collapsed and the cursor is at the middle of a paragraph, remove 4 spaces.\n * 4. When the selection is not collapsed, replace the selected range with a 4 space.\n * 5. When the selection is not collapsed, but all segments are selected, call setModelIndention function to outdent the whole paragraph\n */\nexport function handleTabOnParagraph(\n model: ContentModelDocument,\n paragraph: ContentModelParagraph,\n rawEvent: KeyboardEvent\n) {\n const selectedSegments = paragraph.segments.filter(segment => segment.isSelected);\n const isCollapsed =\n selectedSegments.length === 1 && selectedSegments[0].segmentType === 'SelectionMarker';\n const isAllSelected = paragraph.segments.every(segment => segment.isSelected);\n if ((paragraph.segments[0].segmentType === 'SelectionMarker' && isCollapsed) || isAllSelected) {\n setModelIndentation(model, rawEvent.shiftKey ? 'outdent' : 'indent');\n } else {\n if (!isCollapsed) {\n let firstSelectedSegmentIndex: number | undefined = undefined;\n let lastSelectedSegmentIndex: number | undefined = undefined;\n\n paragraph.segments.forEach((segment, index) => {\n if (segment.isSelected) {\n if (!firstSelectedSegmentIndex) {\n firstSelectedSegmentIndex = index;\n }\n lastSelectedSegmentIndex = index;\n }\n });\n if (firstSelectedSegmentIndex && lastSelectedSegmentIndex) {\n const firstSelectedSegment = paragraph.segments[firstSelectedSegmentIndex];\n const spaceText = createText(\n rawEvent.shiftKey ? tabSpaces : space,\n firstSelectedSegment.format\n );\n const marker = createSelectionMarker(firstSelectedSegment.format);\n paragraph.segments.splice(\n firstSelectedSegmentIndex,\n lastSelectedSegmentIndex - firstSelectedSegmentIndex + 1,\n spaceText,\n marker\n );\n } else {\n return false;\n }\n } else {\n const markerIndex = paragraph.segments.findIndex(\n segment => segment.segmentType === 'SelectionMarker'\n );\n if (!rawEvent.shiftKey) {\n const markerFormat = paragraph.segments[markerIndex].format;\n const tabText = createText(tabSpaces, markerFormat);\n paragraph.segments.splice(markerIndex, 0, tabText);\n } else {\n const tabText = paragraph.segments[markerIndex - 1];\n const tabSpacesLength = tabSpaces.length;\n if (tabText.segmentType == 'Text') {\n const tabSpaceTextLength = tabText.text.length - tabSpacesLength;\n if (tabText.text === tabSpaces) {\n paragraph.segments.splice(markerIndex - 1, 1);\n } else if (tabText.text.substring(tabSpaceTextLength) === tabSpaces) {\n tabText.text = tabText.text.substring(0, tabSpaceTextLength);\n } else {\n return false;\n }\n }\n }\n }\n }\n\n rawEvent.preventDefault();\n return true;\n}\n"]}
@@ -1,3 +1,7 @@
1
+ export { TableEditPlugin } from './tableEdit/TableEditPlugin';
1
2
  export { PastePlugin } from './paste/PastePlugin';
2
3
  export { EditPlugin } from './edit/EditPlugin';
3
4
  export { AutoFormatPlugin, AutoFormatOptions } from './autoFormat/AutoFormatPlugin';
5
+ export { ShortcutBold, ShortcutItalic, ShortcutUnderline, ShortcutClearFormat, ShortcutUndo, ShortcutUndo2, ShortcutRedo, ShortcutRedoMacOS, ShortcutBullet, ShortcutNumbering, ShortcutIncreaseFont, ShortcutDecreaseFont, } from './shortcut/shortcuts';
6
+ export { ShortcutPlugin } from './shortcut/ShortcutPlugin';
7
+ export { ShortcutKeyDefinition, ShortcutCommand } from './shortcut/ShortcutCommand';
package/lib-mjs/index.js CHANGED
@@ -1,4 +1,7 @@
1
+ export { TableEditPlugin } from './tableEdit/TableEditPlugin';
1
2
  export { PastePlugin } from './paste/PastePlugin';
2
3
  export { EditPlugin } from './edit/EditPlugin';
3
4
  export { AutoFormatPlugin } from './autoFormat/AutoFormatPlugin';
5
+ export { ShortcutBold, ShortcutItalic, ShortcutUnderline, ShortcutClearFormat, ShortcutUndo, ShortcutUndo2, ShortcutRedo, ShortcutRedoMacOS, ShortcutBullet, ShortcutNumbering, ShortcutIncreaseFont, ShortcutDecreaseFont, } from './shortcut/shortcuts';
6
+ export { ShortcutPlugin } from './shortcut/ShortcutPlugin';
4
7
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../packages-content-model/roosterjs-content-model-plugins/lib/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAqB,MAAM,+BAA+B,CAAC","sourcesContent":["export { PastePlugin } from './paste/PastePlugin';\nexport { EditPlugin } from './edit/EditPlugin';\nexport { AutoFormatPlugin, AutoFormatOptions } from './autoFormat/AutoFormatPlugin';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../packages-content-model/roosterjs-content-model-plugins/lib/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAqB,MAAM,+BAA+B,CAAC;AAEpF,OAAO,EACH,YAAY,EACZ,cAAc,EACd,iBAAiB,EACjB,mBAAmB,EACnB,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,iBAAiB,EACjB,cAAc,EACd,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,GACvB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC","sourcesContent":["export { TableEditPlugin } from './tableEdit/TableEditPlugin';\nexport { PastePlugin } from './paste/PastePlugin';\nexport { EditPlugin } from './edit/EditPlugin';\nexport { AutoFormatPlugin, AutoFormatOptions } from './autoFormat/AutoFormatPlugin';\n\nexport {\n ShortcutBold,\n ShortcutItalic,\n ShortcutUnderline,\n ShortcutClearFormat,\n ShortcutUndo,\n ShortcutUndo2,\n ShortcutRedo,\n ShortcutRedoMacOS,\n ShortcutBullet,\n ShortcutNumbering,\n ShortcutIncreaseFont,\n ShortcutDecreaseFont,\n} from './shortcut/shortcuts';\nexport { ShortcutPlugin } from './shortcut/ShortcutPlugin';\nexport { ShortcutKeyDefinition, ShortcutCommand } from './shortcut/ShortcutCommand';\n"]}
@@ -1,11 +1,10 @@
1
- import type { EditorPlugin, IStandaloneEditor, PluginEvent } from 'roosterjs-content-model-types';
1
+ import type { EditorPlugin, IEditor, PluginEvent } from 'roosterjs-content-model-types';
2
2
  /**
3
3
  * Paste plugin, handles BeforePaste event and reformat some special content, including:
4
4
  * 1. Content copied from Word
5
5
  * 2. Content copied from Excel
6
6
  * 3. Content copied from Word Online or OneNote Online
7
7
  * 4. Content copied from Power Point
8
- * (This class is still under development, and may still be changed in the future with some breaking changes)
9
8
  */
10
9
  export declare class PastePlugin implements EditorPlugin {
11
10
  private allowExcelNoBorderTable?;
@@ -26,7 +25,7 @@ export declare class PastePlugin implements EditorPlugin {
26
25
  * editor reference so that it can call to any editor method or format API later.
27
26
  * @param editor The editor object
28
27
  */
29
- initialize(editor: IStandaloneEditor): void;
28
+ initialize(editor: IEditor): void;
30
29
  /**
31
30
  * The last method that editor will call to a plugin before it is disposed.
32
31
  * Plugin can take this chance to clear the reference to editor. After this method is
@@ -14,7 +14,6 @@ import { processPastedContentWacComponents } from './WacComponents/processPasted
14
14
  * 2. Content copied from Excel
15
15
  * 3. Content copied from Word Online or OneNote Online
16
16
  * 4. Content copied from Power Point
17
- * (This class is still under development, and may still be changed in the future with some breaking changes)
18
17
  */
19
18
  var PastePlugin = /** @class */ (function () {
20
19
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"PastePlugin.js","sourceRoot":"","sources":["../../../../packages-content-model/roosterjs-content-model-plugins/lib/paste/PastePlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import addParser from './utils/addParser';\nimport { BorderKeys } from 'roosterjs-content-model-dom';\nimport { deprecatedBorderColorParser } from './utils/deprecatedColorParser';\nimport { getPasteSource } from './pasteSourceValidations/getPasteSource';\nimport { parseLink } from './utils/linkParser';\nimport { PastePropertyNames } from './pasteSourceValidations/constants';\nimport { processPastedContentFromExcel } from './Excel/processPastedContentFromExcel';\nimport { processPastedContentFromPowerPoint } from './PowerPoint/processPastedContentFromPowerPoint';\nimport { processPastedContentFromWordDesktop } from './WordDesktop/processPastedContentFromWordDesktop';\nimport { processPastedContentWacComponents } from './WacComponents/processPastedContentWacComponents';\nimport type {\n BorderFormat,\n ContentModelBlockFormat,\n ContentModelTableCellFormat,\n EditorPlugin,\n FormatParser,\n IStandaloneEditor,\n PluginEvent,\n} from 'roosterjs-content-model-types';\n\n/**\n * Paste plugin, handles BeforePaste event and reformat some special content, including:\n * 1. Content copied from Word\n * 2. Content copied from Excel\n * 3. Content copied from Word Online or OneNote Online\n * 4. Content copied from Power Point\n * (This class is still under development, and may still be changed in the future with some breaking changes)\n */\nexport class PastePlugin implements EditorPlugin {\n private editor: IStandaloneEditor | null = null;\n\n /**\n * Construct a new instance of Paste class\n * @param unknownTagReplacement Replace solution of unknown tags, default behavior is to replace with SPAN\n * @param allowExcelNoBorderTable Allow table copied from Excel without border\n */\n constructor(private allowExcelNoBorderTable?: boolean) {}\n\n /**\n * Get name of this plugin\n */\n getName() {\n return 'Paste';\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: IStandaloneEditor) {\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 /**\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 || event.eventType != 'beforePaste') {\n return;\n }\n\n if (!event.domToModelOption) {\n return;\n }\n\n const pasteSource = getPasteSource(event, false);\n const pasteType = event.pasteType;\n\n switch (pasteSource) {\n case 'wordDesktop':\n processPastedContentFromWordDesktop(event, this.editor.getTrustedHTMLHandler());\n break;\n case 'wacComponents':\n processPastedContentWacComponents(event);\n break;\n case 'excelOnline':\n case 'excelDesktop':\n if (pasteType === 'normal' || pasteType === 'mergeFormat') {\n // Handle HTML copied from Excel\n processPastedContentFromExcel(\n event,\n this.editor.getTrustedHTMLHandler(),\n this.allowExcelNoBorderTable\n );\n }\n break;\n case 'googleSheets':\n event.domToModelOption.additionalAllowedTags.push(\n PastePropertyNames.GOOGLE_SHEET_NODE_NAME as Lowercase<string>\n );\n break;\n case 'powerPointDesktop':\n processPastedContentFromPowerPoint(event, this.editor.getTrustedHTMLHandler());\n break;\n }\n\n addParser(event.domToModelOption, 'link', parseLink);\n addParser(event.domToModelOption, 'tableCell', deprecatedBorderColorParser);\n addParser(event.domToModelOption, 'tableCell', tableBorderParser);\n addParser(event.domToModelOption, 'table', deprecatedBorderColorParser);\n\n if (pasteType === 'mergeFormat') {\n addParser(event.domToModelOption, 'block', blockElementParser);\n addParser(event.domToModelOption, 'listLevel', blockElementParser);\n }\n }\n}\n\n/**\n * For block elements that have background color style, remove the background color when user selects the merge current format\n * paste option\n */\nconst blockElementParser: FormatParser<ContentModelBlockFormat> = (\n format: ContentModelBlockFormat,\n element: HTMLElement\n) => {\n if (element.style.backgroundColor) {\n delete format.backgroundColor;\n }\n};\n\nconst ElementBorderKeys = new Map<\n keyof BorderFormat,\n {\n c: keyof CSSStyleDeclaration;\n s: keyof CSSStyleDeclaration;\n w: keyof CSSStyleDeclaration;\n }\n>([\n ['borderTop', { w: 'borderTopWidth', s: 'borderTopStyle', c: 'borderTopColor' }],\n ['borderRight', { w: 'borderRightWidth', s: 'borderRightStyle', c: 'borderRightColor' }],\n ['borderBottom', { w: 'borderBottomWidth', s: 'borderBottomStyle', c: 'borderBottomColor' }],\n ['borderLeft', { w: 'borderLeftWidth', s: 'borderLeftStyle', c: 'borderLeftColor' }],\n]);\n\nfunction tableBorderParser(format: ContentModelTableCellFormat, element: HTMLElement): void {\n BorderKeys.forEach(key => {\n if (!format[key]) {\n const styleSet = ElementBorderKeys.get(key);\n if (\n styleSet &&\n element.style[styleSet.w] &&\n element.style[styleSet.s] &&\n !element.style[styleSet.c]\n ) {\n format[key] = `${element.style[styleSet.w]} ${element.style[styleSet.s]}`;\n }\n }\n });\n}\n"]}
1
+ {"version":3,"file":"PastePlugin.js","sourceRoot":"","sources":["../../../../packages-content-model/roosterjs-content-model-plugins/lib/paste/PastePlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import addParser from './utils/addParser';\nimport { BorderKeys } from 'roosterjs-content-model-dom';\nimport { deprecatedBorderColorParser } from './utils/deprecatedColorParser';\nimport { getPasteSource } from './pasteSourceValidations/getPasteSource';\nimport { parseLink } from './utils/linkParser';\nimport { PastePropertyNames } from './pasteSourceValidations/constants';\nimport { processPastedContentFromExcel } from './Excel/processPastedContentFromExcel';\nimport { processPastedContentFromPowerPoint } from './PowerPoint/processPastedContentFromPowerPoint';\nimport { processPastedContentFromWordDesktop } from './WordDesktop/processPastedContentFromWordDesktop';\nimport { processPastedContentWacComponents } from './WacComponents/processPastedContentWacComponents';\nimport type {\n BorderFormat,\n ContentModelBlockFormat,\n ContentModelTableCellFormat,\n EditorPlugin,\n FormatParser,\n IEditor,\n PluginEvent,\n} from 'roosterjs-content-model-types';\n\n/**\n * Paste plugin, handles BeforePaste event and reformat some special content, including:\n * 1. Content copied from Word\n * 2. Content copied from Excel\n * 3. Content copied from Word Online or OneNote Online\n * 4. Content copied from Power Point\n */\nexport class PastePlugin implements EditorPlugin {\n private editor: IEditor | null = null;\n\n /**\n * Construct a new instance of Paste class\n * @param unknownTagReplacement Replace solution of unknown tags, default behavior is to replace with SPAN\n * @param allowExcelNoBorderTable Allow table copied from Excel without border\n */\n constructor(private allowExcelNoBorderTable?: boolean) {}\n\n /**\n * Get name of this plugin\n */\n getName() {\n return 'Paste';\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 /**\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 || event.eventType != 'beforePaste') {\n return;\n }\n\n if (!event.domToModelOption) {\n return;\n }\n\n const pasteSource = getPasteSource(event, false);\n const pasteType = event.pasteType;\n\n switch (pasteSource) {\n case 'wordDesktop':\n processPastedContentFromWordDesktop(event, this.editor.getTrustedHTMLHandler());\n break;\n case 'wacComponents':\n processPastedContentWacComponents(event);\n break;\n case 'excelOnline':\n case 'excelDesktop':\n if (pasteType === 'normal' || pasteType === 'mergeFormat') {\n // Handle HTML copied from Excel\n processPastedContentFromExcel(\n event,\n this.editor.getTrustedHTMLHandler(),\n this.allowExcelNoBorderTable\n );\n }\n break;\n case 'googleSheets':\n event.domToModelOption.additionalAllowedTags.push(\n PastePropertyNames.GOOGLE_SHEET_NODE_NAME as Lowercase<string>\n );\n break;\n case 'powerPointDesktop':\n processPastedContentFromPowerPoint(event, this.editor.getTrustedHTMLHandler());\n break;\n }\n\n addParser(event.domToModelOption, 'link', parseLink);\n addParser(event.domToModelOption, 'tableCell', deprecatedBorderColorParser);\n addParser(event.domToModelOption, 'tableCell', tableBorderParser);\n addParser(event.domToModelOption, 'table', deprecatedBorderColorParser);\n\n if (pasteType === 'mergeFormat') {\n addParser(event.domToModelOption, 'block', blockElementParser);\n addParser(event.domToModelOption, 'listLevel', blockElementParser);\n }\n }\n}\n\n/**\n * For block elements that have background color style, remove the background color when user selects the merge current format\n * paste option\n */\nconst blockElementParser: FormatParser<ContentModelBlockFormat> = (\n format: ContentModelBlockFormat,\n element: HTMLElement\n) => {\n if (element.style.backgroundColor) {\n delete format.backgroundColor;\n }\n};\n\nconst ElementBorderKeys = new Map<\n keyof BorderFormat,\n {\n c: keyof CSSStyleDeclaration;\n s: keyof CSSStyleDeclaration;\n w: keyof CSSStyleDeclaration;\n }\n>([\n ['borderTop', { w: 'borderTopWidth', s: 'borderTopStyle', c: 'borderTopColor' }],\n ['borderRight', { w: 'borderRightWidth', s: 'borderRightStyle', c: 'borderRightColor' }],\n ['borderBottom', { w: 'borderBottomWidth', s: 'borderBottomStyle', c: 'borderBottomColor' }],\n ['borderLeft', { w: 'borderLeftWidth', s: 'borderLeftStyle', c: 'borderLeftColor' }],\n]);\n\nfunction tableBorderParser(format: ContentModelTableCellFormat, element: HTMLElement): void {\n BorderKeys.forEach(key => {\n if (!format[key]) {\n const styleSet = ElementBorderKeys.get(key);\n if (\n styleSet &&\n element.style[styleSet.w] &&\n element.style[styleSet.s] &&\n !element.style[styleSet.c]\n ) {\n format[key] = `${element.style[styleSet.w]} ${element.style[styleSet.s]}`;\n }\n }\n });\n}\n"]}
@@ -0,0 +1,44 @@
1
+ import type { IEditor } from 'roosterjs-content-model-types';
2
+ /**
3
+ * Definition of the shortcut key
4
+ */
5
+ export interface ShortcutKeyDefinition {
6
+ /**
7
+ * Modifier key for this shortcut, allowed values are:
8
+ * ctrl: Ctrl key (or Meta key on MacOS)
9
+ * alt: Alt key
10
+ */
11
+ modifierKey: 'ctrl' | 'alt';
12
+ /**
13
+ * Whether ALT key is required for this shortcut
14
+ */
15
+ shiftKey: boolean;
16
+ /**
17
+ * Key code for this shortcut. The value should be the value of KeyboardEvent.which
18
+ * We are still using key code here rather than key name (event.key) although event.which is deprecated because of globalization.
19
+ * For example, on US keyboard, Shift+Comma="<" but on Spanish keyboard it is ":"
20
+ * And we still want the shortcut key to be registered on the same key, in that case key name is different but key code keeps the same.
21
+ */
22
+ which: number;
23
+ }
24
+ /**
25
+ * Represents a command for shortcut
26
+ */
27
+ export interface ShortcutCommand {
28
+ /**
29
+ * Definition of the shortcut key
30
+ */
31
+ shortcutKey: ShortcutKeyDefinition;
32
+ /**
33
+ * @optional Required environment for this command
34
+ * all: (Default) This feature is available for all environments
35
+ * mac: This feature is available on MacOS only
36
+ * nonMac: This feature is available on OS other than MacOS
37
+ */
38
+ environment?: 'all' | 'mac' | 'nonMac';
39
+ /**
40
+ * The callback function to invoke when this shortcut is triggered
41
+ * @param editor The editor object
42
+ */
43
+ onClick: (editor: IEditor) => void;
44
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ShortcutCommand.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ShortcutCommand.js","sourceRoot":"","sources":["../../../../packages-content-model/roosterjs-content-model-plugins/lib/shortcut/ShortcutCommand.ts"],"names":[],"mappings":"","sourcesContent":["import type { IEditor } from 'roosterjs-content-model-types';\n\n/**\n * Definition of the shortcut key\n */\nexport interface ShortcutKeyDefinition {\n /**\n * Modifier key for this shortcut, allowed values are:\n * ctrl: Ctrl key (or Meta key on MacOS)\n * alt: Alt key\n */\n modifierKey: 'ctrl' | 'alt';\n\n /**\n * Whether ALT key is required for this shortcut\n */\n shiftKey: boolean;\n\n /**\n * Key code for this shortcut. The value should be the value of KeyboardEvent.which\n * We are still using key code here rather than key name (event.key) although event.which is deprecated because of globalization.\n * For example, on US keyboard, Shift+Comma=\"<\" but on Spanish keyboard it is \":\"\n * And we still want the shortcut key to be registered on the same key, in that case key name is different but key code keeps the same.\n */\n which: number;\n}\n\n/**\n * Represents a command for shortcut\n */\nexport interface ShortcutCommand {\n /**\n * Definition of the shortcut key\n */\n shortcutKey: ShortcutKeyDefinition;\n\n /**\n * @optional Required environment for this command\n * all: (Default) This feature is available for all environments\n * mac: This feature is available on MacOS only\n * nonMac: This feature is available on OS other than MacOS\n */\n environment?: 'all' | 'mac' | 'nonMac';\n\n /**\n * The callback function to invoke when this shortcut is triggered\n * @param editor The editor object\n */\n onClick: (editor: IEditor) => void;\n}\n"]}
@@ -0,0 +1,51 @@
1
+ import type { ShortcutCommand } from './ShortcutCommand';
2
+ import type { EditorPlugin, IEditor, PluginEvent } from 'roosterjs-content-model-types';
3
+ /**
4
+ * Shortcut plugin hook on the specified shortcut keys and trigger related format API
5
+ */
6
+ export declare class ShortcutPlugin implements EditorPlugin {
7
+ private shortcuts;
8
+ private editor;
9
+ private isMac;
10
+ /**
11
+ * Create a new instance of ShortcutPlugin
12
+ * @param [shortcuts=defaultShortcuts] Allowed commands
13
+ */
14
+ constructor(shortcuts?: ShortcutCommand[]);
15
+ /**
16
+ * Get name of this plugin
17
+ */
18
+ getName(): string;
19
+ /**
20
+ * The first method that editor will call to a plugin when editor is initializing.
21
+ * It will pass in the editor instance, plugin should take this chance to save the
22
+ * editor reference so that it can call to any editor method or format API later.
23
+ * @param editor The editor object
24
+ */
25
+ initialize(editor: IEditor): void;
26
+ /**
27
+ * The last method that editor will call to a plugin before it is disposed.
28
+ * Plugin can take this chance to clear the reference to editor. After this method is
29
+ * called, plugin should not call to any editor method since it will result in error.
30
+ */
31
+ dispose(): void;
32
+ /**
33
+ * Check if the plugin should handle the given event exclusively.
34
+ * Handle an event exclusively means other plugin will not receive this event in
35
+ * onPluginEvent method.
36
+ * If two plugins will return true in willHandleEventExclusively() for the same event,
37
+ * the final result depends on the order of the plugins are added into editor
38
+ * @param event The event to check:
39
+ */
40
+ willHandleEventExclusively(event: PluginEvent): boolean;
41
+ /**
42
+ * Core method for a plugin. Once an event happens in editor, editor will call this
43
+ * method of each plugin to handle the event as long as the event is not handled
44
+ * exclusively by another plugin.
45
+ * @param event The event to handle:
46
+ */
47
+ onPluginEvent(event: PluginEvent): void;
48
+ private cacheGetCommand;
49
+ private matchOS;
50
+ private matchShortcut;
51
+ }