@instructure/canvas-rce 5.14.0 → 5.14.2

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 (484) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/DEVELOPMENT.md +1 -1
  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/__tests__/sidebar/reducers/all_files.test.js +28 -0
  17. package/babel.config.js +3 -1
  18. package/build.sh +7 -7
  19. package/es/bridge/Bridge.js +8 -56
  20. package/es/bridge/index.js +1 -0
  21. package/es/canvasFileBrowser/FileBrowser.js +12 -59
  22. package/es/canvasFileBrowser/en-US.js +3 -6
  23. package/es/common/FlashAlert.js +7 -28
  24. package/es/common/browser.js +4 -2
  25. package/es/common/fileUrl.js +104 -59
  26. package/es/common/incremental-loading/LoadMoreButton.js +1 -0
  27. package/es/common/incremental-loading/LoadingIndicator.js +1 -2
  28. package/es/common/incremental-loading/LoadingStatus.js +1 -2
  29. package/es/common/incremental-loading/index.js +1 -0
  30. package/es/common/incremental-loading/useIncrementalLoading.js +1 -3
  31. package/es/common/indicate.js +15 -8
  32. package/es/common/mimeClass.js +3 -4
  33. package/es/common/natcompare.js +1 -4
  34. package/es/defaultTinymceConfig.js +5 -3
  35. package/es/elementDenylist.js +1 -0
  36. package/es/enhance-user-content/doc_previews.js +17 -28
  37. package/es/enhance-user-content/enhance_user_content.js +28 -60
  38. package/es/enhance-user-content/external_links.js +5 -8
  39. package/es/enhance-user-content/index.js +1 -0
  40. package/es/enhance-user-content/instructure_helper.js +25 -38
  41. package/es/enhance-user-content/jqueryish_funcs.js +8 -11
  42. package/es/enhance-user-content/mathml.js +35 -82
  43. package/es/enhance-user-content/media_comment_thumbnail.js +5 -17
  44. package/es/format-message.js +3 -4
  45. package/es/getThemeVars.js +8 -6
  46. package/es/getTranslations.js +1 -78
  47. package/es/index.js +3 -1
  48. package/es/rce/AlertMessageArea.js +1 -1
  49. package/es/rce/DraggingBlocker.js +4 -2
  50. package/es/rce/KeyboardShortcutModal.js +1 -0
  51. package/es/rce/RCE.js +12 -11
  52. package/es/rce/RCEGlobals.js +12 -10
  53. package/es/rce/RCEVariants.js +27 -10
  54. package/es/rce/RCEWrapper.js +167 -386
  55. package/es/rce/RCEWrapperProps.js +8 -3
  56. package/es/rce/RceHtmlEditor.js +5 -8
  57. package/es/rce/ResizeHandle.js +3 -8
  58. package/es/rce/RestoreAutoSaveModal.js +1 -2
  59. package/es/rce/ShowOnFocusButton/index.js +0 -6
  60. package/es/rce/StatusBar.js +8 -37
  61. package/es/rce/alertHandler.js +1 -4
  62. package/es/rce/contentInsertion.js +35 -57
  63. package/es/rce/contentInsertionUtils.js +6 -8
  64. package/es/rce/contentRendering.js +7 -12
  65. package/es/rce/customEvents.js +1 -0
  66. package/es/rce/editorLanguage.js +22 -10
  67. package/es/rce/indicatorRegion.js +6 -5
  68. package/es/rce/normalizeLocale.js +5 -3
  69. package/es/rce/normalizeProps.js +3 -1
  70. package/es/rce/plugins/instructure-ui-icons/plugin.js +21 -3
  71. package/es/rce/plugins/instructure_color/clickCallback.js +84 -0
  72. package/es/rce/plugins/instructure_color/components/ColorPicker.js +299 -0
  73. package/es/rce/plugins/instructure_color/components/ColorPopup.js +68 -0
  74. package/es/rce/plugins/instructure_color/components/colorUtils.js +60 -0
  75. package/es/rce/plugins/instructure_color/plugin.js +40 -0
  76. package/es/rce/plugins/instructure_condensed_buttons/core/ListUtils.js +10 -3
  77. package/es/rce/plugins/instructure_condensed_buttons/plugin.js +1 -0
  78. package/es/rce/plugins/instructure_condensed_buttons/ui/alignment-button.js +1 -2
  79. package/es/rce/plugins/instructure_condensed_buttons/ui/directionality-button.js +3 -2
  80. package/es/rce/plugins/instructure_condensed_buttons/ui/indent-outdent-button.js +1 -0
  81. package/es/rce/plugins/instructure_condensed_buttons/ui/list-button.js +22 -15
  82. package/es/rce/plugins/instructure_condensed_buttons/ui/subscript-superscript-button.js +1 -2
  83. package/es/rce/plugins/instructure_documents/clickCallback.js +1 -0
  84. package/es/rce/plugins/instructure_documents/components/DocumentsPanel.js +1 -9
  85. package/es/rce/plugins/instructure_documents/components/Link.js +3 -18
  86. package/es/rce/plugins/instructure_documents/plugin.js +7 -14
  87. package/es/rce/plugins/instructure_equation/EquationEditorModal/advancedOnlySyntax.js +4 -2
  88. package/es/rce/plugins/instructure_equation/EquationEditorModal/advancedPreference.js +1 -2
  89. package/es/rce/plugins/instructure_equation/EquationEditorModal/index.js +12 -29
  90. package/es/rce/plugins/instructure_equation/EquationEditorModal/latexTextareaUtil.js +11 -12
  91. package/es/rce/plugins/instructure_equation/EquationEditorModal/parseLatex.js +4 -3
  92. package/es/rce/plugins/instructure_equation/EquationEditorModal/styles.js +4 -2
  93. package/es/rce/plugins/instructure_equation/EquationEditorToolbar/buttons.js +13 -7
  94. package/es/rce/plugins/instructure_equation/EquationEditorToolbar/index.js +4 -7
  95. package/es/rce/plugins/instructure_equation/MathIcon/index.js +1 -1
  96. package/es/rce/plugins/instructure_equation/MathIcon/svgs.js +1 -1
  97. package/es/rce/plugins/instructure_equation/clickCallback.js +2 -5
  98. package/es/rce/plugins/instructure_equation/mathlive/index.js +1 -1
  99. package/es/rce/plugins/instructure_equation/plugin.js +7 -10
  100. package/es/rce/plugins/instructure_fullscreen/plugin.js +3 -6
  101. package/es/rce/plugins/instructure_html_view/clickCallback.js +1 -0
  102. package/es/rce/plugins/instructure_html_view/plugin.js +5 -4
  103. package/es/rce/plugins/instructure_icon_maker/clickCallback.js +2 -4
  104. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ColorSection.js +1 -2
  105. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/CreateIconMakerForm.js +1 -0
  106. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/Footer.js +1 -0
  107. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/Group.js +1 -0
  108. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/Header.js +1 -2
  109. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/Course.js +25 -22
  110. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/ImageOptions.js +7 -11
  111. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/ImageSection.js +27 -23
  112. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/ModeSelect.js +5 -4
  113. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/MultiColor/index.js +11 -9
  114. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/MultiColor/svg.js +1 -0
  115. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/SVGList.js +5 -4
  116. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/SVGThumbnail.js +1 -3
  117. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/SingleColor/index.js +7 -7
  118. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/SingleColor/svg.js +1 -0
  119. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/Upload.js +27 -20
  120. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/index.js +1 -0
  121. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/propTypes.js +1 -0
  122. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/utils.js +1 -0
  123. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/Preview.js +4 -4
  124. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ShapeSection.js +1 -2
  125. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/TextSection.js +1 -5
  126. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/index.js +1 -0
  127. package/es/rce/plugins/instructure_icon_maker/components/IconMakerTray.js +18 -33
  128. package/es/rce/plugins/instructure_icon_maker/components/SavedIconMakerList.js +4 -4
  129. package/es/rce/plugins/instructure_icon_maker/plugin.js +10 -14
  130. package/es/rce/plugins/instructure_icon_maker/reducers/imageSection.js +37 -38
  131. package/es/rce/plugins/instructure_icon_maker/reducers/svgSettings.js +24 -24
  132. package/es/rce/plugins/instructure_icon_maker/registerEditToolbar.js +1 -3
  133. package/es/rce/plugins/instructure_icon_maker/svg/constants.js +4 -3
  134. package/es/rce/plugins/instructure_icon_maker/svg/font.js +3 -1
  135. package/es/rce/plugins/instructure_icon_maker/svg/image.js +69 -83
  136. package/es/rce/plugins/instructure_icon_maker/svg/index.js +11 -15
  137. package/es/rce/plugins/instructure_icon_maker/svg/metadata.js +1 -0
  138. package/es/rce/plugins/instructure_icon_maker/svg/settings.js +32 -39
  139. package/es/rce/plugins/instructure_icon_maker/svg/shape.js +1 -49
  140. package/es/rce/plugins/instructure_icon_maker/svg/text.js +7 -92
  141. package/es/rce/plugins/instructure_icon_maker/svg/utils.js +1 -7
  142. package/es/rce/plugins/instructure_icon_maker/utils/IconMakerClose.js +2 -6
  143. package/es/rce/plugins/instructure_icon_maker/utils/IconMakerFormHasChanges.js +1 -15
  144. package/es/rce/plugins/instructure_icon_maker/utils/addIconMakerAttributes.js +3 -4
  145. package/es/rce/plugins/instructure_icon_maker/utils/iconValidation.js +1 -1
  146. package/es/rce/plugins/instructure_icon_maker/utils/iconsLabels.js +1 -0
  147. package/es/rce/plugins/instructure_icon_maker/utils/useDebouncedValue.js +12 -13
  148. package/es/rce/plugins/instructure_image/ImageEmbedOptions.js +6 -24
  149. package/es/rce/plugins/instructure_image/ImageList/Image.js +1 -6
  150. package/es/rce/plugins/instructure_image/ImageList/index.js +1 -2
  151. package/es/rce/plugins/instructure_image/ImageOptionsTray/TrayController.js +7 -27
  152. package/es/rce/plugins/instructure_image/ImageOptionsTray/index.js +3 -16
  153. package/es/rce/plugins/instructure_image/Images/index.js +1 -3
  154. package/es/rce/plugins/instructure_image/clickCallback.js +1 -0
  155. package/es/rce/plugins/instructure_image/plugin.js +13 -18
  156. package/es/rce/plugins/instructure_links/clickCallback.js +1 -0
  157. package/es/rce/plugins/instructure_links/components/AccordionSection.js +1 -0
  158. package/es/rce/plugins/instructure_links/components/CollectionPanel.js +1 -3
  159. package/es/rce/plugins/instructure_links/components/Link.js +7 -19
  160. package/es/rce/plugins/instructure_links/components/LinkOptionsDialog/LinkOptionsDialogController.js +1 -21
  161. package/es/rce/plugins/instructure_links/components/LinkOptionsDialog/index.js +1 -4
  162. package/es/rce/plugins/instructure_links/components/LinkOptionsTray/LinkOptionsTrayController.js +3 -20
  163. package/es/rce/plugins/instructure_links/components/LinkOptionsTray/index.js +1 -12
  164. package/es/rce/plugins/instructure_links/components/LinkSet.js +4 -20
  165. package/es/rce/plugins/instructure_links/components/LinksPanel.js +1 -2
  166. package/es/rce/plugins/instructure_links/components/NavigationPanel.js +7 -9
  167. package/es/rce/plugins/instructure_links/components/NoResults.js +1 -7
  168. package/es/rce/plugins/instructure_links/plugin.js +17 -40
  169. package/es/rce/plugins/instructure_links/validateURL.js +81 -36
  170. package/es/rce/plugins/instructure_media_embed/clickCallback.js +2 -5
  171. package/es/rce/plugins/instructure_media_embed/components/Embed.js +1 -0
  172. package/es/rce/plugins/instructure_media_embed/plugin.js +7 -3
  173. package/es/rce/plugins/instructure_paste/pasteMenuCommand.js +1 -5
  174. package/es/rce/plugins/instructure_paste/plugin.js +27 -29
  175. package/es/rce/plugins/instructure_rce_external_tools/ExternalToolsEnv.js +14 -53
  176. package/es/rce/plugins/instructure_rce_external_tools/RceToolWrapper.js +21 -49
  177. package/es/rce/plugins/instructure_rce_external_tools/components/ExternalToolDialog/ExternalToolDialog.js +11 -42
  178. package/es/rce/plugins/instructure_rce_external_tools/components/ExternalToolDialog/ExternalToolDialogModal.js +1 -2
  179. package/es/rce/plugins/instructure_rce_external_tools/components/ExternalToolDialog/ExternalToolDialogTray.js +1 -1
  180. package/es/rce/plugins/instructure_rce_external_tools/components/ExternalToolSelectionDialog/ExternalToolSelectionDialog.js +2 -10
  181. package/es/rce/plugins/instructure_rce_external_tools/components/ExternalToolSelectionDialog/ExternalToolSelectionItem.js +1 -2
  182. package/es/rce/plugins/instructure_rce_external_tools/components/util/ExpandoText.js +1 -0
  183. package/es/rce/plugins/instructure_rce_external_tools/components/util/ToolLaunchIframe.js +2 -1
  184. package/es/rce/plugins/instructure_rce_external_tools/constants.js +28 -0
  185. package/es/rce/plugins/instructure_rce_external_tools/dialog-helper.js +19 -4
  186. package/es/rce/plugins/instructure_rce_external_tools/helpers/tags.js +0 -2
  187. package/es/rce/plugins/instructure_rce_external_tools/jquery/jquery.dropdownList.js +130 -136
  188. package/es/rce/plugins/instructure_rce_external_tools/lti11-content-items/RceLti11ContentItem.js +100 -95
  189. package/es/rce/plugins/instructure_rce_external_tools/lti13-content-items/Lti13ContentItemJson.js +1 -0
  190. package/es/rce/plugins/instructure_rce_external_tools/lti13-content-items/RceLti13ContentItem.js +2 -19
  191. package/es/rce/plugins/instructure_rce_external_tools/lti13-content-items/models/BaseLinkContentItem.js +1 -14
  192. package/es/rce/plugins/instructure_rce_external_tools/lti13-content-items/models/HtmlFragmentContentItem.js +1 -6
  193. package/es/rce/plugins/instructure_rce_external_tools/lti13-content-items/models/ImageContentItem.js +1 -9
  194. package/es/rce/plugins/instructure_rce_external_tools/lti13-content-items/models/LinkContentItem.js +1 -1
  195. package/es/rce/plugins/instructure_rce_external_tools/lti13-content-items/models/ResourceLinkContentItem.js +3 -5
  196. package/es/rce/plugins/instructure_rce_external_tools/lti13-content-items/processEditorContentItems.js +18 -10
  197. package/es/rce/plugins/instructure_rce_external_tools/lti13-content-items/rceLti13ContentItemFromJson.js +4 -4
  198. package/es/rce/plugins/instructure_rce_external_tools/plugin.js +7 -16
  199. package/es/rce/plugins/instructure_rce_external_tools/util/addParentFrameContextToUrl.js +1 -1
  200. package/es/rce/plugins/instructure_record/AudioOptionsTray/TrayController.js +1 -25
  201. package/es/rce/plugins/instructure_record/AudioOptionsTray/index.js +1 -4
  202. package/es/rce/plugins/instructure_record/MediaPanel/index.js +1 -9
  203. package/es/rce/plugins/instructure_record/VideoOptionsTray/TrayController.js +8 -51
  204. package/es/rce/plugins/instructure_record/VideoOptionsTray/index.js +4 -17
  205. package/es/rce/plugins/instructure_record/clickCallback.js +7 -15
  206. package/es/rce/plugins/instructure_record/mediaTranslations.js +1 -0
  207. package/es/rce/plugins/instructure_record/plugin.js +11 -18
  208. package/es/rce/plugins/instructure_search_and_replace/clickCallback.js +2 -5
  209. package/es/rce/plugins/instructure_search_and_replace/components/FindReplaceTray.js +20 -35
  210. package/es/rce/plugins/instructure_search_and_replace/components/FindReplaceTrayController.js +3 -18
  211. package/es/rce/plugins/instructure_search_and_replace/getSelectionContext.js +2 -9
  212. package/es/rce/plugins/instructure_search_and_replace/plugin.js +1 -3
  213. package/es/rce/plugins/instructure_studio_media_options/plugin.js +1 -1
  214. package/es/rce/plugins/instructure_wordcount/clickCallback.js +2 -5
  215. package/es/rce/plugins/instructure_wordcount/components/WordCountModal.js +1 -4
  216. package/es/rce/plugins/instructure_wordcount/plugin.js +1 -0
  217. package/es/rce/plugins/instructure_wordcount/utils/countContent.js +1 -8
  218. package/es/rce/plugins/instructure_wordcount/utils/tableContent.js +1 -0
  219. package/es/rce/plugins/shared/CanvasContentTray.js +43 -63
  220. package/es/rce/plugins/shared/CheckerboardStyling.js +1 -1
  221. package/es/rce/plugins/shared/ColorInput.js +5 -14
  222. package/es/rce/plugins/shared/ConditionalTooltip.js +1 -0
  223. package/es/rce/plugins/shared/ContentSelection.js +17 -58
  224. package/es/rce/plugins/shared/DimensionUtils.js +1 -8
  225. package/es/rce/plugins/shared/DimensionsInput/DimensionInput.js +6 -6
  226. package/es/rce/plugins/shared/DimensionsInput/index.js +37 -15
  227. package/es/rce/plugins/shared/DimensionsInput/useDimensionsState.js +5 -29
  228. package/es/rce/plugins/shared/ErrorBoundary.js +2 -5
  229. package/es/rce/plugins/shared/EventUtils.js +1 -3
  230. package/es/rce/plugins/shared/Filter.js +8 -38
  231. package/es/rce/plugins/shared/FixedContentTray.js +3 -3
  232. package/es/rce/plugins/shared/ImageCropper/DirectionRegion.js +1 -8
  233. package/es/rce/plugins/shared/ImageCropper/Modal.js +4 -7
  234. package/es/rce/plugins/shared/ImageCropper/Preview.js +7 -11
  235. package/es/rce/plugins/shared/ImageCropper/constants.js +1 -0
  236. package/es/rce/plugins/shared/ImageCropper/controls/CustomNumberInput.js +2 -5
  237. package/es/rce/plugins/shared/ImageCropper/controls/ResetControls.js +1 -0
  238. package/es/rce/plugins/shared/ImageCropper/controls/RotationControls.js +1 -10
  239. package/es/rce/plugins/shared/ImageCropper/controls/ShapeControls.js +1 -0
  240. package/es/rce/plugins/shared/ImageCropper/controls/ZoomControls.js +1 -11
  241. package/es/rce/plugins/shared/ImageCropper/controls/index.js +1 -0
  242. package/es/rce/plugins/shared/ImageCropper/controls/useDebouncedNumericValue.js +3 -16
  243. package/es/rce/plugins/shared/ImageCropper/controls/utils.js +1 -2
  244. package/es/rce/plugins/shared/ImageCropper/imageCropUtils.js +1 -10
  245. package/es/rce/plugins/shared/ImageCropper/index.js +1 -0
  246. package/es/rce/plugins/shared/ImageCropper/propTypes.js +1 -0
  247. package/es/rce/plugins/shared/ImageCropper/reducers/imageCropper.js +15 -14
  248. package/es/rce/plugins/shared/ImageCropper/shape.js +1 -0
  249. package/es/rce/plugins/shared/ImageCropper/svg/index.js +1 -2
  250. package/es/rce/plugins/shared/ImageCropper/svg/shape.js +1 -17
  251. package/es/rce/plugins/shared/ImageCropper/svg/utils.js +1 -0
  252. package/es/rce/plugins/shared/ImageCropper/useKeyMouseEvents.js +19 -46
  253. package/es/rce/plugins/shared/ImageCropper/useMouseWheel.js +8 -10
  254. package/es/rce/plugins/shared/ImageOptionsForm.js +1 -2
  255. package/es/rce/plugins/shared/LinkDisplay.js +1 -2
  256. package/es/rce/plugins/shared/PreviewIcon.js +1 -6
  257. package/es/rce/plugins/shared/Previewable.js +1 -0
  258. package/es/rce/plugins/shared/RceFileBrowser.js +5 -7
  259. package/es/rce/plugins/shared/StoreContext.js +1 -2
  260. package/es/rce/plugins/shared/StudioLtiSupportUtils.js +10 -6
  261. package/es/rce/plugins/shared/UnknownFileTypePanel.js +1 -0
  262. package/es/rce/plugins/shared/Upload/CanvasContentPanel.js +13 -18
  263. package/es/rce/plugins/shared/Upload/CategoryProcessor.js +1 -1
  264. package/es/rce/plugins/shared/Upload/ComputerPanel.js +8 -26
  265. package/es/rce/plugins/shared/Upload/PanelFilter.js +3 -12
  266. package/es/rce/plugins/shared/Upload/SvgCategoryProcessor.js +4 -3
  267. package/es/rce/plugins/shared/Upload/UploadFile.js +15 -18
  268. package/es/rce/plugins/shared/Upload/UploadFileModal.js +9 -25
  269. package/es/rce/plugins/shared/Upload/UrlPanel.js +1 -0
  270. package/es/rce/plugins/shared/Upload/UsageRightsSelectBox.js +7 -12
  271. package/es/rce/plugins/shared/Upload/doFileUpload.js +4 -6
  272. package/es/rce/plugins/shared/Upload/index.js +1 -0
  273. package/es/rce/plugins/shared/ai_tools/AIResponseModal.js +1 -3
  274. package/es/rce/plugins/shared/ai_tools/AIToolsTray.js +6 -24
  275. package/es/rce/plugins/shared/ai_tools/aiicons.js +1 -0
  276. package/es/rce/plugins/shared/ai_tools/index.js +1 -0
  277. package/es/rce/plugins/shared/buildDownloadUrl.js +0 -2
  278. package/es/rce/plugins/shared/canvasContentUtils.js +6 -9
  279. package/es/rce/plugins/shared/compressionUtils.js +1 -8
  280. package/es/rce/plugins/shared/dateUtils.js +1 -1
  281. package/es/rce/plugins/shared/do-fetch-api-effect/defaultFetchOptions.js +4 -2
  282. package/es/rce/plugins/shared/do-fetch-api-effect/doFetchApi.js +7 -10
  283. package/es/rce/plugins/shared/do-fetch-api-effect/index.js +1 -0
  284. package/es/rce/plugins/shared/do-fetch-api-effect/parse-link-header.js +6 -20
  285. package/es/rce/plugins/shared/do-fetch-api-effect/query-string-encoding.js +5 -3
  286. package/es/rce/plugins/shared/fileShape.js +4 -9
  287. package/es/rce/plugins/shared/fileTypeUtils.js +32 -42
  288. package/es/rce/plugins/shared/fileUtils.js +1 -2
  289. package/es/rce/plugins/shared/linkUtils.js +1 -16
  290. package/es/rce/plugins/shared/round.js +1 -0
  291. package/es/rce/plugins/shared/trayUtils.js +4 -3
  292. package/es/rce/plugins/shared/useDataUrl.js +9 -9
  293. package/es/rce/plugins/shared/useFilterSettings.js +3 -3
  294. package/es/rce/plugins/tinymce-a11y-checker/components/ColorField.js +2 -6
  295. package/es/rce/plugins/tinymce-a11y-checker/components/checker.js +5 -63
  296. package/es/rce/plugins/tinymce-a11y-checker/components/color-picker.js +1 -2
  297. package/es/rce/plugins/tinymce-a11y-checker/components/placeholder-svg.js +1 -0
  298. package/es/rce/plugins/tinymce-a11y-checker/components/pointer.js +1 -0
  299. package/es/rce/plugins/tinymce-a11y-checker/node-checker.js +1 -6
  300. package/es/rce/plugins/tinymce-a11y-checker/plugin.js +4 -7
  301. package/es/rce/plugins/tinymce-a11y-checker/rules/adjacent-links.js +3 -26
  302. package/es/rce/plugins/tinymce-a11y-checker/rules/headings-sequence.js +9 -38
  303. package/es/rce/plugins/tinymce-a11y-checker/rules/headings-start-at-h2.js +1 -5
  304. package/es/rce/plugins/tinymce-a11y-checker/rules/img-alt-filename.js +1 -2
  305. package/es/rce/plugins/tinymce-a11y-checker/rules/img-alt-length.js +1 -1
  306. package/es/rce/plugins/tinymce-a11y-checker/rules/img-alt.js +1 -2
  307. package/es/rce/plugins/tinymce-a11y-checker/rules/index.js +1 -0
  308. package/es/rce/plugins/tinymce-a11y-checker/rules/large-text-contrast.js +1 -4
  309. package/es/rce/plugins/tinymce-a11y-checker/rules/list-structure.js +5 -24
  310. package/es/rce/plugins/tinymce-a11y-checker/rules/paragraphs-for-headings.js +1 -3
  311. package/es/rce/plugins/tinymce-a11y-checker/rules/small-text-contrast.js +1 -6
  312. package/es/rce/plugins/tinymce-a11y-checker/rules/table-caption.js +1 -3
  313. package/es/rce/plugins/tinymce-a11y-checker/rules/table-header-scope.js +1 -2
  314. package/es/rce/plugins/tinymce-a11y-checker/rules/table-header.js +1 -9
  315. package/es/rce/plugins/tinymce-a11y-checker/utils/colors.js +1 -0
  316. package/es/rce/plugins/tinymce-a11y-checker/utils/describe.js +1 -7
  317. package/es/rce/plugins/tinymce-a11y-checker/utils/dom.js +1 -26
  318. package/es/rce/plugins/tinymce-a11y-checker/utils/indicate.js +16 -15
  319. package/es/rce/plugins/tinymce-a11y-checker/utils/rgb-hex.js +7 -10
  320. package/es/rce/plugins/tinymce-a11y-checker/utils/strings.js +1 -4
  321. package/es/rce/root.js +9 -8
  322. package/es/rce/sanitizePlugins.js +1 -3
  323. package/es/rce/style.js +1 -4
  324. package/es/rce/tinyRCE.js +13 -9
  325. package/es/rce/tinymce.oxide.content.min.css.js +1 -0
  326. package/es/rce/tinymce.oxide.skin.min.css.js +1 -0
  327. package/es/rce/transformContent.js +8 -10
  328. package/es/rce/types.js +1 -0
  329. package/es/rce/userOS.js +1 -1
  330. package/es/rce/wrapInitCb.js +50 -43
  331. package/es/rcs/api.js +61 -116
  332. package/es/rcs/buildError.js +5 -17
  333. package/es/rcs/fake.js +4 -13
  334. package/es/sidebar/actions/all_files.js +2 -0
  335. package/es/sidebar/actions/data.js +4 -7
  336. package/es/sidebar/actions/documents.js +9 -6
  337. package/es/sidebar/actions/files.js +3 -6
  338. package/es/sidebar/actions/filter.js +1 -0
  339. package/es/sidebar/actions/flickr.js +1 -1
  340. package/es/sidebar/actions/images.js +12 -11
  341. package/es/sidebar/actions/links.js +1 -0
  342. package/es/sidebar/actions/media.js +12 -10
  343. package/es/sidebar/actions/session.js +1 -3
  344. package/es/sidebar/actions/ui.js +1 -0
  345. package/es/sidebar/actions/upload.js +14 -39
  346. package/es/sidebar/containers/Sidebar.js +1 -2
  347. package/es/sidebar/containers/sidebarHandlers.js +3 -1
  348. package/es/sidebar/dragHtml.js +5 -3
  349. package/es/sidebar/reducers/all_files.js +4 -3
  350. package/es/sidebar/reducers/collection.js +12 -13
  351. package/es/sidebar/reducers/collections.js +5 -5
  352. package/es/sidebar/reducers/documents.js +6 -13
  353. package/es/sidebar/reducers/files.js +3 -3
  354. package/es/sidebar/reducers/filter.js +1 -8
  355. package/es/sidebar/reducers/flickr.js +9 -9
  356. package/es/sidebar/reducers/folder.js +15 -15
  357. package/es/sidebar/reducers/folders.js +3 -3
  358. package/es/sidebar/reducers/images.js +3 -13
  359. package/es/sidebar/reducers/index.js +3 -1
  360. package/es/sidebar/reducers/media.js +6 -13
  361. package/es/sidebar/reducers/newPageLinkExpanded.js +1 -2
  362. package/es/sidebar/reducers/noop.js +1 -0
  363. package/es/sidebar/reducers/rootFolderId.js +1 -2
  364. package/es/sidebar/reducers/session.js +3 -3
  365. package/es/sidebar/reducers/ui.js +3 -16
  366. package/es/sidebar/reducers/upload.js +8 -40
  367. package/es/sidebar/store/configureStore.js +1 -0
  368. package/es/sidebar/store/initialState.js +13 -24
  369. package/es/translations/locales/ab.js +1 -0
  370. package/es/translations/locales/ar.js +67 -9
  371. package/es/translations/locales/ca.js +67 -9
  372. package/es/translations/locales/cs.js +1 -0
  373. package/es/translations/locales/cs_CZ.js +1 -0
  374. package/es/translations/locales/cy.js +67 -9
  375. package/es/translations/locales/da-x-k12.js +67 -9
  376. package/es/translations/locales/da.js +67 -9
  377. package/es/translations/locales/da_DK.js +1 -0
  378. package/es/translations/locales/de.js +67 -9
  379. package/es/translations/locales/el.js +4 -0
  380. package/es/translations/locales/en-AU-x-unimelb.js +67 -9
  381. package/es/translations/locales/en-GB-x-ukhe.js +67 -9
  382. package/es/translations/locales/en.js +72 -8
  383. package/es/translations/locales/en_AU.js +67 -9
  384. package/es/translations/locales/en_CA.js +67 -9
  385. package/es/translations/locales/en_CY.js +67 -9
  386. package/es/translations/locales/en_GB.js +67 -9
  387. package/es/translations/locales/en_NZ.js +1 -0
  388. package/es/translations/locales/en_SE.js +1 -0
  389. package/es/translations/locales/en_US.js +1 -0
  390. package/es/translations/locales/es.js +67 -9
  391. package/es/translations/locales/es_ES.js +67 -9
  392. package/es/translations/locales/es_GT.js +1 -0
  393. package/es/translations/locales/fa_IR.js +7 -0
  394. package/es/translations/locales/fi.js +67 -9
  395. package/es/translations/locales/fr.js +67 -9
  396. package/es/translations/locales/fr_CA.js +68 -10
  397. package/es/translations/locales/ga.js +5 -13
  398. package/es/translations/locales/he.js +7 -0
  399. package/es/translations/locales/hi.js +67 -9
  400. package/es/translations/locales/ht.js +67 -9
  401. package/es/translations/locales/hu.js +7 -6
  402. package/es/translations/locales/hu_HU.js +1 -0
  403. package/es/translations/locales/hy.js +1 -0
  404. package/es/translations/locales/id.js +67 -9
  405. package/es/translations/locales/id_ID.js +1 -0
  406. package/es/translations/locales/is.js +67 -9
  407. package/es/translations/locales/it.js +67 -9
  408. package/es/translations/locales/ja.js +67 -9
  409. package/es/translations/locales/ko.js +1 -0
  410. package/es/translations/locales/ko_KR.js +1 -0
  411. package/es/translations/locales/lt.js +1 -0
  412. package/es/translations/locales/lt_LT.js +1 -0
  413. package/es/translations/locales/mi.js +67 -9
  414. package/es/translations/locales/mn_MN.js +1 -0
  415. package/es/translations/locales/ms.js +67 -9
  416. package/es/translations/locales/nb-x-k12.js +67 -9
  417. package/es/translations/locales/nb.js +67 -9
  418. package/es/translations/locales/nl.js +67 -9
  419. package/es/translations/locales/nl_NL.js +1 -0
  420. package/es/translations/locales/nn.js +7 -6
  421. package/es/translations/locales/pl.js +67 -9
  422. package/es/translations/locales/pt.js +67 -9
  423. package/es/translations/locales/pt_BR.js +67 -9
  424. package/es/translations/locales/ro.js +1 -0
  425. package/es/translations/locales/ru.js +67 -9
  426. package/es/translations/locales/se.js +1 -0
  427. package/es/translations/locales/sl.js +67 -9
  428. package/es/translations/locales/sv-x-k12.js +67 -9
  429. package/es/translations/locales/sv.js +67 -9
  430. package/es/translations/locales/sv_SE.js +1 -0
  431. package/es/translations/locales/tg.js +1 -0
  432. package/es/translations/locales/th.js +67 -9
  433. package/es/translations/locales/th_TH.js +1 -0
  434. package/es/translations/locales/tl_PH.js +1 -0
  435. package/es/translations/locales/tr.js +7 -0
  436. package/es/translations/locales/uk_UA.js +7 -0
  437. package/es/translations/locales/vi.js +67 -9
  438. package/es/translations/locales/vi_VN.js +1 -0
  439. package/es/translations/locales/zh-Hans.js +67 -9
  440. package/es/translations/locales/zh-Hant.js +67 -9
  441. package/es/translations/locales/zh.js +67 -9
  442. package/es/translations/locales/zh_HK.js +67 -9
  443. package/es/translations/locales/zh_TW.Big5.js +1 -0
  444. package/es/translations/locales/zh_TW.js +1 -0
  445. package/es/translations/tinymce/ar_SA.js +1 -0
  446. package/es/translations/tinymce/fi.js +1 -0
  447. package/es/translations/tinymce/ga.js +1 -0
  448. package/es/translations/tinymce/id.js +1 -0
  449. package/es/translations/tinymce/ru.js +1 -0
  450. package/es/translations/tinymce/ru_RU.js +1 -0
  451. package/es/translations/tinymce/sl.js +1 -0
  452. package/es/translations/tinymce/sr.js +1 -0
  453. package/es/translations/tinymce/th.js +1 -0
  454. package/es/translations/tinymce/uk_UA.js +1 -0
  455. package/es/translations/tinymce/vi_VN.js +1 -0
  456. package/es/util/TypedDict.js +4 -2
  457. package/es/util/encrypted-storage.js +3 -13
  458. package/es/util/file-url-util.js +1 -6
  459. package/es/util/fullscreenHelpers.js +4 -1
  460. package/es/util/instui-icon-helper.js +4 -3
  461. package/es/util/loadingPlaceholder.js +38 -39
  462. package/es/util/simpleCache.js +0 -3
  463. package/es/util/string-util.js +1 -1
  464. package/es/util/textarea-editing-util.js +3 -7
  465. package/es/util/tinymce-plugin-util.js +0 -5
  466. package/es/util/url-util.js +16 -25
  467. package/eslint.config.js +239 -0
  468. package/jest.config.js +1 -1
  469. package/package.json +77 -82
  470. package/scripts/build-canvas +2 -1
  471. package/scripts/build.js +4 -4
  472. package/scripts/publish_to_npm.sh +1 -1
  473. package/testcafe/RCEWrapper.test.js +0 -1
  474. package/testcafe/StatusBar.test.js +0 -1
  475. package/testcafe/axe.test.js +3 -4
  476. package/testcafe/enhanceUserContent.test.js +0 -1
  477. package/tsconfig.json +20 -15
  478. package/.eslintrc +0 -45
  479. package/.prettierignore +0 -6
  480. package/es/common/components/FileTree/File.js +0 -64
  481. package/es/common/components/FileTree/Folder.js +0 -110
  482. package/es/common/components/FileTree/index.js +0 -84
  483. package/es/common/components/FileTree/styles.js +0 -72
  484. package/es/common/components/Loading.js +0 -83
