@instructure/canvas-rce 5.14.1 → 5.15.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 (489) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/DEVELOPMENT.md +2 -2
  3. package/README.md +0 -8
  4. package/__tests__/common/indicate.test.js +84 -0
  5. package/__tests__/common/mimeClass.test.js +85 -0
  6. package/__tests__/module/contentInsertionUtils.test.js +52 -0
  7. package/__tests__/module/indicatorRegion.test.js +75 -0
  8. package/__tests__/module/normalizeLocale.test.js +46 -0
  9. package/__tests__/module/normalizeProps.test.js +51 -0
  10. package/__tests__/module/sanitizePlugins.test.js +48 -0
  11. package/__tests__/module/wrapInitCb.test.js +56 -0
  12. package/__tests__/rcs/api.test.js +819 -0
  13. package/{mocha-reporter-config.js → __tests__/sidebar/actions/all_files.test.js} +10 -9
  14. package/__tests__/sidebar/actions/data.test.js +196 -0
  15. package/__tests__/sidebar/actions/utils.js +44 -0
  16. package/{es/rce/__mocks__/_mockStudioPlayer.js → __tests__/sidebar/reducers/all_files.test.js} +12 -4
  17. package/babel.config.js +3 -1
  18. package/es/bridge/Bridge.js +18 -73
  19. package/es/bridge/index.js +1 -0
  20. package/es/canvasFileBrowser/FileBrowser.js +21 -77
  21. package/es/canvasFileBrowser/en-US.js +3 -6
  22. package/es/common/FlashAlert.js +15 -39
  23. package/es/common/browser.js +4 -2
  24. package/es/common/fileUrl.js +105 -64
  25. package/es/common/incremental-loading/LoadMoreButton.js +4 -4
  26. package/es/common/incremental-loading/LoadingIndicator.js +1 -2
  27. package/es/common/incremental-loading/LoadingStatus.js +5 -13
  28. package/es/common/incremental-loading/index.js +1 -0
  29. package/es/common/incremental-loading/useIncrementalLoading.js +1 -3
  30. package/es/common/indicate.js +16 -10
  31. package/es/common/mimeClass.js +3 -4
  32. package/es/common/natcompare.js +1 -4
  33. package/es/defaultTinymceConfig.js +5 -3
  34. package/es/elementDenylist.js +1 -0
  35. package/es/enhance-user-content/doc_previews.js +24 -35
  36. package/es/enhance-user-content/enhance_user_content.js +32 -67
  37. package/es/enhance-user-content/external_links.js +6 -9
  38. package/es/enhance-user-content/index.js +1 -0
  39. package/es/enhance-user-content/instructure_helper.js +22 -50
  40. package/es/enhance-user-content/jqueryish_funcs.js +8 -11
  41. package/es/enhance-user-content/mathml.js +48 -107
  42. package/es/enhance-user-content/media_comment_thumbnail.js +6 -25
  43. package/es/format-message.js +4 -5
  44. package/es/getThemeVars.js +8 -6
  45. package/es/getTranslations.js +1 -78
  46. package/es/index.d.ts +59 -0
  47. package/es/index.js +6 -6
  48. package/es/rce/AlertMessageArea.js +15 -16
  49. package/es/rce/DraggingBlocker.js +4 -2
  50. package/es/rce/KeyboardShortcutModal.js +3 -2
  51. package/es/rce/RCE.js +16 -17
  52. package/es/rce/RCEGlobals.js +12 -10
  53. package/es/rce/RCEVariants.js +29 -14
  54. package/es/rce/RCEWrapper.js +530 -641
  55. package/es/rce/RCEWrapper.utils.js +131 -0
  56. package/es/rce/RCEWrapperProps.js +9 -5
  57. package/es/rce/RceHtmlEditor.js +17 -19
  58. package/es/rce/ResizeHandle.js +4 -10
  59. package/es/rce/RestoreAutoSaveModal.js +1 -2
  60. package/es/rce/ShowOnFocusButton/index.js +2 -8
  61. package/es/rce/StatusBar.js +10 -44
  62. package/es/rce/alertHandler.js +1 -4
  63. package/es/rce/contentInsertion.js +36 -59
  64. package/es/rce/contentInsertionUtils.js +6 -8
  65. package/es/rce/contentRendering.js +13 -17
  66. package/es/rce/customEvents.js +1 -0
  67. package/es/rce/editorLanguage.js +23 -11
  68. package/es/rce/indicatorRegion.js +7 -7
  69. package/es/rce/normalizeLocale.js +5 -3
  70. package/es/rce/normalizeProps.js +7 -5
  71. package/es/rce/plugins/instructure-ui-icons/plugin.js +21 -3
  72. package/es/rce/plugins/instructure_color/clickCallback.js +82 -0
  73. package/es/rce/plugins/instructure_color/components/ColorPicker.js +294 -0
  74. package/es/rce/plugins/instructure_color/components/ColorPopup.js +67 -0
  75. package/es/rce/plugins/instructure_color/components/colorUtils.js +60 -0
  76. package/es/rce/plugins/instructure_color/plugin.js +40 -0
  77. package/es/rce/plugins/instructure_condensed_buttons/core/ListUtils.js +10 -3
  78. package/es/rce/plugins/instructure_condensed_buttons/plugin.js +1 -0
  79. package/es/rce/plugins/instructure_condensed_buttons/ui/alignment-button.js +1 -2
  80. package/es/rce/plugins/instructure_condensed_buttons/ui/directionality-button.js +3 -2
  81. package/es/rce/plugins/instructure_condensed_buttons/ui/indent-outdent-button.js +1 -0
  82. package/es/rce/plugins/instructure_condensed_buttons/ui/list-button.js +26 -25
  83. package/es/rce/plugins/instructure_condensed_buttons/ui/subscript-superscript-button.js +2 -3
  84. package/es/rce/plugins/instructure_documents/clickCallback.js +1 -0
  85. package/es/rce/plugins/instructure_documents/components/DocumentsPanel.js +1 -9
  86. package/es/rce/plugins/instructure_documents/components/Link.js +4 -20
  87. package/es/rce/plugins/instructure_documents/plugin.js +7 -14
  88. package/es/rce/plugins/instructure_equation/EquationEditorModal/advancedOnlySyntax.js +4 -2
  89. package/es/rce/plugins/instructure_equation/EquationEditorModal/advancedPreference.js +1 -2
  90. package/es/rce/plugins/instructure_equation/EquationEditorModal/index.js +17 -37
  91. package/es/rce/plugins/instructure_equation/EquationEditorModal/latexTextareaUtil.js +14 -15
  92. package/es/rce/plugins/instructure_equation/EquationEditorModal/parseLatex.js +6 -5
  93. package/es/rce/plugins/instructure_equation/EquationEditorModal/styles.js +4 -2
  94. package/es/rce/plugins/instructure_equation/EquationEditorToolbar/buttons.js +14 -8
  95. package/es/rce/plugins/instructure_equation/EquationEditorToolbar/index.js +13 -18
  96. package/es/rce/plugins/instructure_equation/MathIcon/index.js +4 -5
  97. package/es/rce/plugins/instructure_equation/MathIcon/svgs.js +1 -1
  98. package/es/rce/plugins/instructure_equation/clickCallback.js +2 -5
  99. package/es/rce/plugins/instructure_equation/mathlive/index.js +167 -16
  100. package/es/rce/plugins/instructure_equation/plugin.js +7 -10
  101. package/es/rce/plugins/instructure_fullscreen/plugin.js +1 -6
  102. package/es/rce/plugins/instructure_html_view/clickCallback.js +1 -0
  103. package/es/rce/plugins/instructure_html_view/plugin.js +5 -4
  104. package/es/rce/plugins/instructure_icon_maker/clickCallback.js +5 -8
  105. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ColorSection.js +47 -51
  106. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/CreateIconMakerForm.js +10 -10
  107. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/Footer.js +11 -11
  108. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/Group.js +6 -6
  109. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/Header.js +8 -10
  110. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/Course.js +32 -31
  111. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/ImageOptions.js +24 -35
  112. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/ImageSection.js +32 -32
  113. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/ModeSelect.js +11 -11
  114. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/MultiColor/index.js +16 -15
  115. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/MultiColor/svg.js +1 -0
  116. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/SVGList.js +11 -11
  117. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/SVGThumbnail.js +9 -13
  118. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/SingleColor/index.js +12 -13
  119. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/SingleColor/svg.js +33 -80
  120. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/Upload.js +34 -28
  121. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/index.js +1 -0
  122. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/propTypes.js +1 -0
  123. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/utils.js +5 -5
  124. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/Preview.js +7 -8
  125. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ShapeSection.js +5 -7
  126. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/TextSection.js +5 -10
  127. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/index.js +1 -0
  128. package/es/rce/plugins/instructure_icon_maker/components/IconMakerTray.js +38 -60
  129. package/es/rce/plugins/instructure_icon_maker/components/SavedIconMakerList.js +4 -4
  130. package/es/rce/plugins/instructure_icon_maker/plugin.js +10 -14
  131. package/es/rce/plugins/instructure_icon_maker/reducers/imageSection.js +37 -38
  132. package/es/rce/plugins/instructure_icon_maker/reducers/svgSettings.js +24 -24
  133. package/es/rce/plugins/instructure_icon_maker/registerEditToolbar.js +2 -4
  134. package/es/rce/plugins/instructure_icon_maker/svg/constants.js +4 -3
  135. package/es/rce/plugins/instructure_icon_maker/svg/font.js +3 -1
  136. package/es/rce/plugins/instructure_icon_maker/svg/image.js +74 -90
  137. package/es/rce/plugins/instructure_icon_maker/svg/index.js +17 -24
  138. package/es/rce/plugins/instructure_icon_maker/svg/metadata.js +1 -0
  139. package/es/rce/plugins/instructure_icon_maker/svg/settings.js +48 -58
  140. package/es/rce/plugins/instructure_icon_maker/svg/shape.js +5 -54
  141. package/es/rce/plugins/instructure_icon_maker/svg/text.js +35 -124
  142. package/es/rce/plugins/instructure_icon_maker/svg/utils.js +3 -11
  143. package/es/rce/plugins/instructure_icon_maker/utils/IconMakerClose.js +4 -9
  144. package/es/rce/plugins/instructure_icon_maker/utils/IconMakerFormHasChanges.js +1 -15
  145. package/es/rce/plugins/instructure_icon_maker/utils/addIconMakerAttributes.js +3 -4
  146. package/es/rce/plugins/instructure_icon_maker/utils/iconValidation.js +2 -3
  147. package/es/rce/plugins/instructure_icon_maker/utils/iconsLabels.js +1 -0
  148. package/es/rce/plugins/instructure_icon_maker/utils/useDebouncedValue.js +12 -13
  149. package/es/rce/plugins/instructure_image/ImageEmbedOptions.js +9 -31
  150. package/es/rce/plugins/instructure_image/ImageList/Image.js +8 -14
  151. package/es/rce/plugins/instructure_image/ImageList/index.js +8 -10
  152. package/es/rce/plugins/instructure_image/ImageOptionsTray/TrayController.js +9 -31
  153. package/es/rce/plugins/instructure_image/ImageOptionsTray/index.js +6 -19
  154. package/es/rce/plugins/instructure_image/Images/index.js +1 -3
  155. package/es/rce/plugins/instructure_image/clickCallback.js +1 -0
  156. package/es/rce/plugins/instructure_image/plugin.js +14 -20
  157. package/es/rce/plugins/instructure_links/clickCallback.js +1 -0
  158. package/es/rce/plugins/instructure_links/components/AccordionSection.js +8 -8
  159. package/es/rce/plugins/instructure_links/components/CollectionPanel.js +1 -3
  160. package/es/rce/plugins/instructure_links/components/Link.js +68 -84
  161. package/es/rce/plugins/instructure_links/components/LinkOptionsDialog/LinkOptionsDialogController.js +2 -23
  162. package/es/rce/plugins/instructure_links/components/LinkOptionsDialog/index.js +3 -6
  163. package/es/rce/plugins/instructure_links/components/LinkOptionsTray/LinkOptionsTrayController.js +3 -20
  164. package/es/rce/plugins/instructure_links/components/LinkOptionsTray/index.js +3 -14
  165. package/es/rce/plugins/instructure_links/components/LinkSet.js +32 -57
  166. package/es/rce/plugins/instructure_links/components/LinksPanel.js +22 -10
  167. package/es/rce/plugins/instructure_links/components/NavigationPanel.js +7 -9
  168. package/es/rce/plugins/instructure_links/components/NoResults.js +7 -14
  169. package/es/rce/plugins/instructure_links/plugin.js +23 -49
  170. package/es/rce/plugins/instructure_links/validateURL.js +81 -36
  171. package/es/rce/plugins/instructure_media_embed/clickCallback.js +5 -9
  172. package/es/rce/plugins/instructure_media_embed/components/Embed.js +7 -7
  173. package/es/rce/plugins/instructure_media_embed/plugin.js +7 -3
  174. package/es/rce/plugins/instructure_paste/pasteMenuCommand.js +1 -5
  175. package/es/rce/plugins/instructure_paste/plugin.js +29 -33
  176. package/es/rce/plugins/instructure_rce_external_tools/ExternalToolsEnv.js +31 -79
  177. package/es/rce/plugins/instructure_rce_external_tools/RceToolWrapper.js +24 -83
  178. package/es/rce/plugins/instructure_rce_external_tools/components/ExternalToolDialog/ExternalToolDialog.js +39 -69
  179. package/es/rce/plugins/instructure_rce_external_tools/components/ExternalToolDialog/ExternalToolDialogModal.js +1 -2
  180. package/es/rce/plugins/instructure_rce_external_tools/components/ExternalToolDialog/ExternalToolDialogTray.js +1 -1
  181. package/es/rce/plugins/instructure_rce_external_tools/components/ExternalToolSelectionDialog/ExternalToolSelectionDialog.js +5 -14
  182. package/es/rce/plugins/instructure_rce_external_tools/components/ExternalToolSelectionDialog/ExternalToolSelectionItem.js +1 -2
  183. package/es/rce/plugins/instructure_rce_external_tools/components/util/ExpandoText.js +1 -0
  184. package/es/rce/plugins/instructure_rce_external_tools/components/util/ToolLaunchIframe.js +2 -1
  185. package/es/rce/plugins/instructure_rce_external_tools/constants.js +28 -0
  186. package/es/rce/plugins/instructure_rce_external_tools/dialog-helper.js +20 -6
  187. package/es/rce/plugins/instructure_rce_external_tools/helpers/tags.js +0 -2
  188. package/es/rce/plugins/instructure_rce_external_tools/jquery/jquery.dropdownList.js +129 -136
  189. package/es/rce/plugins/instructure_rce_external_tools/lti11-content-items/RceLti11ContentItem.js +110 -112
  190. package/es/rce/plugins/instructure_rce_external_tools/lti13-content-items/Lti13ContentItemJson.js +1 -0
  191. package/es/rce/plugins/instructure_rce_external_tools/lti13-content-items/RceLti13ContentItem.js +4 -21
  192. package/es/rce/plugins/instructure_rce_external_tools/lti13-content-items/models/BaseLinkContentItem.js +5 -19
  193. package/es/rce/plugins/instructure_rce_external_tools/lti13-content-items/models/HtmlFragmentContentItem.js +1 -6
  194. package/es/rce/plugins/instructure_rce_external_tools/lti13-content-items/models/ImageContentItem.js +1 -9
  195. package/es/rce/plugins/instructure_rce_external_tools/lti13-content-items/models/LinkContentItem.js +1 -1
  196. package/es/rce/plugins/instructure_rce_external_tools/lti13-content-items/models/ResourceLinkContentItem.js +3 -5
  197. package/es/rce/plugins/instructure_rce_external_tools/lti13-content-items/processEditorContentItems.js +23 -16
  198. package/es/rce/plugins/instructure_rce_external_tools/lti13-content-items/rceLti13ContentItemFromJson.js +3 -4
  199. package/es/rce/plugins/instructure_rce_external_tools/plugin.js +11 -20
  200. package/es/rce/plugins/instructure_rce_external_tools/util/addParentFrameContextToUrl.js +1 -1
  201. package/es/rce/plugins/instructure_rce_external_tools/util/externalToolsForToolbar.js +42 -0
  202. package/es/rce/plugins/instructure_record/AudioOptionsTray/TrayController.js +6 -35
  203. package/es/rce/plugins/instructure_record/AudioOptionsTray/index.js +13 -17
  204. package/es/rce/plugins/instructure_record/MediaPanel/index.js +1 -9
  205. package/es/rce/plugins/instructure_record/VideoOptionsTray/TrayController.js +16 -66
  206. package/es/rce/plugins/instructure_record/VideoOptionsTray/index.js +21 -35
  207. package/es/rce/plugins/instructure_record/clickCallback.js +32 -44
  208. package/es/rce/plugins/instructure_record/mediaTranslations.js +1 -0
  209. package/es/rce/plugins/instructure_record/plugin.js +11 -18
  210. package/es/rce/plugins/instructure_search_and_replace/clickCallback.js +4 -8
  211. package/es/rce/plugins/instructure_search_and_replace/components/FindReplaceTray.js +34 -51
  212. package/es/rce/plugins/instructure_search_and_replace/components/FindReplaceTrayController.js +12 -30
  213. package/es/rce/plugins/instructure_search_and_replace/getSelectionContext.js +2 -9
  214. package/es/rce/plugins/instructure_search_and_replace/plugin.js +2 -5
  215. package/es/rce/plugins/instructure_studio_media_options/plugin.js +1 -1
  216. package/es/rce/plugins/instructure_wordcount/clickCallback.js +5 -9
  217. package/es/rce/plugins/instructure_wordcount/components/WordCountModal.js +27 -37
  218. package/es/rce/plugins/instructure_wordcount/plugin.js +1 -0
  219. package/es/rce/plugins/instructure_wordcount/utils/countContent.js +4 -11
  220. package/es/rce/plugins/instructure_wordcount/utils/tableContent.js +6 -8
  221. package/es/rce/plugins/shared/CanvasContentTray.js +29 -63
  222. package/es/rce/plugins/shared/CheckerboardStyling.js +1 -1
  223. package/es/rce/plugins/shared/ColorInput.js +27 -39
  224. package/es/rce/plugins/shared/ConditionalTooltip.js +6 -6
  225. package/es/rce/plugins/shared/ContentSelection.js +29 -78
  226. package/es/rce/plugins/shared/DimensionUtils.js +3 -12
  227. package/es/rce/plugins/shared/DimensionsInput/DimensionInput.js +6 -6
  228. package/es/rce/plugins/shared/DimensionsInput/index.js +37 -15
  229. package/es/rce/plugins/shared/DimensionsInput/useDimensionsState.js +5 -29
  230. package/es/rce/plugins/shared/ErrorBoundary.js +2 -5
  231. package/es/rce/plugins/shared/EventUtils.js +2 -4
  232. package/es/rce/plugins/shared/Filter.js +8 -38
  233. package/es/rce/plugins/shared/FixedContentTray.js +16 -17
  234. package/es/rce/plugins/shared/ImageCropper/DirectionRegion.js +4 -12
  235. package/es/rce/plugins/shared/ImageCropper/Modal.js +16 -20
  236. package/es/rce/plugins/shared/ImageCropper/Preview.js +18 -24
  237. package/es/rce/plugins/shared/ImageCropper/constants.js +1 -0
  238. package/es/rce/plugins/shared/ImageCropper/controls/CustomNumberInput.js +10 -14
  239. package/es/rce/plugins/shared/ImageCropper/controls/ResetControls.js +4 -4
  240. package/es/rce/plugins/shared/ImageCropper/controls/RotationControls.js +5 -15
  241. package/es/rce/plugins/shared/ImageCropper/controls/ShapeControls.js +8 -11
  242. package/es/rce/plugins/shared/ImageCropper/controls/ZoomControls.js +5 -16
  243. package/es/rce/plugins/shared/ImageCropper/controls/index.js +5 -5
  244. package/es/rce/plugins/shared/ImageCropper/controls/useDebouncedNumericValue.js +16 -31
  245. package/es/rce/plugins/shared/ImageCropper/controls/utils.js +1 -2
  246. package/es/rce/plugins/shared/ImageCropper/imageCropUtils.js +19 -31
  247. package/es/rce/plugins/shared/ImageCropper/index.js +1 -0
  248. package/es/rce/plugins/shared/ImageCropper/propTypes.js +1 -0
  249. package/es/rce/plugins/shared/ImageCropper/reducers/imageCropper.js +15 -14
  250. package/es/rce/plugins/shared/ImageCropper/shape.js +1 -0
  251. package/es/rce/plugins/shared/ImageCropper/svg/index.js +1 -2
  252. package/es/rce/plugins/shared/ImageCropper/svg/shape.js +5 -22
  253. package/es/rce/plugins/shared/ImageCropper/svg/utils.js +3 -4
  254. package/es/rce/plugins/shared/ImageCropper/useKeyMouseEvents.js +20 -50
  255. package/es/rce/plugins/shared/ImageCropper/useMouseWheel.js +8 -10
  256. package/es/rce/plugins/shared/ImageOptionsForm.js +18 -20
  257. package/es/rce/plugins/shared/LinkDisplay.js +9 -11
  258. package/es/rce/plugins/shared/PreviewIcon.js +9 -15
  259. package/es/rce/plugins/shared/Previewable.js +1 -0
  260. package/es/rce/plugins/shared/RceFileBrowser.js +7 -10
  261. package/es/rce/plugins/shared/StoreContext.js +9 -12
  262. package/es/rce/plugins/shared/StudioLtiSupportUtils.js +15 -12
  263. package/es/rce/plugins/shared/UnknownFileTypePanel.js +1 -0
  264. package/es/rce/plugins/shared/Upload/CanvasContentPanel.js +19 -25
  265. package/es/rce/plugins/shared/Upload/CategoryProcessor.js +2 -3
  266. package/es/rce/plugins/shared/Upload/ComputerPanel.js +19 -40
  267. package/es/rce/plugins/shared/Upload/PanelFilter.js +10 -20
  268. package/es/rce/plugins/shared/Upload/SvgCategoryProcessor.js +4 -3
  269. package/es/rce/plugins/shared/Upload/UploadFile.js +32 -38
  270. package/es/rce/plugins/shared/Upload/UploadFileModal.js +37 -59
  271. package/es/rce/plugins/shared/Upload/UrlPanel.js +5 -5
  272. package/es/rce/plugins/shared/Upload/UsageRightsSelectBox.js +25 -36
  273. package/es/rce/plugins/shared/Upload/doFileUpload.js +10 -13
  274. package/es/rce/plugins/shared/Upload/index.js +1 -0
  275. package/es/rce/plugins/shared/ai_tools/AIResponseModal.js +8 -11
  276. package/es/rce/plugins/shared/ai_tools/AIToolsTray.js +19 -40
  277. package/es/rce/plugins/shared/ai_tools/aiicons.js +3 -2
  278. package/es/rce/plugins/shared/ai_tools/index.js +1 -0
  279. package/es/rce/plugins/shared/buildDownloadUrl.js +0 -2
  280. package/es/rce/plugins/shared/canvasContentUtils.js +7 -11
  281. package/es/rce/plugins/shared/compressionUtils.js +18 -28
  282. package/es/rce/plugins/shared/dateUtils.js +1 -1
  283. package/es/rce/plugins/shared/do-fetch-api-effect/defaultFetchOptions.js +4 -2
  284. package/es/rce/plugins/shared/do-fetch-api-effect/doFetchApi.js +18 -24
  285. package/es/rce/plugins/shared/do-fetch-api-effect/get-cookie.js +1 -1
  286. package/es/rce/plugins/shared/do-fetch-api-effect/index.js +1 -0
  287. package/es/rce/plugins/shared/do-fetch-api-effect/parse-link-header.js +6 -20
  288. package/es/rce/plugins/shared/do-fetch-api-effect/query-string-encoding.js +5 -3
  289. package/es/rce/plugins/shared/fileShape.js +4 -9
  290. package/es/rce/plugins/shared/fileTypeUtils.js +34 -47
  291. package/es/rce/plugins/shared/fileUtils.js +1 -2
  292. package/es/rce/plugins/shared/linkUtils.js +1 -16
  293. package/es/rce/plugins/shared/round.js +2 -2
  294. package/es/rce/plugins/shared/trayUtils.js +7 -3
  295. package/es/rce/plugins/shared/useDataUrl.js +13 -14
  296. package/es/rce/plugins/shared/useFilterSettings.js +3 -3
  297. package/es/rce/plugins/tinymce-a11y-checker/components/ColorField.js +4 -8
  298. package/es/rce/plugins/tinymce-a11y-checker/components/checker.js +12 -72
  299. package/es/rce/plugins/tinymce-a11y-checker/components/color-picker.js +1 -2
  300. package/es/rce/plugins/tinymce-a11y-checker/components/placeholder-svg.js +1 -0
  301. package/es/rce/plugins/tinymce-a11y-checker/components/pointer.js +1 -0
  302. package/es/rce/plugins/tinymce-a11y-checker/node-checker.js +2 -9
  303. package/es/rce/plugins/tinymce-a11y-checker/plugin.js +18 -24
  304. package/es/rce/plugins/tinymce-a11y-checker/rules/adjacent-links.js +3 -26
  305. package/es/rce/plugins/tinymce-a11y-checker/rules/headings-sequence.js +9 -38
  306. package/es/rce/plugins/tinymce-a11y-checker/rules/headings-start-at-h2.js +2 -7
  307. package/es/rce/plugins/tinymce-a11y-checker/rules/img-alt-filename.js +1 -2
  308. package/es/rce/plugins/tinymce-a11y-checker/rules/img-alt-length.js +1 -1
  309. package/es/rce/plugins/tinymce-a11y-checker/rules/img-alt.js +1 -2
  310. package/es/rce/plugins/tinymce-a11y-checker/rules/index.js +1 -0
  311. package/es/rce/plugins/tinymce-a11y-checker/rules/large-text-contrast.js +2 -6
  312. package/es/rce/plugins/tinymce-a11y-checker/rules/list-structure.js +5 -24
  313. package/es/rce/plugins/tinymce-a11y-checker/rules/paragraphs-for-headings.js +1 -3
  314. package/es/rce/plugins/tinymce-a11y-checker/rules/small-text-contrast.js +2 -8
  315. package/es/rce/plugins/tinymce-a11y-checker/rules/table-caption.js +1 -3
  316. package/es/rce/plugins/tinymce-a11y-checker/rules/table-header-scope.js +1 -2
  317. package/es/rce/plugins/tinymce-a11y-checker/rules/table-header.js +1 -9
  318. package/es/rce/plugins/tinymce-a11y-checker/utils/colors.js +1 -0
  319. package/es/rce/plugins/tinymce-a11y-checker/utils/describe.js +1 -7
  320. package/es/rce/plugins/tinymce-a11y-checker/utils/dom.js +3 -30
  321. package/es/rce/plugins/tinymce-a11y-checker/utils/indicate.js +18 -18
  322. package/es/rce/plugins/tinymce-a11y-checker/utils/rgb-hex.js +6 -12
  323. package/es/rce/plugins/tinymce-a11y-checker/utils/strings.js +1 -4
  324. package/es/rce/root.js +17 -16
  325. package/es/rce/sanitizePlugins.js +1 -3
  326. package/es/rce/style.js +1 -4
  327. package/es/rce/tinyRCE.js +14 -9
  328. package/es/rce/tinymce.oxide.content.min.css.js +1 -0
  329. package/es/rce/tinymce.oxide.skin.min.css.js +1 -0
  330. package/es/rce/transformContent.js +9 -11
  331. package/es/rce/types.js +1 -0
  332. package/es/rce/userOS.js +1 -1
  333. package/es/rce/wrapInitCb.js +50 -43
  334. package/es/rcs/api.js +100 -171
  335. package/es/rcs/buildError.js +8 -20
  336. package/es/rcs/fake.js +9 -20
  337. package/es/sidebar/actions/all_files.js +2 -0
  338. package/es/sidebar/actions/data.js +4 -7
  339. package/es/sidebar/actions/documents.js +19 -18
  340. package/es/sidebar/actions/files.js +21 -28
  341. package/es/sidebar/actions/filter.js +5 -5
  342. package/es/sidebar/actions/flickr.js +1 -1
  343. package/es/sidebar/actions/images.js +32 -37
  344. package/es/sidebar/actions/links.js +1 -0
  345. package/es/sidebar/actions/media.js +27 -28
  346. package/es/sidebar/actions/session.js +2 -5
  347. package/es/sidebar/actions/ui.js +1 -0
  348. package/es/sidebar/actions/upload.js +38 -74
  349. package/es/sidebar/containers/Sidebar.js +1 -2
  350. package/es/sidebar/containers/sidebarHandlers.js +9 -13
  351. package/es/sidebar/dragHtml.js +11 -5
  352. package/es/sidebar/reducers/all_files.js +5 -6
  353. package/es/sidebar/reducers/collection.js +12 -15
  354. package/es/sidebar/reducers/collections.js +6 -8
  355. package/es/sidebar/reducers/documents.js +7 -16
  356. package/es/sidebar/reducers/files.js +4 -6
  357. package/es/sidebar/reducers/filter.js +8 -23
  358. package/es/sidebar/reducers/flickr.js +10 -12
  359. package/es/sidebar/reducers/folder.js +16 -18
  360. package/es/sidebar/reducers/folders.js +4 -6
  361. package/es/sidebar/reducers/images.js +4 -16
  362. package/es/sidebar/reducers/index.js +3 -1
  363. package/es/sidebar/reducers/media.js +7 -16
  364. package/es/sidebar/reducers/newPageLinkExpanded.js +2 -5
  365. package/es/sidebar/reducers/noop.js +2 -2
  366. package/es/sidebar/reducers/rootFolderId.js +2 -5
  367. package/es/sidebar/reducers/session.js +4 -6
  368. package/es/sidebar/reducers/ui.js +6 -25
  369. package/es/sidebar/reducers/upload.js +16 -64
  370. package/es/sidebar/store/configureStore.js +1 -0
  371. package/es/sidebar/store/initialState.js +14 -26
  372. package/es/translations/locales/ab.js +1 -0
  373. package/es/translations/locales/ar.js +72 -8
  374. package/es/translations/locales/ca.js +72 -8
  375. package/es/translations/locales/cs.js +1 -0
  376. package/es/translations/locales/cs_CZ.js +1 -0
  377. package/es/translations/locales/cy.js +72 -8
  378. package/es/translations/locales/da-x-k12.js +72 -8
  379. package/es/translations/locales/da.js +72 -8
  380. package/es/translations/locales/da_DK.js +1 -0
  381. package/es/translations/locales/de.js +72 -8
  382. package/es/translations/locales/el.js +4 -0
  383. package/es/translations/locales/en-AU-x-unimelb.js +72 -8
  384. package/es/translations/locales/en-GB-x-ukhe.js +72 -8
  385. package/es/translations/locales/en.js +72 -8
  386. package/es/translations/locales/en_AU.js +72 -8
  387. package/es/translations/locales/en_CA.js +72 -8
  388. package/es/translations/locales/en_CY.js +72 -8
  389. package/es/translations/locales/en_GB.js +72 -8
  390. package/es/translations/locales/en_NZ.js +1 -0
  391. package/es/translations/locales/en_SE.js +1 -0
  392. package/es/translations/locales/en_US.js +1 -0
  393. package/es/translations/locales/es.js +72 -8
  394. package/es/translations/locales/es_ES.js +72 -8
  395. package/es/translations/locales/es_GT.js +1 -0
  396. package/es/translations/locales/fa_IR.js +7 -0
  397. package/es/translations/locales/fi.js +72 -8
  398. package/es/translations/locales/fr.js +72 -8
  399. package/es/translations/locales/fr_CA.js +73 -9
  400. package/es/translations/locales/ga.js +5 -13
  401. package/es/translations/locales/he.js +7 -0
  402. package/es/translations/locales/hi.js +72 -8
  403. package/es/translations/locales/ht.js +72 -8
  404. package/es/translations/locales/hu.js +7 -6
  405. package/es/translations/locales/hu_HU.js +1 -0
  406. package/es/translations/locales/hy.js +1 -0
  407. package/es/translations/locales/id.js +72 -8
  408. package/es/translations/locales/id_ID.js +1 -0
  409. package/es/translations/locales/is.js +72 -8
  410. package/es/translations/locales/it.js +72 -8
  411. package/es/translations/locales/ja.js +72 -8
  412. package/es/translations/locales/ko.js +1 -0
  413. package/es/translations/locales/ko_KR.js +1 -0
  414. package/es/translations/locales/lt.js +1 -0
  415. package/es/translations/locales/lt_LT.js +1 -0
  416. package/es/translations/locales/mi.js +72 -8
  417. package/es/translations/locales/mn_MN.js +1 -0
  418. package/es/translations/locales/ms.js +72 -8
  419. package/es/translations/locales/nb-x-k12.js +72 -8
  420. package/es/translations/locales/nb.js +72 -8
  421. package/es/translations/locales/nl.js +72 -8
  422. package/es/translations/locales/nl_NL.js +1 -0
  423. package/es/translations/locales/nn.js +7 -6
  424. package/es/translations/locales/pl.js +72 -8
  425. package/es/translations/locales/pt.js +72 -8
  426. package/es/translations/locales/pt_BR.js +72 -8
  427. package/es/translations/locales/ro.js +1 -0
  428. package/es/translations/locales/ru.js +72 -8
  429. package/es/translations/locales/se.js +1 -0
  430. package/es/translations/locales/sl.js +72 -8
  431. package/es/translations/locales/sv-x-k12.js +72 -8
  432. package/es/translations/locales/sv.js +72 -8
  433. package/es/translations/locales/sv_SE.js +1 -0
  434. package/es/translations/locales/tg.js +1 -0
  435. package/es/translations/locales/th.js +72 -8
  436. package/es/translations/locales/th_TH.js +1 -0
  437. package/es/translations/locales/tl_PH.js +1 -0
  438. package/es/translations/locales/tr.js +7 -0
  439. package/es/translations/locales/uk_UA.js +7 -0
  440. package/es/translations/locales/vi.js +72 -8
  441. package/es/translations/locales/vi_VN.js +1 -0
  442. package/es/translations/locales/zh-Hans.js +72 -8
  443. package/es/translations/locales/zh-Hant.js +72 -8
  444. package/es/translations/locales/zh.js +72 -8
  445. package/es/translations/locales/zh_HK.js +72 -8
  446. package/es/translations/locales/zh_TW.Big5.js +1 -0
  447. package/es/translations/locales/zh_TW.js +1 -0
  448. package/es/translations/tinymce/ar_SA.js +1 -0
  449. package/es/translations/tinymce/fi.js +1 -0
  450. package/es/translations/tinymce/ga.js +1 -0
  451. package/es/translations/tinymce/id.js +1 -0
  452. package/es/translations/tinymce/ru.js +1 -0
  453. package/es/translations/tinymce/ru_RU.js +1 -0
  454. package/es/translations/tinymce/sl.js +1 -0
  455. package/es/translations/tinymce/sr.js +1 -0
  456. package/es/translations/tinymce/th.js +1 -0
  457. package/es/translations/tinymce/uk_UA.js +1 -0
  458. package/es/translations/tinymce/vi_VN.js +1 -0
  459. package/es/util/TypedDict.js +4 -2
  460. package/es/util/elem-util.js +1 -1
  461. package/es/util/encrypted-storage.js +3 -13
  462. package/es/util/file-url-util.js +2 -7
  463. package/es/util/fullscreenHelpers.js +9 -9
  464. package/es/util/instui-icon-helper.js +4 -3
  465. package/es/util/loadingPlaceholder.js +39 -41
  466. package/es/util/simpleCache.js +1 -5
  467. package/es/util/string-util.js +1 -1
  468. package/es/util/textarea-editing-util.js +3 -7
  469. package/es/util/tinymce-plugin-util.js +0 -5
  470. package/es/util/url-util.js +20 -29
  471. package/eslint.config.js +250 -0
  472. package/jest.config.js +1 -1
  473. package/locales/en.json +190 -10
  474. package/package.json +78 -82
  475. package/scripts/build-canvas +2 -1
  476. package/scripts/build.js +4 -4
  477. package/scripts/installTranslations.js +7 -8
  478. package/testcafe/RCEWrapper.test.js +0 -1
  479. package/testcafe/StatusBar.test.js +0 -1
  480. package/testcafe/axe.test.js +3 -4
  481. package/testcafe/enhanceUserContent.test.js +0 -1
  482. package/tsconfig.json +21 -16
  483. package/{es/rce/__mocks__/styleMock.js → types/format-message-generate-id.d.ts} +6 -2
  484. package/{es/rce/plugins/shared/__mocks__/screenfull.js → types/js-beautify.d.ts} +4 -7
  485. package/.eslintrc +0 -45
  486. package/.prettierignore +0 -6
  487. package/es/rce/__mocks__/_mockCryptoEs.js +0 -124
  488. package/es/rce/__mocks__/tinymceReact.js +0 -55
  489. package/es/rce/plugins/tinymce-a11y-checker/rules/__mocks__/index.js +0 -53
