@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,18 +15,19 @@
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 classnames from 'classnames';
19
20
  import { renderAudio, renderImage, renderLink, renderLinkedImage, renderVideo } from './contentRendering';
20
21
  import { cleanUrl, getAnchorElement, isImageFigure, isOnlyTextSelected } from './contentInsertionUtils';
21
22
  import { mediaPlayerURLFromFile } from './plugins/shared/fileTypeUtils';
22
23
  import { absoluteToRelativeUrl } from '../common/fileUrl';
24
+
23
25
  /** * generic content insertion ** */
26
+
24
27
  // when the editor is hidden, just replace the selected portion of the textarea
25
28
  // with the content. branching is for cross-browser
26
-
27
29
  function replaceTextareaSelection(editor, content) {
28
30
  const element = editor.getElement();
29
-
30
31
  if ('selectionStart' in element) {
31
32
  // mozilla / dom 3.0
32
33
  const before = element.value.substr(0, element.selectionStart);
@@ -41,7 +42,6 @@ function replaceTextareaSelection(editor, content) {
41
42
  element.value += content;
42
43
  }
43
44
  }
44
-
45
45
  export function insertContent(editor, content) {
46
46
  if (editor.isHidden()) {
47
47
  // replaces the textarea selection with the new image. no element returned
@@ -57,66 +57,60 @@ export function insertContent(editor, content) {
57
57
  if (editor.iframeElement) {
58
58
  editor.iframeElement.scrollIntoView();
59
59
  }
60
- }, 100); // there's a bug in tinymce where insertContent calls execCommand('mceInsertContent'),
60
+ }, 100);
61
+ // there's a bug in tinymce where insertContent calls execCommand('mceInsertContent'),
61
62
  // but doesn't correctly forward the second "args" argument. Let's go right for
62
63
  // execCommand
63
64
  // editor.insertContent(content, {skip_focus: true})
64
-
65
65
  editor.execCommand('mceInsertContent', false, content, {
66
66
  skip_focus: true
67
67
  });
68
68
  return editor.selection.getEnd();
69
69
  }
70
70
  }
71
+
71
72
  /** * image insertion ** */
72
73
 
73
74
  function isElemImg(elem) {
74
75
  return elem && elem.nodeName.toLowerCase() === 'img';
75
76
  }
76
-
77
77
  function isElemAnchor(elem) {
78
78
  return elem && elem.nodeName.toLowerCase() === 'a';
79
79
  }
80
+
80
81
  /*
81
82
  check if we should preserve the parent anchor tag. the criteria is pretty
82
83
  strict based on if we have a single image selected with an anchor tag
83
84
  surrounding
84
85
  */
85
-
86
-
87
86
  function shouldPreserveImgAnchor(editor) {
88
87
  const selection = editor.selection;
89
88
  const selectedRange = selection.getRng();
90
89
  return isElemImg(selection.getNode()) && isElemAnchor(selectedRange.startContainer) && selectedRange.startContainer === selectedRange.endContainer;
91
90
  }
