roosterjs-content-model-plugins 9.1.0 → 9.3.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 (289) hide show
  1. package/lib/autoFormat/AutoFormatPlugin.d.ts +15 -5
  2. package/lib/autoFormat/AutoFormatPlugin.js +41 -4
  3. package/lib/autoFormat/AutoFormatPlugin.js.map +1 -1
  4. package/lib/autoFormat/link/createLink.js +2 -0
  5. package/lib/autoFormat/link/createLink.js.map +1 -1
  6. package/lib/autoFormat/list/keyboardListTrigger.js +7 -9
  7. package/lib/autoFormat/list/keyboardListTrigger.js.map +1 -1
  8. package/lib/autoFormat/numbers/transformFraction.d.ts +5 -0
  9. package/lib/autoFormat/numbers/transformFraction.js +27 -0
  10. package/lib/autoFormat/numbers/transformFraction.js.map +1 -0
  11. package/lib/autoFormat/numbers/transformOrdinals.d.ts +5 -0
  12. package/lib/autoFormat/numbers/transformOrdinals.js +32 -0
  13. package/lib/autoFormat/numbers/transformOrdinals.js.map +1 -0
  14. package/lib/customReplace/CustomReplacePlugin.d.ts +61 -0
  15. package/lib/customReplace/CustomReplacePlugin.js +87 -0
  16. package/lib/customReplace/CustomReplacePlugin.js.map +1 -0
  17. package/lib/edit/EditPlugin.js +19 -1
  18. package/lib/edit/EditPlugin.js.map +1 -1
  19. package/lib/edit/inputSteps/handleEnterOnList.js +8 -1
  20. package/lib/edit/inputSteps/handleEnterOnList.js.map +1 -1
  21. package/lib/edit/keyboardDelete.js +1 -0
  22. package/lib/edit/keyboardDelete.js.map +1 -1
  23. package/lib/edit/keyboardInput.js +1 -0
  24. package/lib/edit/keyboardInput.js.map +1 -1
  25. package/lib/edit/keyboardTab.js +5 -5
  26. package/lib/edit/keyboardTab.js.map +1 -1
  27. package/lib/edit/tabUtils/handleTabOnList.d.ts +2 -2
  28. package/lib/edit/tabUtils/handleTabOnList.js +3 -3
  29. package/lib/edit/tabUtils/handleTabOnList.js.map +1 -1
  30. package/lib/edit/tabUtils/handleTabOnParagraph.d.ts +2 -2
  31. package/lib/edit/tabUtils/handleTabOnParagraph.js +2 -2
  32. package/lib/edit/tabUtils/handleTabOnParagraph.js.map +1 -1
  33. package/lib/hyperlink/HyperlinkPlugin.js +4 -1
  34. package/lib/hyperlink/HyperlinkPlugin.js.map +1 -1
  35. package/lib/index.d.ts +8 -1
  36. package/lib/index.js +8 -1
  37. package/lib/index.js.map +1 -1
  38. package/lib/markdown/utils/setFormat.js +11 -9
  39. package/lib/markdown/utils/setFormat.js.map +1 -1
  40. package/lib/picker/PickerHandler.d.ts +112 -0
  41. package/lib/picker/PickerHandler.js +3 -0
  42. package/lib/picker/PickerHandler.js.map +1 -0
  43. package/lib/picker/PickerHelper.d.ts +22 -0
  44. package/lib/picker/PickerHelper.js +3 -0
  45. package/lib/picker/PickerHelper.js.map +1 -0
  46. package/lib/picker/PickerHelperImpl.d.ts +25 -0
  47. package/lib/picker/PickerHelperImpl.js +54 -0
  48. package/lib/picker/PickerHelperImpl.js.map +1 -0
  49. package/lib/picker/PickerPlugin.d.ts +54 -0
  50. package/lib/picker/PickerPlugin.js +217 -0
  51. package/lib/picker/PickerPlugin.js.map +1 -0
  52. package/lib/picker/getQueryString.d.ts +5 -0
  53. package/lib/picker/getQueryString.js +36 -0
  54. package/lib/picker/getQueryString.js.map +1 -0
  55. package/lib/pluginUtils/Rect/getDOMInsertPointRect.d.ts +7 -0
  56. package/lib/pluginUtils/Rect/getDOMInsertPointRect.js +57 -0
  57. package/lib/pluginUtils/Rect/getDOMInsertPointRect.js.map +1 -0
  58. package/lib/shortcut/ShortcutPlugin.js +1 -0
  59. package/lib/shortcut/ShortcutPlugin.js.map +1 -1
  60. package/lib/shortcut/shortcuts.d.ts +7 -0
  61. package/lib/shortcut/shortcuts.js +15 -1
  62. package/lib/shortcut/shortcuts.js.map +1 -1
  63. package/lib/shortcut/utils/setShortcutIndentationCommand.js +2 -2
  64. package/lib/shortcut/utils/setShortcutIndentationCommand.js.map +1 -1
  65. package/lib/tableEdit/OnTableEditorCreatedCallback.d.ts +5 -0
  66. package/lib/tableEdit/OnTableEditorCreatedCallback.js +3 -0
  67. package/lib/tableEdit/OnTableEditorCreatedCallback.js.map +1 -0
  68. package/lib/tableEdit/TableEditPlugin.d.ts +7 -1
  69. package/lib/tableEdit/TableEditPlugin.js +7 -2
  70. package/lib/tableEdit/TableEditPlugin.js.map +1 -1
  71. package/lib/tableEdit/editors/TableEditor.d.ts +9 -1
  72. package/lib/tableEdit/editors/TableEditor.js +51 -15
  73. package/lib/tableEdit/editors/TableEditor.js.map +1 -1
  74. package/lib/tableEdit/editors/features/CellResizer.d.ts +9 -1
  75. package/lib/tableEdit/editors/features/CellResizer.js +11 -3
  76. package/lib/tableEdit/editors/features/CellResizer.js.map +1 -1
  77. package/lib/tableEdit/editors/features/TableEditFeature.d.ts +1 -1
  78. package/lib/tableEdit/editors/features/TableEditFeature.js +6 -6
  79. package/lib/tableEdit/editors/features/TableEditFeature.js.map +1 -1
  80. package/lib/tableEdit/editors/features/TableEditFeatureName.d.ts +4 -0
  81. package/lib/tableEdit/editors/features/TableEditFeatureName.js +3 -0
  82. package/lib/tableEdit/editors/features/TableEditFeatureName.js.map +1 -0
  83. package/lib/tableEdit/editors/features/TableInserter.d.ts +10 -1
  84. package/lib/tableEdit/editors/features/TableInserter.js +18 -12
  85. package/lib/tableEdit/editors/features/TableInserter.js.map +1 -1
  86. package/lib/tableEdit/editors/features/TableMover.d.ts +48 -3
  87. package/lib/tableEdit/editors/features/TableMover.js +212 -24
  88. package/lib/tableEdit/editors/features/TableMover.js.map +1 -1
  89. package/lib/tableEdit/editors/features/TableResizer.d.ts +7 -2
  90. package/lib/tableEdit/editors/features/TableResizer.js +25 -6
  91. package/lib/tableEdit/editors/features/TableResizer.js.map +1 -1
  92. package/lib/watermark/WatermarkPlugin.d.ts +1 -1
  93. package/lib/watermark/WatermarkPlugin.js +2 -1
  94. package/lib/watermark/WatermarkPlugin.js.map +1 -1
  95. package/lib/watermark/isModelEmptyFast.js +4 -0
  96. package/lib/watermark/isModelEmptyFast.js.map +1 -1
  97. package/lib-amd/autoFormat/AutoFormatPlugin.d.ts +15 -5
  98. package/lib-amd/autoFormat/AutoFormatPlugin.js +39 -5
  99. package/lib-amd/autoFormat/AutoFormatPlugin.js.map +1 -1
  100. package/lib-amd/autoFormat/link/createLink.js +2 -0
  101. package/lib-amd/autoFormat/link/createLink.js.map +1 -1
  102. package/lib-amd/autoFormat/list/keyboardListTrigger.js +7 -9
  103. package/lib-amd/autoFormat/list/keyboardListTrigger.js.map +1 -1
  104. package/lib-amd/autoFormat/numbers/transformFraction.d.ts +5 -0
  105. package/lib-amd/autoFormat/numbers/transformFraction.js +28 -0
  106. package/lib-amd/autoFormat/numbers/transformFraction.js.map +1 -0
  107. package/lib-amd/autoFormat/numbers/transformOrdinals.d.ts +5 -0
  108. package/lib-amd/autoFormat/numbers/transformOrdinals.js +33 -0
  109. package/lib-amd/autoFormat/numbers/transformOrdinals.js.map +1 -0
  110. package/lib-amd/customReplace/CustomReplacePlugin.d.ts +61 -0
  111. package/lib-amd/customReplace/CustomReplacePlugin.js +88 -0
  112. package/lib-amd/customReplace/CustomReplacePlugin.js.map +1 -0
  113. package/lib-amd/edit/EditPlugin.js +19 -1
  114. package/lib-amd/edit/EditPlugin.js.map +1 -1
  115. package/lib-amd/edit/inputSteps/handleEnterOnList.js +8 -2
  116. package/lib-amd/edit/inputSteps/handleEnterOnList.js.map +1 -1
  117. package/lib-amd/edit/keyboardDelete.js +1 -0
  118. package/lib-amd/edit/keyboardDelete.js.map +1 -1
  119. package/lib-amd/edit/keyboardInput.js +1 -0
  120. package/lib-amd/edit/keyboardInput.js.map +1 -1
  121. package/lib-amd/edit/keyboardTab.js +5 -5
  122. package/lib-amd/edit/keyboardTab.js.map +1 -1
  123. package/lib-amd/edit/tabUtils/handleTabOnList.d.ts +2 -2
  124. package/lib-amd/edit/tabUtils/handleTabOnList.js +3 -3
  125. package/lib-amd/edit/tabUtils/handleTabOnList.js.map +1 -1
  126. package/lib-amd/edit/tabUtils/handleTabOnParagraph.d.ts +2 -2
  127. package/lib-amd/edit/tabUtils/handleTabOnParagraph.js +2 -2
  128. package/lib-amd/edit/tabUtils/handleTabOnParagraph.js.map +1 -1
  129. package/lib-amd/hyperlink/HyperlinkPlugin.js +4 -1
  130. package/lib-amd/hyperlink/HyperlinkPlugin.js.map +1 -1
  131. package/lib-amd/index.d.ts +8 -1
  132. package/lib-amd/index.js +6 -2
  133. package/lib-amd/index.js.map +1 -1
  134. package/lib-amd/markdown/utils/setFormat.js +11 -9
  135. package/lib-amd/markdown/utils/setFormat.js.map +1 -1
  136. package/lib-amd/picker/PickerHandler.d.ts +112 -0
  137. package/lib-amd/picker/PickerHandler.js +5 -0
  138. package/lib-amd/picker/PickerHandler.js.map +1 -0
  139. package/lib-amd/picker/PickerHelper.d.ts +22 -0
  140. package/lib-amd/picker/PickerHelper.js +5 -0
  141. package/lib-amd/picker/PickerHelper.js.map +1 -0
  142. package/lib-amd/picker/PickerHelperImpl.d.ts +25 -0
  143. package/lib-amd/picker/PickerHelperImpl.js +53 -0
  144. package/lib-amd/picker/PickerHelperImpl.js.map +1 -0
  145. package/lib-amd/picker/PickerPlugin.d.ts +54 -0
  146. package/lib-amd/picker/PickerPlugin.js +215 -0
  147. package/lib-amd/picker/PickerPlugin.js.map +1 -0
  148. package/lib-amd/picker/getQueryString.d.ts +5 -0
  149. package/lib-amd/picker/getQueryString.js +37 -0
  150. package/lib-amd/picker/getQueryString.js.map +1 -0
  151. package/lib-amd/pluginUtils/Rect/getDOMInsertPointRect.d.ts +7 -0
  152. package/lib-amd/pluginUtils/Rect/getDOMInsertPointRect.js +58 -0
  153. package/lib-amd/pluginUtils/Rect/getDOMInsertPointRect.js.map +1 -0
  154. package/lib-amd/shortcut/ShortcutPlugin.js +1 -0
  155. package/lib-amd/shortcut/ShortcutPlugin.js.map +1 -1
  156. package/lib-amd/shortcut/shortcuts.d.ts +7 -0
  157. package/lib-amd/shortcut/shortcuts.js +15 -1
  158. package/lib-amd/shortcut/shortcuts.js.map +1 -1
  159. package/lib-amd/shortcut/utils/setShortcutIndentationCommand.js +2 -2
  160. package/lib-amd/shortcut/utils/setShortcutIndentationCommand.js.map +1 -1
  161. package/lib-amd/tableEdit/OnTableEditorCreatedCallback.d.ts +5 -0
  162. package/lib-amd/tableEdit/OnTableEditorCreatedCallback.js +5 -0
  163. package/lib-amd/tableEdit/OnTableEditorCreatedCallback.js.map +1 -0
  164. package/lib-amd/tableEdit/TableEditPlugin.d.ts +7 -1
  165. package/lib-amd/tableEdit/TableEditPlugin.js +7 -2
  166. package/lib-amd/tableEdit/TableEditPlugin.js.map +1 -1
  167. package/lib-amd/tableEdit/editors/TableEditor.d.ts +9 -1
  168. package/lib-amd/tableEdit/editors/TableEditor.js +51 -15
  169. package/lib-amd/tableEdit/editors/TableEditor.js.map +1 -1
  170. package/lib-amd/tableEdit/editors/features/CellResizer.d.ts +9 -1
  171. package/lib-amd/tableEdit/editors/features/CellResizer.js +11 -3
  172. package/lib-amd/tableEdit/editors/features/CellResizer.js.map +1 -1
  173. package/lib-amd/tableEdit/editors/features/TableEditFeature.d.ts +1 -1
  174. package/lib-amd/tableEdit/editors/features/TableEditFeature.js +6 -6
  175. package/lib-amd/tableEdit/editors/features/TableEditFeature.js.map +1 -1
  176. package/lib-amd/tableEdit/editors/features/TableEditFeatureName.d.ts +4 -0
  177. package/lib-amd/tableEdit/editors/features/TableEditFeatureName.js +5 -0
  178. package/lib-amd/tableEdit/editors/features/TableEditFeatureName.js.map +1 -0
  179. package/lib-amd/tableEdit/editors/features/TableInserter.d.ts +10 -1
  180. package/lib-amd/tableEdit/editors/features/TableInserter.js +18 -12
  181. package/lib-amd/tableEdit/editors/features/TableInserter.js.map +1 -1
  182. package/lib-amd/tableEdit/editors/features/TableMover.d.ts +48 -3
  183. package/lib-amd/tableEdit/editors/features/TableMover.js +212 -25
  184. package/lib-amd/tableEdit/editors/features/TableMover.js.map +1 -1
  185. package/lib-amd/tableEdit/editors/features/TableResizer.d.ts +7 -2
  186. package/lib-amd/tableEdit/editors/features/TableResizer.js +25 -7
  187. package/lib-amd/tableEdit/editors/features/TableResizer.js.map +1 -1
  188. package/lib-amd/watermark/WatermarkPlugin.d.ts +1 -1
  189. package/lib-amd/watermark/WatermarkPlugin.js +2 -1
  190. package/lib-amd/watermark/WatermarkPlugin.js.map +1 -1
  191. package/lib-amd/watermark/isModelEmptyFast.js +4 -0
  192. package/lib-amd/watermark/isModelEmptyFast.js.map +1 -1
  193. package/lib-mjs/autoFormat/AutoFormatPlugin.d.ts +15 -5
  194. package/lib-mjs/autoFormat/AutoFormatPlugin.js +41 -4
  195. package/lib-mjs/autoFormat/AutoFormatPlugin.js.map +1 -1
  196. package/lib-mjs/autoFormat/link/createLink.js +3 -1
  197. package/lib-mjs/autoFormat/link/createLink.js.map +1 -1
  198. package/lib-mjs/autoFormat/list/keyboardListTrigger.js +7 -9
  199. package/lib-mjs/autoFormat/list/keyboardListTrigger.js.map +1 -1
  200. package/lib-mjs/autoFormat/numbers/transformFraction.d.ts +5 -0
  201. package/lib-mjs/autoFormat/numbers/transformFraction.js +23 -0
  202. package/lib-mjs/autoFormat/numbers/transformFraction.js.map +1 -0
  203. package/lib-mjs/autoFormat/numbers/transformOrdinals.d.ts +5 -0
  204. package/lib-mjs/autoFormat/numbers/transformOrdinals.js +28 -0
  205. package/lib-mjs/autoFormat/numbers/transformOrdinals.js.map +1 -0
  206. package/lib-mjs/customReplace/CustomReplacePlugin.d.ts +61 -0
  207. package/lib-mjs/customReplace/CustomReplacePlugin.js +84 -0
  208. package/lib-mjs/customReplace/CustomReplacePlugin.js.map +1 -0
  209. package/lib-mjs/edit/EditPlugin.js +19 -1
  210. package/lib-mjs/edit/EditPlugin.js.map +1 -1
  211. package/lib-mjs/edit/inputSteps/handleEnterOnList.js +8 -1
  212. package/lib-mjs/edit/inputSteps/handleEnterOnList.js.map +1 -1
  213. package/lib-mjs/edit/keyboardDelete.js +1 -0
  214. package/lib-mjs/edit/keyboardDelete.js.map +1 -1
  215. package/lib-mjs/edit/keyboardInput.js +1 -0
  216. package/lib-mjs/edit/keyboardInput.js.map +1 -1
  217. package/lib-mjs/edit/keyboardTab.js +5 -5
  218. package/lib-mjs/edit/keyboardTab.js.map +1 -1
  219. package/lib-mjs/edit/tabUtils/handleTabOnList.d.ts +2 -2
  220. package/lib-mjs/edit/tabUtils/handleTabOnList.js +3 -3
  221. package/lib-mjs/edit/tabUtils/handleTabOnList.js.map +1 -1
  222. package/lib-mjs/edit/tabUtils/handleTabOnParagraph.d.ts +2 -2
  223. package/lib-mjs/edit/tabUtils/handleTabOnParagraph.js +2 -2
  224. package/lib-mjs/edit/tabUtils/handleTabOnParagraph.js.map +1 -1
  225. package/lib-mjs/hyperlink/HyperlinkPlugin.js +4 -1
  226. package/lib-mjs/hyperlink/HyperlinkPlugin.js.map +1 -1
  227. package/lib-mjs/index.d.ts +8 -1
  228. package/lib-mjs/index.js +4 -1
  229. package/lib-mjs/index.js.map +1 -1
  230. package/lib-mjs/markdown/utils/setFormat.js +11 -9
  231. package/lib-mjs/markdown/utils/setFormat.js.map +1 -1
  232. package/lib-mjs/picker/PickerHandler.d.ts +112 -0
  233. package/lib-mjs/picker/PickerHandler.js +2 -0
  234. package/lib-mjs/picker/PickerHandler.js.map +1 -0
  235. package/lib-mjs/picker/PickerHelper.d.ts +22 -0
  236. package/lib-mjs/picker/PickerHelper.js +2 -0
  237. package/lib-mjs/picker/PickerHelper.js.map +1 -0
  238. package/lib-mjs/picker/PickerHelperImpl.d.ts +25 -0
  239. package/lib-mjs/picker/PickerHelperImpl.js +51 -0
  240. package/lib-mjs/picker/PickerHelperImpl.js.map +1 -0
  241. package/lib-mjs/picker/PickerPlugin.d.ts +54 -0
  242. package/lib-mjs/picker/PickerPlugin.js +214 -0
  243. package/lib-mjs/picker/PickerPlugin.js.map +1 -0
  244. package/lib-mjs/picker/getQueryString.d.ts +5 -0
  245. package/lib-mjs/picker/getQueryString.js +32 -0
  246. package/lib-mjs/picker/getQueryString.js.map +1 -0
  247. package/lib-mjs/pluginUtils/Rect/getDOMInsertPointRect.d.ts +7 -0
  248. package/lib-mjs/pluginUtils/Rect/getDOMInsertPointRect.js +53 -0
  249. package/lib-mjs/pluginUtils/Rect/getDOMInsertPointRect.js.map +1 -0
  250. package/lib-mjs/shortcut/ShortcutPlugin.js +2 -1
  251. package/lib-mjs/shortcut/ShortcutPlugin.js.map +1 -1
  252. package/lib-mjs/shortcut/shortcuts.d.ts +7 -0
  253. package/lib-mjs/shortcut/shortcuts.js +14 -0
  254. package/lib-mjs/shortcut/shortcuts.js.map +1 -1
  255. package/lib-mjs/shortcut/utils/setShortcutIndentationCommand.js +2 -2
  256. package/lib-mjs/shortcut/utils/setShortcutIndentationCommand.js.map +1 -1
  257. package/lib-mjs/tableEdit/OnTableEditorCreatedCallback.d.ts +5 -0
  258. package/lib-mjs/tableEdit/OnTableEditorCreatedCallback.js +2 -0
  259. package/lib-mjs/tableEdit/OnTableEditorCreatedCallback.js.map +1 -0
  260. package/lib-mjs/tableEdit/TableEditPlugin.d.ts +7 -1
  261. package/lib-mjs/tableEdit/TableEditPlugin.js +7 -2
  262. package/lib-mjs/tableEdit/TableEditPlugin.js.map +1 -1
  263. package/lib-mjs/tableEdit/editors/TableEditor.d.ts +9 -1
  264. package/lib-mjs/tableEdit/editors/TableEditor.js +52 -16
  265. package/lib-mjs/tableEdit/editors/TableEditor.js.map +1 -1
  266. package/lib-mjs/tableEdit/editors/features/CellResizer.d.ts +9 -1
  267. package/lib-mjs/tableEdit/editors/features/CellResizer.js +10 -2
  268. package/lib-mjs/tableEdit/editors/features/CellResizer.js.map +1 -1
  269. package/lib-mjs/tableEdit/editors/features/TableEditFeature.d.ts +1 -1
  270. package/lib-mjs/tableEdit/editors/features/TableEditFeature.js +6 -6
  271. package/lib-mjs/tableEdit/editors/features/TableEditFeature.js.map +1 -1
  272. package/lib-mjs/tableEdit/editors/features/TableEditFeatureName.d.ts +4 -0
  273. package/lib-mjs/tableEdit/editors/features/TableEditFeatureName.js +2 -0
  274. package/lib-mjs/tableEdit/editors/features/TableEditFeatureName.js.map +1 -0
  275. package/lib-mjs/tableEdit/editors/features/TableInserter.d.ts +10 -1
  276. package/lib-mjs/tableEdit/editors/features/TableInserter.js +17 -11
  277. package/lib-mjs/tableEdit/editors/features/TableInserter.js.map +1 -1
  278. package/lib-mjs/tableEdit/editors/features/TableMover.d.ts +48 -3
  279. package/lib-mjs/tableEdit/editors/features/TableMover.js +209 -24
  280. package/lib-mjs/tableEdit/editors/features/TableMover.js.map +1 -1
  281. package/lib-mjs/tableEdit/editors/features/TableResizer.d.ts +7 -2
  282. package/lib-mjs/tableEdit/editors/features/TableResizer.js +23 -4
  283. package/lib-mjs/tableEdit/editors/features/TableResizer.js.map +1 -1
  284. package/lib-mjs/watermark/WatermarkPlugin.d.ts +1 -1
  285. package/lib-mjs/watermark/WatermarkPlugin.js +2 -1
  286. package/lib-mjs/watermark/WatermarkPlugin.js.map +1 -1
  287. package/lib-mjs/watermark/isModelEmptyFast.js +4 -0
  288. package/lib-mjs/watermark/isModelEmptyFast.js.map +1 -1
  289. package/package.json +5 -5
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PickerHandler.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-plugins/lib/picker/PickerHandler.ts"],"names":[],"mappings":"","sourcesContent":["import type { PickerHelper } from './PickerHelper';\nimport type { DOMInsertPoint } from 'roosterjs-content-model-types';\n\n/**\n * Direction option for picker\n */\nexport type PickerDirection =\n /**\n * Show options horizontally\n */\n | 'horizontal'\n /**\n * Show options vertically\n */\n | 'vertical'\n\n /**\n * Show options in both direction (2-D picker)\n */\n | 'both';\n\n/**\n * Change mode that PickerPlugin will pass to child class\n */\nexport type PickerSelectionChangMode =\n /**\n * When user press Right (\"horizontal\" mode or \"both\" mode) (Left in RTL) or Down (\"vertical\" mode),\n * select the next option\n */\n | 'next'\n\n /**\n * When user press Left (\"horizontal\" mode or \"both\" mode) (Right in RTL) or Up (\"vertical\" mode),\n * select the previous option\n */\n | 'previous'\n\n /**\n * When user press Down (\"both\" mode),\n * select the next row\n */\n | 'nextRow'\n\n /**\n * When user press Up (\"both\" mode),\n * select the previous row\n */\n | 'previousRow'\n\n /**\n * When user press PageDown,\n * switch to next page\n */\n | 'nextPage'\n\n /**\n * When user press PageUp,\n * switch to previous page\n */\n | 'previousPage'\n\n /**\n * When user press Home,\n * Select the first item in current row\n */\n | 'firstInRow'\n\n /**\n * When user press End,\n * Select the last item in current row\n */\n | 'lastInRow'\n\n /**\n * When user press CTRL (or META on Mac) + Home,\n * Select the very first item\n */\n | 'first'\n\n /**\n * When user press CTRL (or META on Mac) + End,\n * Select the very last item\n */\n | 'last';\n\n/**\n * Represents the interface a handler for picker plugin. Developer need to implement this interface to create a new type of picker\n */\nexport interface PickerHandler {\n /**\n * Initialize the picker handler, pass in editor and PickerPlugin instance so that the handler can save them\n * @param editor The editor instance\n * @param pickerPlugin The PickerPlugin instance\n */\n onInitialize: (helper: PickerHelper) => void;\n\n /**\n * Dispose the picker handler\n */\n onDispose: () => void;\n\n /**\n * Notify the picker handler that user has typed trigger character so handler should show picker now\n * @param queryString Current query string\n * @param insertPoint Insert point where user is typing, can be used for calculating picker position\n * @returns A picker direction to let picker plugin know what kind of picker is opened. Picker plugin will use this value\n * to decide how to handle keyboard event to change selection. Return null means picker is not actually opened\n */\n onTrigger: (queryString: string, insertPoint: DOMInsertPoint) => PickerDirection | null;\n\n /**\n * Notify the picker handler that picker should be closed now\n */\n onClosePicker?(): void;\n\n /**\n * Notify the picker handler that user has changed current typed query string\n */\n onQueryStringChanged?(queryString: string): void;\n\n /**\n * Notify the picker handler that user has decide to select the current option in picker\n */\n onSelect?(): void;\n\n /**\n * Notify the picker handler that user is using keyboard to change current selection\n * @param mode The moving mode. Handler code can use this value to decide which item need to be selected\n */\n onSelectionChanged?(mode: PickerSelectionChangMode): void;\n}\n"]}
@@ -0,0 +1,22 @@
1
+ import type { ContentModelDocument, FormatContentModelOptions, IEditor } from 'roosterjs-content-model-types';
2
+ /**
3
+ * Represents the interface of picker plugin, provides necessary utility functions for pickers
4
+ */
5
+ export interface PickerHelper {
6
+ /**
7
+ * The editor instance
8
+ */
9
+ readonly editor: IEditor;
10
+ /**
11
+ * Replace the query string with a given Content Model.
12
+ * This is used for commit a change from picker and insert the committed content into editor.
13
+ * @param model The Content Model to insert
14
+ * @param options Options for formatting content model
15
+ * @param canUndoByBackspace Whether this change can be undone using Backspace key
16
+ */
17
+ replaceQueryString: (model: ContentModelDocument, options?: FormatContentModelOptions, canUndoByBackspace?: boolean) => void;
18
+ /**
19
+ * Notify Picker Plugin that picker is closed from the handler code, so picker plugin can quit the suggesting state
20
+ */
21
+ closePicker: () => void;
22
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=PickerHelper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PickerHelper.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-plugins/lib/picker/PickerHelper.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n ContentModelDocument,\n FormatContentModelOptions,\n IEditor,\n} from 'roosterjs-content-model-types';\n\n/**\n * Represents the interface of picker plugin, provides necessary utility functions for pickers\n */\nexport interface PickerHelper {\n /**\n * The editor instance\n */\n readonly editor: IEditor;\n\n /**\n * Replace the query string with a given Content Model.\n * This is used for commit a change from picker and insert the committed content into editor.\n * @param model The Content Model to insert\n * @param options Options for formatting content model\n * @param canUndoByBackspace Whether this change can be undone using Backspace key\n */\n replaceQueryString: (\n model: ContentModelDocument,\n options?: FormatContentModelOptions,\n canUndoByBackspace?: boolean\n ) => void;\n\n /**\n * Notify Picker Plugin that picker is closed from the handler code, so picker plugin can quit the suggesting state\n */\n closePicker: () => void;\n}\n"]}
@@ -0,0 +1,25 @@
1
+ import type { ContentModelDocument, FormatContentModelOptions, IEditor } from 'roosterjs-content-model-types';
2
+ import type { PickerDirection, PickerHandler } from './PickerHandler';
3
+ import type { PickerHelper } from './PickerHelper';
4
+ /**
5
+ * @internal
6
+ */
7
+ export declare class PickerHelperImpl implements PickerHelper {
8
+ readonly editor: IEditor;
9
+ readonly handler: PickerHandler;
10
+ private triggerCharacter;
11
+ direction: PickerDirection | null;
12
+ constructor(editor: IEditor, handler: PickerHandler, triggerCharacter: string);
13
+ /**
14
+ * Replace the query string with a given Content Model.
15
+ * This is used for commit a change from picker and insert the committed content into editor.
16
+ * @param model The Content Model to insert
17
+ * @param options Options for formatting content model
18
+ * @param canUndoByBackspace Whether this change can be undone using Backspace key
19
+ */
20
+ replaceQueryString(model: ContentModelDocument, options?: FormatContentModelOptions, canUndoByBackspace?: boolean): void;
21
+ /**
22
+ * Notify Picker Plugin that picker is closed from the handler code, so picker plugin can quit the suggesting state
23
+ */
24
+ closePicker(): void;
25
+ }
@@ -0,0 +1,51 @@
1
+ import { formatTextSegmentBeforeSelectionMarker } from 'roosterjs-content-model-api';
2
+ import { getQueryString } from './getQueryString';
3
+ import { mergeModel } from 'roosterjs-content-model-dom';
4
+ /**
5
+ * @internal
6
+ */
7
+ var PickerHelperImpl = /** @class */ (function () {
8
+ function PickerHelperImpl(editor, handler, triggerCharacter) {
9
+ this.editor = editor;
10
+ this.handler = handler;
11
+ this.triggerCharacter = triggerCharacter;
12
+ this.direction = null;
13
+ }
14
+ /**
15
+ * Replace the query string with a given Content Model.
16
+ * This is used for commit a change from picker and insert the committed content into editor.
17
+ * @param model The Content Model to insert
18
+ * @param options Options for formatting content model
19
+ * @param canUndoByBackspace Whether this change can be undone using Backspace key
20
+ */
21
+ PickerHelperImpl.prototype.replaceQueryString = function (model, options, canUndoByBackspace) {
22
+ var _this = this;
23
+ this.editor.focus();
24
+ formatTextSegmentBeforeSelectionMarker(this.editor, function (target, previousSegment, paragraph, _, context) {
25
+ var potentialSegments = [];
26
+ var queryString = getQueryString(_this.triggerCharacter, paragraph, previousSegment, potentialSegments);
27
+ if (queryString) {
28
+ potentialSegments.forEach(function (x) { return (x.isSelected = true); });
29
+ mergeModel(target, model, context);
30
+ context.canUndoByBackspace = canUndoByBackspace;
31
+ return true;
32
+ }
33
+ else {
34
+ return false;
35
+ }
36
+ }, options);
37
+ };
38
+ /**
39
+ * Notify Picker Plugin that picker is closed from the handler code, so picker plugin can quit the suggesting state
40
+ */
41
+ PickerHelperImpl.prototype.closePicker = function () {
42
+ var _a, _b;
43
+ if (this.direction) {
44
+ this.direction = null;
45
+ (_b = (_a = this.handler).onClosePicker) === null || _b === void 0 ? void 0 : _b.call(_a);
46
+ }
47
+ };
48
+ return PickerHelperImpl;
49
+ }());
50
+ export { PickerHelperImpl };
51
+ //# sourceMappingURL=PickerHelperImpl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PickerHelperImpl.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-plugins/lib/picker/PickerHelperImpl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sCAAsC,EAAE,MAAM,6BAA6B,CAAC;AACrF,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAUzD;;GAEG;AACH;IAGI,0BACoB,MAAe,EACf,OAAsB,EAC9B,gBAAwB;QAFhB,WAAM,GAAN,MAAM,CAAS;QACf,YAAO,GAAP,OAAO,CAAe;QAC9B,qBAAgB,GAAhB,gBAAgB,CAAQ;QAL7B,cAAS,GAA2B,IAAI,CAAC;IAM7C,CAAC;IAEJ;;;;;;OAMG;IACH,6CAAkB,GAAlB,UACI,KAA2B,EAC3B,OAAmC,EACnC,kBAA4B;QAHhC,iBA6BC;QAxBG,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAEpB,sCAAsC,CAClC,IAAI,CAAC,MAAM,EACX,UAAC,MAAM,EAAE,eAAe,EAAE,SAAS,EAAE,CAAC,EAAE,OAAO;YAC3C,IAAM,iBAAiB,GAAuB,EAAE,CAAC;YACjD,IAAM,WAAW,GAAG,cAAc,CAC9B,KAAI,CAAC,gBAAgB,EACrB,SAAS,EACT,eAAe,EACf,iBAAiB,CACpB,CAAC;YAEF,IAAI,WAAW,EAAE;gBACb,iBAAiB,CAAC,OAAO,CAAC,UAAA,CAAC,IAAI,OAAA,CAAC,CAAC,CAAC,UAAU,GAAG,IAAI,CAAC,EAArB,CAAqB,CAAC,CAAC;gBACtD,UAAU,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;gBACnC,OAAO,CAAC,kBAAkB,GAAG,kBAAkB,CAAC;gBAChD,OAAO,IAAI,CAAC;aACf;iBAAM;gBACH,OAAO,KAAK,CAAC;aAChB;QACL,CAAC,EACD,OAAO,CACV,CAAC;IACN,CAAC;IAED;;OAEG;IACH,sCAAW,GAAX;;QACI,IAAI,IAAI,CAAC,SAAS,EAAE;YAChB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;YACtB,MAAA,MAAA,IAAI,CAAC,OAAO,EAAC,aAAa,kDAAI,CAAC;SAClC;IACL,CAAC;IACL,uBAAC;AAAD,CAAC,AAxDD,IAwDC","sourcesContent":["import { formatTextSegmentBeforeSelectionMarker } from 'roosterjs-content-model-api';\nimport { getQueryString } from './getQueryString';\nimport { mergeModel } from 'roosterjs-content-model-dom';\nimport type {\n ContentModelDocument,\n ContentModelText,\n FormatContentModelOptions,\n IEditor,\n} from 'roosterjs-content-model-types';\nimport type { PickerDirection, PickerHandler } from './PickerHandler';\nimport type { PickerHelper } from './PickerHelper';\n\n/**\n * @internal\n */\nexport class PickerHelperImpl implements PickerHelper {\n public direction: PickerDirection | null = null;\n\n constructor(\n public readonly editor: IEditor,\n public readonly handler: PickerHandler,\n private triggerCharacter: string\n ) {}\n\n /**\n * Replace the query string with a given Content Model.\n * This is used for commit a change from picker and insert the committed content into editor.\n * @param model The Content Model to insert\n * @param options Options for formatting content model\n * @param canUndoByBackspace Whether this change can be undone using Backspace key\n */\n replaceQueryString(\n model: ContentModelDocument,\n options?: FormatContentModelOptions,\n canUndoByBackspace?: boolean\n ): void {\n this.editor.focus();\n\n formatTextSegmentBeforeSelectionMarker(\n this.editor,\n (target, previousSegment, paragraph, _, context) => {\n const potentialSegments: ContentModelText[] = [];\n const queryString = getQueryString(\n this.triggerCharacter,\n paragraph,\n previousSegment,\n potentialSegments\n );\n\n if (queryString) {\n potentialSegments.forEach(x => (x.isSelected = true));\n mergeModel(target, model, context);\n context.canUndoByBackspace = canUndoByBackspace;\n return true;\n } else {\n return false;\n }\n },\n options\n );\n }\n\n /**\n * Notify Picker Plugin that picker is closed from the handler code, so picker plugin can quit the suggesting state\n */\n closePicker() {\n if (this.direction) {\n this.direction = null;\n this.handler.onClosePicker?.();\n }\n }\n}\n"]}
@@ -0,0 +1,54 @@
1
+ import type { PickerHandler } from './PickerHandler';
2
+ import type { EditorPlugin, IEditor, PluginEvent } from 'roosterjs-content-model-types';
3
+ /**
4
+ * PickerPlugin represents a plugin of editor which can handle picker related behaviors, including
5
+ * - Show picker when special trigger key is pressed
6
+ * - Hide picker
7
+ * - Change selection in picker by Up/Down/Left/Right
8
+ * - Apply selected item in picker
9
+ *
10
+ * PickerPlugin doesn't provide any UI, it just wraps related DOM events and invoke callback functions.
11
+ */
12
+ export declare class PickerPlugin implements EditorPlugin {
13
+ private triggerCharacter;
14
+ private readonly handler;
15
+ private isMac;
16
+ private lastQueryString;
17
+ private helper;
18
+ /**
19
+ * Construct a new instance of PickerPlugin class
20
+ * @param triggerCharacter The character to trigger a picker to be shown
21
+ * @param handler Picker handler for receiving picker state change events
22
+ */
23
+ constructor(triggerCharacter: string, handler: PickerHandler);
24
+ /**
25
+ * Get a friendly name
26
+ */
27
+ getName(): string;
28
+ /**
29
+ * Initialize this plugin. This should only be called from Editor
30
+ * @param editor Editor instance
31
+ */
32
+ initialize(editor: IEditor): void;
33
+ /**
34
+ * Dispose this plugin
35
+ */
36
+ dispose(): void;
37
+ /**
38
+ * Check if the plugin should handle the given event exclusively.
39
+ * Handle an event exclusively means other plugin will not receive this event in
40
+ * onPluginEvent method.
41
+ * If two plugins will return true in willHandleEventExclusively() for the same event,
42
+ * the final result depends on the order of the plugins are added into editor
43
+ * @param event The event to check
44
+ */
45
+ willHandleEventExclusively(event: PluginEvent): boolean;
46
+ /**
47
+ * Handle events triggered from editor
48
+ * @param event PluginEvent object
49
+ */
50
+ onPluginEvent(event: PluginEvent): void;
51
+ private onSuggestingKeyDown;
52
+ private onSuggestingInput;
53
+ private onInput;
54
+ }
@@ -0,0 +1,214 @@
1
+ import { ChangeSource, isCursorMovingKey, isPunctuation } from 'roosterjs-content-model-dom';
2
+ import { formatTextSegmentBeforeSelectionMarker } from 'roosterjs-content-model-api';
3
+ import { getQueryString } from './getQueryString';
4
+ import { PickerHelperImpl } from './PickerHelperImpl';
5
+ /**
6
+ * PickerPlugin represents a plugin of editor which can handle picker related behaviors, including
7
+ * - Show picker when special trigger key is pressed
8
+ * - Hide picker
9
+ * - Change selection in picker by Up/Down/Left/Right
10
+ * - Apply selected item in picker
11
+ *
12
+ * PickerPlugin doesn't provide any UI, it just wraps related DOM events and invoke callback functions.
13
+ */
14
+ var PickerPlugin = /** @class */ (function () {
15
+ /**
16
+ * Construct a new instance of PickerPlugin class
17
+ * @param triggerCharacter The character to trigger a picker to be shown
18
+ * @param handler Picker handler for receiving picker state change events
19
+ */
20
+ function PickerPlugin(triggerCharacter, handler) {
21
+ this.triggerCharacter = triggerCharacter;
22
+ this.handler = handler;
23
+ this.isMac = false;
24
+ this.lastQueryString = '';
25
+ this.helper = null;
26
+ }
27
+ /**
28
+ * Get a friendly name
29
+ */
30
+ PickerPlugin.prototype.getName = function () {
31
+ return 'Picker';
32
+ };
33
+ /**
34
+ * Initialize this plugin. This should only be called from Editor
35
+ * @param editor Editor instance
36
+ */
37
+ PickerPlugin.prototype.initialize = function (editor) {
38
+ this.isMac = !!editor.getEnvironment().isMac;
39
+ this.helper = new PickerHelperImpl(editor, this.handler, this.triggerCharacter);
40
+ this.handler.onInitialize(this.helper);
41
+ };
42
+ /**
43
+ * Dispose this plugin
44
+ */
45
+ PickerPlugin.prototype.dispose = function () {
46
+ this.handler.onDispose();
47
+ this.helper = null;
48
+ };
49
+ /**
50
+ * Check if the plugin should handle the given event exclusively.
51
+ * Handle an event exclusively means other plugin will not receive this event in
52
+ * onPluginEvent method.
53
+ * If two plugins will return true in willHandleEventExclusively() for the same event,
54
+ * the final result depends on the order of the plugins are added into editor
55
+ * @param event The event to check
56
+ */
57
+ PickerPlugin.prototype.willHandleEventExclusively = function (event) {
58
+ var _a;
59
+ return (!!((_a = this.helper) === null || _a === void 0 ? void 0 : _a.direction) &&
60
+ event.eventType == 'keyDown' &&
61
+ (isCursorMovingKey(event.rawEvent) ||
62
+ event.rawEvent.key == 'Enter' ||
63
+ event.rawEvent.key == 'Tab' ||
64
+ event.rawEvent.key == 'Escape'));
65
+ };
66
+ /**
67
+ * Handle events triggered from editor
68
+ * @param event PluginEvent object
69
+ */
70
+ PickerPlugin.prototype.onPluginEvent = function (event) {
71
+ if (!this.helper) {
72
+ return;
73
+ }
74
+ switch (event.eventType) {
75
+ case 'contentChanged':
76
+ if (this.helper.direction) {
77
+ if (event.source == ChangeSource.SetContent) {
78
+ this.helper.closePicker();
79
+ }
80
+ else {
81
+ this.onSuggestingInput(this.helper);
82
+ }
83
+ }
84
+ break;
85
+ case 'keyDown':
86
+ if (this.helper.direction) {
87
+ this.onSuggestingKeyDown(this.helper, event.rawEvent);
88
+ }
89
+ break;
90
+ case 'input':
91
+ if (this.helper.direction) {
92
+ this.onSuggestingInput(this.helper);
93
+ }
94
+ else {
95
+ this.onInput(this.helper, event.rawEvent);
96
+ }
97
+ break;
98
+ case 'mouseUp':
99
+ if (this.helper.direction) {
100
+ this.helper.closePicker();
101
+ }
102
+ break;
103
+ }
104
+ };
105
+ PickerPlugin.prototype.onSuggestingKeyDown = function (helper, event) {
106
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
107
+ switch (event.key) {
108
+ case 'ArrowLeft':
109
+ case 'ArrowRight':
110
+ if (helper.direction == 'horizontal' || helper.direction == 'both') {
111
+ var isIncrement = event.key == 'ArrowRight';
112
+ if (helper.editor.getDOMHelper().isRightToLeft()) {
113
+ isIncrement = !isIncrement;
114
+ }
115
+ (_b = (_a = this.handler).onSelectionChanged) === null || _b === void 0 ? void 0 : _b.call(_a, isIncrement ? 'next' : 'previous');
116
+ }
117
+ event.preventDefault();
118
+ break;
119
+ case 'ArrowUp':
120
+ case 'ArrowDown':
121
+ {
122
+ var isIncrement = event.key == 'ArrowDown';
123
+ if (helper.direction != 'horizontal') {
124
+ (_d = (_c = this.handler).onSelectionChanged) === null || _d === void 0 ? void 0 : _d.call(_c, helper.direction == 'both'
125
+ ? isIncrement
126
+ ? 'nextRow'
127
+ : 'previousRow'
128
+ : isIncrement
129
+ ? 'next'
130
+ : 'previous');
131
+ }
132
+ }
133
+ event.preventDefault();
134
+ break;
135
+ case 'PageUp':
136
+ case 'PageDown':
137
+ (_f = (_e = this.handler).onSelectionChanged) === null || _f === void 0 ? void 0 : _f.call(_e, event.key == 'PageDown' ? 'nextPage' : 'previousPage');
138
+ event.preventDefault();
139
+ break;
140
+ case 'Home':
141
+ case 'End':
142
+ var hasCtrl = this.isMac ? event.metaKey : event.ctrlKey;
143
+ (_h = (_g = this.handler).onSelectionChanged) === null || _h === void 0 ? void 0 : _h.call(_g, event.key == 'Home'
144
+ ? hasCtrl
145
+ ? 'first'
146
+ : 'firstInRow'
147
+ : hasCtrl
148
+ ? 'last'
149
+ : 'lastInRow');
150
+ event.preventDefault();
151
+ break;
152
+ case 'Escape':
153
+ helper.closePicker();
154
+ event.preventDefault();
155
+ break;
156
+ case 'Enter':
157
+ case 'Tab':
158
+ (_k = (_j = this.handler).onSelect) === null || _k === void 0 ? void 0 : _k.call(_j);
159
+ event.preventDefault();
160
+ break;
161
+ }
162
+ };
163
+ PickerPlugin.prototype.onSuggestingInput = function (helper) {
164
+ var _this = this;
165
+ if (!formatTextSegmentBeforeSelectionMarker(helper.editor, function (_, segment, paragraph) {
166
+ var _a, _b;
167
+ var newQueryString = getQueryString(_this.triggerCharacter, paragraph, segment).replace(/[\u0020\u00A0]/g, ' ');
168
+ var oldQueryString = _this.lastQueryString;
169
+ if (newQueryString &&
170
+ ((newQueryString.length >= oldQueryString.length &&
171
+ newQueryString.indexOf(oldQueryString) == 0) ||
172
+ (newQueryString.length < oldQueryString.length &&
173
+ oldQueryString.indexOf(newQueryString) == 0))) {
174
+ _this.lastQueryString = newQueryString;
175
+ (_b = (_a = _this.handler).onQueryStringChanged) === null || _b === void 0 ? void 0 : _b.call(_a, newQueryString);
176
+ }
177
+ else {
178
+ helper.closePicker();
179
+ }
180
+ return false;
181
+ })) {
182
+ helper.closePicker();
183
+ }
184
+ };
185
+ PickerPlugin.prototype.onInput = function (helper, event) {
186
+ var _this = this;
187
+ if (event.inputType == 'insertText' && event.data == this.triggerCharacter) {
188
+ formatTextSegmentBeforeSelectionMarker(helper.editor, function (_, segment) {
189
+ if (segment.text.endsWith(_this.triggerCharacter)) {
190
+ var charBeforeTrigger = segment.text[segment.text.length - 2];
191
+ if (!charBeforeTrigger ||
192
+ !charBeforeTrigger.trim() ||
193
+ isPunctuation(charBeforeTrigger)) {
194
+ var selection = helper.editor.getDOMSelection();
195
+ var pos = (selection === null || selection === void 0 ? void 0 : selection.type) == 'range' && selection.range.collapsed
196
+ ? {
197
+ node: selection.range.startContainer,
198
+ offset: selection.range.startOffset,
199
+ }
200
+ : null;
201
+ if (pos) {
202
+ _this.lastQueryString = _this.triggerCharacter;
203
+ helper.direction = _this.handler.onTrigger(_this.lastQueryString, pos);
204
+ }
205
+ }
206
+ }
207
+ return false;
208
+ });
209
+ }
210
+ };
211
+ return PickerPlugin;
212
+ }());
213
+ export { PickerPlugin };
214
+ //# sourceMappingURL=PickerPlugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PickerPlugin.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-plugins/lib/picker/PickerPlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { ChangeSource, isCursorMovingKey, isPunctuation } from 'roosterjs-content-model-dom';\nimport { formatTextSegmentBeforeSelectionMarker } from 'roosterjs-content-model-api';\nimport { getQueryString } from './getQueryString';\nimport { PickerHelperImpl } from './PickerHelperImpl';\nimport type { PickerHandler } from './PickerHandler';\nimport type {\n DOMInsertPoint,\n EditorPlugin,\n IEditor,\n PluginEvent,\n} from 'roosterjs-content-model-types';\n\n/**\n * PickerPlugin represents a plugin of editor which can handle picker related behaviors, including\n * - Show picker when special trigger key is pressed\n * - Hide picker\n * - Change selection in picker by Up/Down/Left/Right\n * - Apply selected item in picker\n *\n * PickerPlugin doesn't provide any UI, it just wraps related DOM events and invoke callback functions.\n */\nexport class PickerPlugin implements EditorPlugin {\n private isMac: boolean = false;\n private lastQueryString = '';\n private helper: PickerHelperImpl | null = null;\n\n /**\n * Construct a new instance of PickerPlugin class\n * @param triggerCharacter The character to trigger a picker to be shown\n * @param handler Picker handler for receiving picker state change events\n */\n constructor(private triggerCharacter: string, private readonly handler: PickerHandler) {}\n\n /**\n * Get a friendly name\n */\n getName() {\n return 'Picker';\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.isMac = !!editor.getEnvironment().isMac;\n this.helper = new PickerHelperImpl(editor, this.handler, this.triggerCharacter);\n this.handler.onInitialize(this.helper);\n }\n\n /**\n * Dispose this plugin\n */\n dispose() {\n this.handler.onDispose();\n this.helper = null;\n }\n\n /**\n * Check if the plugin should handle the given event exclusively.\n * Handle an event exclusively means other plugin will not receive this event in\n * onPluginEvent method.\n * If two plugins will return true in willHandleEventExclusively() for the same event,\n * the final result depends on the order of the plugins are added into editor\n * @param event The event to check\n */\n willHandleEventExclusively(event: PluginEvent) {\n return (\n !!this.helper?.direction &&\n event.eventType == 'keyDown' &&\n (isCursorMovingKey(event.rawEvent) ||\n event.rawEvent.key == 'Enter' ||\n event.rawEvent.key == 'Tab' ||\n event.rawEvent.key == 'Escape')\n );\n }\n\n /**\n * Handle events triggered from editor\n * @param event PluginEvent object\n */\n onPluginEvent(event: PluginEvent) {\n if (!this.helper) {\n return;\n }\n\n switch (event.eventType) {\n case 'contentChanged':\n if (this.helper.direction) {\n if (event.source == ChangeSource.SetContent) {\n this.helper.closePicker();\n } else {\n this.onSuggestingInput(this.helper);\n }\n }\n break;\n\n case 'keyDown':\n if (this.helper.direction) {\n this.onSuggestingKeyDown(this.helper, event.rawEvent);\n }\n break;\n\n case 'input':\n if (this.helper.direction) {\n this.onSuggestingInput(this.helper);\n } else {\n this.onInput(this.helper, event.rawEvent);\n }\n break;\n\n case 'mouseUp':\n if (this.helper.direction) {\n this.helper.closePicker();\n }\n break;\n }\n }\n\n private onSuggestingKeyDown(helper: PickerHelperImpl, event: KeyboardEvent) {\n switch (event.key) {\n case 'ArrowLeft':\n case 'ArrowRight':\n if (helper.direction == 'horizontal' || helper.direction == 'both') {\n let isIncrement = event.key == 'ArrowRight';\n\n if (helper.editor.getDOMHelper().isRightToLeft()) {\n isIncrement = !isIncrement;\n }\n\n this.handler.onSelectionChanged?.(isIncrement ? 'next' : 'previous');\n }\n\n event.preventDefault();\n break;\n case 'ArrowUp':\n case 'ArrowDown':\n {\n const isIncrement = event.key == 'ArrowDown';\n\n if (helper.direction != 'horizontal') {\n this.handler.onSelectionChanged?.(\n helper.direction == 'both'\n ? isIncrement\n ? 'nextRow'\n : 'previousRow'\n : isIncrement\n ? 'next'\n : 'previous'\n );\n }\n }\n\n event.preventDefault();\n break;\n case 'PageUp':\n case 'PageDown':\n this.handler.onSelectionChanged?.(\n event.key == 'PageDown' ? 'nextPage' : 'previousPage'\n );\n\n event.preventDefault();\n break;\n case 'Home':\n case 'End':\n const hasCtrl = this.isMac ? event.metaKey : event.ctrlKey;\n this.handler.onSelectionChanged?.(\n event.key == 'Home'\n ? hasCtrl\n ? 'first'\n : 'firstInRow'\n : hasCtrl\n ? 'last'\n : 'lastInRow'\n );\n\n event.preventDefault();\n break;\n case 'Escape':\n helper.closePicker();\n event.preventDefault();\n break;\n\n case 'Enter':\n case 'Tab':\n this.handler.onSelect?.();\n event.preventDefault();\n break;\n }\n }\n\n private onSuggestingInput(helper: PickerHelperImpl) {\n if (\n !formatTextSegmentBeforeSelectionMarker(helper.editor, (_, segment, paragraph) => {\n const newQueryString = getQueryString(\n this.triggerCharacter,\n paragraph,\n segment\n ).replace(/[\\u0020\\u00A0]/g, ' ');\n const oldQueryString = this.lastQueryString;\n\n if (\n newQueryString &&\n ((newQueryString.length >= oldQueryString.length &&\n newQueryString.indexOf(oldQueryString) == 0) ||\n (newQueryString.length < oldQueryString.length &&\n oldQueryString.indexOf(newQueryString) == 0))\n ) {\n this.lastQueryString = newQueryString;\n this.handler.onQueryStringChanged?.(newQueryString);\n } else {\n helper.closePicker();\n }\n\n return false;\n })\n ) {\n helper.closePicker();\n }\n }\n\n private onInput(helper: PickerHelperImpl, event: InputEvent) {\n if (event.inputType == 'insertText' && event.data == this.triggerCharacter) {\n formatTextSegmentBeforeSelectionMarker(helper.editor, (_, segment) => {\n if (segment.text.endsWith(this.triggerCharacter)) {\n const charBeforeTrigger = segment.text[segment.text.length - 2];\n\n if (\n !charBeforeTrigger ||\n !charBeforeTrigger.trim() ||\n isPunctuation(charBeforeTrigger)\n ) {\n const selection = helper.editor.getDOMSelection();\n const pos: DOMInsertPoint | null =\n selection?.type == 'range' && selection.range.collapsed\n ? {\n node: selection.range.startContainer,\n offset: selection.range.startOffset,\n }\n : null;\n\n if (pos) {\n this.lastQueryString = this.triggerCharacter;\n helper.direction = this.handler.onTrigger(this.lastQueryString, pos);\n }\n }\n }\n\n return false;\n });\n }\n }\n}\n"]}
@@ -0,0 +1,5 @@
1
+ import type { ContentModelParagraph, ContentModelText } from 'roosterjs-content-model-types';
2
+ /**
3
+ * @internal
4
+ */
5
+ export declare function getQueryString(triggerCharacter: string, paragraph: ContentModelParagraph, previousSegment: ContentModelText, splittedSegmentResult?: ContentModelText[]): string;
@@ -0,0 +1,32 @@
1
+ import { splitTextSegment } from '../pluginUtils/splitTextSegment';
2
+ /**
3
+ * @internal
4
+ */
5
+ export function getQueryString(triggerCharacter, paragraph, previousSegment, splittedSegmentResult) {
6
+ var result = '';
7
+ var i = paragraph.segments.indexOf(previousSegment);
8
+ for (; i >= 0; i--) {
9
+ var segment = paragraph.segments[i];
10
+ if (segment.segmentType != 'Text') {
11
+ result = '';
12
+ break;
13
+ }
14
+ var index = segment.text.lastIndexOf(triggerCharacter);
15
+ if (index >= 0) {
16
+ result = segment.text.substring(index) + result;
17
+ splittedSegmentResult === null || splittedSegmentResult === void 0 ? void 0 : splittedSegmentResult.unshift(index > 0
18
+ ? splitTextSegment(segment, paragraph, index, segment.text.length)
19
+ : segment);
20
+ break;
21
+ }
22
+ else {
23
+ result = segment.text + result;
24
+ splittedSegmentResult === null || splittedSegmentResult === void 0 ? void 0 : splittedSegmentResult.unshift(segment);
25
+ }
26
+ }
27
+ if (i < 0) {
28
+ result = '';
29
+ }
30
+ return result;
31
+ }
32
+ //# sourceMappingURL=getQueryString.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getQueryString.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-plugins/lib/picker/getQueryString.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAGnE;;GAEG;AACH,MAAM,UAAU,cAAc,CAC1B,gBAAwB,EACxB,SAAgC,EAChC,eAAiC,EACjC,qBAA0C;IAE1C,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,IAAI,CAAC,GAAG,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;IAEpD,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE;QAChB,IAAM,OAAO,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QAEtC,IAAI,OAAO,CAAC,WAAW,IAAI,MAAM,EAAE;YAC/B,MAAM,GAAG,EAAE,CAAC;YACZ,MAAM;SACT;QAED,IAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,gBAAgB,CAAC,CAAC;QAEzD,IAAI,KAAK,IAAI,CAAC,EAAE;YACZ,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC;YAEhD,qBAAqB,aAArB,qBAAqB,uBAArB,qBAAqB,CAAE,OAAO,CAC1B,KAAK,GAAG,CAAC;gBACL,CAAC,CAAC,gBAAgB,CAAC,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC;gBAClE,CAAC,CAAC,OAAO,CAChB,CAAC;YAEF,MAAM;SACT;aAAM;YACH,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,MAAM,CAAC;YAE/B,qBAAqB,aAArB,qBAAqB,uBAArB,qBAAqB,CAAE,OAAO,CAAC,OAAO,CAAC,CAAC;SAC3C;KACJ;IAED,IAAI,CAAC,GAAG,CAAC,EAAE;QACP,MAAM,GAAG,EAAE,CAAC;KACf;IAED,OAAO,MAAM,CAAC;AAClB,CAAC","sourcesContent":["import { splitTextSegment } from '../pluginUtils/splitTextSegment';\nimport type { ContentModelParagraph, ContentModelText } from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\nexport function getQueryString(\n triggerCharacter: string,\n paragraph: ContentModelParagraph,\n previousSegment: ContentModelText,\n splittedSegmentResult?: ContentModelText[]\n): string {\n let result = '';\n let i = paragraph.segments.indexOf(previousSegment);\n\n for (; i >= 0; i--) {\n const segment = paragraph.segments[i];\n\n if (segment.segmentType != 'Text') {\n result = '';\n break;\n }\n\n const index = segment.text.lastIndexOf(triggerCharacter);\n\n if (index >= 0) {\n result = segment.text.substring(index) + result;\n\n splittedSegmentResult?.unshift(\n index > 0\n ? splitTextSegment(segment, paragraph, index, segment.text.length)\n : segment\n );\n\n break;\n } else {\n result = segment.text + result;\n\n splittedSegmentResult?.unshift(segment);\n }\n }\n\n if (i < 0) {\n result = '';\n }\n\n return result;\n}\n"]}
@@ -0,0 +1,7 @@
1
+ import type { DOMInsertPoint, Rect } from 'roosterjs-content-model-types';
2
+ /**
3
+ * Get bounding rect of the given DOM insert point
4
+ * @param doc The document object
5
+ * @param pos The input DOM insert point
6
+ */
7
+ export declare function getDOMInsertPointRect(doc: Document, pos: DOMInsertPoint): Rect | null;
@@ -0,0 +1,53 @@
1
+ import { isNodeOfType, normalizeRect } from 'roosterjs-content-model-dom';
2
+ /**
3
+ * Get bounding rect of the given DOM insert point
4
+ * @param doc The document object
5
+ * @param pos The input DOM insert point
6
+ */
7
+ export function getDOMInsertPointRect(doc, pos) {
8
+ var _a;
9
+ var node = pos.node, offset = pos.offset;
10
+ var range = doc.createRange();
11
+ range.setStart(node, offset);
12
+ // 1) try to get rect using range.getBoundingClientRect()
13
+ var rect = normalizeRect(range.getBoundingClientRect());
14
+ if (rect) {
15
+ return rect;
16
+ }
17
+ // 2) try to get rect using range.getClientRects
18
+ while (node.lastChild) {
19
+ if (offset == node.childNodes.length) {
20
+ node = node.lastChild;
21
+ offset = node.childNodes.length;
22
+ }
23
+ else {
24
+ node = node.childNodes[offset];
25
+ offset = 0;
26
+ }
27
+ }
28
+ var rects = range.getClientRects && range.getClientRects();
29
+ rect = rects && rects.length == 1 ? normalizeRect(rects[0]) : null;
30
+ if (rect) {
31
+ return rect;
32
+ }
33
+ // 3) if node is text node, try inserting a SPAN and get the rect of SPAN for others
34
+ if (isNodeOfType(node, 'TEXT_NODE')) {
35
+ var span = node.ownerDocument.createElement('span');
36
+ span.textContent = '\u200b';
37
+ range.insertNode(span);
38
+ rect = normalizeRect(span.getBoundingClientRect());
39
+ (_a = span.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(span);
40
+ if (rect) {
41
+ return rect;
42
+ }
43
+ }
44
+ // 4) try getBoundingClientRect on element
45
+ if (isNodeOfType(node, 'ELEMENT_NODE') && node.getBoundingClientRect) {
46
+ rect = normalizeRect(node.getBoundingClientRect());
47
+ if (rect) {
48
+ return rect;
49
+ }
50
+ }
51
+ return null;
52
+ }
53
+ //# sourceMappingURL=getDOMInsertPointRect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getDOMInsertPointRect.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/pluginUtils/Rect/getDOMInsertPointRect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAG1E;;;;GAIG;AACH,MAAM,UAAU,qBAAqB,CAAC,GAAa,EAAE,GAAmB;;IAC9D,IAAA,IAAI,GAAa,GAAG,KAAhB,EAAE,MAAM,GAAK,GAAG,OAAR,CAAS;IAC3B,IAAM,KAAK,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;IAEhC,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAE7B,yDAAyD;IACzD,IAAI,IAAI,GAAG,aAAa,CAAC,KAAK,CAAC,qBAAqB,EAAE,CAAC,CAAC;IAExD,IAAI,IAAI,EAAE;QACN,OAAO,IAAI,CAAC;KACf;IAED,gDAAgD;IAChD,OAAO,IAAI,CAAC,SAAS,EAAE;QACnB,IAAI,MAAM,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE;YAClC,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC;YACtB,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;SACnC;aAAM;YACH,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;YAC/B,MAAM,GAAG,CAAC,CAAC;SACd;KACJ;IAED,IAAM,KAAK,GAAG,KAAK,CAAC,cAAc,IAAI,KAAK,CAAC,cAAc,EAAE,CAAC;IAC7D,IAAI,GAAG,KAAK,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACnE,IAAI,IAAI,EAAE;QACN,OAAO,IAAI,CAAC;KACf;IAED,oFAAoF;IACpF,IAAI,YAAY,CAAC,IAAI,EAAE,WAAW,CAAC,EAAE;QACjC,IAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAEtD,IAAI,CAAC,WAAW,GAAG,QAAQ,CAAC;QAC5B,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACvB,IAAI,GAAG,aAAa,CAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC,CAAC;QACnD,MAAA,IAAI,CAAC,UAAU,0CAAE,WAAW,CAAC,IAAI,CAAC,CAAC;QAEnC,IAAI,IAAI,EAAE;YACN,OAAO,IAAI,CAAC;SACf;KACJ;IAED,0CAA0C;IAC1C,IAAI,YAAY,CAAC,IAAI,EAAE,cAAc,CAAC,IAAI,IAAI,CAAC,qBAAqB,EAAE;QAClE,IAAI,GAAG,aAAa,CAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC,CAAC;QAEnD,IAAI,IAAI,EAAE;YACN,OAAO,IAAI,CAAC;SACf;KACJ;IAED,OAAO,IAAI,CAAC;AAChB,CAAC","sourcesContent":["import { isNodeOfType, normalizeRect } from 'roosterjs-content-model-dom';\nimport type { DOMInsertPoint, Rect } from 'roosterjs-content-model-types';\n\n/**\n * Get bounding rect of the given DOM insert point\n * @param doc The document object\n * @param pos The input DOM insert point\n */\nexport function getDOMInsertPointRect(doc: Document, pos: DOMInsertPoint): Rect | null {\n let { node, offset } = pos;\n const range = doc.createRange();\n\n range.setStart(node, offset);\n\n // 1) try to get rect using range.getBoundingClientRect()\n let rect = normalizeRect(range.getBoundingClientRect());\n\n if (rect) {\n return rect;\n }\n\n // 2) try to get rect using range.getClientRects\n while (node.lastChild) {\n if (offset == node.childNodes.length) {\n node = node.lastChild;\n offset = node.childNodes.length;\n } else {\n node = node.childNodes[offset];\n offset = 0;\n }\n }\n\n const rects = range.getClientRects && range.getClientRects();\n rect = rects && rects.length == 1 ? normalizeRect(rects[0]) : null;\n if (rect) {\n return rect;\n }\n\n // 3) if node is text node, try inserting a SPAN and get the rect of SPAN for others\n if (isNodeOfType(node, 'TEXT_NODE')) {\n const span = node.ownerDocument.createElement('span');\n\n span.textContent = '\\u200b';\n range.insertNode(span);\n rect = normalizeRect(span.getBoundingClientRect());\n span.parentNode?.removeChild(span);\n\n if (rect) {\n return rect;\n }\n }\n\n // 4) try getBoundingClientRect on element\n if (isNodeOfType(node, 'ELEMENT_NODE') && node.getBoundingClientRect) {\n rect = normalizeRect(node.getBoundingClientRect());\n\n if (rect) {\n return rect;\n }\n }\n\n return null;\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import { cacheGetEventData } from 'roosterjs-content-model-dom';
2
- import { ShortcutBold, ShortcutBullet, ShortcutClearFormat, ShortcutDecreaseFont, ShortcutIncreaseFont, ShortcutIndentList, ShortcutItalic, ShortcutNumbering, ShortcutOutdentList, ShortcutRedo, ShortcutRedoMacOS, ShortcutUnderline, ShortcutUndo, ShortcutUndo2, } from './shortcuts';
2
+ import { ShortcutBold, ShortcutBullet, ShortcutClearFormat, ShortcutDecreaseFont, ShortcutIncreaseFont, ShortcutIndentList, ShortcutItalic, ShortcutNumbering, ShortcutOutdentList, ShortcutRedo, ShortcutRedoAlt, ShortcutRedoMacOS, ShortcutUnderline, ShortcutUndo, ShortcutUndo2, } from './shortcuts';
3
3
  var defaultShortcuts = [
4
4
  ShortcutBold,
5
5
  ShortcutItalic,
@@ -8,6 +8,7 @@ var defaultShortcuts = [
8
8
  ShortcutUndo,
9
9
  ShortcutUndo2,
10
10
  ShortcutRedo,
11
+ ShortcutRedoAlt,
11
12
  ShortcutRedoMacOS,
12
13
  ShortcutBullet,
13
14
  ShortcutNumbering,
@@ -1 +1 @@
1
- {"version":3,"file":"ShortcutPlugin.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-plugins/lib/shortcut/ShortcutPlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { cacheGetEventData } from 'roosterjs-content-model-dom';\nimport type { ShortcutCommand, ShortcutKeyDefinition } from './ShortcutCommand';\nimport {\n ShortcutBold,\n ShortcutBullet,\n ShortcutClearFormat,\n ShortcutDecreaseFont,\n ShortcutIncreaseFont,\n ShortcutIndentList,\n ShortcutItalic,\n ShortcutNumbering,\n ShortcutOutdentList,\n ShortcutRedo,\n ShortcutRedoMacOS,\n ShortcutUnderline,\n ShortcutUndo,\n ShortcutUndo2,\n} from './shortcuts';\nimport type {\n EditorPlugin,\n IEditor,\n KeyDownEvent,\n PluginEvent,\n} from 'roosterjs-content-model-types';\n\nconst defaultShortcuts: ShortcutCommand[] = [\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 ShortcutIndentList,\n ShortcutOutdentList,\n];\nconst CommandCacheKey = '__ShortcutCommandCache';\n\n/**\n * Shortcut plugin hook on the specified shortcut keys and trigger related format API\n */\nexport class ShortcutPlugin implements EditorPlugin {\n private editor: IEditor | null = null;\n private isMac = false;\n\n /**\n * Create a new instance of ShortcutPlugin\n * @param [shortcuts=defaultShortcuts] Allowed commands\n */\n constructor(private shortcuts: ShortcutCommand[] = defaultShortcuts) {}\n\n /**\n * Get name of this plugin\n */\n getName() {\n return 'Shortcut';\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 this.isMac = !!this.editor.getEnvironment().isMac;\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 * Check if the plugin should handle the given event exclusively.\n * Handle an event exclusively means other plugin will not receive this event in\n * onPluginEvent method.\n * If two plugins will return true in willHandleEventExclusively() for the same event,\n * the final result depends on the order of the plugins are added into editor\n * @param event The event to check:\n */\n willHandleEventExclusively(event: PluginEvent) {\n return (\n event.eventType == 'keyDown' &&\n (event.rawEvent.ctrlKey || event.rawEvent.altKey || event.rawEvent.metaKey) &&\n !!this.cacheGetCommand(event)\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.editor && event.eventType == 'keyDown') {\n const command = this.cacheGetCommand(event);\n\n if (command) {\n command.onClick(this.editor);\n event.rawEvent.preventDefault();\n }\n }\n }\n\n private cacheGetCommand(event: KeyDownEvent) {\n return cacheGetEventData(event, CommandCacheKey, event => {\n const editor = this.editor;\n\n return (\n editor &&\n this.shortcuts.filter(\n command =>\n this.matchOS(command.environment) &&\n this.matchShortcut(command.shortcutKey, event.rawEvent)\n )[0]\n );\n });\n }\n\n private matchOS(environment?: 'all' | 'mac' | 'nonMac') {\n switch (environment) {\n case 'mac':\n return this.isMac;\n\n case 'nonMac':\n return !this.isMac;\n\n default:\n return true;\n }\n }\n\n private matchShortcut(shortcutKey: ShortcutKeyDefinition, event: KeyboardEvent) {\n const { ctrlKey, altKey, shiftKey, which, metaKey } = event;\n const ctrlOrMeta = this.isMac ? metaKey : ctrlKey;\n const matchModifier =\n (shortcutKey.modifierKey == 'ctrl' && ctrlOrMeta && !altKey) ||\n (shortcutKey.modifierKey == 'alt' && altKey && !ctrlOrMeta);\n\n return matchModifier && shiftKey == shortcutKey.shiftKey && shortcutKey.which == which;\n }\n}\n"]}
1
+ {"version":3,"file":"ShortcutPlugin.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-plugins/lib/shortcut/ShortcutPlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { cacheGetEventData } from 'roosterjs-content-model-dom';\nimport type { ShortcutCommand, ShortcutKeyDefinition } from './ShortcutCommand';\nimport {\n ShortcutBold,\n ShortcutBullet,\n ShortcutClearFormat,\n ShortcutDecreaseFont,\n ShortcutIncreaseFont,\n ShortcutIndentList,\n ShortcutItalic,\n ShortcutNumbering,\n ShortcutOutdentList,\n ShortcutRedo,\n ShortcutRedoAlt,\n ShortcutRedoMacOS,\n ShortcutUnderline,\n ShortcutUndo,\n ShortcutUndo2,\n} from './shortcuts';\nimport type {\n EditorPlugin,\n IEditor,\n KeyDownEvent,\n PluginEvent,\n} from 'roosterjs-content-model-types';\n\nconst defaultShortcuts: ShortcutCommand[] = [\n ShortcutBold,\n ShortcutItalic,\n ShortcutUnderline,\n ShortcutClearFormat,\n ShortcutUndo,\n ShortcutUndo2,\n ShortcutRedo,\n ShortcutRedoAlt,\n ShortcutRedoMacOS,\n ShortcutBullet,\n ShortcutNumbering,\n ShortcutIncreaseFont,\n ShortcutDecreaseFont,\n ShortcutIndentList,\n ShortcutOutdentList,\n];\nconst CommandCacheKey = '__ShortcutCommandCache';\n\n/**\n * Shortcut plugin hook on the specified shortcut keys and trigger related format API\n */\nexport class ShortcutPlugin implements EditorPlugin {\n private editor: IEditor | null = null;\n private isMac = false;\n\n /**\n * Create a new instance of ShortcutPlugin\n * @param [shortcuts=defaultShortcuts] Allowed commands\n */\n constructor(private shortcuts: ShortcutCommand[] = defaultShortcuts) {}\n\n /**\n * Get name of this plugin\n */\n getName() {\n return 'Shortcut';\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 this.isMac = !!this.editor.getEnvironment().isMac;\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 * Check if the plugin should handle the given event exclusively.\n * Handle an event exclusively means other plugin will not receive this event in\n * onPluginEvent method.\n * If two plugins will return true in willHandleEventExclusively() for the same event,\n * the final result depends on the order of the plugins are added into editor\n * @param event The event to check:\n */\n willHandleEventExclusively(event: PluginEvent) {\n return (\n event.eventType == 'keyDown' &&\n (event.rawEvent.ctrlKey || event.rawEvent.altKey || event.rawEvent.metaKey) &&\n !!this.cacheGetCommand(event)\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.editor && event.eventType == 'keyDown') {\n const command = this.cacheGetCommand(event);\n\n if (command) {\n command.onClick(this.editor);\n event.rawEvent.preventDefault();\n }\n }\n }\n\n private cacheGetCommand(event: KeyDownEvent) {\n return cacheGetEventData(event, CommandCacheKey, event => {\n const editor = this.editor;\n\n return (\n editor &&\n this.shortcuts.filter(\n command =>\n this.matchOS(command.environment) &&\n this.matchShortcut(command.shortcutKey, event.rawEvent)\n )[0]\n );\n });\n }\n\n private matchOS(environment?: 'all' | 'mac' | 'nonMac') {\n switch (environment) {\n case 'mac':\n return this.isMac;\n\n case 'nonMac':\n return !this.isMac;\n\n default:\n return true;\n }\n }\n\n private matchShortcut(shortcutKey: ShortcutKeyDefinition, event: KeyboardEvent) {\n const { ctrlKey, altKey, shiftKey, which, metaKey } = event;\n const ctrlOrMeta = this.isMac ? metaKey : ctrlKey;\n const matchModifier =\n (shortcutKey.modifierKey == 'ctrl' && ctrlOrMeta && !altKey) ||\n (shortcutKey.modifierKey == 'alt' && altKey && !ctrlOrMeta);\n\n return matchModifier && shiftKey == shortcutKey.shiftKey && shortcutKey.which == which;\n }\n}\n"]}
@@ -42,11 +42,18 @@ export declare const ShortcutUndo2: ShortcutCommand;
42
42
  */
43
43
  export declare const ShortcutRedo: ShortcutCommand;
44
44
  /**
45
+ * @deprecated
45
46
  * Shortcut command for Redo 2
46
47
  * Windows: N/A
47
48
  * MacOS: Meta + Shift + Z
48
49
  */
49
50
  export declare const ShortcutRedoMacOS: ShortcutCommand;
51
+ /**
52
+ * Shortcut command for Redo 3
53
+ * Windows: Ctrl + Shift + Z
54
+ * MacOS: Meta + Shift + Z
55
+ */
56
+ export declare const ShortcutRedoAlt: ShortcutCommand;
50
57
  /**
51
58
  * Shortcut command for Bullet List
52
59
  * Windows: Ctrl + . (Period)