@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
@@ -15,17 +15,21 @@
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 from 'react';
19
- import ReactDOM from 'react-dom';
20
+ import { createRoot } from 'react-dom/client';
20
21
  import formatMessage from '../format-message';
21
22
  import { Spinner } from '@instructure/ui-spinner';
22
23
  import { getData, setData } from './jqueryish_funcs';
23
- export const previewableMimeTypes = ['application/vnd.openxmlformats-officedocument.wordprocessingml.template', 'application/vnd.oasis.opendocument.spreadsheet', 'application/vnd.sun.xml.writer', 'application/excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'text/rtf', 'application/vnd.openxmlformats-officedocument.spreadsheetml.template', 'application/vnd.sun.xml.impress', 'application/vnd.sun.xml.calc', 'application/vnd.ms-excel', 'application/msword', 'application/mspowerpoint', 'application/rtf', 'application/vnd.oasis.opendocument.presentation', 'application/vnd.oasis.opendocument.text', 'application/vnd.openxmlformats-officedocument.presentationml.template', 'application/vnd.openxmlformats-officedocument.presentationml.slideshow', 'text/plain', 'application/vnd.openxmlformats-officedocument.presentationml.presentation', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/postscript', 'application/pdf', 'application/vnd.ms-powerpoint']; // check to see if a file of a certan mimeType is previewable inline in the browser
24
- // ex: isPreviewable("application/mspowerpoint") -> true
24
+ export const previewableMimeTypes = ['application/vnd.openxmlformats-officedocument.wordprocessingml.template', 'application/vnd.oasis.opendocument.spreadsheet', 'application/vnd.sun.xml.writer', 'application/excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'text/rtf', 'application/vnd.openxmlformats-officedocument.spreadsheetml.template', 'application/vnd.sun.xml.impress', 'application/vnd.sun.xml.calc', 'application/vnd.ms-excel', 'application/msword', 'application/mspowerpoint', 'application/rtf', 'application/vnd.oasis.opendocument.presentation', 'application/vnd.oasis.opendocument.text', 'application/vnd.openxmlformats-officedocument.presentationml.template', 'application/vnd.openxmlformats-officedocument.presentationml.slideshow', 'text/plain', 'application/vnd.openxmlformats-officedocument.presentationml.presentation', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/postscript', 'application/pdf', 'application/vnd.ms-powerpoint'];
25
25
 
26
+ // check to see if a file of a certan mimeType is previewable inline in the browser
27
+ // ex: isPreviewable("application/mspowerpoint") -> true
26
28
  export function isPreviewable(mimeType) {
27
29
  return previewableMimeTypes.includes(mimeType);
28
- } // Show a loading spinner
30
+ }
31
+
32
+ // Show a loading spinner
29
33
  // The typical use is to show the spinner next to a canvas file link
30
34
  // while the inline preview is loading. It's also used when previewing
31
35
  // student submitted files in speedgrader, in which case $link is really