@@ -0,0 +1,131 @@
1
+ /*
2
+ * Copyright (C) 2025 - present Instructure, Inc.
3
+ *
4
+ * This file is part of Canvas.
5
+ *
6
+ * Canvas is free software: you can redistribute it and/or modify it under
7
+ * the terms of the GNU Affero General Public License as published by the Free
8
+ * Software Foundation, version 3 of the License.
9
+ *
10
+ * Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
11
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12
+ * A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
13
+ * details.
14
+ *
15
+ * You should have received a copy of the GNU Affero General Public License along
16
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ import formatMessage from '../format-message';
20
+
21
+ // standard: string of tinymce menu commands
22
+ // e.g. 'instructure_links | inserttable instructure_media_embed | hr'
23
+ // custom: a string of tinymce menu commands
24
+ // returns: standard + custom with any duplicate commands removed from custom
25
+ export function mergeMenuItems(standard, custom) {
26
+ let c = custom?.trim?.();
27
+ if (!c) return standard;
28
+ const s = new Set(standard.split(/[\s|]+/));
29
+ // remove any duplicates
30
+ const c_array = c.split(/\s+/).filter(m => !s.has(m));
31
+ c = c_array.join(' ').replace(/^\s*\|\s*/, '').replace(/\s*\|\s*$/, '');
32
+ return `${standard} | ${c}`;
33
+ }
34
+
35
+ // standard: the incoming tinymce menu object
36
+ // custom: tinymce menu object to merge into standard
37
+ // returns: the merged result by mutating incoming standard arg.
38
+ // It will add commands to existing menus, or add a new menu
39
+ // if the custom one does not exist
40
+ export function mergeMenu(standard, custom) {
41
+ if (!custom) return standard;
42
+ Object.keys(custom).forEach(k => {
43
+ const curr_m = standard[k];
44
+ if (curr_m) {
45
+ curr_m.items = mergeMenuItems(curr_m.items, custom[k].items);
46
+ } else {
47
+ standard[k] = {
48
+ ...custom[k]
49
+ };
50
+ }
51
+ });
52
+ return standard;
53
+ }
54
+
55
+ // standard: incoming tinymce toolbar array
56
+ // custom: tinymce toolbar array to merge into standard
57
+ // returns: the merged result by mutating the incoming standard arg.
58
+ // It will add commands to existing toolbars, or add a new toolbar
59
+ // if the custom one does not exist
60
+ export function mergeToolbar(standard, custom) {
61
+ if (!custom) return standard;
62
+ // merge given toolbar data into the default toolbar
63
+ custom.forEach(tb => {
64
+ const curr_tb = standard.find(t => tb.name && formatMessage(tb.name) === t.name);
65
+ if (curr_tb) {
66
+ curr_tb.items.splice(curr_tb.items.length, 0, ...tb.items);
67
+ } else {
68
+ standard.push(tb);
69
+ }
70
+ });
71
+ return standard;
72
+ }
73
+
74
+ // standard: incoming array of plugin names
75
+ // custom: array of plugin names to merge
76
+ // exclusions: array of plugins to remove
77
+ // returns: the merged result, duplicates and exclusions removed
78
+ export function mergePlugins(standard, custom = [], exclusions = []) {
79
+ const union = new Set(standard);
80
+ for (const c of custom) {
81
+ union.add(c);
82
+ }
83
+ for (const e of exclusions) {
84
+ union.delete(e);
85
+ }
86
+ return [...union];
87
+ }
88
+ export function focusToolbar(el) {
89
+ const $firstToolbarButton = el.querySelector('.tox-tbtn');
90
+ if ($firstToolbarButton) {
91
+ $firstToolbarButton.focus();
92
+ }
93
+ }
94
+ export function focusFirstMenuButton(el) {
95
+ const $firstMenu = el.querySelector('.tox-mbtn');
96
+ if ($firstMenu) {
97
+ $firstMenu.focus();
98
+ }
99
+ }
100
+ export function isElementWithinTable(node) {
101
+ let elem = node;
102
+ while (elem) {
103
+ if (elem.tagName === 'TABLE' || elem.tagName === 'TD' || elem.tagName === 'TH') {
104
+ return true;
105
+ }
106
+ elem = elem.parentElement;
107
+ }
108
+ return false;
109
+ }
110
+
111
+ // plugins is an array of strings
112
+ // the convention is that plugins starting with '-',
113
+ // i.e. a hyphen, are to be disabled in the RCE instance
114
+ export function parsePluginsToExclude(plugins) {
115
+ return plugins.filter(plugin => plugin.length > 0 && plugin[0] === '-').map(pluginToIgnore => pluginToIgnore.slice(1));
116
+ }
117
+
118
+ // if a placeholder image shows up in autosaved content, we have to remove it
119
+ // because the data url gets converted to a blob, which is not valid when restored.
120
+ // besides, the placeholder is intended to be temporary while the file
121
+ // is being uploaded
122
+ export function patchAutosavedContent(content, asText = false) {
123
+ const temp = document.createElement('div');
124
+ temp.innerHTML = content;
125
+ temp.querySelectorAll('[data-placeholder-for]').forEach(placeholder => {
126
+ // @ts-expect-error
127
+ placeholder.parentElement.removeChild(placeholder);
128
+ });
129
+ if (asText) return temp.textContent;
130
+ return temp.innerHTML;
131
+ }
@@ -15,10 +15,12 @@
15
15
  * You should have received a copy of the GNU Affero General Public License along