@@ -23,6 +23,7 @@
23
23
  * because figuring this stuff out wasn't trivial and
24
24
  * I didn't want to lose it.
25
25
  ********************************************************* */
26
+
26
27
  import formatMessage from '../../../format-message';
27
28
  import { showFlashAlert } from '../../../common/FlashAlert';
28
29
  export function initPasteMenuCommand(ed, handlePasteOrDrop) {
@@ -39,7 +40,6 @@ export function initPasteMenuCommand(ed, handlePasteOrDrop) {
39
40
  text: formatMessage('Paste'),
40
41
  icon: 'paste',
41
42
  onAction: () => ed.execCommand('instructurePaste'),
42
-
43
43
  onSetup(_api) {
44
44
  // If I add the shortcut, then it overwrites the browsers
45
45
  // built-in keyboard shortcut for paste. we don't want that
@@ -47,15 +47,12 @@ export function initPasteMenuCommand(ed, handlePasteOrDrop) {
47
47
  ed.execCommand('instructurePaste');
48
48
  });
49
49
  }
50
-
51
50
  });
52
-
53
51
  async function handlePasteMenuCommand() {
54
52
  try {
55
53
  const cbitems = await window.navigator.clipboard.read();
56
54
  const cbitem = cbitems[0];
57
55
  const imageType = cbitem.types.find(t => /^image\//.test(t));
58
-
59
56
  if (imageType) {
60
57
  const blob = await cbitem.getType(imageType);
61
58
  const file = new File([blob], imageType.replace('/', '.'), {
@@ -92,7 +89,6 @@ export function initPasteMenuCommand(ed, handlePasteOrDrop) {
92
89
  });
93
90
  } else {
94
91
  const textType = cbitem.types.find(t => /^text\//.test(t));
95
-
96
92
  if (textType) {
97
93
  const blob = await cbitem.getType(textType);
98
94
  const text = await blob.text();
@@ -1,5 +1,3 @@
1
- // @ts-nocheck
2
-
3
1
  /*
4
2
  * Copyright (C) 2022 - present Instructure, Inc.
5
3
  *
@@ -17,6 +15,7 @@
17
15
  * You should have received a copy of the GNU Affero General Public License along
18
16
  * with this program. If not, see <http://www.gnu.org/licenses/>.
19
17
  */
18
+
20
19
  import tinymce from 'tinymce';
21
20
  import bridge from '../../../bridge';
22
21
  import configureStore from '../../../sidebar/store/configureStore';
@@ -34,7 +33,9 @@ const config = {
34
33
  session: null,
35
34
  // null: we haven't gotten it yet, false: we don't need it
36
35
  sessionPromise: null
37
- }; // when UploadFile renders
36
+ };
37
+
38
+ // when UploadFile renders
38
39
  // <StoreProvider {...trayProps}>
39
40
  // {contentProps => {
40
41
  // return (
@@ -43,17 +44,18 @@ const config = {
43
44
  // (We don't seem to have a way to grab an existing store)
44
45
  // So the configureStore and getSession logic gets repeated here for the
45
46
  // automatic file upload when pasting or dropping a file on the RCE
46
-
47
+ // @ts-expect-error
47
48
  function initStore(initProps) {
48
49
  if (config.store === null) {
49
50
  config.store = configureStore(initProps);
50
51
  }
51
-
52
52
  if (config.session === null) {
53
53
  if (initProps.host && initProps.jwt) {
54
54
  config.sessionPromise = getSession(config.store.dispatch, config.store.getState).then(() => {
55
55
  config.session = config.store.getState().session;
56
- }).catch(_err => {
56
+ })
57
+ // @ts-expect-error
58
+ .catch(_err => {
57
59
  // eslint-disable-next-line no-console
58
60
  console.error('The Paste plugin failed to get canvas session data.');
59
61
  });
@@ -63,12 +65,11 @@ function initStore(initProps) {
63
65
  config.sessionPromise = Promise.resolve();
64
66
  }
65
67
  }
66
-
67
68
  return config.store;
68
69
  }
69
-
70
70
  tinymce.PluginManager.add('instructure_paste', function (editor) {
71
71
  const store = initStore(bridge.trayProps.get(editor));
72
+
72
73
  /**
73
74
  * Starts the file upload (and insertion) process for the given file.
74
75
  *
@@ -76,13 +77,11 @@ tinymce.PluginManager.add('instructure_paste', function (editor) {
76
77
  *
77
78
  * @returns a promise that resolves when the user has made their choice about uploading the file
78
79
  */
79
-
80
80
  async function requestFileInsertion(file) {
81
81
  // it's very doubtful that we won't have retrieved the session data yet,
82
82
  // since it takes a while for the RCE to initialize, but if we haven't
83
83
  // wait until we do to carry on and finish pasting.
84
84
  await config.sessionPromise;
85
-
86
85
  if (config.session === null) {
87
86
  // we failed to get the session and don't know if usage rights are required in this course|group
88
87
  // In all probability, the file upload will fail too, but I feel like we have to do something here.
@@ -90,12 +89,11 @@ tinymce.PluginManager.add('instructure_paste', function (editor) {
90
89
  message: formatMessage('If Usage Rights are required, the file will not publish until enabled in the Files page.'),
91
90
  type: 'info'
92
91
  });
93
- } // even though usage rights might be required by the course, canvas has no place
94
- // on the user to store it. Only Group and Course.
95
-
92
+ }
96
93
 
94
+ // even though usage rights might be required by the course, canvas has no place
95
+ // on the user to store it. Only Group and Course.
97
96
  const requiresUsageRights = config.session.usageRightsRequired && /course|group/.test(bridge.trayProps.get(editor).contextType);
98
-
99
97
  if (requiresUsageRights) {
100
98
  return doFileUpload(editor, document, {
101
99
  accept: file.type,
@@ -114,61 +112,61 @@ tinymce.PluginManager.add('instructure_paste', function (editor) {
114
112
  domObject: file
115
113
  };
116
114
  let tabContext = 'documents';
117
-
118
115
  if (isImage(file.type)) {
119
116
  tabContext = 'images';
120
117
  } else if (isAudioOrVideo(file.type)) {
121
118
  tabContext = 'media';
122
119
  }
123
-
124
120
  store.dispatch(uploadToMediaFolder(tabContext, fileMetaProps));
125
121
  return 'submitted';
126
122
  }
127
123
  }
128
-
129
124
  async function handlePasteOrDrop(event) {
130
125
  var _bridge$activeEditor, _bridge$activeEditor$, _editor$rceWrapper;
131
-
132
126
  const isPaste = event.type === 'paste';
133
127
  const dataTransfer = isPaste ? event.clipboardData : event.dataTransfer;
134
128
  const files = Array.from((dataTransfer === null || dataTransfer === void 0 ? void 0 : dataTransfer.files) || []);
135
129
  const types = (dataTransfer === null || dataTransfer === void 0 ? void 0 : dataTransfer.types) || [];
136
- const isAudioVideoDisabled = (_bridge$activeEditor = bridge.activeEditor()) === null || _bridge$activeEditor === void 0 ? void 0 : (_bridge$activeEditor$ = _bridge$activeEditor.props) === null || _bridge$activeEditor$ === void 0 ? void 0 : _bridge$activeEditor$.instRecordDisabled; // delegate to tiny if there aren't any files to handle
130
+ const isAudioVideoDisabled = (_bridge$activeEditor = bridge.activeEditor()) === null || _bridge$activeEditor === void 0 ? void 0 : (_bridge$activeEditor$ = _bridge$activeEditor.props) === null || _bridge$activeEditor$ === void 0 ? void 0 : _bridge$activeEditor$.instRecordDisabled;
131
+
132
+ // delegate to tiny if there aren't any files to handle
133
+ if (!types.includes('Files')) return;
137
134
 
138
- if (!types.includes('Files')) return; // delegate to tiny if there is Microsoft Word content, because it may contain an image
135
+ // delegate to tiny if there is Microsoft Word content, because it may contain an image
139
136
  // rendering of the content and we don't want to incorrectly paste the image
140
137
  // instead of the actual rich content, which TinyMCE has special handing for
138
+ if (isMicrosoftWordContentInEvent(event)) return;
141
139
 
142
- if (isMicrosoftWordContentInEvent(event)) return; // we're pasting file(s), prevent the default tinymce pasting behavior
140
+ // we're pasting file(s), prevent the default tinymce pasting behavior
141
+ event.preventDefault();
143
142
 
144
- event.preventDefault(); // Ensure the editor has focus, because downstream code requires that it does, and drag-n-drop
143
+ // Ensure the editor has focus, because downstream code requires that it does, and drag-n-drop
145
144
  // events can be started when the editor doesn't have focus.
145
+ if (!editor.hasFocus()) (_editor$rceWrapper = editor.rceWrapper) === null || _editor$rceWrapper === void 0 ? void 0 : _editor$rceWrapper.focus();
146
146
 
147
- if (!editor.hasFocus()) (_editor$rceWrapper = editor.rceWrapper) === null || _editor$rceWrapper === void 0 ? void 0 : _editor$rceWrapper.focus(); // Checking if we've encountered an issue with file processing for paste events in the browser
147
+ // Checking if we've encountered an issue with file processing for paste events in the browser
148
148
  // Specifically implementing due to this bug in Firefox: https://bugzilla.mozilla.org/show_bug.cgi?id=1699743
149
149
  // However, there could be other issues that cause this condition so it's a nice safety net regardless
150
-
151
150
  if (isPaste && files.some(file => file.size === 0)) {
151
+ // @ts-expect-error
152
152
  showFlashAlert({
153
153
  message: formatMessage('One or more files failed to paste. Please try uploading or dragging and dropping files.'),
154
154
  type: 'error'
155
155
  });
156
156
  return;
157
157
  }
158
-
159
158
  for (const file of files) {
160
159
  if (isAudioVideoDisabled && isAudioOrVideo(file.type)) {
161
160
  // Skip audio and video files when disabled
162
161
  continue;
163
- } // This will finish once the dialog is closed, if one was created, putting this in a loop allows us
162
+ }
163
+
164
+ // This will finish once the dialog is closed, if one was created, putting this in a loop allows us
164
165
  // to show a dialog for each file without them conflicting.
165
166
  // eslint-disable-next-line no-await-in-loop
166
-
167
-
168
167
  await requestFileInsertion(file);
169
168
  }
170
169
  }
171
-
172
170
  editor.on('paste', handlePasteOrDrop);
173
171
  editor.on('drop', handlePasteOrDrop);
174
172
  });
@@ -1,5 +1,3 @@
1
- // @ts-nocheck
2
-
3
1
  /*
4
2
  * Copyright (C) 2023 - present Instructure, Inc.
5
3
  *
@@ -17,65 +15,55 @@
17
15
  * You should have received a copy of the GNU Affero General Public License along
18
16
  * with this program. If not, see <http://www.gnu.org/licenses/>.
19
17
  */
18
+
20
19
  import RCEWrapper from '../../RCEWrapper';
20
+ import { fallbackIframeAllowances } from './constants';
21
21
 
22
- /**
23
- * Fallback iframe allowances used when they aren't provided to the editor.
24
- */
25
- export const fallbackIframeAllowances = ['geolocation *', 'microphone *', 'camera *', 'midi *', 'encrypted-media *', 'autoplay *', 'clipboard-write *', 'display-capture *'];
26
22
  /**
27
23
  * Type of the "editor buttons" that come from Canvas.
28
24
  *
29
25
  * They're actually the available LTI Tool configurations, so we give them a more reasonable name here.
30
26
  */
31
27
 
28
+ /**
29
+ * Subset of TinyMCE used by the ExternalTools dialog. Used to document the subset of the API that we use so
30
+ * it's easier to test.
31
+ */
32
+
32
33
  /**
33
34
  * Gets the environment information for the external tools dialog for a given tinyMCE editor.
34
35
  */
35
36
  export function externalToolsEnvFor(editor) {
36
37
  const props = () => {
37
38
  var _ref, _RCEWrapper$getByEdit;
38
-
39
39
  return (_ref = (_RCEWrapper$getByEdit = RCEWrapper.getByEditor(editor)) === null || _RCEWrapper$getByEdit === void 0 ? void 0 : _RCEWrapper$getByEdit.props) !== null && _ref !== void 0 ? _ref : undefined;
40
40
  };
41
-
42
41
  let cachedCanvasToolId;
43
-
44
42
  function nonNullishArray(arr) {
45
43
  return arr === null || arr === void 0 ? void 0 : arr.filter(it => it != null);
46
44
  }
47
-
48
45
  return {
49
46
  editor: editor !== null && editor !== void 0 ? editor : null,
50
-
51
47
  get rceWrapper() {
52
48
  var _RCEWrapper$getByEdit2;
53
-
54
49
  return (_RCEWrapper$getByEdit2 = RCEWrapper.getByEditor(editor)) !== null && _RCEWrapper$getByEdit2 !== void 0 ? _RCEWrapper$getByEdit2 : null;
55
50
  },
56
-
57
51
  get availableRceLtiTools() {
58
52
  var _nonNullishArray, _props;
59
-
60
53
  return (_nonNullishArray = nonNullishArray((_props = props()) === null || _props === void 0 ? void 0 : _props.ltiTools)) !== null && _nonNullishArray !== void 0 ? _nonNullishArray : [];
61
54
  },
62
-
63
55
  /**
64
56
  * Gets information about the context in which the editor is launched.
65
57
  */
66
58
  get contextAssetInfo() {
67
59
  var _props2;
68
-
69
60
  const trayProps = (_props2 = props()) === null || _props2 === void 0 ? void 0 : _props2.trayProps;
70
-
71
61
  if (trayProps != null) {
72
62
  var _trayProps$containing;
73
-
74
63
  const {
75
64
  contextId,
76
65
  contextType
77
66
  } = (_trayProps$containing = trayProps.containingContext) !== null && _trayProps$containing !== void 0 ? _trayProps$containing : trayProps;
78
-
79
67
  if (contextId != null && contextId.length > 0 && contextType != null && contextType.length > 0) {
80
68
  return {
81
69
  contextType,
@@ -83,93 +71,66 @@ export function externalToolsEnvFor(editor) {
83
71
  };
84
72
  }
85
73
  }
86
-
87
74
  return null;
88
75
  },
89
-
90
76
  get resourceSelectionUrlOverride() {
91
77
  var _props$externalToolsC, _props3, _props3$externalTools;
92
-
93
78
  return (_props$externalToolsC = (_props3 = props()) === null || _props3 === void 0 ? void 0 : (_props3$externalTools = _props3.externalToolsConfig) === null || _props3$externalTools === void 0 ? void 0 : _props3$externalTools.resourceSelectionUrlOverride) !== null && _props$externalToolsC !== void 0 ? _props$externalToolsC : null;
94
79
  },
95
-
96
80
  get ltiIframeAllowPolicy() {
97
81
  var _nonNullishArray2, _props4, _props4$externalTools;
98
-
99
82
  return ((_nonNullishArray2 = nonNullishArray((_props4 = props()) === null || _props4 === void 0 ? void 0 : (_props4$externalTools = _props4.externalToolsConfig) === null || _props4$externalTools === void 0 ? void 0 : _props4$externalTools.ltiIframeAllowances)) !== null && _nonNullishArray2 !== void 0 ? _nonNullishArray2 : fallbackIframeAllowances).join('; ');
100
83
  },
101
-
102
84
  get isA2StudentView() {
103
85
  var _props$externalToolsC2, _props5, _props5$externalTools;
104
-
105
86
  return (_props$externalToolsC2 = (_props5 = props()) === null || _props5 === void 0 ? void 0 : (_props5$externalTools = _props5.externalToolsConfig) === null || _props5$externalTools === void 0 ? void 0 : _props5$externalTools.isA2StudentView) !== null && _props$externalToolsC2 !== void 0 ? _props$externalToolsC2 : false;
106
87
  },
107
-
108
88
  get maxMruTools() {
109
89
  var _props$externalToolsC3, _props6, _props6$externalTools;
110
-
111
90
  return (_props$externalToolsC3 = (_props6 = props()) === null || _props6 === void 0 ? void 0 : (_props6$externalTools = _props6.externalToolsConfig) === null || _props6$externalTools === void 0 ? void 0 : _props6$externalTools.maxMruTools) !== null && _props$externalToolsC3 !== void 0 ? _props$externalToolsC3 : 5;
112
91
  },
113
-
114
92
  get canvasOrigin() {
115
93
  var _props$canvasOrigin, _props7;
116
-
117
94
  return (_props$canvasOrigin = (_props7 = props()) === null || _props7 === void 0 ? void 0 : _props7.canvasOrigin) !== null && _props$canvasOrigin !== void 0 ? _props$canvasOrigin : window.location.origin;
118
95
  },
119
-
120
96
  /**
121
97
  * Gets the context id that should be used when launching LTI iframes.
122
98
  */
123
99
  get containingCanvasLtiToolId() {
124
100
  var _props8, _props8$externalTools;
125
-
126
101
  const propsToolId = (_props8 = props()) === null || _props8 === void 0 ? void 0 : (_props8$externalTools = _props8.externalToolsConfig) === null || _props8$externalTools === void 0 ? void 0 : _props8$externalTools.containingCanvasLtiToolId;
127
-
128
102
  if (typeof propsToolId === 'string') {
129
103
  return propsToolId;
130
104
  }
131
-
132
105
  try {
133
106
  if (cachedCanvasToolId === undefined) {
134
107
  // Fall back on localStorage until NQ implements
135
108
  cachedCanvasToolId = window.localStorage.getItem('canvas_tool_id');
136
109
  }
137
-
138
110
  return cachedCanvasToolId;
139
111
  } catch {
140
112
  return null;
141
113
  }
142
114
  },
143
-
144
115
  get editorSelection() {
145
116
  var _editor$selection$get, _editor$selection;
146
-
147
117
  return (_editor$selection$get = editor === null || editor === void 0 ? void 0 : (_editor$selection = editor.selection) === null || _editor$selection === void 0 ? void 0 : _editor$selection.getContent()) !== null && _editor$selection$get !== void 0 ? _editor$selection$get : null;
148
118
  },
149
-
150
119
  get editorContent() {
151
120
  var _editor$getContent;
152
-
153
121
  return (_editor$getContent = editor === null || editor === void 0 ? void 0 : editor.getContent()) !== null && _editor$getContent !== void 0 ? _editor$getContent : null;
154
122
  },
155
-
156
123
  insertCode(code) {
157
124
  var _this$rceWrapper;
158
-
159
- (_this$rceWrapper = this.rceWrapper) === null || _this$rceWrapper === void 0 ? void 0 : _this$rceWrapper.insertCode(code);
125
+ if ((_this$rceWrapper = this.rceWrapper) !== null && _this$rceWrapper !== void 0 && _this$rceWrapper.insertCode) {
126
+ this.rceWrapper.insertCode(code);
127
+ }
160
128
  },
161
-
162
129
  replaceCode(code) {
163
130
  var _this$rceWrapper2;
164
-
165
- (_this$rceWrapper2 = this.rceWrapper) === null || _this$rceWrapper2 === void 0 ? void 0 : _this$rceWrapper2.replaceCode(code);
131
+ if ((_this$rceWrapper2 = this.rceWrapper) !== null && _this$rceWrapper2 !== void 0 && _this$rceWrapper2.replaceCode) {
132
+ this.rceWrapper.replaceCode(code);
133
+ }
166
134
  }
167
-
168
135
  };
169
- }
170
- /**
171
- * Name of the parameter used to indicate to Canvas that it is being loaded in an iframe inside of an
172
- * LTI tool. It should be set to the global id of the containing tool.
173
- */
174
-
175
- export const PARENT_FRAME_CONTEXT_PARAM = 'parent_frame_context';
136
+ }
@@ -15,22 +15,24 @@
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 { openToolDialogFor } from './dialog-helper';
19
20
  import { simpleCache } from '../../../util/simpleCache';
20
- import { instUiIconsArray } from '../../../util/instui-icon-helper'; // @ts-ignore
21
+ import { instUiIconsArray } from '../../../util/instui-icon-helper';
21
22
 
23
+ // @ts-ignore
22
24
  import { IconLtiSolid } from '@instructure/ui-icons/es/svg';
23
25
  export function externalToolsForToolbar(tools) {
24
26
  // Limit of not on_by_default but favorited tools is 2
25
27
  const favorited = tools.filter(it => it.favorite && !it.on_by_default).slice(0, 2) || [];
26
28
  const onByDefault = tools.filter(it => it.on_by_default && it.favorite) || [];
27
- const set = new Map(); // Remove possible overlaps between favorited and onByDefault, otherwise
28
- // we'd have duplicate buttons in the toolbar.
29
+ const set = new Map();
29
30
 
31
+ // Remove possible overlaps between favorited and onByDefault, otherwise
32
+ // we'd have duplicate buttons in the toolbar.
30
33
  for (const toolInfo of favorited.concat(onByDefault)) {
31
34
  set.set(toolInfo.id, toolInfo);
32
35
  }
33
-
34
36
  return Array.from(set.values()).sort((a, b) => {
35
37
  if (a.on_by_default && !b.on_by_default) {
36
38
  return -1;
@@ -45,75 +47,59 @@ export function externalToolsForToolbar(tools) {
45
47
  }
46
48
  });
47
49
  }
50
+
48
51
  /**
49
52
  * Helper class for the connection between an external tool registration and a particular TinyMCE instance.
50
53
  */
51
-
52
54
  export class RceToolWrapper {
53
55
  static forEditorEnv(env) {
54
56
  let toolConfigs = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : env.availableRceLtiTools;
55
57
  let mruIds = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : loadMruToolIds();
56
58
  return toolConfigs.map(it => new RceToolWrapper(env, it, mruIds));
57
59
  }
58
-
59
60
  get editor() {
60
61
  return this.env.editor;
61
62
  }
62
-
63
63
  constructor(env, toolInfo, mruToolIds) {
64
- this.env = env;
65
- this.toolInfo = toolInfo;
66
64
  this.iconId = void 0;
67
65
  this.isMruTool = void 0;
66
+ this.env = env;
67
+ this.toolInfo = toolInfo;
68
68
  this.iconId = registerToolIcon(env, toolInfo);
69
69
  this.isMruTool = mruToolIds.includes(String(toolInfo.id));
70
70
  }
71
-
72
71
  get id() {
73
72
  return String(this.toolInfo.id);
74
73
  }
75
-
76
74
  get title() {
77
75
  var _this$toolInfo$name;
78
-
79
76
  return (_this$toolInfo$name = this.toolInfo.name) !== null && _this$toolInfo$name !== void 0 ? _this$toolInfo$name : `Unknown tool (${String(this.toolInfo.id)})`;
80
77
  }
81
-
82
78
  get description() {
83
79
  return this.toolInfo.description;
84
80
  }
85
-
86
81
  get favorite() {
87
82
  var _this$toolInfo$favori;
88
-
89
83
  return (_this$toolInfo$favori = this.toolInfo.favorite) !== null && _this$toolInfo$favori !== void 0 ? _this$toolInfo$favori : false;
90
84
  }
91
-
92
85
  get image() {
93
86
  var _parseIconValueFor;
94
-
95
87
  return (_parseIconValueFor = parseIconValueFor(this.toolInfo)) === null || _parseIconValueFor === void 0 ? void 0 : _parseIconValueFor.iconUrl;
96
88
  }
97
-
98
89
  get width() {
99
90
  return this.toolInfo.width;
100
91
  }
101
-
102
92
  get height() {
103
93
  return this.toolInfo.height;
104
94
  }
105
-
106
95
  get use_tray() {
107
96
  return this.toolInfo.use_tray;
108
97
  }
109
-
110
98
  get on_by_default() {
111
99
  return this.toolInfo.on_by_default;
112
100
  }
113
-
114
101
  asToolbarButton() {
115
102
  var _this$iconId;
116
-
117
103
  return {
118
104
  type: 'button',
119
105
  icon: (_this$iconId = this.iconId) !== null && _this$iconId !== void 0 ? _this$iconId : undefined,
@@ -121,10 +107,8 @@ export class RceToolWrapper {
121
107
  onAction: () => this.openDialog()
122
108
  };
123
109
  }
124
-
125
110
  asMenuItem() {
126
111
  var _this$iconId2;
127
-
128
112
  return {
129
113
  type: 'menuitem',
130
114
  text: this.title,
@@ -132,48 +116,44 @@ export class RceToolWrapper {
132
116
  onAction: () => this.openDialog()
133
117
  };
134
118
  }
135
-
136
119
  openDialog() {
137
120
  addMruToolId(this.id, this.env);
138
121
  openToolDialogFor(this);
139
122
  }
140
-
141
123
  }
142
124
  export function parseIconValueFor(toolInfo) {
143
125
  const result = {};
144
- const canvasIconClass = toolInfo.canvas_icon_class; // URL embedded in canvas_icon_class, which happens in some cases (see MAT-1354)
126
+ const canvasIconClass = toolInfo.canvas_icon_class;
145
127
 
128
+ // URL embedded in canvas_icon_class, which happens in some cases (see MAT-1354)
146
129
  if (typeof canvasIconClass === 'object') {
147
130
  const iconUrl = canvasIconClass === null || canvasIconClass === void 0 ? void 0 : canvasIconClass.icon_url;
148
-
149
131
  if (typeof iconUrl === 'string' && iconUrl !== '') {
150
132
  result.iconUrl = iconUrl;
151
133
  }
152
- } // URL at the top level takes precedence
153
-
134
+ }
154
135
 
136
+ // URL at the top level takes precedence
155
137
  if (typeof toolInfo.icon_url === 'string' && toolInfo.icon_url !== '') {
156
138
  result.iconUrl = toolInfo.icon_url;
157
- } // Icon class as string
158
-
139
+ }
159
140
 
141
+ // Icon class as string
160
142
  if (typeof canvasIconClass === 'string' && canvasIconClass !== '') {
161
143
  result.canvasIconClass = canvasIconClass;
162
144
  }
163
-
164
145
  return result;
165
146
  }
166
-
167
147
  function registerToolIcon(env, toolInfo) {
168
148
  if (env.editor == null) return undefined;
169
149
  const iconId = 'lti_tool_' + String(toolInfo.id);
170
150
  const {
171
151
  iconUrl,
172
152
  canvasIconClass
173
- } = parseIconValueFor(toolInfo); // We need to strip off the icon- or icon_ prefix from the icon class name to match instui icons
153
+ } = parseIconValueFor(toolInfo);
174
154
 
155
+ // We need to strip off the icon- or icon_ prefix from the icon class name to match instui icons
175
156
  const iconGlyphName = (canvasIconClass !== null && canvasIconClass !== void 0 ? canvasIconClass : '').replace(/^icon[-_]/, '');
176
-
177
157
  if (iconUrl != null && iconUrl.length > 0) {
178
158
  // Icon image provided
179
159
  env.editor.ui.registry.addIcon(iconId, svgImageCache.get(iconUrl));
@@ -181,18 +161,16 @@ function registerToolIcon(env, toolInfo) {
181
161
  } else if (iconGlyphName != null && iconGlyphName.length > 0) {
182
162
  // InstUI icon used
183
163
  const instUiIcon = instUiIconsArray.find(it => it.variant === 'Line' && it.glyphName === iconGlyphName);
184
-
185
164
  if (instUiIcon != null) {
186
165
  env.editor.ui.registry.addIcon(iconId, instUiIcon.src);
187
166
  return iconId;
188
167
  }
189
- } // Fallback to default icon
190
-
168
+ }
191
169
 
170
+ // Fallback to default icon
192
171
  env.editor.ui.registry.addIcon(iconId, IconLtiSolid.src);
193
172
  return iconId;
194
173
  }
195
-
196
174
  const svgImageCache = simpleCache(imageUrl => {
197
175
  // Sanitize input against XSS
198
176
  const svg = document.createElement('svg');
@@ -206,32 +184,28 @@ const svgImageCache = simpleCache(imageUrl => {
206
184
  svg.appendChild(image);
207
185
  return svg.outerHTML;
208
186
  });
187
+
209
188
  /**
210
189
  * Loads the list of most recently used external tool ids.
211
190
  */
212
-
213
191
  export function loadMruToolIds() {
214
192
  let list;
215
-
216
193
  try {
217
194
  var _window$localStorage$, _window$localStorage;
218
-
219
195
  list = JSON.parse((_window$localStorage$ = (_window$localStorage = window.localStorage) === null || _window$localStorage === void 0 ? void 0 : _window$localStorage.getItem('ltimru')) !== null && _window$localStorage$ !== void 0 ? _window$localStorage$ : '[]');
220
196
  } catch (ex) {
221
197
  // eslint-disable-next-line no-console
222
198
  console.warn('Found bad LTI MRU data', ex.message);
223
199
  }
224
-
225
200
  return Array.isArray(list) ? list.filter(it => it != null).map(it => String(it)) : [];
226
201
  }
202
+
227
203
  /**
228
204
  * Loads the list of most recently used external tool ids.
229
205
  */
230
-
231
206
  export function storeMruToolIds(toolIds) {
232
207
  try {
233
208
  var _window$localStorage2;
234
-
235
209
  (_window$localStorage2 = window.localStorage) === null || _window$localStorage2 === void 0 ? void 0 : _window$localStorage2.setItem('ltimru', JSON.stringify(toolIds));
236
210
  } catch (ex) {
237
211
  // eslint-disable-next-line no-console
@@ -240,13 +214,11 @@ export function storeMruToolIds(toolIds) {
240
214
  }
241
215
  export function addMruToolId(toolId, env) {
242
216
  const initialMruToolIds = loadMruToolIds();
243
-
244
217
  if (!initialMruToolIds.includes(toolId)) {
245
218
  const newToolIds = [toolId, ...initialMruToolIds.slice(0, env.maxMruTools - 1)];
246
219
  storeMruToolIds(newToolIds);
247
220
  return newToolIds;
248
221
  }
249
-
250
222
  return initialMruToolIds;
251
223
  }
252
224
  export function buildToolMenuItems(availableTools, viewAllItem) {