@@ -35,9 +39,7 @@ export function isPreviewable(mimeType) {
35
39
  //
36
40
  // $link: the DOM node that serves as the reference for locating the spinner
37
41
  // position: one of 'adjacent' or 'centered'
38
-
39
- export function showLoadingImage($link) {
40
- let position = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'adjacent';
42
+ export function showLoadingImage($link, position = 'adjacent') {
41
43
  const dir = $link && window.getComputedStyle($link).direction || 'ltr';
42
44
  const boundingBox = $link.getBoundingClientRect();
43
45
  const offsetLeft = boundingBox.left + (position === 'adjacent' ? dir === 'ltr' ? boundingBox.width : -24 : boundingBox.width / 2);
@@ -50,7 +52,6 @@ export function showLoadingImage($link) {
50
52
  const list = getData($link, 'loading_images') || [];
51
53
  list.push($imageHolder);
52
54
  setData($link, 'loading_images', list);
53
-
54
55
  if (!$link.style.position || $link.style.position === 'static') {
55
56
  const top = `${boundingBox.top + window.scrollY + (position === 'adjacent' ? 0 : boundingBox.height / 2)}px`;
56
57
  const left = `${offsetLeft}px`;
@@ -62,20 +63,22 @@ export function showLoadingImage($link) {
62
63
  $imageHolder.setAttribute('style', `z-index:${zIndex}; position: absolute; top: ${top}; left: ${left}; margin-inline-start:${imageMarginInlineStart}; margin-top: ${imageMarginTop}`);
63
64
  $link.appendChild($imageHolder);
64
65
  }
65
-
66
- ReactDOM.render( /*#__PURE__*/React.createElement(Spinner, {
66
+ const root = createRoot($imageHolder);
67
+ root.render(/*#__PURE__*/React.createElement(Spinner, {
67
68
  size: "x-small",
68
69
  renderTitle: formatMessage('Loading')
69
- }), $imageHolder);
70
+ }));
70
71
  return $link;
71
72
  }
72
73
  export function removeLoadingImage($link) {
73
- var _$link$querySelector;
74
-
75
- (_$link$querySelector = $link.querySelector('.loading_image')) === null || _$link$querySelector === void 0 ? void 0 : _$link$querySelector.remove();
74
+ $link.querySelector('.loading_image')?.remove();
76
75
  const list = getData($link, 'loading_images') || [];
77
76
  list.forEach(item => {
78
77
  if (item) {
78
+ const root = item._reactRoot;
79
+ if (root) {
80
+ root.unmount();
81
+ }
79
82
  item.remove();
80
83
  }
81
84
  });
@@ -95,7 +98,6 @@ export function loadDocPreview($container, options) {
95
98
  if (!($container instanceof HTMLElement)) {
96
99
  throw new Error('loadDocPreview requires a DOM element as first argument');
97
100
  }
98
-
99
101
  function tellAppIViewedThisInline() {
100
102
  // if I have a url to ping back to the app that I viewed this file inline, ping it.
101
103
  if (opts.attachment_view_inline_ping_url) {
@@ -104,7 +106,6 @@ export function loadDocPreview($container, options) {
104
106
  });
105
107
  }
106
108
  }
107
-
108
109
  if (opts.crocodoc_session_url) {
109
110
  const sanitizedUrl = sanitizeUrl(opts.crocodoc_session_url);
110
111
  const iframe = document.createElement('iframe');
@@ -143,12 +144,10 @@ export function loadDocPreview($container, options) {
143
144
  embedded: true,
144
145
  url: opts.public_url
145
146
  }).toString()}`;
146
-
147
147
  if (!opts.ajax_valid || opts.ajax_valid()) {
148
148
  const iframe = document.createElement('iframe');
149
149
  iframe.addEventListener('load', () => {
150
150
  tellAppIViewedThisInline('google');
151
-
152
151
  if (typeof opts.ready === 'function') {
153
152
  opts.ready();
154
153
  }
@@ -159,43 +158,37 @@ export function loadDocPreview($container, options) {
159
158
  $container.appendChild(iframe);
160
159
  }
161
160
  };
162
-
163
161
  if (opts.public_url) {
164
162
  loadGooglePreview();
165
163
  } else if (opts.attachment_id) {
166
164
  let url = `/api/v1/files/${opts.attachment_id}/public_url.json`;
167
-
168
165
  if (opts.submission_id) {
169
166
  url += '?' + new URLSearchParams({
170
167
  submission_id: opts.submission_id
171
168
  }).toString();
172
169
  }
173
-
174
170
  if (opts.verifier) {
175
171
  url += `${opts.submission_id ? '&' : '?'}verifier=${opts.verifier}`;
176
172
  } else {
177
173
  const match = window.location.search.match(/verifier=([^&]+)(?:&|$)/);
178
174
  const ver = match && match[1];
179
-
180
175
  if (ver) {
181
176
  url += `${opts.submission_id ? '&' : '?'}verifier=${ver}`;
182
177
  }
183
178
  }
184
-
185
- showLoadingImage($container, 'centered'); // eslint-disable-next-line promise/catch-or-return
186
-
179
+ showLoadingImage($container, 'centered');
187
180
  fetch(url).then(response => {
188
181
  if (!response.ok) throw new Error(`${response.status}: ${response.statusText}`);
189
182
  return response;
190
183
  }).then(response => response.json()).then(data => {
191
184
  if (data.public_url) {
192
- opts = { ...opts,
185
+ opts = {
186
+ ...opts,
193
187
  ...data
194
188
  };
195
189
  loadGooglePreview();
196
190
  }
197
191
  }).catch(ex => {
198
- // eslint-disable-next-line no-console
199
192
  console.error(ex);
200
193
  }).finally(() => {
201
194
  removeLoadingImage($container);
@@ -204,31 +197,27 @@ export function loadDocPreview($container, options) {
204
197
  } else {
205
198
  // else fall back with a message that the document can't be viewed inline
206
199
  const paragraph = document.createElement('p');
207
-
208
200
  if (opts.attachment_preview_processing) {
209
201
  paragraph.textContent = formatMessage('The document preview is currently being processed. Please try again later.');
210
202
  } else {
211
203
  paragraph.textContent = formatMessage('This document cannot be displayed within Canvas.');
212
204
  }
213
-
214
- $container.empty().append(paragraph);
205
+ $container.replaceChildren();
206
+ $container.appendChild(paragraph);
215
207
  }
216
208
  }
209
+
217
210
  /**
218
211
  * Replaces bad urls with harmless urls in cases where bad urls might cause harm
219
212
  * @param {string} url
220
213
  */
221
-
222
214
  export function sanitizeUrl(url) {
223
215
  const defaultUrl = 'about:blank';
224
-
225
216
  try {
226
- const parsedUrl = new URL(url, window.location.origin); // eslint-disable-next-line no-script-url
227
-
217
+ const parsedUrl = new URL(url, window.location.origin);
228
218
  if (parsedUrl.protocol === 'javascript:') {
229
219
  return defaultUrl;
230
220
  }
231
-
232
221
  return url;
233
222
  } catch (e) {
234
223
  // URL() throws TypeError if url is not a valid URL
@@ -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 { IconDownloadLine } from '@instructure/ui-icons/es/svg';
19
20
  import formatMessage from '../format-message';
20
21
  import { closest, getData, hide, insertAfter, setData, show } from './jqueryish_funcs';
@@ -23,10 +24,10 @@ import mediaCommentThumbnail from './media_comment_thumbnail';
23
24
  import { addParentFrameContextToUrl } from '../rce/plugins/instructure_rce_external_tools/util/addParentFrameContextToUrl';
24
25
  import { MathJaxDirective, Mathml } from './mathml';
25
26
  import { makeExternalLinkIcon } from './external_links';
26
- import getTranslations from '../getTranslations'; // in jest the es directory doesn't exist so stub the undefined svg
27
-
28
- const IconDownloadSVG = (IconDownloadLine === null || IconDownloadLine === void 0 ? void 0 : IconDownloadLine.src) || '<svg></svg>';
27
+ import getTranslations from '../getTranslations';
29
28
 
29
+ // in jest the es directory doesn't exist so stub the undefined svg
30
+ const IconDownloadSVG = IconDownloadLine?.src || '<svg></svg>';
30
31
  function makeDownloadButton(download_url, filename) {
31
32
  const a = document.createElement('a');
32
33
  a.setAttribute('class', 'file_download_btn');
@@ -47,11 +48,9 @@ function makeDownloadButton(download_url, filename) {
47
48
  a.appendChild(srspan);
48
49
  return a;
49
50
  }
50
-
51
51
  function handleYoutubeLink($link) {
52
52
  const href = $link.getAttribute('href');
53
53
  const id = youTubeID(href || '');
54
-
55
54
  if (id && !$link.classList.contains('inline_disabled')) {
56
55
  const $after = document.createElement('a');
57
56
  $after.setAttribute('href', href);
@@ -97,62 +96,48 @@ function handleYoutubeLink($link) {
97
96
  insertAfter($after, $link);
98
97
  }
99
98
  }
100
-
101
99
  let preview_counter = 0;
102
-
103
100
  function previewId() {
104
101
  return `preview_${++preview_counter}`;
105
102
  }
106
-
107
103
  function buildUrl(url) {
108
104
  try {
109
105
  return new URL(url);
110
- } catch (e) {// Don't raise an error
106
+ } catch (e) {
107
+ // Don't raise an error
111
108
  }
112
109
  }
113
-
114
110
  const addResourceIdentifiersToStudioContent = content => {
115
111
  content.querySelectorAll('iframe.lti-embed').forEach(iframe => {
116
- var _userContentContainer, _userContentContainer2;
117
-
118
112
  const url = buildUrl(iframe.getAttribute('src'));
119
-
120
113
  if (!url || !url.pathname.includes('external_tools/retrieve') || !url.search.includes('instructuremedia.com') || !url.search.includes('custom_arc_media_id')) {
121
114
  return;
122
115
  }
123
-
124
116
  const userContentContainer = iframe.closest('.user_content');
125
-
126
- if (userContentContainer !== null && userContentContainer !== void 0 && (_userContentContainer = userContentContainer.dataset) !== null && _userContentContainer !== void 0 && _userContentContainer.resourceType && userContentContainer !== null && userContentContainer !== void 0 && (_userContentContainer2 = userContentContainer.dataset) !== null && _userContentContainer2 !== void 0 && _userContentContainer2.resourceId) {
117
+ if (userContentContainer?.dataset?.resourceType && userContentContainer?.dataset?.resourceId) {
127
118
  url.searchParams.set('com_instructure_course_canvas_resource_type', userContentContainer.dataset.resourceType);
128
119
  url.searchParams.set('com_instructure_course_canvas_resource_id', userContentContainer.dataset.resourceId);
129
120
  iframe.src = url.href;
130
121
  }
131
122
  });
132
123
  };
133
-
134
- export function enhanceUserContent() {
135
- let container = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : document;
136
- let opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
124
+ export function enhanceUserContent(container = document, opts = {}) {
137
125
  const {
138
126
  customEnhanceFunc,
139
127
  canvasOrigin,
140
128
  kalturaSettings,
141
129
  disableGooglePreviews,
142
130
  canvasLinksTarget,
143
-
144
131
  /**
145
132
  * For MathML configuration
146
133
  */
147
134
  new_math_equation_handling,
148
135
  explicit_latex_typesetting,
149
136
  locale,
150
-
151
137
  /**
152
138
  * When used inside of an LTI tool, this contains the canvas global id of the tool.
153
139
  */
154
140
  containingCanvasLtiToolId,
155
-
156
141
  /**
157
142
  * Contingency plan in case new instfs media links cause problems in rich content.
158
143
  */
@@ -166,12 +151,10 @@ export function enhanceUserContent() {
166
151
  console.error('Failed loading the language file for', locale, '. Falling back to English.');
167
152
  });
168
153
  const content = container instanceof HTMLElement && container || document.getElementById('content') || document;
169
-
170
154
  const showFilePreviewEx = event => showFilePreview(event, {
171
155
  canvasOrigin,
172
156
  disableGooglePreviews
173
157
  });
174
-
175
158
  content.querySelectorAll('.user_content:not(.enhanced)').forEach(elem => {
176
159
  elem.classList.add('unenhanced');
177
160
  explicit_latex_typesetting && elem.classList.add(MathJaxDirective.Process);
@@ -186,43 +169,40 @@ export function enhanceUserContent() {
186
169
  explicit_latex_typesetting && mathml.processNewMathInElem(unenhanced_elem);
187
170
  unenhanced_elem.querySelectorAll('img').forEach(img => {
188
171
  const src = img.getAttribute('src');
189
-
190
172
  if (!/^\/[^/]/.test(src)) {
191
173
  return;
192
- } // if the image file is unpublished it's replaced with the lock image
174
+ }
175
+
176
+ // if the image file is unpublished it's replaced with the lock image
193
177
  // and canvas adds hidden=1 to the URL.
194
178
  // we also need to strip the alt text
195
-
196
-
197
179
  if (/hidden=1$/.test(src)) {
198
180
  img.setAttribute('alt', formatMessage('This image is currently unavailable'));
199
181
  }
200
182
  });
201
- setData(unenhanced_elem, 'unenhanced_content_html', unenhanced_elem.innerHTML); // If instfs links are causing content problems,
202
- // use this to show users old links instead
183
+ setData(unenhanced_elem, 'unenhanced_content_html', unenhanced_elem.innerHTML);
203
184
 
185
+ // If instfs links are causing content problems,
186
+ // use this to show users old links instead
204
187
  if (replaceInstFSLinksWithOldLinks) {
205
188
  const attributes = ['href', 'src'];
206
189
  const selector = '[href], [src]';
207
190
  const oldLinkAttribute = 'data-old-link';
208
191
  unenhanced_elem.querySelectorAll(selector).forEach(element => {
209
192
  const oldLink = element.getAttribute(oldLinkAttribute);
210
-
211
193
  if (!oldLink) {
212
194
  return;
213
195
  }
214
-
215
196
  for (const a of attributes) {
216
197
  const newLink = element.getAttribute(a);
217
-
218
198
  if (newLink && newLink != oldLink) {
219
199
  element.setAttribute(a, oldLink);
220
200
  }
221
201
  }
222
202
  });
223
- } // guarantee relative links point to canvas
224
-
203
+ }
225
204
 
205
+ // guarantee relative links point to canvas
226
206
  if (canvasOrigin) {
227
207
  const attributes = ['href', 'src'];
228
208
  const selector = '[href], [src]';
@@ -230,38 +210,34 @@ export function enhanceUserContent() {
230
210
  try {
231
211
  for (const a of attributes) {
232
212
  const potentialUrl = element.getAttribute(a);
233
-
234
213
  if (!/^\/[^/]/.test(potentialUrl)) {
235
214
  continue;
236
215
  }
237
-
238
216
  const absoluteUrl = new URL(potentialUrl, canvasOrigin);
239
217
  element.setAttribute(a, absoluteUrl.href);
240
-
241
218
  if (canvasLinksTarget && element.tagName === 'A' && (!element.getAttribute('target') || element.getAttribute('target') === '_blank')) {
242
219
  element.setAttribute('target', canvasLinksTarget);
243
220
  }
244
221
  }
245
- } catch (_ignore) {// canvasOrigin probably isn't a valid base url
222
+ } catch (_ignore) {
223
+ // canvasOrigin probably isn't a valid base url
246
224
  }
247
225
  });
248
- } // add parent_frame_context to canvas iframes to allow them loading inside another LTI tool
249
-
226
+ }
250
227
 
228
+ // add parent_frame_context to canvas iframes to allow them loading inside another LTI tool
251
229
  if (containingCanvasLtiToolId != null) {
252
230
  unenhanced_elem.querySelectorAll('iframe[src]').forEach(iframeElem => {
253
231
  const src = iframeElem.getAttribute('src');
254
-
255
232
  if (src.startsWith(canvasOrigin)) {
256
233
  iframeElem.setAttribute('src', addParentFrameContextToUrl(src, containingCanvasLtiToolId));
257
234
  }
258
235
  });
259
- } // tell LTI tools that they are launching from within the active RCE
260
-
236
+ }
261
237
 
238
+ // tell LTI tools that they are launching from within the active RCE
262
239
  unenhanced_elem.querySelectorAll('iframe[src]').forEach(iframeElem => {
263
240
  const src = iframeElem.getAttribute('src');
264
-
265
241
  if (src.startsWith(canvasOrigin)) {
266
242
  iframeElem.setAttribute('src', src.replace('display=in_rce', 'display=borderless'));
267
243
  }
@@ -275,9 +251,7 @@ export function enhanceUserContent() {
275
251
  const $linkSpan = document.createElement('span');
276
252
  const $linkText = childLink.innerHTML;
277
253
  $linkSpan.innerHTML = $linkText;
278
-
279
254
  while (childLink.firstChild) childLink.removeChild(childLink.firstChild);
280
-
281
255
  childLink.appendChild($linkSpan);
282
256
  const externalLinkIcon = makeExternalLinkIcon(childLink);
283
257
  childLink.appendChild(externalLinkIcon);
@@ -285,21 +259,20 @@ export function enhanceUserContent() {
285
259
  addResourceIdentifiersToStudioContent(unenhanced_elem);
286
260
  });
287
261
  content.querySelectorAll('a.instructure_file_link, a.instructure_scribd_file').forEach(file_link => {
288
- const href = buildUrl(file_link.href); // Don't attempt to enhance links with no href
262
+ const href = buildUrl(file_link.href);
289
263
 
264
+ // Don't attempt to enhance links with no href
290
265
  if (!href) return;
291
266
  const matchesCanvasFile = href.pathname.match(/(?:\/(courses|groups|users)\/\d+)?\/files\/([\d~]+)(?=[!*'();:@&=+$,/?#\[\]]|$)/);
292
-
293
267
  if (!matchesCanvasFile) {
294
268
  // a bug in the new RCE added instructure_file_link class name to all links
295
269
  // only proceed if this is a canvas file link
296
270
  return;
297
271
  }
298
-
299
272
  if (file_link.textContent.trim()) {
300
273
  file_link.addEventListener('click', showFilePreviewEx);
301
- const filename = file_link.textContent; // instructure_file_link_holder is used to find file_preview_link
302
-
274
+ const filename = file_link.textContent;
275
+ // instructure_file_link_holder is used to find file_preview_link
303
276
  const $span = document.createElement('span');
304
277
  $span.setAttribute('class', 'instructure_file_holder link_holder instructure_file_link_holder');
305
278
  const qs = href.searchParams;
@@ -307,7 +280,6 @@ export function enhanceUserContent() {
307
280
  qs.append('download_frd', '1');
308
281
  const download_url = `${href.origin}${href.pathname.replace(/(?:\/(download|preview))?$/, '/download')}?${qs}`;
309
282
  const $download_btn = makeDownloadButton(download_url, filename);
310
-
311
283
  if (file_link.classList.contains('instructure_scribd_file')) {
312
284
  if (file_link.classList.contains('no_preview')) {
313
285
  // link downloads
@@ -321,22 +293,21 @@ export function enhanceUserContent() {
321
293
  file_link.classList.add('file_preview_link');
322
294
  }
323
295
  }
324
-
325
296
  file_link.classList.remove('instructure_file_link');
326
297
  file_link.classList.remove('instructure_scribd_file');
327
298
  file_link.parentElement.replaceChild($span, file_link);
328
299
  $span.appendChild(file_link);
329
300
  if ($download_btn) $span.appendChild($download_btn);
330
301
  }
331
- }); // Some schools have been using 'file_preview_link' for inline previews
302
+ });
303
+
304
+ // Some schools have been using 'file_preview_link' for inline previews
332
305
  // outside of the RCE so find them all after we've gone through and
333
306
  // added our own (above)
334
-
335
307
  content.querySelectorAll('.instructure_file_link_holder a.file_preview_link, .instructure_file_link_holder a.scribd_file_preview_link').forEach($link => {
336
308
  if ($link.classList.contains('previewable')) {
337
309
  return;
338
310
  }
339
-
340
311
  const preview_id = previewId();
341
312
  $link.setAttribute('aria-expanded', 'false');
342
313
  $link.setAttribute('aria-controls', preview_id);
@@ -348,7 +319,6 @@ export function enhanceUserContent() {
348
319
  $preview_container.id = preview_id;
349
320
  $preview_container.setAttribute('style', 'display: none;');
350
321
  $link.parentElement.appendChild($preview_container);
351
-
352
322
  if ($link.classList.contains('auto_open')) {
353
323
  $link.click();
354
324
  }
@@ -357,27 +327,22 @@ export function enhanceUserContent() {
357
327
  unenhanced_anchors.forEach($anchor => {
358
328
  $anchor.querySelectorAll('img.media_comment_thumbnail').forEach($thumbnail => {
359
329
  const a = closest($thumbnail, 'a', content);
360
- a === null || a === void 0 ? void 0 : a.classList.add('instructure_inline_media_comment');
330
+ a?.classList.add('instructure_inline_media_comment');
361
331
  });
362
-
363
332
  if ($anchor.matches('.instructure_inline_media_comment')) {
364
333
  $anchor.classList.remove('no-underline');
365
334
  mediaCommentThumbnail($anchor, 'normal', false, kalturaSettings);
366
335
  }
367
-
368
336
  if ($anchor.matches('.instructure_video_link, .instructure_audio_link')) {
369
337
  mediaCommentThumbnail($anchor, 'normal', true, kalturaSettings);
370
338
  }
371
-
372
339
  if (!$anchor.matches('.youtubed')) {
373
340
  handleYoutubeLink($anchor);
374
341
  }
375
342
  });
376
-
377
343
  if (customEnhanceFunc) {
378
344
  customEnhanceFunc();
379
345
  }
380
-
381
346
  content.querySelectorAll('.user_content.unenhanced').forEach($elem => {
382
347
  $elem.classList.remove('unenhanced');
383
348
  $elem.classList.add('enhanced');
@@ -387,9 +352,9 @@ export function enhanceUserContent() {
387
352
  $elem.submit();
388
353
  $elem.classList.add('submitted');
389
354
  });
390
- }, 10); // Remove sandbox attribute from user content iframes to fix busted
355
+ }, 10);
356
+ // Remove sandbox attribute from user content iframes to fix busted
391
357
  // third-party content, like Google Drive documents.
392
-
393
358
  document.querySelectorAll('.user_content iframe[sandbox="allow-scripts allow-forms allow-same-origin"]').forEach(frame => {
394
359
  frame.removeAttribute('sandbox');
395
360
  const src = frame.src;
@@ -15,10 +15,11 @@
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 { IconExternalLinkLine } from '@instructure/ui-icons/es/svg';
19
20
  import { getTld } from './instructure_helper';
20
21
  import formatMessage from '../format-message';
21
- const IconExternalLinkSVG = (IconExternalLinkLine === null || IconExternalLinkLine === void 0 ? void 0 : IconExternalLinkLine.src) || '<svg></svg>';
22
+ const IconExternalLinkSVG = IconExternalLinkLine?.src || '<svg></svg>';
22
23
  export function makeExternalLinkIcon(forLink) {
23
24
  const dir = forLink && window.getComputedStyle(forLink).direction || 'ltr';
24
25
  const $icon = document.createElement('span');
@@ -42,19 +43,17 @@ export function makeAllExternalLinksExternalLinks() {
42
43
  if (!content) return;
43
44
  const tld = getTld(window.location.hostname);
44
45
  const links = content.querySelectorAll(`a[href*="//"]:not([href*="${tld}"])`); // technique for finding "external" links copied from https://davidwalsh.name/external-links-css
45
-
46
46
  for (let i = 0; i < links.length; i++) {
47
- const $link = links[i]; // don't mess with the ones that were already processed in enhanceUserContent
48
-
47
+ const $link = links[i];
48
+ // don't mess with the ones that were already processed in enhanceUserContent
49
49
  if ($link.classList.contains('external')) continue;
50
50
  if ($link.matches('.open_in_a_new_tab')) continue;
51
51
  if ($link.querySelectorAll('img').length > 0) continue;
52
52
  if ($link.matches('.not_external')) continue;
53
- if ($link.matches('.exclude_external_icon')) continue; // we have some pre-instui buttons that are styled links
54
-
53
+ if ($link.matches('.exclude_external_icon')) continue;
54
+ // we have some pre-instui buttons that are styled links
55
55
  if ($link.classList.contains('btn')) continue;
56
56
  const $linkToReplace = $link;
57
-
58
57
  if ($linkToReplace) {
59
58
  const $linkIndicator = makeExternalLinkIcon();
60
59
  $linkToReplace.classList.add('external');
@@ -64,9 +63,7 @@ export function makeAllExternalLinksExternalLinks() {
64
63
  const $linkSpan = document.createElement('span');
65
64
  const $linkText = $linkToReplace.innerHTML;
66
65
  $linkSpan.innerHTML = $linkText;
67
-
68
66
  while ($linkToReplace.firstChild) $linkToReplace.removeChild($linkToReplace.firstChild);
69
-
70
67
  $linkToReplace.appendChild($linkSpan);
71
68
  $linkToReplace.appendChild($linkIndicator);
72
69
  }
@@ -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 mediaCommentThumbnail from './media_comment_thumbnail';
19
20
  export * from './enhance_user_content';
20
21
  export { isPreviewable, loadDocPreview } from './doc_previews';