16
16
  * with this program. If not, see <http://www.gnu.org/licenses/>.
17
17
  */
18
+
18
19
  import PropTypes from 'prop-types';
19
20
  import { trayPropTypes } from './plugins/shared/CanvasContentTray';
20
21
  import { RCEVariantValues } from './RCEVariants';
21
- import { PRETTY_HTML_EDITOR_VIEW, RAW_HTML_EDITOR_VIEW, WYSIWYG_VIEW } from './StatusBar'; // This file contains the prop types for the RCEWrapper component, so that types can be shared without having
22
+ import { PRETTY_HTML_EDITOR_VIEW, RAW_HTML_EDITOR_VIEW, WYSIWYG_VIEW } from './StatusBar';
23
+ // This file contains the prop types for the RCEWrapper component, so that types can be shared without having
22
24
  // to refactor RCEWrapper.js into typescript.
23
25
 
24
26
  export const toolbarPropType = PropTypes.arrayOf(PropTypes.shape({
@@ -34,7 +36,8 @@ export const toolbarPropType = PropTypes.arrayOf(PropTypes.shape({
34
36
  // registered with tinymce
35
37
  items: PropTypes.arrayOf(PropTypes.string).isRequired
36
38
  }));
37
- export const menuPropType = PropTypes.objectOf( // the key is the name of the menu item a plugin has
39
+ export const menuPropType = PropTypes.objectOf(
40
+ // the key is the name of the menu item a plugin has
38
41
  // registered with tinymce. If it does not exist in the
39
42
  // default menubar, it will be added.
40
43
  PropTypes.shape({
@@ -57,12 +60,13 @@ export const ltiToolsPropType = PropTypes.arrayOf(PropTypes.shape({
57
60
  height: PropTypes.number,
58
61
  width: PropTypes.number,
59
62
  use_tray: PropTypes.bool,
60
- canvas_icon_class: PropTypes.oneOfType([PropTypes.string, // Sometimes this is an object with an icon_url. Not sure why, see MAT-1354
63
+ canvas_icon_class: PropTypes.oneOfType([PropTypes.string,
64
+ // Sometimes this is an object with an icon_url. Not sure why, see MAT-1354
61
65
  PropTypes.shape({
62
66
  icon_url: PropTypes.string
63
67
  }), PropTypes.any])
64
68
  }));
65
- export const editorOptionsPropType = PropTypes.shape({
69
+ export const EditorOptionsPropType = PropTypes.shape({
66
70
  // height of the RCE.
67
71
  // if a number interpreted as pixels.
68
72
  // if a string as a CSS value.
@@ -100,7 +104,7 @@ export const rceWrapperPropTypes = {
100
104
  }),
101
105
  canvasOrigin: PropTypes.string,
102
106
  defaultContent: PropTypes.string,
103
- editorOptions: editorOptionsPropType,
107
+ editorOptions: EditorOptionsPropType,
104
108
  handleUnmount: PropTypes.func,
105
109
  editorView: PropTypes.oneOf([WYSIWYG_VIEW, PRETTY_HTML_EDITOR_VIEW, RAW_HTML_EDITOR_VIEW]),
106
110
  renderKBShortcutModal: PropTypes.bool,
@@ -1,3 +1,4 @@
1
+ import _pt from "prop-types";
1
2
  /*
2
3
  * Copyright (C) 2020 - present Instructure, Inc.
3
4
  *
@@ -15,18 +16,14 @@
15
16
  * You should have received a copy of the GNU Affero General Public License along
16
17
  * with this program. If not, see <http://www.gnu.org/licenses/>.
17
18
  */
18
- import React, { useCallback, useEffect, useRef, useState } from 'react';
19
- import { func, string } from 'prop-types';
19
+ import React, { useEffect, useState } from 'react';
20
20
  import formatMessage from '../format-message';
21
21
  import { SourceCodeEditor } from '@instructure/ui-source-code-editor';
22
22
  import beautify from 'js-beautify';
23
23
  const RceHtmlEditor = /*#__PURE__*/React.forwardRef((props, editorRef) => {
24
- const [code, setCode] = useState(props.code);
24
+ const [_code, setCode] = useState(props.code);
25
25
  const label = formatMessage('html code editor');
26
26
  const [dir, setDir] = useState(getComputedStyle(document.body, null).direction);
27
- useEffect(() => {
28
- setCode(beautify.html(props.code)); // eslint-disable-next-line react-hooks/exhaustive-deps
29
- }, []);
30
27
  useEffect(() => {
31
28
  // INSTUI sets the CodeEditor's surrounding label's
32
29
  // display inline-block so it doesn't fill the width
@@ -47,18 +44,20 @@ const RceHtmlEditor = /*#__PURE__*/React.forwardRef((props, editorRef) => {
47
44
  }
48
45
  `;
49
46
  document.head.appendChild(stylesheet);
50
- } // odds are, this won't change the dir.
51
-
52
-
53
- setDir(getComputedStyle(editorRef.current || document.body, null).direction);
47
+ }
48
+ // odds are, this won't change the dir.
49
+ if (editorRef && 'current' in editorRef) {
50
+ setDir(getComputedStyle(editorRef.current || document.body, null).direction);
51
+ }
54
52
  }, [dir, editorRef]);
55
- const direction = ['ltr', 'rtl'].includes(dir) ? dir : 'ltr'; // setting height on the container keeps the RCE toolbar from jumping
53
+ const direction = ['ltr', 'rtl'].includes(dir) ? dir : 'ltr';
56
54
 
55
+ // setting height on the container keeps the RCE toolbar from jumping
57
56
  return /*#__PURE__*/React.createElement("div", {
58
57
  ref: editorRef,
59
58
  className: "RceHtmlEditor",
60
59
  style: {
61
- height: props.height,
60
+ height: props.height || 'auto',
62
61
  overflow: 'hidden',
63
62
  textAlign: 'start'
64
63
  }
@@ -71,21 +70,20 @@ const RceHtmlEditor = /*#__PURE__*/React.forwardRef((props, editorRef) => {
71
70
  spellcheck: true,
72
71
  direction: direction,
73
72
  rtlMoveVisually: true,
74
- height: props.height,
75
- value: code,
73
+ height: props.height || 'auto',
74
+ defaultValue: beautify.html(props.code),
76
75
  onChange: value => {
77
76
  setCode(value);
78
- props.onChange(value);
77
+ props.onChange?.(value);
79
78
  }
80
79
  }));
81
80
  });
82
81
  RceHtmlEditor.propTypes = {
83
- code: string.isRequired,
84
- height: string,
85
- onChange: func
82
+ code: _pt.string.isRequired,
83
+ height: _pt.string,
84
+ onChange: _pt.func
86
85
  };
87
86
  RceHtmlEditor.defaultProps = {
88
- height: 'auto',
89
87
  onChange: _value => {}
90
88
  };
91
89
  export default RceHtmlEditor;
@@ -15,6 +15,7 @@
15
15
  * You should have received a copy of the GNU Affero General Public License along
16
16
  * with this program. If not, see <http://www.gnu.org/licenses/>.
17
17
  */
18
+
18
19
  import React, { useState } from 'react';
19
20
  import { func, string, number } from 'prop-types';
20
21
  import { DraggableCore } from 'react-draggable';
@@ -40,29 +41,22 @@ export default function ResizeHandle(props) {
40
41
  });
41
42
  }
42
43
  }
43
-
44
44
  function handleFocus(event) {
45
- var _props$onFocus;
46
-
47
45
  setIsFocused(true);
48
- (_props$onFocus = props.onFocus) === null || _props$onFocus === void 0 ? void 0 : _props$onFocus.call(props, event);
46
+ props.onFocus?.(event);
49
47
  }
50
-
51
48
  function handleBlur() {
52
49
  setIsFocused(false);
53
50
  }
54
-
55
51
  function handleDragStart(_e) {
56
52
  setDragging(true);
57
53
  }
58
-
59
54
  function handleDragStop(_e) {
60
55
  setDragging(false);
61
56
  }
62
-
63
- const [dragging, setDragging] = useState(false); // tracking isFocused rather than leveraging instui Focusable
57
+ const [dragging, setDragging] = useState(false);
58
+ // tracking isFocused rather than leveraging instui Focusable
64
59
  // because Focusable doesn't detect whan ResizeHandle gets focus
65
-
66
60
  const [isFocused, setIsFocused] = useState(false);
67
61
  return /*#__PURE__*/React.createElement(View, {
68
62
  "aria-label": formatMessage('Drag handle. Use up and down arrows to resize'),
@@ -15,6 +15,7 @@
15
15
  * You should have received a copy of the GNU Affero General Public License along
16
16
  * with this program. If not, see <http://www.gnu.org/licenses/>.
17
17
  */
18
+
18
19
  import React, { useState } from 'react';
19
20
  import { bool, func, string } from 'prop-types';
20
21
  import { Alert } from '@instructure/ui-alerts';
@@ -26,9 +27,7 @@ import { View } from '@instructure/ui-view';
26
27
  import formatMessage from '../format-message';
27
28
  export default function RestoreAutoSaveModal(props) {
28
29
  const [previewExpanded, setPreviewExpanded] = useState(false);
29
-
30
30
  const toggleLabel = () => previewExpanded ? formatMessage('Click to hide preview') : formatMessage('Click to show preview');
31
-
32
31
  return /*#__PURE__*/React.createElement(Modal, {
33
32
  "data-testid": "RCE_RestoreAutoSaveModal",
34
33
  "data-mce-component": true,
@@ -30,32 +30,28 @@ const hideStyle = {
30
30
  left: '-9999px'
31
31
  };
32
32
  export default class ShowOnFocusButton extends Component {
33
- constructor() {
34
- super(...arguments);
33
+ constructor(...args) {
34
+ super(...args);
35
35
  this.state = {
36
36
  visible: false
37
37
  };
38
-
39
38
  this.handleFocus = () => {
40
39
  this.setState({
41
40
  visible: true
42
41
  });
43
42
  };
44
-
45
43
  this.handleBlur = () => {
46
44
  this.setState({
47
45
  visible: false
48
46
  });
49
47
  };
50
48
  }
51
-
52
49
  focus() {
53
50
  this.btnRef.focus();
54
51
  this.setState({
55
52
  visible: true
56
53
  });
57
54
  }
58
-
59
55
  renderButton() {
60
56
  return /*#__PURE__*/React.createElement(IconButton, {
61
57
  id: this.props.id,
@@ -74,14 +70,12 @@ export default class ShowOnFocusButton extends Component {
74
70
  withBorder: false
75
71
  }, this.props.children);
76
72
  }
77
-
78
73
  render() {
79
74
  return /*#__PURE__*/React.createElement("div", {
80
75
  "data-testid": "ShowOnFocusButton__wrapper",
81
76
  style: this.state.visible ? null : hideStyle
82
77
  }, this.renderButton());
83
78
  }
84
-
85
79
  }
86
80
  ShowOnFocusButton.propTypes = {
87
81
  children: oneOfType([node, func]).isRequired,
@@ -15,6 +15,7 @@
15
15
  * You should have received a copy of the GNU Affero General Public License along
16
16
  * with this program. If not, see <http://www.gnu.org/licenses/>.
17
17
  */
18
+
18
19
  import React, { useEffect, useRef, useState } from 'react';
19
20
  import ReactDOM from 'react-dom';
20
21
  import { arrayOf, bool, func, number, oneOf, string } from 'prop-types';
@@ -34,9 +35,9 @@ import { FS_ENABLED } from '../util/fullscreenHelpers';
34
35
  import { AIWandSVG } from './plugins/shared/ai_tools';
35
36
  export const WYSIWYG_VIEW = 'WYSIWYG';
36
37
  export const PRETTY_HTML_EDITOR_VIEW = 'PRETTY';
37
- export const RAW_HTML_EDITOR_VIEW = 'RAW'; // I don't know why eslint is reporting this, the props are all used
38
+ export const RAW_HTML_EDITOR_VIEW = 'RAW';
38
39
 
39
- /* eslint-disable react/no-unused-prop-types */
40
+ // I don't know why eslint is reporting this, the props are all used
40
41
 
41
42
  StatusBar.propTypes = {
42
43
  id: string.isRequired,
@@ -65,24 +66,18 @@ StatusBar.defaultProps = {
65
66
  a11yErrorsCount: 0,
66
67
  disabledPlugins: []
67
68
  };
68
- /* eslint-enable react/no-unused-prop-types */
69
- // we use the array index because pathname may not be unique
70
69
 
71
- /* eslint-disable react/no-array-index-key */
70
+ // we use the array index because pathname may not be unique
72
71
 
73
- function renderPathString(_ref) {
74
- let {
75
- path
76
- } = _ref;
72
+ function renderPathString({
73
+ path
74
+ }) {
77
75
  return path.reduce((result, pathName, index) => {
78
- return result.concat( /*#__PURE__*/React.createElement("span", {
76
+ return result.concat(/*#__PURE__*/React.createElement("span", {
79
77
  key: `${pathName}-${index}`
80
78
  }, /*#__PURE__*/React.createElement(Text, null, index > 0 ? /*#__PURE__*/React.createElement(IconMiniArrowEndLine, null) : null, pathName)));
81
79
  }, []);
82
80
  }
83
- /* eslint-enable react/no-array-index-key */
84
-
85
-
86
81
  function emptyTagIcon() {
87
82
  return /*#__PURE__*/React.createElement(SVGIcon, {
88
83
  viewBox: "0 0 24 24",
@@ -96,13 +91,11 @@ function emptyTagIcon() {
96
91
  fontSize: "16"
97
92
  }, "</>")));
98
93
  }
99
-
100
94
  function findFocusable(el) {
101
95
  // eslint-disable-next-line react/no-find-dom-node
102
96
  const element = ReactDOM.findDOMNode(el);
103
97
  return element ? Array.from(element.querySelectorAll('[tabindex]')) : [];
104
98
  }
105
-
106
99
  export default function StatusBar(props) {
107
100
  const [focusedBtnId, setFocusedBtnId] = useState(null);
108
101
  const [includeEdtrDesc, setIncludeEdtrDesc] = useState(false);
@@ -117,10 +110,9 @@ export default function StatusBar(props) {
117
110
  // move focus to the next button over.
118
111
  if (isHtmlView() && /rce-kbshortcut-btn|rce-a11y-btn/.test(focusedBtnId)) {
119
112
  setFocusedBtnId('rce-edit-btn');
120
- } // adding a delay before including the HTML Editor description to wait the focus moves to the RCE
113
+ }
114
+ // adding a delay before including the HTML Editor description to wait the focus moves to the RCE
121
115
  // and prevent JAWS from reading the aria-describedby element when switching back to RCE view
122
-
123
-
124
116
  const timerid = setTimeout(() => {
125
117
  setIncludeEdtrDesc(!isHtmlView());
126
118
  }, 100);
@@ -130,26 +122,21 @@ export default function StatusBar(props) {
130
122
  function isAvailable(plugin) {
131
123
  return !props.disabledPlugins.includes(plugin);
132
124
  }
133
-
134
125
  function isFeature(feature_name) {
135
126
  return props.features.includes(feature_name);
136
127
  }
137
-
138
128
  function preferredHtmlEditor() {
139
129
  if (props.preferredHtmlEditor) return props.preferredHtmlEditor;
140
130
  return PRETTY_HTML_EDITOR_VIEW;
141
131
  }
142
-
143
132
  function getHtmlEditorView(event) {
144
133
  if (!event.shiftKey) return preferredHtmlEditor();
145
134
  return preferredHtmlEditor() === RAW_HTML_EDITOR_VIEW ? PRETTY_HTML_EDITOR_VIEW : RAW_HTML_EDITOR_VIEW;
146
135
  }
147
-
148
136
  function handleKey(event) {
149
137
  const buttons = findFocusable(statusBarRef.current).filter(b => !b.disabled);
150
138
  const focusedIndex = buttons.findIndex(b => b.getAttribute('data-btn-id') === focusedBtnId);
151
139
  let newFocusedIndex;
152
-
153
140
  if (event.keyCode === keycode.codes.right) {
154
141
  newFocusedIndex = (focusedIndex + 1) % buttons.length;
155
142
  } else if (event.keyCode === keycode.codes.left) {
@@ -157,20 +144,16 @@ export default function StatusBar(props) {
157
144
  } else {
158
145
  return;
159
146
  }
160
-
161
147
  buttons[newFocusedIndex].focus();
162
148
  setFocusedBtnId(buttons[newFocusedIndex].getAttribute('data-btn-id'));
163
149
  }
164
-
165
150
  function isHtmlView() {
166
151
  return props.editorView !== WYSIWYG_VIEW;
167
152
  }
168
-
169
153
  function tabIndexForBtn(itemId) {
170
154
  const tabindex = focusedBtnId === itemId ? 0 : -1;
171
155
  return tabindex;
172
156
  }
173
-
174
157
  function renderPath() {
175
158
  return /*#__PURE__*/React.createElement(View, {
176
159
  "data-testid": "whole-status-bar-path",
@@ -179,7 +162,6 @@ export default function StatusBar(props) {
179
162
  }
180
163
  }, renderPathString(props));
181
164
  }
182
-
183
165
  function renderA11yButton() {
184
166
  const a11y = formatMessage('Accessibility Checker');
185
167
  const a11yButtonId = 'rce-a11y-btn';
@@ -197,11 +179,9 @@ export default function StatusBar(props) {
197
179
  withBackground: false,
198
180
  withBorder: false
199
181
  }, /*#__PURE__*/React.createElement(IconA11yLine, null));
200
-
201
182
  if (props.a11yErrorsCount <= 0) {
202
183
  return button;
203
184
  }
204
-
205
185
  return /*#__PURE__*/React.createElement(InstUISettingsProvider, {
206
186
  theme: {
207
187
  componentOverrides: {
@@ -215,7 +195,6 @@ export default function StatusBar(props) {
215
195
  countUntil: 100
216
196
  }, button));
217
197
  }
218
-
219
198
  function renderHtmlEditorMessage() {
220
199
  const message = props.editorView === PRETTY_HTML_EDITOR_VIEW ? formatMessage('Sadly, the pretty HTML editor is not keyboard accessible. Access the raw HTML editor here.') : formatMessage('Access the pretty HTML editor');
221
200
  const label = props.editorView === PRETTY_HTML_EDITOR_VIEW ? formatMessage('Switch to raw HTML Editor') : formatMessage('Switch to pretty HTML Editor');
@@ -238,7 +217,6 @@ export default function StatusBar(props) {
238
217
  onFocus: () => setFocusedBtnId('rce-editormessage-btn')
239
218
  }, label));
240
219
  }
241
-
242
220
  function renderIconButtons() {
243
221
  if (isHtmlView()) return null;
244
222
  const ai_tools = isFeature('ai_tools');
@@ -257,7 +235,6 @@ export default function StatusBar(props) {
257
235
  tabIndex: tabIndexForBtn('rce-ai-btn'),
258
236
  onClick: event => {
259
237
  event.target.focus(); // FF doesn't focus buttons on click
260
-
261
238
  props.onAI();
262
239
  },
263
240
  onFocus: () => setFocusedBtnId('rce-ai-btn'),
@@ -279,7 +256,6 @@ export default function StatusBar(props) {
279
256
  tabIndex: tabIndexForBtn('rce-kbshortcut-btn'),
280
257
  onClick: event => {
281
258
  event.target.focus(); // FF doesn't focus buttons on click
282
-
283
259
  props.onKBShortcutModalOpen();
284
260
  },
285
261
  onFocus: () => setFocusedBtnId('rce-kbshortcut-btn'),
@@ -288,7 +264,6 @@ export default function StatusBar(props) {
288
264
  withBorder: false
289
265
  }, /*#__PURE__*/React.createElement(IconKeyboardShortcutsLine, null)), a11y_checker && !props.readOnly && isAvailable('ally_checker') && renderA11yButton());
290
266
  }
291
-
292
267
  function renderWordCount() {
293
268
  if (isHtmlView()) return null;
294
269
  const wordCount = formatMessage(`{count, plural,
@@ -312,17 +287,14 @@ export default function StatusBar(props) {
312
287
  title: formatMessage('View word and character counts')
313
288
  }, wordCount)));
314
289
  }
315
-
316
290
  function renderSection3(html_view, fullscreen, resize_handle) {
317
291
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
318
292
  className: css(styles.separator)
319
293
  }), html_view && renderToggleHtml(), fullscreen && renderFullscreen(), resize_handle && renderResizeHandle());
320
294
  }
321
-
322
295
  function descMsg() {
323
296
  return preferredHtmlEditor() === RAW_HTML_EDITOR_VIEW ? formatMessage('Shift-O to open the pretty html editor.') : formatMessage('The pretty html editor is not keyboard accessible. Press Shift O to open the raw html editor.');
324
297
  }
325
-
326
298
  function renderToggleHtml() {
327
299
  const toggleToHtml = formatMessage('Switch to the html editor');
328
300
  const toggleToRich = formatMessage('Switch to the rich text editor');
@@ -358,16 +330,13 @@ export default function StatusBar(props) {
358
330
  id: "edit-button-desc"
359
331
  }, descMsg()));
360
332
  }
361
-
362
333
  function renderFullscreen() {
363
334
  if (props.readOnly) return null;
364
335
  if (!document[FS_ENABLED]) return null;
365
-
366
336
  if (props.editorView === RAW_HTML_EDITOR_VIEW && !('requestFullscreen' in document.body)) {
367
337
  // this is safari, which refuses to fullscreen a textarea
368
338
  return null;
369
339
  }
370
-
371
340
  const fullscreen = props.rceIsFullscreen ? formatMessage('Exit Fullscreen') : formatMessage('Fullscreen');
372
341
  return /*#__PURE__*/React.createElement(IconButton, {
373
342
  "data-btn-id": "rce-fullscreen-btn",
@@ -384,7 +353,6 @@ export default function StatusBar(props) {
384
353
  withBorder: false
385
354
  }, props.rceIsFullscreen ? /*#__PURE__*/React.createElement(IconExitFullScreenLine, null) : /*#__PURE__*/React.createElement(IconFullScreenLine, null));
386
355
  }
387
-
388
356
  function renderResizeHandle() {
389
357
  if (props.rceIsFullscreen) return null;
390
358
  return /*#__PURE__*/React.createElement(ResizeHandle, {
@@ -396,7 +364,6 @@ export default function StatusBar(props) {
396
364
  }
397
365
  });
398
366
  }
399
-
400
367
  const flexJustify = isHtmlView() ? 'end' : 'start';
401
368
  const html_view = isFeature('html_view') && isAvailable('instructure_html_view');
402
369
  const fullscreen = isFeature('fullscreen') && isAvailable('instructure_fullscreen');
@@ -406,7 +373,6 @@ export default function StatusBar(props) {
406
373
  componentOverrides: {
407
374
  IconButton: {
408
375
  secondaryGhostColor: 'rgb(34, 47, 62)' // to match tinymce's button color
409
-
410
376
  }
411
377
  }
412
378
  }
@@ -28,19 +28,16 @@ export class AlertHandler {
28
28
  if (this.alertFunc == null) {
29
29
  throw new Error('Tried to alert without alertFunc being set first');
30
30
  }
31
-
32
31
  this.alertFunc(alert);
33
32
  };
34
-
35
33
  this.alertFunc = alertFunc;
36
34
  }
35
+
37
36
  /**
38
37
  * Calls the registered alertFunc assuming one has been set, otherwise
39
38
  * it throws.
40
39
  *
41
40
  * @memberof AlertHandler
42
41
  */
43
-
44
-
45
42
  }
46
43
  export default new AlertHandler();