92
-
93
91
  export function insertImage(editor, image, canvasOrigin) {
94
92
  let content = '';
95
-
96
93
  if (shouldPreserveImgAnchor(editor)) {
97
94
  content = renderLinkedImage(editor.selection.getRng().startContainer, image, canvasOrigin);
98
95
  } else {
99
96
  // render the image, constraining its size on insertion
100
- const imgNode = editor.selection.getNode(); // apply selected styles only in course/user images
101
-
97
+ const imgNode = editor.selection.getNode();
98
+ // apply selected styles only in course/user images
102
99
  if (isElemImg(imgNode) && !image['data-inst-icon-maker-icon']) {
103
100
  const customStyles = imgNode.style;
104
101
  const customWidth = imgNode.getAttribute('width');
105
102
  const parseStyles = {};
106
-
107
103
  for (let i = 0; i < customStyles.length; ++i) {
108
104
  const cssAttribute = customStyles.item(i);
109
105
  parseStyles[cssAttribute] = customStyles[cssAttribute];
110
106
  }
111
-
112
107
  image.width = customWidth;
113
108
  image.style = parseStyles;
114
109
  }
115
-
116
- content = renderImage({ ...image
110
+ content = renderImage({
111
+ ...image
117
112
  }, canvasOrigin);
118
113
  }
119
-
120
114
  return insertContent(editor, content);
121
115
  }
122
116
  export function insertEquation(editor, latex) {
@@ -124,8 +118,9 @@ export function insertEquation(editor, latex) {
124
118
  const sel = editor.selection.getNode();
125
119
  const imgSz = sel ? parseFloat(editor.dom.doc.defaultView.getComputedStyle(sel).getPropertyValue('font-size')) || 1 : docSz;
126
120
  const scale = imgSz / docSz;
127
- const url = `/equation_images/${encodeURIComponent(encodeURIComponent(latex))}?scale=${scale}`; // if I simply create the html string, xsslint fails jenkins
121
+ const url = `/equation_images/${encodeURIComponent(encodeURIComponent(latex))}?scale=${scale}`;
128
122
 
123
+ // if I simply create the html string, xsslint fails jenkins
129
124
  const img = document.createElement('img');
130
125
  img.setAttribute('alt', `LaTeX: ${latex}`);
131
126
  img.setAttribute('title', latex);
@@ -135,41 +130,38 @@ export function insertEquation(editor, latex) {
135
130
  img.setAttribute('data-ignore-a11y-check', '');
136
131
  return insertContent(editor, img.outerHTML);
137
132
  }
133
+
138
134
  /** * link insertion ** */
139
- // checks if there's an existing anchor containing the cursor
140
135
 
136
+ // checks if there's an existing anchor containing the cursor
141
137
  function currentLink(editor, link) {
142
138
  const cursor = link.selectionDetails && link.selectionDetails.node ? link.selectionDetails.node : editor.selection.getNode(); // This doesn't work in IE 11, but will stop brokeness in other browsers
143
-
144
139
  return editor.dom.getParent(cursor, 'a');
145
- } // checks if the editor has a current selection (vs. just a cursor position)
146
-
140
+ }
147
141
 
142
+ // checks if the editor has a current selection (vs. just a cursor position)
148
143
  function hasSelection(editor) {
149
144
  let selection = editor.selection.getContent();
150
145
  selection = editor.dom.decode(selection);
151
146
  return !!selection && selection !== '';
152
147
  }
153
-
154
148
  export function existingContentToLink(editor, link) {
155
149
  return !editor.isHidden() && (link && (currentLink(editor, link) || !!link.selectedContent) || hasSelection(editor));
156
- } // Parses HTML string with support in old browsers because jQuery's parseHTML was added in 1.8.
150
+ }
157
151
 
152
+ // Parses HTML string with support in old browsers because jQuery's parseHTML was added in 1.8.
158
153
  function parseHTML(htmlString) {
159
154
  const tmp = document.implementation.createHTMLDocument();
160
155
  tmp.body.innerHTML = htmlString.trim();
161
156
  return tmp.body.children;
162
157
  }
163
-
164
158
  function selectionIsImg(editor) {
165
159
  const selection = editor.selection.getContent();
166
160
  return editor.dom.$(parseHTML(selection)).is('img');
167
161
  }
168
-
169
162
  export function existingContentToLinkIsImg(editor) {
170
163
  return !editor.isHidden() && selectionIsImg(editor);
171
164
  }
172
-
173
165
  function decorateLinkWithEmbed(link) {
174
166
  const type = link.embed && link.embed.type;
175
167
  link.class = classnames(link.class, {
@@ -182,34 +174,31 @@ function decorateLinkWithEmbed(link) {
182
174
  inline_disabled: link.embed && link.embed.disableInlinePreview,
183
175
  no_preview: link.embed && link.embed.noPreview
184
176
  });
185
-
186
177
  if (link.embed.type === 'video' || link.embed.type === 'audio') {
187
178
  link.id = `media_comment_${link.embed.id || 'maybe'}`;
188
179
  }
189
180
  }
190
-
191
181
  export function insertLink(editor, link, canvasOrigin) {
192
- const linkAttrs = { ...link
182
+ const linkAttrs = {
183
+ ...link
193
184
  };
194
-
195
185
  if (linkAttrs.embed) {
196
186
  decorateLinkWithEmbed(linkAttrs);
197
187
  delete linkAttrs.embed;
198
188
  }
199
-
200
189
  return insertUndecoratedLink(editor, linkAttrs, canvasOrigin);
201
190
  }
202
-
203
191
  function textForLink(linkProps, editor, anchorElm) {
204
192
  // Some actions (like editing the link text in the link tray)
205
193
  // require an explicit update to the link text
206
- if (linkProps.forceRename) return linkProps.text; // Other actions (link highlighting an existing link and changing
207
- // the linked file) should use the anchor text if present
194
+ if (linkProps.forceRename) return linkProps.text;
208
195
 
196
+ // Other actions (link highlighting an existing link and changing
197
+ // the linked file) should use the anchor text if present
209
198
  return getAnchorText(editor.selection, anchorElm) || linkProps.text;
210
- } // link edit/create logic based on tinymce/plugins/link/plugin.ts
211
-
199
+ }
212
200
 
201
+ // link edit/create logic based on tinymce/plugins/link/plugin.ts
213
202
  function insertUndecoratedLink(editor, linkProps, canvasOrigin) {
214
203
  const selectedElm = editor.selection.getNode();
215
204
  const anchorElm = getAnchorElement(editor, selectedElm);
@@ -218,8 +207,8 @@ function insertUndecoratedLink(editor, linkProps, canvasOrigin) {
218
207
  format: 'text'
219
208
  });
220
209
  const onlyText = isOnlyTextSelected(selectedContent);
221
- const linkText = onlyText && textForLink(linkProps, editor, anchorElm); // only keep the props we want as attributes on the <a>
222
-
210
+ const linkText = onlyText && textForLink(linkProps, editor, anchorElm);
211
+ // only keep the props we want as attributes on the <a>
223
212
  const linkAttrs = {
224
213
  id: linkProps.id,
225
214
  href: absoluteToRelativeUrl(cleanUrl(linkProps.href || linkProps.url), canvasOrigin),
@@ -230,11 +219,9 @@ function insertUndecoratedLink(editor, linkProps, canvasOrigin) {
230
219
  'data-course-type': linkProps['data-course-type'],
231
220
  'data-published': linkProps['data-published']
232
221
  };
233
-
234
222
  if (linkAttrs.target === '_blank') {
235
223
  linkAttrs.rel = 'noopener noreferrer';
236
224
  }
237
-
238
225
  if (anchorElm && !editor.selection.isCollapsed()) {
239
226
  updateLink(editor, anchorElm, linkText, linkAttrs);
240
227
  } else if (selectedContent) {
@@ -246,26 +233,21 @@ function insertUndecoratedLink(editor, linkProps, canvasOrigin) {
246
233
  } else {
247
234
  createLink(editor, selectedElm, linkText, linkAttrs, canvasOrigin);
248
235
  }
249
-
250
236
  return editor.selection.getEnd(); // this will be the newly created or updated content
251
237
  }
252
-
253
238
  function getAnchorText(selection, anchorElm) {
254
239
  return anchorElm ? anchorElm.innerText : selection.getContent({
255
240
  format: 'text'
256
241
  });
257
242
  }
258
-
259
243
  function updateLink(editor, anchorElm, text, linkAttrs) {
260
244
  if (text && anchorElm.innerText !== text) {
261
245
  anchorElm.innerText = text;
262
246
  }
263
-
264
247
  editor.dom.setAttribs(anchorElm, linkAttrs);
265
248
  editor.selection.select(anchorElm);
266
249
  editor.undoManager.add();
267
250
  }
268
-
269
251
  function createLink(editor, selectedElm, text, linkAttrs, canvasOrigin) {
270
252
  if (isImageFigure(selectedElm)) {
271
253
  linkImageFigure(editor, selectedElm, linkAttrs, canvasOrigin);
@@ -277,17 +259,15 @@ function createLink(editor, selectedElm, text, linkAttrs, canvasOrigin) {
277
259
  editor.execCommand('mceInsertLink', false, linkAttrs);
278
260
  }
279
261
  }
280
-
281
262
  function linkImageFigure(editor, fig, attrs, canvasOrigin) {
282
263
  const img = fig.tagName === 'IMG' ? fig : editor.dom.select('img', fig)[0];
283
-
284
264
  if (img) {
285
265
  const a = renderLink(attrs, img, canvasOrigin);
286
266
  img.parentNode.insertBefore(a, img);
287
267
  }
288
268
  }
289
- /* ** video insertion ** */
290
269
 
270
+ /* ** video insertion ** */
291
271
 
292
272
  export function insertVideo(editor, video, canvasOrigin) {
293
273
  return insertMedia(editor, video, renderVideo, canvasOrigin);
@@ -295,30 +275,27 @@ export function insertVideo(editor, video, canvasOrigin) {
295
275
  export function insertAudio(editor, audio, canvasOrigin) {
296
276
  return insertMedia(editor, audio, renderAudio, canvasOrigin);
297
277
  }
298
-
299
278
  function insertMedia(editor, media, renderMedia, canvasOrigin) {
300
279
  const src = mediaPlayerURLFromFile(media, canvasOrigin);
301
-
302
280
  if (editor.selection.isCollapsed()) {
303
- var _result;
304
-
305
- let result = insertContent(editor, renderMedia(media, canvasOrigin)); // for some reason, editor.selection.getEnd() returned from
281
+ let result = insertContent(editor, renderMedia(media, canvasOrigin));
282
+ // for some reason, editor.selection.getEnd() returned from
306
283
  // insertContent is parent paragraph when inserting the
307
284
  // media iframe. Look for the iframe with the right
308
285
  // src attribute. (Aside: tinymce strips the id or data-*
309
286
  // attributes from the iframe, that's why we can't look for those)
287
+ result = result.querySelector(`iframe[src="${src}"]`);
310
288
 
311
- result = result.querySelector(`iframe[src="${src}"]`); // When the iframe is inserted, it doesn't allow the media to play
289
+ // When the iframe is inserted, it doesn't allow the media to play
312
290
  // because the wrapping span captures the click events. Setting
313
291
  // contentEditable to false disables this behavior.
314
-
315
- if ((_result = result) !== null && _result !== void 0 && _result.parentElement) {
292
+ if (result?.parentElement) {
316
293
  editor.dom.setAttrib(result.parentElement, 'contenteditable', false);
317
294
  }
318
-
319
295
  return result;
320
296
  } else {
321
- return insertLink(editor, { ...media,
297
+ return insertLink(editor, {
298
+ ...media,
322
299
  href: src
323
300
  }, canvasOrigin);
324
301
  }
@@ -34,32 +34,30 @@
34
34
  */
35
35
  export function cleanUrl(input) {
36
36
  let url = input;
37
-
38
37
  if (input) {
39
38
  if (input.match(/@/) && !input.match(/\//) && !input.match(/^mailto:/)) {
40
39
  url = 'mailto:' + input;
41
40
  } else if (!input.match(/^\w+:\/\//) && !input.match(/^(?:mailto|skype|tel):/) && !input.match(/^\//)) {
42
41
  url = 'http://' + input;
43
42
  }
44
-
45
43
  if (url.indexOf('@') != -1 && url.indexOf('mailto:') != 0 && !url.match(/^http/)) {
46
44
  url = 'mailto:' + url;
47
45
  }
48
46
  }
49
-
50
47
  return url;
51
- } // given the current selection, find the containing anchor
48
+ }
52
49
 
50
+ // given the current selection, find the containing anchor
53
51
  export function getAnchorElement(editor, selectedElm) {
54
52
  selectedElm = selectedElm || editor.selection.getNode();
55
-
56
53
  if (isImageFigure(selectedElm)) {
57
54
  return editor.dom.select('a[href]', selectedElm)[0];
58
55
  } else {
59
56
  return editor.dom.getParent(selectedElm, 'a[href]');
60
57
  }
61
- } // is the selection only text, or are other elements selected
58
+ }
62
59
 
60
+ // is the selection only text, or are other elements selected
63
61
  const d = document.createElement('div');
64
62
  export function isOnlyTextSelected(html) {
65
63
  // this regex-based code is lifted from tinymce's link plugin, but I didn't like it.
@@ -76,10 +74,10 @@ export function isOKToLink(html) {
76
74
  if (/(?:<(iframe|audio|video)|data-placeholder-for)/.test(html)) {
77
75
  return false;
78
76
  }
79
-
80
77
  return true;
81
78
  }
82
79
  export function isImageFigure(elm) {
83
- return elm && elm.nodeName === 'FIGURE' && /\bimage\b/i.test(elm.className) // (elm.nodeName === 'IMG' || (elm.nodeName === 'FIGURE' && /\bimage\b/i.test(elm.className)))
80
+ return elm && elm.nodeName === 'FIGURE' && /\bimage\b/i.test(elm.className)
81
+ // (elm.nodeName === 'IMG' || (elm.nodeName === 'FIGURE' && /\bimage\b/i.test(elm.className)))
84
82
  ;
85
83
  }
@@ -15,6 +15,7 @@
15
15
  * You should have received a copy of the GNU Affero General Public License along
16
16
  * with this program. If not, see <http://www.gnu.org/licenses/>.
17
17
  */
18
+
18
19
  import React from 'react';
19
20
  import { renderToStaticMarkup } from 'react-dom/server';
20
21
  import { cleanUrl } from './contentInsertionUtils';
@@ -23,39 +24,38 @@ import { VIDEO_SIZE_DEFAULT, AUDIO_PLAYER_SIZE } from './plugins/instructure_rec
23
24
  import { mediaPlayerURLFromFile } from './plugins/shared/fileTypeUtils';
24
25
  import { prepEmbedSrc, prepLinkedSrc, absoluteToRelativeUrl } from '../common/fileUrl';
25
26
  export function renderLink(data, contents, canvasOrigin) {
26
- const linkAttrs = { ...data
27
+ const linkAttrs = {
28
+ ...data
27
29
  };
28
30
  linkAttrs.href = prepLinkedSrc(linkAttrs.href || linkAttrs.url);
29
31
  delete linkAttrs.url;
30
-
31
32
  if (linkAttrs.href) {
32
33
  linkAttrs.href = absoluteToRelativeUrl(cleanUrl(linkAttrs.href), canvasOrigin);
33
34
  }
34
-
35
35
  linkAttrs.title = linkAttrs.title || formatMessage('Link');
36
36
  const children = contents || linkAttrs.text || linkAttrs.title;
37
37
  delete linkAttrs.selectionDetails;
38
38
  delete linkAttrs.text;
39
39
  linkAttrs.className = linkAttrs.class;
40
- delete linkAttrs.class; // renderToStaticMarkup isn't happy with bool attributes
40
+ delete linkAttrs.class;
41
41
 
42
+ // renderToStaticMarkup isn't happy with bool attributes
42
43
  Object.keys(linkAttrs).forEach(attr => {
43
44
  if (typeof linkAttrs[attr] === 'boolean') linkAttrs[attr] = linkAttrs[attr].toString();
44
45
  });
45
- return renderToStaticMarkup( /*#__PURE__*/React.createElement("a", linkAttrs, children));
46
+ return renderToStaticMarkup(/*#__PURE__*/React.createElement("a", linkAttrs, children));
46
47
  }
47
48
  export function renderLinkedImage(linkElem, image, canvasOrigin) {
48
49
  const linkHref = linkElem.getAttribute('href');
49
50
  image.href = prepEmbedSrc(image.href, canvasOrigin);
50
- return renderToStaticMarkup( /*#__PURE__*/React.createElement("a", {
51
+ return renderToStaticMarkup(/*#__PURE__*/React.createElement("a", {
51
52
  href: absoluteToRelativeUrl(linkHref, canvasOrigin),
52
53
  "data-mce-href": linkHref
53
54
  }, constructJSXImageElement(image, canvasOrigin, {
54
55
  doNotLink: true
55
56
  })));
56
57
  }
57
- export function constructJSXImageElement(image, canvasOrigin) {
58
- let opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
58
+ export function constructJSXImageElement(image, canvasOrigin, opts = {}) {
59
59
  const {
60
60
  href,
61
61
  url,
@@ -69,22 +69,19 @@ export function constructJSXImageElement(image, canvasOrigin) {
69
69
  } = image;
70
70
  const imageSrc = absoluteToRelativeUrl(href || url || src, canvasOrigin);
71
71
  let altText = alt_text || title || display_name || '';
72
-
73
72
  if (isDecorativeImage) {
74
73
  altText = '';
75
74
  otherAttributes.role = 'presentation';
76
75
  }
77
-
78
76
  delete otherAttributes.contextType; // react doesn't like these
79
-
80
77
  delete otherAttributes.contextId;
81
78
  const ret = /*#__PURE__*/React.createElement("img", Object.assign({
82
79
  alt: altText,
83
80
  src: imageSrc,
84
81
  width: image.width,
85
- height: image.height
82
+ height: image.height,
83
+ loading: "lazy"
86
84
  }, otherAttributes));
87
-
88
85
  if (link && !opts.doNotLink) {
89
86
  return /*#__PURE__*/React.createElement("a", {
90
87
  href: absoluteToRelativeUrl(link, canvasOrigin),
@@ -92,7 +89,6 @@ export function constructJSXImageElement(image, canvasOrigin) {
92
89
  rel: "noopener noreferrer"
93
90
  }, ret);
94
91
  }
95
-
96
92
  return ret;
97
93
  }
98
94
  export function renderImage(image, canvasOrigin, opts) {
@@ -107,6 +103,7 @@ export function renderVideo(video, canvasOrigin) {
107
103
  allowfullscreen
108
104
  data-media-id="${getMediaId(video)}"
109
105
  data-media-type="video"
106
+ loading="lazy"
110
107
  src="${src}"
111
108
  style="width:${VIDEO_SIZE_DEFAULT.width};height:${VIDEO_SIZE_DEFAULT.height};display:inline-block;"
112
109
  title="${formatMessage('Video player for {title}', {
@@ -120,6 +117,7 @@ export function renderAudio(audio, canvasOrigin) {
120
117
  <iframe
121
118
  data-media-id="${getMediaId(audio)}"
122
119
  data-media-type="audio"
120
+ loading="lazy"
123
121
  src="${src}"
124
122
  style="width:${AUDIO_PLAYER_SIZE.width};height:${AUDIO_PLAYER_SIZE.height};display:inline-block;"
125
123
  title="${formatMessage('Audio player for {title}', {
@@ -132,12 +130,10 @@ export function getMediaId(media) {
132
130
  return media.media_id || media.media_entry_id || media.id || media.file_id;
133
131
  }
134
132
  export function updateImage(editor, img, attrs) {
135
- var _editor$rceWrapper;
136
-
137
133
  // Workaround: When passing empty string to editor.dom.setAttribs it removes the attribute
138
134
  img.setAttribute('alt', attrs.altText);
139
135
  editor.dom.setAttribs(img, {
140
- src: absoluteToRelativeUrl(attrs.url, (_editor$rceWrapper = editor.rceWrapper) === null || _editor$rceWrapper === void 0 ? void 0 : _editor$rceWrapper.getCanvasUrl()),
136
+ src: absoluteToRelativeUrl(attrs.url, editor.rceWrapper?.getCanvasUrl()),
141
137
  role: attrs.isDecorativeImage ? 'presentation' : null,
142
138
  width: attrs.appliedWidth,
143
139
  height: attrs.appliedHeight
@@ -15,4 +15,5 @@
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
  export const VIEW_CHANGE = 'ViewChange'; // Emitted when the RCE view changes (example: WYSIWYG -> RAW)
@@ -15,8 +15,17 @@
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
  // if a locale is absent, we don't expect to receive it from canvas, but we'll
19
20
  // treat it the same as how we explicitly use english for Maori.
21
+
22
+ /**
23
+ * Mapping of locales to their corresponding TinyMCE language codes.
24
+ * If a locale is absent, we don't expect to receive it from Canvas,
25
+ * but we'll treat it the same as how we explicitly use English for Maori.
26
+ *
27
+ * @type {Object<string, string | undefined>}
28
+ */
20
29
  const mapping = {
21
30
  ar: 'ar_SA',
22
31
  bg: 'bg_BG',
@@ -26,7 +35,7 @@ const mapping = {
26
35
  da: 'da',
27
36
  de: 'de',
28
37
  el: 'el',
29
- // returning undefined tell tinymce to use it's default (en) strings
38
+ // returning undefined tells tinymce to use its default (en) strings
30
39
  en: undefined,
31
40
  // tinymce doesn't have Australian strings, so just pretend it's en-GB
32
41
  'en-AU': 'en_GB',
@@ -76,28 +85,31 @@ const mapping = {
76
85
  'zh-HK': 'zh_TW',
77
86
  'zh-Hans': 'zh_CN',
78
87
  'zh-Hant': 'zh_TW'
79
- }; // still expose it as a method for consistent usage and in case we ever have to
80
- // add special casing or null interpretation in the future
88
+ };
81
89
 
90
+ /**
91
+ * Function to return the corresponding TinyMCE language code for a given locale.
92
+ * If the locale is not provided, it will return the default language (English).
93
+ * If the locale contains underscores, they are replaced with hyphens for compatibility.
94
+ * If the locale contains a custom variant (e.g., -x-), the base language is used for mapping.
95
+ *
96
+ * @param {string} [locale] - The locale string.
97
+ * @returns {string | undefined} The corresponding TinyMCE language code, or undefined if not found.
98
+ */
82
99
  function editorLanguage(locale) {
83
100
  if (!locale) {
84
101
  return mapping.en;
85
102
  }
86
-
87
103
  if (locale.match('_')) {
88
104
  locale = locale.replace('_', '-');
89
- } // tinymce won't know about custom locales, use the base one for mapping
90
-
91
-
105
+ }
106
+ // tinymce won't know about custom locales, use the base one for mapping
92
107
  if (locale.match('-x-')) {
93
108
  locale = locale.split('-x-')[0];
94
109
  }
95
-
96
110
  if (mapping[locale]) {
97
111
  return mapping[locale];
98
112
  }
99
-
100
113
  return mapping[locale.split('-')[0]];
101
114
  }
102
-
103
- module.exports = editorLanguage;
115
+ exports.editorLanguage = editorLanguage;
@@ -15,12 +15,13 @@
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
- import offset from 'bloody-offset'; // the editor's iframe
19
18
 
19
+ import offset from 'bloody-offset';
20
+
21
+ // the editor's iframe
20
22
  function editorIframe(editor) {
21
23
  return editor.getContainer().querySelector('iframe');
22
24
  }
23
-
24
25
  function box(el) {
25
26
  const b = el.getBoundingClientRect();
26
27
  return {
@@ -29,14 +30,13 @@ function box(el) {
29
30
  width: b.right - b.left,
30
31
  height: b.bottom - b.top
31
32
  };
32
- } //
33
+ }
34
+
35
+ //
33
36
  // the shape of the target's sillhouette on the editor's container. have to
34
37
  // subtract out the iframe's scroll since the target's position is relative to
35
38
  // the iframe's _document_, not its visible window.
36
-
37
-
38
- export default function indicatorRegion(editor, target) {
39
- let offsetFn = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : offset;
39
+ export default function indicatorRegion(editor, target, offsetFn = offset) {
40
40
  const iframe = editorIframe(editor);
41
41
  const outerShape = offsetFn(iframe);
42
42
  const innerShape = box(target);
@@ -15,10 +15,12 @@
15
15
  * You should have received a copy of the GNU Affero General Public License along
16
16
  * with this program. If not, see <http://www.gnu.org/licenses/>.
17
17
  */
18
- import { getLocaleList } from '../getTranslations'; // keys = "qualified" locales old canvas sent, values = corresponding standard
18
+
19
+ import { getLocaleList } from '../getTranslations';
20
+
21
+ // keys = "qualified" locales old canvas sent, values = corresponding standard
19
22
  // locales that canvas now sends. old locales absent from this mapping (e.g.
20
23
  // pt-BR) didn't change.
21
-
22
24
  const mapping = {
23
25
  fa: 'fa-IR',
24
26
  uk: 'uk-UA',
@@ -27,7 +29,6 @@ const mapping = {
27
29
  };
28
30
  export default function normalizeLocale(locale) {
29
31
  const recognized = getLocaleList();
30
-
31
32
  if (!locale) {
32
33
  // default to english
33
34
  return 'en';
@@ -42,6 +43,7 @@ export default function normalizeLocale(locale) {
42
43
  locale = locale.split('-x-')[0];
43
44
  return normalizeLocale(locale);
44
45
  } else if (recognized.indexOf(locale.split('-')[0]) >= 0) {
46
+ // pass through base locale if recognized
45
47
  return locale.split('-')[0];
46
48
  } else {
47
49
  // default to english for unrecognized locales
@@ -15,15 +15,17 @@
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 wrapInitCb from './wrapInitCb';
19
- export default function (props, tinymce) {
20
- const initialEditorOptions = props.editorOptions(tinymce);
21
- const editorOptions = wrapInitCb(props.mirroredAttrs, initialEditorOptions);
22
- return { // other props, including overrides
20
+ export default function normalizeProps(props, tinyMCE) {
21
+ const initialEditorOptions = props.editorOptions ? props.editorOptions(tinyMCE) : {};
22
+ const editorOptions = wrapInitCb(props.mirroredAttrs || {}, initialEditorOptions);
23
+ return {
24
+ // other props, including overrides
23
25
  ...props,
24
26
  // enforced values, in addition to props and cannot be overridden by
25
27
  // props
26
28
  editorOptions,
27
- tinymce
29
+ tinymce: tinyMCE
28
30
  };
29
31
  }