@instructure/canvas-rce 5.14.1 → 5.14.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (481) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/DEVELOPMENT.md +1 -1
  3. package/README.md +0 -8
  4. package/__tests__/common/indicate.test.js +84 -0
  5. package/__tests__/common/mimeClass.test.js +85 -0
  6. package/__tests__/module/contentInsertionUtils.test.js +52 -0
  7. package/__tests__/module/indicatorRegion.test.js +75 -0
  8. package/__tests__/module/normalizeLocale.test.js +46 -0
  9. package/__tests__/module/normalizeProps.test.js +51 -0
  10. package/__tests__/module/sanitizePlugins.test.js +48 -0
  11. package/__tests__/module/wrapInitCb.test.js +56 -0
  12. package/__tests__/rcs/api.test.js +819 -0
  13. package/{mocha-reporter-config.js → __tests__/sidebar/actions/all_files.test.js} +10 -9
  14. package/__tests__/sidebar/actions/data.test.js +196 -0
  15. package/__tests__/sidebar/actions/utils.js +44 -0
  16. package/{es/rce/plugins/shared/__mocks__/screenfull.js → __tests__/sidebar/reducers/all_files.test.js} +10 -6
  17. package/babel.config.js +3 -1
  18. package/es/bridge/Bridge.js +8 -56
  19. package/es/bridge/index.js +1 -0
  20. package/es/canvasFileBrowser/FileBrowser.js +12 -59
  21. package/es/canvasFileBrowser/en-US.js +3 -6
  22. package/es/common/FlashAlert.js +7 -28
  23. package/es/common/browser.js +4 -2
  24. package/es/common/fileUrl.js +104 -59
  25. package/es/common/incremental-loading/LoadMoreButton.js +1 -0
  26. package/es/common/incremental-loading/LoadingIndicator.js +1 -2
  27. package/es/common/incremental-loading/LoadingStatus.js +1 -2
  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 +15 -8
  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 +17 -28
  36. package/es/enhance-user-content/enhance_user_content.js +28 -60
  37. package/es/enhance-user-content/external_links.js +5 -8
  38. package/es/enhance-user-content/index.js +1 -0
  39. package/es/enhance-user-content/instructure_helper.js +12 -34
  40. package/es/enhance-user-content/jqueryish_funcs.js +8 -11
  41. package/es/enhance-user-content/mathml.js +35 -82
  42. package/es/enhance-user-content/media_comment_thumbnail.js +5 -17
  43. package/es/format-message.js +3 -4
  44. package/es/getThemeVars.js +8 -6
  45. package/es/getTranslations.js +1 -78
  46. package/es/index.js +3 -1
  47. package/es/rce/AlertMessageArea.js +1 -1
  48. package/es/rce/DraggingBlocker.js +4 -2
  49. package/es/rce/KeyboardShortcutModal.js +1 -0
  50. package/es/rce/RCE.js +12 -11
  51. package/es/rce/RCEGlobals.js +12 -10
  52. package/es/rce/RCEVariants.js +27 -10
  53. package/es/rce/RCEWrapper.js +167 -386
  54. package/es/rce/RCEWrapperProps.js +8 -3
  55. package/es/rce/RceHtmlEditor.js +5 -8
  56. package/es/rce/ResizeHandle.js +3 -8
  57. package/es/rce/RestoreAutoSaveModal.js +1 -2
  58. package/es/rce/ShowOnFocusButton/index.js +0 -6
  59. package/es/rce/StatusBar.js +8 -37
  60. package/es/rce/alertHandler.js +1 -4
  61. package/es/rce/contentInsertion.js +35 -57
  62. package/es/rce/contentInsertionUtils.js +6 -8
  63. package/es/rce/contentRendering.js +7 -12
  64. package/es/rce/customEvents.js +1 -0
  65. package/es/rce/editorLanguage.js +22 -10
  66. package/es/rce/indicatorRegion.js +6 -5
  67. package/es/rce/normalizeLocale.js +5 -3
  68. package/es/rce/normalizeProps.js +3 -1
  69. package/es/rce/plugins/instructure-ui-icons/plugin.js +21 -3
  70. package/es/rce/plugins/instructure_color/clickCallback.js +84 -0
  71. package/es/rce/plugins/instructure_color/components/ColorPicker.js +299 -0
  72. package/es/rce/plugins/instructure_color/components/ColorPopup.js +68 -0
  73. package/es/rce/plugins/instructure_color/components/colorUtils.js +60 -0
  74. package/es/rce/plugins/instructure_color/plugin.js +40 -0
  75. package/es/rce/plugins/instructure_condensed_buttons/core/ListUtils.js +10 -3
  76. package/es/rce/plugins/instructure_condensed_buttons/plugin.js +1 -0
  77. package/es/rce/plugins/instructure_condensed_buttons/ui/alignment-button.js +1 -2
  78. package/es/rce/plugins/instructure_condensed_buttons/ui/directionality-button.js +3 -2
  79. package/es/rce/plugins/instructure_condensed_buttons/ui/indent-outdent-button.js +1 -0
  80. package/es/rce/plugins/instructure_condensed_buttons/ui/list-button.js +22 -15
  81. package/es/rce/plugins/instructure_condensed_buttons/ui/subscript-superscript-button.js +1 -2
  82. package/es/rce/plugins/instructure_documents/clickCallback.js +1 -0
  83. package/es/rce/plugins/instructure_documents/components/DocumentsPanel.js +1 -9
  84. package/es/rce/plugins/instructure_documents/components/Link.js +3 -18
  85. package/es/rce/plugins/instructure_documents/plugin.js +7 -14
  86. package/es/rce/plugins/instructure_equation/EquationEditorModal/advancedOnlySyntax.js +4 -2
  87. package/es/rce/plugins/instructure_equation/EquationEditorModal/advancedPreference.js +1 -2
  88. package/es/rce/plugins/instructure_equation/EquationEditorModal/index.js +12 -29
  89. package/es/rce/plugins/instructure_equation/EquationEditorModal/latexTextareaUtil.js +11 -12
  90. package/es/rce/plugins/instructure_equation/EquationEditorModal/parseLatex.js +4 -3
  91. package/es/rce/plugins/instructure_equation/EquationEditorModal/styles.js +4 -2
  92. package/es/rce/plugins/instructure_equation/EquationEditorToolbar/buttons.js +13 -7
  93. package/es/rce/plugins/instructure_equation/EquationEditorToolbar/index.js +4 -7
  94. package/es/rce/plugins/instructure_equation/MathIcon/index.js +1 -1
  95. package/es/rce/plugins/instructure_equation/MathIcon/svgs.js +1 -1
  96. package/es/rce/plugins/instructure_equation/clickCallback.js +2 -5
  97. package/es/rce/plugins/instructure_equation/mathlive/index.js +1 -1
  98. package/es/rce/plugins/instructure_equation/plugin.js +7 -10
  99. package/es/rce/plugins/instructure_fullscreen/plugin.js +3 -6
  100. package/es/rce/plugins/instructure_html_view/clickCallback.js +1 -0
  101. package/es/rce/plugins/instructure_html_view/plugin.js +5 -4
  102. package/es/rce/plugins/instructure_icon_maker/clickCallback.js +2 -4
  103. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ColorSection.js +1 -2
  104. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/CreateIconMakerForm.js +1 -0
  105. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/Footer.js +1 -0
  106. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/Group.js +1 -0
  107. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/Header.js +1 -2
  108. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/Course.js +25 -22
  109. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/ImageOptions.js +7 -11
  110. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/ImageSection.js +27 -23
  111. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/ModeSelect.js +5 -4
  112. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/MultiColor/index.js +11 -9
  113. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/MultiColor/svg.js +1 -0
  114. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/SVGList.js +5 -4
  115. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/SVGThumbnail.js +1 -3
  116. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/SingleColor/index.js +7 -7
  117. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/SingleColor/svg.js +1 -0
  118. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/Upload.js +27 -20
  119. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/index.js +1 -0
  120. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/propTypes.js +1 -0
  121. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/utils.js +1 -0
  122. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/Preview.js +4 -4
  123. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ShapeSection.js +1 -2
  124. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/TextSection.js +1 -5
  125. package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/index.js +1 -0
  126. package/es/rce/plugins/instructure_icon_maker/components/IconMakerTray.js +18 -33
  127. package/es/rce/plugins/instructure_icon_maker/components/SavedIconMakerList.js +4 -4
  128. package/es/rce/plugins/instructure_icon_maker/plugin.js +10 -14
  129. package/es/rce/plugins/instructure_icon_maker/reducers/imageSection.js +37 -38
  130. package/es/rce/plugins/instructure_icon_maker/reducers/svgSettings.js +24 -24
  131. package/es/rce/plugins/instructure_icon_maker/registerEditToolbar.js +1 -3
  132. package/es/rce/plugins/instructure_icon_maker/svg/constants.js +4 -3
  133. package/es/rce/plugins/instructure_icon_maker/svg/font.js +3 -1
  134. package/es/rce/plugins/instructure_icon_maker/svg/image.js +69 -83
  135. package/es/rce/plugins/instructure_icon_maker/svg/index.js +11 -15
  136. package/es/rce/plugins/instructure_icon_maker/svg/metadata.js +1 -0
  137. package/es/rce/plugins/instructure_icon_maker/svg/settings.js +32 -39
  138. package/es/rce/plugins/instructure_icon_maker/svg/shape.js +1 -49
  139. package/es/rce/plugins/instructure_icon_maker/svg/text.js +7 -92
  140. package/es/rce/plugins/instructure_icon_maker/svg/utils.js +1 -7
  141. package/es/rce/plugins/instructure_icon_maker/utils/IconMakerClose.js +2 -6
  142. package/es/rce/plugins/instructure_icon_maker/utils/IconMakerFormHasChanges.js +1 -15
  143. package/es/rce/plugins/instructure_icon_maker/utils/addIconMakerAttributes.js +3 -4
  144. package/es/rce/plugins/instructure_icon_maker/utils/iconValidation.js +1 -1
  145. package/es/rce/plugins/instructure_icon_maker/utils/iconsLabels.js +1 -0
  146. package/es/rce/plugins/instructure_icon_maker/utils/useDebouncedValue.js +12 -13
  147. package/es/rce/plugins/instructure_image/ImageEmbedOptions.js +6 -24
  148. package/es/rce/plugins/instructure_image/ImageList/Image.js +1 -6
  149. package/es/rce/plugins/instructure_image/ImageList/index.js +1 -2
  150. package/es/rce/plugins/instructure_image/ImageOptionsTray/TrayController.js +7 -27
  151. package/es/rce/plugins/instructure_image/ImageOptionsTray/index.js +3 -16
  152. package/es/rce/plugins/instructure_image/Images/index.js +1 -3
  153. package/es/rce/plugins/instructure_image/clickCallback.js +1 -0
  154. package/es/rce/plugins/instructure_image/plugin.js +13 -18
  155. package/es/rce/plugins/instructure_links/clickCallback.js +1 -0
  156. package/es/rce/plugins/instructure_links/components/AccordionSection.js +1 -0
  157. package/es/rce/plugins/instructure_links/components/CollectionPanel.js +1 -3
  158. package/es/rce/plugins/instructure_links/components/Link.js +7 -19
  159. package/es/rce/plugins/instructure_links/components/LinkOptionsDialog/LinkOptionsDialogController.js +1 -21
  160. package/es/rce/plugins/instructure_links/components/LinkOptionsDialog/index.js +1 -4
  161. package/es/rce/plugins/instructure_links/components/LinkOptionsTray/LinkOptionsTrayController.js +3 -20
  162. package/es/rce/plugins/instructure_links/components/LinkOptionsTray/index.js +1 -12
  163. package/es/rce/plugins/instructure_links/components/LinkSet.js +4 -20
  164. package/es/rce/plugins/instructure_links/components/LinksPanel.js +1 -2
  165. package/es/rce/plugins/instructure_links/components/NavigationPanel.js +7 -9
  166. package/es/rce/plugins/instructure_links/components/NoResults.js +1 -7
  167. package/es/rce/plugins/instructure_links/plugin.js +17 -40
  168. package/es/rce/plugins/instructure_links/validateURL.js +81 -36
  169. package/es/rce/plugins/instructure_media_embed/clickCallback.js +2 -5
  170. package/es/rce/plugins/instructure_media_embed/components/Embed.js +1 -0
  171. package/es/rce/plugins/instructure_media_embed/plugin.js +7 -3
  172. package/es/rce/plugins/instructure_paste/pasteMenuCommand.js +1 -5
  173. package/es/rce/plugins/instructure_paste/plugin.js +27 -29
  174. package/es/rce/plugins/instructure_rce_external_tools/ExternalToolsEnv.js +14 -53
  175. package/es/rce/plugins/instructure_rce_external_tools/RceToolWrapper.js +21 -49
  176. package/es/rce/plugins/instructure_rce_external_tools/components/ExternalToolDialog/ExternalToolDialog.js +11 -42
  177. package/es/rce/plugins/instructure_rce_external_tools/components/ExternalToolDialog/ExternalToolDialogModal.js +1 -2
  178. package/es/rce/plugins/instructure_rce_external_tools/components/ExternalToolDialog/ExternalToolDialogTray.js +1 -1
  179. package/es/rce/plugins/instructure_rce_external_tools/components/ExternalToolSelectionDialog/ExternalToolSelectionDialog.js +2 -10
  180. package/es/rce/plugins/instructure_rce_external_tools/components/ExternalToolSelectionDialog/ExternalToolSelectionItem.js +1 -2
  181. package/es/rce/plugins/instructure_rce_external_tools/components/util/ExpandoText.js +1 -0
  182. package/es/rce/plugins/instructure_rce_external_tools/components/util/ToolLaunchIframe.js +2 -1
  183. package/es/rce/{__mocks__/_mockStudioPlayer.js → plugins/instructure_rce_external_tools/constants.js} +11 -3
  184. package/es/rce/plugins/instructure_rce_external_tools/dialog-helper.js +19 -4
  185. package/es/rce/plugins/instructure_rce_external_tools/helpers/tags.js +0 -2
  186. package/es/rce/plugins/instructure_rce_external_tools/jquery/jquery.dropdownList.js +130 -136
  187. package/es/rce/plugins/instructure_rce_external_tools/lti11-content-items/RceLti11ContentItem.js +100 -95
  188. package/es/rce/plugins/instructure_rce_external_tools/lti13-content-items/Lti13ContentItemJson.js +1 -0
  189. package/es/rce/plugins/instructure_rce_external_tools/lti13-content-items/RceLti13ContentItem.js +2 -19
  190. package/es/rce/plugins/instructure_rce_external_tools/lti13-content-items/models/BaseLinkContentItem.js +1 -14
  191. package/es/rce/plugins/instructure_rce_external_tools/lti13-content-items/models/HtmlFragmentContentItem.js +1 -6
  192. package/es/rce/plugins/instructure_rce_external_tools/lti13-content-items/models/ImageContentItem.js +1 -9
  193. package/es/rce/plugins/instructure_rce_external_tools/lti13-content-items/models/LinkContentItem.js +1 -1
  194. package/es/rce/plugins/instructure_rce_external_tools/lti13-content-items/models/ResourceLinkContentItem.js +3 -5
  195. package/es/rce/plugins/instructure_rce_external_tools/lti13-content-items/processEditorContentItems.js +18 -10
  196. package/es/rce/plugins/instructure_rce_external_tools/lti13-content-items/rceLti13ContentItemFromJson.js +4 -4
  197. package/es/rce/plugins/instructure_rce_external_tools/plugin.js +7 -16
  198. package/es/rce/plugins/instructure_rce_external_tools/util/addParentFrameContextToUrl.js +1 -1
  199. package/es/rce/plugins/instructure_record/AudioOptionsTray/TrayController.js +1 -25
  200. package/es/rce/plugins/instructure_record/AudioOptionsTray/index.js +1 -4
  201. package/es/rce/plugins/instructure_record/MediaPanel/index.js +1 -9
  202. package/es/rce/plugins/instructure_record/VideoOptionsTray/TrayController.js +8 -51
  203. package/es/rce/plugins/instructure_record/VideoOptionsTray/index.js +4 -17
  204. package/es/rce/plugins/instructure_record/clickCallback.js +7 -15
  205. package/es/rce/plugins/instructure_record/mediaTranslations.js +1 -0
  206. package/es/rce/plugins/instructure_record/plugin.js +11 -18
  207. package/es/rce/plugins/instructure_search_and_replace/clickCallback.js +2 -5
  208. package/es/rce/plugins/instructure_search_and_replace/components/FindReplaceTray.js +20 -35
  209. package/es/rce/plugins/instructure_search_and_replace/components/FindReplaceTrayController.js +3 -18
  210. package/es/rce/plugins/instructure_search_and_replace/getSelectionContext.js +2 -9
  211. package/es/rce/plugins/instructure_search_and_replace/plugin.js +1 -3
  212. package/es/rce/plugins/instructure_studio_media_options/plugin.js +1 -1
  213. package/es/rce/plugins/instructure_wordcount/clickCallback.js +2 -5
  214. package/es/rce/plugins/instructure_wordcount/components/WordCountModal.js +1 -4
  215. package/es/rce/plugins/instructure_wordcount/plugin.js +1 -0
  216. package/es/rce/plugins/instructure_wordcount/utils/countContent.js +1 -8
  217. package/es/rce/plugins/instructure_wordcount/utils/tableContent.js +1 -0
  218. package/es/rce/plugins/shared/CanvasContentTray.js +22 -49
  219. package/es/rce/plugins/shared/CheckerboardStyling.js +1 -1
  220. package/es/rce/plugins/shared/ColorInput.js +5 -14
  221. package/es/rce/plugins/shared/ConditionalTooltip.js +1 -0
  222. package/es/rce/plugins/shared/ContentSelection.js +17 -58
  223. package/es/rce/plugins/shared/DimensionUtils.js +1 -8
  224. package/es/rce/plugins/shared/DimensionsInput/DimensionInput.js +6 -6
  225. package/es/rce/plugins/shared/DimensionsInput/index.js +37 -15
  226. package/es/rce/plugins/shared/DimensionsInput/useDimensionsState.js +5 -29
  227. package/es/rce/plugins/shared/ErrorBoundary.js +2 -5
  228. package/es/rce/plugins/shared/EventUtils.js +1 -3
  229. package/es/rce/plugins/shared/Filter.js +8 -38
  230. package/es/rce/plugins/shared/FixedContentTray.js +3 -3
  231. package/es/rce/plugins/shared/ImageCropper/DirectionRegion.js +1 -8
  232. package/es/rce/plugins/shared/ImageCropper/Modal.js +4 -7
  233. package/es/rce/plugins/shared/ImageCropper/Preview.js +7 -11
  234. package/es/rce/plugins/shared/ImageCropper/constants.js +1 -0
  235. package/es/rce/plugins/shared/ImageCropper/controls/CustomNumberInput.js +2 -5
  236. package/es/rce/plugins/shared/ImageCropper/controls/ResetControls.js +1 -0
  237. package/es/rce/plugins/shared/ImageCropper/controls/RotationControls.js +1 -10
  238. package/es/rce/plugins/shared/ImageCropper/controls/ShapeControls.js +1 -0
  239. package/es/rce/plugins/shared/ImageCropper/controls/ZoomControls.js +1 -11
  240. package/es/rce/plugins/shared/ImageCropper/controls/index.js +1 -0
  241. package/es/rce/plugins/shared/ImageCropper/controls/useDebouncedNumericValue.js +3 -16
  242. package/es/rce/plugins/shared/ImageCropper/controls/utils.js +1 -2
  243. package/es/rce/plugins/shared/ImageCropper/imageCropUtils.js +1 -10
  244. package/es/rce/plugins/shared/ImageCropper/index.js +1 -0
  245. package/es/rce/plugins/shared/ImageCropper/propTypes.js +1 -0
  246. package/es/rce/plugins/shared/ImageCropper/reducers/imageCropper.js +15 -14
  247. package/es/rce/plugins/shared/ImageCropper/shape.js +1 -0
  248. package/es/rce/plugins/shared/ImageCropper/svg/index.js +1 -2
  249. package/es/rce/plugins/shared/ImageCropper/svg/shape.js +1 -17
  250. package/es/rce/plugins/shared/ImageCropper/svg/utils.js +1 -0
  251. package/es/rce/plugins/shared/ImageCropper/useKeyMouseEvents.js +19 -46
  252. package/es/rce/plugins/shared/ImageCropper/useMouseWheel.js +8 -10
  253. package/es/rce/plugins/shared/ImageOptionsForm.js +1 -2
  254. package/es/rce/plugins/shared/LinkDisplay.js +1 -2
  255. package/es/rce/plugins/shared/PreviewIcon.js +1 -6
  256. package/es/rce/plugins/shared/Previewable.js +1 -0
  257. package/es/rce/plugins/shared/RceFileBrowser.js +5 -7
  258. package/es/rce/plugins/shared/StoreContext.js +1 -2
  259. package/es/rce/plugins/shared/StudioLtiSupportUtils.js +10 -6
  260. package/es/rce/plugins/shared/UnknownFileTypePanel.js +1 -0
  261. package/es/rce/plugins/shared/Upload/CanvasContentPanel.js +13 -18
  262. package/es/rce/plugins/shared/Upload/CategoryProcessor.js +1 -1
  263. package/es/rce/plugins/shared/Upload/ComputerPanel.js +8 -26
  264. package/es/rce/plugins/shared/Upload/PanelFilter.js +3 -12
  265. package/es/rce/plugins/shared/Upload/SvgCategoryProcessor.js +4 -3
  266. package/es/rce/plugins/shared/Upload/UploadFile.js +15 -18
  267. package/es/rce/plugins/shared/Upload/UploadFileModal.js +9 -25
  268. package/es/rce/plugins/shared/Upload/UrlPanel.js +1 -0
  269. package/es/rce/plugins/shared/Upload/UsageRightsSelectBox.js +7 -12
  270. package/es/rce/plugins/shared/Upload/doFileUpload.js +4 -6
  271. package/es/rce/plugins/shared/Upload/index.js +1 -0
  272. package/es/rce/plugins/shared/ai_tools/AIResponseModal.js +1 -3
  273. package/es/rce/plugins/shared/ai_tools/AIToolsTray.js +6 -24
  274. package/es/rce/plugins/shared/ai_tools/aiicons.js +1 -0
  275. package/es/rce/plugins/shared/ai_tools/index.js +1 -0
  276. package/es/rce/plugins/shared/buildDownloadUrl.js +0 -2
  277. package/es/rce/plugins/shared/canvasContentUtils.js +6 -9
  278. package/es/rce/plugins/shared/compressionUtils.js +1 -8
  279. package/es/rce/plugins/shared/dateUtils.js +1 -1
  280. package/es/rce/plugins/shared/do-fetch-api-effect/defaultFetchOptions.js +4 -2
  281. package/es/rce/plugins/shared/do-fetch-api-effect/doFetchApi.js +7 -10
  282. package/es/rce/plugins/shared/do-fetch-api-effect/index.js +1 -0
  283. package/es/rce/plugins/shared/do-fetch-api-effect/parse-link-header.js +6 -20
  284. package/es/rce/plugins/shared/do-fetch-api-effect/query-string-encoding.js +5 -3
  285. package/es/rce/plugins/shared/fileShape.js +4 -9
  286. package/es/rce/plugins/shared/fileTypeUtils.js +32 -42
  287. package/es/rce/plugins/shared/fileUtils.js +1 -2
  288. package/es/rce/plugins/shared/linkUtils.js +1 -16
  289. package/es/rce/plugins/shared/round.js +1 -0
  290. package/es/rce/plugins/shared/trayUtils.js +4 -3
  291. package/es/rce/plugins/shared/useDataUrl.js +9 -9
  292. package/es/rce/plugins/shared/useFilterSettings.js +3 -3
  293. package/es/rce/plugins/tinymce-a11y-checker/components/ColorField.js +2 -6
  294. package/es/rce/plugins/tinymce-a11y-checker/components/checker.js +5 -63
  295. package/es/rce/plugins/tinymce-a11y-checker/components/color-picker.js +1 -2
  296. package/es/rce/plugins/tinymce-a11y-checker/components/placeholder-svg.js +1 -0
  297. package/es/rce/plugins/tinymce-a11y-checker/components/pointer.js +1 -0
  298. package/es/rce/plugins/tinymce-a11y-checker/node-checker.js +1 -6
  299. package/es/rce/plugins/tinymce-a11y-checker/plugin.js +4 -7
  300. package/es/rce/plugins/tinymce-a11y-checker/rules/adjacent-links.js +3 -26
  301. package/es/rce/plugins/tinymce-a11y-checker/rules/headings-sequence.js +9 -38
  302. package/es/rce/plugins/tinymce-a11y-checker/rules/headings-start-at-h2.js +1 -5
  303. package/es/rce/plugins/tinymce-a11y-checker/rules/img-alt-filename.js +1 -2
  304. package/es/rce/plugins/tinymce-a11y-checker/rules/img-alt-length.js +1 -1
  305. package/es/rce/plugins/tinymce-a11y-checker/rules/img-alt.js +1 -2
  306. package/es/rce/plugins/tinymce-a11y-checker/rules/index.js +1 -0
  307. package/es/rce/plugins/tinymce-a11y-checker/rules/large-text-contrast.js +1 -4
  308. package/es/rce/plugins/tinymce-a11y-checker/rules/list-structure.js +5 -24
  309. package/es/rce/plugins/tinymce-a11y-checker/rules/paragraphs-for-headings.js +1 -3
  310. package/es/rce/plugins/tinymce-a11y-checker/rules/small-text-contrast.js +1 -6
  311. package/es/rce/plugins/tinymce-a11y-checker/rules/table-caption.js +1 -3
  312. package/es/rce/plugins/tinymce-a11y-checker/rules/table-header-scope.js +1 -2
  313. package/es/rce/plugins/tinymce-a11y-checker/rules/table-header.js +1 -9
  314. package/es/rce/plugins/tinymce-a11y-checker/utils/colors.js +1 -0
  315. package/es/rce/plugins/tinymce-a11y-checker/utils/describe.js +1 -7
  316. package/es/rce/plugins/tinymce-a11y-checker/utils/dom.js +1 -26
  317. package/es/rce/plugins/tinymce-a11y-checker/utils/indicate.js +16 -15
  318. package/es/rce/plugins/tinymce-a11y-checker/utils/rgb-hex.js +7 -10
  319. package/es/rce/plugins/tinymce-a11y-checker/utils/strings.js +1 -4
  320. package/es/rce/root.js +9 -8
  321. package/es/rce/sanitizePlugins.js +1 -3
  322. package/es/rce/style.js +1 -4
  323. package/es/rce/tinyRCE.js +13 -9
  324. package/es/rce/tinymce.oxide.content.min.css.js +1 -0
  325. package/es/rce/tinymce.oxide.skin.min.css.js +1 -0
  326. package/es/rce/transformContent.js +8 -10
  327. package/es/rce/types.js +1 -0
  328. package/es/rce/userOS.js +1 -1
  329. package/es/rce/wrapInitCb.js +50 -43
  330. package/es/rcs/api.js +61 -116
  331. package/es/rcs/buildError.js +5 -17
  332. package/es/rcs/fake.js +4 -13
  333. package/es/sidebar/actions/all_files.js +2 -0
  334. package/es/sidebar/actions/data.js +4 -7
  335. package/es/sidebar/actions/documents.js +9 -6
  336. package/es/sidebar/actions/files.js +3 -6
  337. package/es/sidebar/actions/filter.js +1 -0
  338. package/es/sidebar/actions/flickr.js +1 -1
  339. package/es/sidebar/actions/images.js +12 -11
  340. package/es/sidebar/actions/links.js +1 -0
  341. package/es/sidebar/actions/media.js +12 -10
  342. package/es/sidebar/actions/session.js +1 -3
  343. package/es/sidebar/actions/ui.js +1 -0
  344. package/es/sidebar/actions/upload.js +14 -39
  345. package/es/sidebar/containers/Sidebar.js +1 -2
  346. package/es/sidebar/containers/sidebarHandlers.js +3 -1
  347. package/es/sidebar/dragHtml.js +5 -3
  348. package/es/sidebar/reducers/all_files.js +4 -3
  349. package/es/sidebar/reducers/collection.js +12 -13
  350. package/es/sidebar/reducers/collections.js +5 -5
  351. package/es/sidebar/reducers/documents.js +6 -13
  352. package/es/sidebar/reducers/files.js +3 -3
  353. package/es/sidebar/reducers/filter.js +1 -8
  354. package/es/sidebar/reducers/flickr.js +9 -9
  355. package/es/sidebar/reducers/folder.js +15 -15
  356. package/es/sidebar/reducers/folders.js +3 -3
  357. package/es/sidebar/reducers/images.js +3 -13
  358. package/es/sidebar/reducers/index.js +3 -1
  359. package/es/sidebar/reducers/media.js +6 -13
  360. package/es/sidebar/reducers/newPageLinkExpanded.js +1 -2
  361. package/es/sidebar/reducers/noop.js +1 -0
  362. package/es/sidebar/reducers/rootFolderId.js +1 -2
  363. package/es/sidebar/reducers/session.js +3 -3
  364. package/es/sidebar/reducers/ui.js +3 -16
  365. package/es/sidebar/reducers/upload.js +8 -40
  366. package/es/sidebar/store/configureStore.js +1 -0
  367. package/es/sidebar/store/initialState.js +13 -24
  368. package/es/translations/locales/ab.js +1 -0
  369. package/es/translations/locales/ar.js +67 -9
  370. package/es/translations/locales/ca.js +67 -9
  371. package/es/translations/locales/cs.js +1 -0
  372. package/es/translations/locales/cs_CZ.js +1 -0
  373. package/es/translations/locales/cy.js +67 -9
  374. package/es/translations/locales/da-x-k12.js +67 -9
  375. package/es/translations/locales/da.js +67 -9
  376. package/es/translations/locales/da_DK.js +1 -0
  377. package/es/translations/locales/de.js +67 -9
  378. package/es/translations/locales/el.js +4 -0
  379. package/es/translations/locales/en-AU-x-unimelb.js +67 -9
  380. package/es/translations/locales/en-GB-x-ukhe.js +67 -9
  381. package/es/translations/locales/en.js +72 -8
  382. package/es/translations/locales/en_AU.js +67 -9
  383. package/es/translations/locales/en_CA.js +67 -9
  384. package/es/translations/locales/en_CY.js +67 -9
  385. package/es/translations/locales/en_GB.js +67 -9
  386. package/es/translations/locales/en_NZ.js +1 -0
  387. package/es/translations/locales/en_SE.js +1 -0
  388. package/es/translations/locales/en_US.js +1 -0
  389. package/es/translations/locales/es.js +67 -9
  390. package/es/translations/locales/es_ES.js +67 -9
  391. package/es/translations/locales/es_GT.js +1 -0
  392. package/es/translations/locales/fa_IR.js +7 -0
  393. package/es/translations/locales/fi.js +67 -9
  394. package/es/translations/locales/fr.js +67 -9
  395. package/es/translations/locales/fr_CA.js +68 -10
  396. package/es/translations/locales/ga.js +5 -13
  397. package/es/translations/locales/he.js +7 -0
  398. package/es/translations/locales/hi.js +67 -9
  399. package/es/translations/locales/ht.js +67 -9
  400. package/es/translations/locales/hu.js +7 -6
  401. package/es/translations/locales/hu_HU.js +1 -0
  402. package/es/translations/locales/hy.js +1 -0
  403. package/es/translations/locales/id.js +67 -9
  404. package/es/translations/locales/id_ID.js +1 -0
  405. package/es/translations/locales/is.js +67 -9
  406. package/es/translations/locales/it.js +67 -9
  407. package/es/translations/locales/ja.js +67 -9
  408. package/es/translations/locales/ko.js +1 -0
  409. package/es/translations/locales/ko_KR.js +1 -0
  410. package/es/translations/locales/lt.js +1 -0
  411. package/es/translations/locales/lt_LT.js +1 -0
  412. package/es/translations/locales/mi.js +67 -9
  413. package/es/translations/locales/mn_MN.js +1 -0
  414. package/es/translations/locales/ms.js +67 -9
  415. package/es/translations/locales/nb-x-k12.js +67 -9
  416. package/es/translations/locales/nb.js +67 -9
  417. package/es/translations/locales/nl.js +67 -9
  418. package/es/translations/locales/nl_NL.js +1 -0
  419. package/es/translations/locales/nn.js +7 -6
  420. package/es/translations/locales/pl.js +67 -9
  421. package/es/translations/locales/pt.js +67 -9
  422. package/es/translations/locales/pt_BR.js +67 -9
  423. package/es/translations/locales/ro.js +1 -0
  424. package/es/translations/locales/ru.js +67 -9
  425. package/es/translations/locales/se.js +1 -0
  426. package/es/translations/locales/sl.js +67 -9
  427. package/es/translations/locales/sv-x-k12.js +67 -9
  428. package/es/translations/locales/sv.js +67 -9
  429. package/es/translations/locales/sv_SE.js +1 -0
  430. package/es/translations/locales/tg.js +1 -0
  431. package/es/translations/locales/th.js +67 -9
  432. package/es/translations/locales/th_TH.js +1 -0
  433. package/es/translations/locales/tl_PH.js +1 -0
  434. package/es/translations/locales/tr.js +7 -0
  435. package/es/translations/locales/uk_UA.js +7 -0
  436. package/es/translations/locales/vi.js +67 -9
  437. package/es/translations/locales/vi_VN.js +1 -0
  438. package/es/translations/locales/zh-Hans.js +67 -9
  439. package/es/translations/locales/zh-Hant.js +67 -9
  440. package/es/translations/locales/zh.js +67 -9
  441. package/es/translations/locales/zh_HK.js +67 -9
  442. package/es/translations/locales/zh_TW.Big5.js +1 -0
  443. package/es/translations/locales/zh_TW.js +1 -0
  444. package/es/translations/tinymce/ar_SA.js +1 -0
  445. package/es/translations/tinymce/fi.js +1 -0
  446. package/es/translations/tinymce/ga.js +1 -0
  447. package/es/translations/tinymce/id.js +1 -0
  448. package/es/translations/tinymce/ru.js +1 -0
  449. package/es/translations/tinymce/ru_RU.js +1 -0
  450. package/es/translations/tinymce/sl.js +1 -0
  451. package/es/translations/tinymce/sr.js +1 -0
  452. package/es/translations/tinymce/th.js +1 -0
  453. package/es/translations/tinymce/uk_UA.js +1 -0
  454. package/es/translations/tinymce/vi_VN.js +1 -0
  455. package/es/util/TypedDict.js +4 -2
  456. package/es/util/encrypted-storage.js +3 -13
  457. package/es/util/file-url-util.js +1 -6
  458. package/es/util/fullscreenHelpers.js +4 -1
  459. package/es/util/instui-icon-helper.js +4 -3
  460. package/es/util/loadingPlaceholder.js +38 -39
  461. package/es/util/simpleCache.js +0 -3
  462. package/es/util/string-util.js +1 -1
  463. package/es/util/textarea-editing-util.js +3 -7
  464. package/es/util/tinymce-plugin-util.js +0 -5
  465. package/es/util/url-util.js +16 -25
  466. package/eslint.config.js +239 -0
  467. package/jest.config.js +1 -1
  468. package/package.json +76 -81
  469. package/scripts/build-canvas +2 -1
  470. package/scripts/build.js +4 -4
  471. package/testcafe/RCEWrapper.test.js +0 -1
  472. package/testcafe/StatusBar.test.js +0 -1
  473. package/testcafe/axe.test.js +3 -4
  474. package/testcafe/enhanceUserContent.test.js +0 -1
  475. package/tsconfig.json +20 -15
  476. package/.eslintrc +0 -45
  477. package/.prettierignore +0 -6
  478. package/es/rce/__mocks__/_mockCryptoEs.js +0 -124
  479. package/es/rce/__mocks__/styleMock.js +0 -18
  480. package/es/rce/__mocks__/tinymceReact.js +0 -55
  481. package/es/rce/plugins/tinymce-a11y-checker/rules/__mocks__/index.js +0 -53
@@ -0,0 +1,84 @@
1
+ /*
2
+ * Copyright (C) 2023 - present Instructure, Inc.
3
+ *
4
+ * This file is part of Canvas.
5
+ *
6
+ * Canvas is free software: you can redistribute it and/or modify it under
7
+ * the terms of the GNU Affero General Public License as published by the Free
8
+ * Software Foundation, version 3 of the License.
9
+ *
10
+ * Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
11
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12
+ * A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
13
+ * details.
14
+ *
15
+ * You should have received a copy of the GNU Affero General Public License along
16
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ import React from 'react';
20
+ import { createRoot } from 'react-dom/client';
21
+ import tinycolor from 'tinycolor2';
22
+ import { ColorPopup } from './components/ColorPopup';
23
+ const CONTAINER_ID = 'instructure-color-popup-container';
24
+ export default function (editor) {
25
+ var _container;
26
+ let container = document.getElementById(CONTAINER_ID);
27
+ if (container == null) {
28
+ container = document.createElement('div');
29
+ container.id = CONTAINER_ID;
30
+ document.body.appendChild(container);
31
+ }
32
+ const handleDismiss = () => {
33
+ if (container) {
34
+ var _container$_reactRoot;
35
+ (_container$_reactRoot = container._reactRoot) === null || _container$_reactRoot === void 0 ? void 0 : _container$_reactRoot.unmount();
36
+ container._reactRoot = null;
37
+ }
38
+ };
39
+ const handleChange = newcolors => {
40
+ editor.undoManager.transact(() => {
41
+ if (newcolors.fgcolor) {
42
+ editor.execCommand('forecolor', false, newcolors.fgcolor);
43
+ }
44
+ if (newcolors.bgcolor) {
45
+ editor.execCommand('hilitecolor', false, newcolors.bgcolor);
46
+ }
47
+ if (newcolors.fgcolor || newcolors.bgcolor) {
48
+ editor.nodeChanged();
49
+ }
50
+ handleDismiss();
51
+ });
52
+ };
53
+ if ((_container = container) !== null && _container !== void 0 && _container._reactRoot) {
54
+ handleDismiss();
55
+ document.removeEventListener('rce-text-block-popup-close', handleDismiss);
56
+ return;
57
+ }
58
+ document.addEventListener('rce-text-block-popup-close', handleDismiss);
59
+ const defaultTextColor = window.getComputedStyle(editor.getBody()).getPropertyValue('--ic-brand-font-color-dark').toLowerCase();
60
+ const styl = window.getComputedStyle(editor.selection.getNode());
61
+ const textColor = tinycolor(styl.getPropertyValue('color')).toHexString();
62
+ const bgColor_ = tinycolor(styl.getPropertyValue('background-color'));
63
+ const bgColor = bgColor_.getAlpha() === 1 ? bgColor_.toHexString() : bgColor_.toHex8String();
64
+ const target = document.querySelector('svg[data-id="color-button"]');
65
+ const root = createRoot(container);
66
+ container._reactRoot = root;
67
+ root.render(/*#__PURE__*/React.createElement(ColorPopup, {
68
+ tabs: {
69
+ foreground: {
70
+ color: textColor,
71
+ default: defaultTextColor
72
+ },
73
+ background: {
74
+ color: bgColor,
75
+ default: '#ffffff'
76
+ },
77
+ effectiveBgColor: '#ffffff'
78
+ },
79
+ open: true,
80
+ positionTarget: target,
81
+ onCancel: handleDismiss,
82
+ onChange: handleChange
83
+ }));
84
+ }
@@ -0,0 +1,299 @@
1
+ import _pt from "prop-types";
2
+ /*
3
+ * Copyright (C) 2024 - present Instructure, Inc.
4
+ *
5
+ * This file is part of Canvas.
6
+ *
7
+ * Canvas is free software: you can redistribute it and/or modify it under
8
+ * the terms of the GNU Affero General Public License as published by the Free
9
+ * Software Foundation, version 3 of the License.
10
+ *
11
+ * Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
12
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
13
+ * A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
14
+ * details.
15
+ *
16
+ * You should have received a copy of the GNU Affero General Public License along
17
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
18
+ */
19
+
20
+ import React, { useCallback, useState } from 'react';
21
+ import tinycolor from 'tinycolor2';
22
+ import formatMessage from '../../../../format-message';
23
+ import { Button } from '@instructure/ui-buttons';
24
+ import { ColorPreset, ColorMixer, ColorContrast } from '@instructure/ui-color-picker';
25
+ import { Flex } from '@instructure/ui-flex';
26
+ import { Pill } from '@instructure/ui-pill';
27
+ import { RadioInputGroup, RadioInput } from '@instructure/ui-radio-input';
28
+ import { Tabs } from '@instructure/ui-tabs';
29
+ import { Text } from '@instructure/ui-text';
30
+ import { ToggleDetails } from '@instructure/ui-toggle-details';
31
+ import { View } from '@instructure/ui-view';
32
+ import { isTransparent, getContrastStatus, getDefaultColors } from './colorUtils';
33
+
34
+ // A custom type constraint that enforces at least one key is present
35
+
36
+ const ColorPicker = _ref => {
37
+ var _tabs$foreground, _tabs$background, _tabs$background2, _tabs$border, _tabs$foreground2, _tabs$background3, _tabs$background4, _tabs$background5, _tabs$border2, _tabs$border3, _tabs$border4;
38
+ let {
39
+ tabs,
40
+ colorsInUse,
41
+ onCancel,
42
+ onSave
43
+ } = _ref;
44
+ const [currFgColor, setCurrFgColor] = useState((_tabs$foreground = tabs.foreground) === null || _tabs$foreground === void 0 ? void 0 : _tabs$foreground.color);
45
+ const [currBgColor, setCurrBgColor] = useState(isTransparent((_tabs$background = tabs.background) === null || _tabs$background === void 0 ? void 0 : _tabs$background.color) ? tabs.effectiveBgColor || '#ffffff' : (_tabs$background2 = tabs.background) === null || _tabs$background2 === void 0 ? void 0 : _tabs$background2.color);
46
+ const [currBorderColor, setCurrBorderColor] = useState((_tabs$border = tabs.border) === null || _tabs$border === void 0 ? void 0 : _tabs$border.color);
47
+ const [activeTab, setActiveTab] = useState(() => {
48
+ if (tabs.foreground) return 'foreground';
49
+ if (tabs.background) return 'background';
50
+ return 'border';
51
+ });
52
+ const [defaultColors] = useState(getDefaultColors());
53
+ const [customForeground, setCustomForeground] = useState(!!((_tabs$foreground2 = tabs.foreground) !== null && _tabs$foreground2 !== void 0 && _tabs$foreground2.color) && tabs.foreground.color !== tabs.foreground.default);
54
+ const [customBackground, setCustomBackground] = useState(!isTransparent((_tabs$background3 = tabs.background) === null || _tabs$background3 === void 0 ? void 0 : _tabs$background3.color) && ((_tabs$background4 = tabs.background) === null || _tabs$background4 === void 0 ? void 0 : _tabs$background4.color) !== ((_tabs$background5 = tabs.background) === null || _tabs$background5 === void 0 ? void 0 : _tabs$background5.default));
55
+ const [customBorder, setCustomBorder] = useState(!isTransparent((_tabs$border2 = tabs.border) === null || _tabs$border2 === void 0 ? void 0 : _tabs$border2.color) && ((_tabs$border3 = tabs.border) === null || _tabs$border3 === void 0 ? void 0 : _tabs$border3.color) !== ((_tabs$border4 = tabs.border) === null || _tabs$border4 === void 0 ? void 0 : _tabs$border4.default));
56
+ const handleFgColorChange = useCallback(newColor => {
57
+ setCurrFgColor(newColor);
58
+ }, []);
59
+ const handleBgColorChange = useCallback(newColor => {
60
+ const c = tinycolor(newColor).toHexString();
61
+ setCurrBgColor(c);
62
+ }, []);
63
+ const handleBorderColorChange = useCallback(newColor => {
64
+ setCurrBorderColor(newColor);
65
+ }, []);
66
+ const handleTabChange = useCallback((_event, tabData) => {
67
+ setActiveTab(tabData.id);
68
+ }, []);
69
+ const handleChangePickAColor = useCallback((_e, value) => {
70
+ const isCustom = value === 'custom';
71
+ if (activeTab === 'foreground') {
72
+ setCustomForeground(isCustom);
73
+ if (!isCustom) {
74
+ setCurrFgColor(undefined);
75
+ }
76
+ } else if (activeTab === 'background') {
77
+ setCustomBackground(isCustom);
78
+ if (!isCustom) {
79
+ setCurrBgColor(undefined);
80
+ }
81
+ } else if (activeTab === 'border') {
82
+ setCustomBorder(isCustom);
83
+ if (!isCustom) {
84
+ setCurrBorderColor('#00000000');
85
+ }
86
+ }
87
+ }, [activeTab]);
88
+ const handleCancel = useCallback(() => {
89
+ onCancel();
90
+ }, [onCancel]);
91
+ const handleSubmit = useCallback(() => {
92
+ setActiveTab(currFgColor ? 'foreground' : 'background');
93
+ const newcolors = {};
94
+ if (customForeground && currFgColor) {
95
+ const c = tinycolor(currFgColor).toHexString();
96
+ newcolors.fgcolor = c;
97
+ }
98
+ if (customBackground && currBgColor) {
99
+ const c = tinycolor(currBgColor).toHexString();
100
+ newcolors.bgcolor = c;
101
+ }
102
+ if (currBorderColor) {
103
+ newcolors.bordercolor = customBorder && !isTransparent(currBorderColor) ? currBorderColor : undefined;
104
+ if (newcolors.bordercolor) {
105
+ const c = tinycolor(newcolors.bordercolor).toHexString();
106
+ newcolors.bordercolor = c;
107
+ }
108
+ }
109
+ onSave(newcolors);
110
+ }, [currBgColor, currBorderColor, currFgColor, customBackground, customBorder, customForeground, onSave]);
111
+ const getColorPresets = variant => {
112
+ var _tabs$background6, _tabs$foreground3;
113
+ const defaults = defaultColors;
114
+ if ((_tabs$background6 = tabs.background) !== null && _tabs$background6 !== void 0 && _tabs$background6.default) {
115
+ defaults[0] = tabs.background.default;
116
+ }
117
+ if ((_tabs$foreground3 = tabs.foreground) !== null && _tabs$foreground3 !== void 0 && _tabs$foreground3.default) {
118
+ defaults[1] = tabs.foreground.default;
119
+ }
120
+ // return only unique colors
121
+ return [...defaults, ...((colorsInUse === null || colorsInUse === void 0 ? void 0 : colorsInUse[variant]) || [])].filter((c, i, a) => a.indexOf(c) === i && !isTransparent(c));
122
+ };
123
+ const renderColorMixer = (variant, enabled) => {
124
+ let value = currBgColor;
125
+ let onSelectColor = handleBgColorChange;
126
+ if (variant === 'foreground') {
127
+ value = currFgColor;
128
+ onSelectColor = handleFgColorChange;
129
+ }
130
+ if (variant === 'border') {
131
+ value = currBorderColor;
132
+ onSelectColor = handleBorderColorChange;
133
+ }
134
+ if (isTransparent(value)) value = '#fff'; // or the ColorMixer will return a transparent color
135
+
136
+ return /*#__PURE__*/React.createElement(ColorMixer, {
137
+ "data-testid": "color-mixer",
138
+ disabled: !enabled,
139
+ value: value,
140
+ withAlpha: false,
141
+ onChange: onSelectColor,
142
+ rgbRedInputScreenReaderLabel: formatMessage('Input field for red'),
143
+ rgbGreenInputScreenReaderLabel: formatMessage('Input field for green'),
144
+ rgbBlueInputScreenReaderLabel: formatMessage('Input field for blue'),
145
+ rgbAlphaInputScreenReaderLabel: formatMessage('Input field for alpha'),
146
+ colorSliderNavigationExplanationScreenReaderLabel: formatMessage("You are on a color slider. To navigate the slider left or right, use the 'A' and 'D' buttons respectively"),
147
+ alphaSliderNavigationExplanationScreenReaderLabel: formatMessage("You are on an alpha slider. To navigate the slider left or right, use the 'A' and 'D' buttons respectively"),
148
+ colorPaletteNavigationExplanationScreenReaderLabel: formatMessage("You are on a color palette. To navigate on the palette up, left, down or right, use the 'W', 'A', 'S' and 'D' buttons respectively")
149
+ });
150
+ };
151
+ const renderColorPreset = (variant, enabled) => {
152
+ let currColor = currBgColor;
153
+ if (variant === 'foreground') currColor = currFgColor || defaultColors[1];
154
+ if (variant === 'border') currColor = currBorderColor || '#00000000';
155
+ let onSelectColor = handleBgColorChange;
156
+ if (variant === 'foreground') onSelectColor = handleFgColorChange;
157
+ if (variant === 'border') onSelectColor = handleBorderColorChange;
158
+ return /*#__PURE__*/React.createElement(ColorPreset, {
159
+ "data-testid": "color-preset",
160
+ disabled: !enabled,
161
+ label: formatMessage('Previously chosen colors'),
162
+ colors: getColorPresets(variant),
163
+ selected: currColor,
164
+ onSelect: onSelectColor
165
+ });
166
+ };
167
+
168
+ // this will only get called if either tabs.foreground or tabs.border is defined
169
+ const getFirstColor = () => {
170
+ let firstColor, firstColorLabel;
171
+ if (activeTab === 'foreground' || activeTab === 'background' && !!tabs.foreground) {
172
+ var _tabs$foreground4;
173
+ firstColor = currFgColor || ((_tabs$foreground4 = tabs.foreground) === null || _tabs$foreground4 === void 0 ? void 0 : _tabs$foreground4.default) || defaultColors[0];
174
+ firstColorLabel = formatMessage('Color');
175
+ } else if (activeTab === 'border' || activeTab === 'background' && !!tabs.border) {
176
+ var _tabs$border5;
177
+ firstColor = currBorderColor || ((_tabs$border5 = tabs.border) === null || _tabs$border5 === void 0 ? void 0 : _tabs$border5.default) || defaultColors[0];
178
+ firstColorLabel = formatMessage('Border');
179
+ }
180
+ // @ts-expect-error
181
+ return {
182
+ firstColor,
183
+ firstColorLabel
184
+ };
185
+ };
186
+ const renderColorContrastSummary = () => {
187
+ const {
188
+ firstColor
189
+ } = getFirstColor();
190
+ const ok = getContrastStatus(firstColor, currBgColor || tabs.effectiveBgColor || '#fff');
191
+ return /*#__PURE__*/React.createElement(Flex, {
192
+ as: "div",
193
+ gap: "x-large"
194
+ }, /*#__PURE__*/React.createElement(Text, {
195
+ weight: "bold"
196
+ }, formatMessage('Color Contrast')), /*#__PURE__*/React.createElement(Pill, {
197
+ color: ok ? 'success' : 'danger'
198
+ }, ok ? formatMessage('PASS') : formatMessage('FAIL')));
199
+ };
200
+ const renderColorContrast = () => {
201
+ if (!(tabs.background || tabs.effectiveBgColor)) return null;
202
+ if (!(tabs.foreground || tabs.border)) return null;
203
+ if (!currBgColor) return null;
204
+ const {
205
+ firstColor,
206
+ firstColorLabel
207
+ } = getFirstColor();
208
+ if (firstColor === null) return null;
209
+ return /*#__PURE__*/React.createElement(ToggleDetails, {
210
+ summary: renderColorContrastSummary(),
211
+ "data-testid": "color-contrast-summary"
212
+ }, /*#__PURE__*/React.createElement(View, {
213
+ as: "div",
214
+ margin: "small 0 0 0"
215
+ }, /*#__PURE__*/React.createElement(ColorContrast, {
216
+ "data-testid": "color-contrast",
217
+ firstColor: firstColor,
218
+ secondColor: currBgColor || tabs.effectiveBgColor || '#fff',
219
+ label: formatMessage('Color Contrast Ratio'),
220
+ successLabel: formatMessage('PASS'),
221
+ failureLabel: formatMessage('FAIL'),
222
+ normalTextLabel: formatMessage('Normal text'),
223
+ largeTextLabel: formatMessage('Large text'),
224
+ graphicsTextLabel: formatMessage('Graphics text'),
225
+ firstColorLabel: firstColorLabel,
226
+ secondColorLabel: formatMessage('Background')
227
+ })));
228
+ };
229
+ const renderTab = variant => {
230
+ let choosersEnabled = true;
231
+ if (variant === 'foreground') {
232
+ choosersEnabled = customForeground;
233
+ } else if (variant === 'background') {
234
+ choosersEnabled = customBackground;
235
+ } else if (variant === 'border') {
236
+ choosersEnabled = customBorder;
237
+ }
238
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(View, {
239
+ as: "div",
240
+ margin: "0 0 small 0"
241
+ }, /*#__PURE__*/React.createElement(RadioInputGroup, {
242
+ layout: "columns",
243
+ name: "pickcolor",
244
+ description: formatMessage('Pick a color'),
245
+ size: "small",
246
+ value: choosersEnabled ? 'custom' : 'none',
247
+ onChange: handleChangePickAColor
248
+ }, /*#__PURE__*/React.createElement(RadioInput, {
249
+ label: formatMessage('Default'),
250
+ value: "none"
251
+ }), /*#__PURE__*/React.createElement(RadioInput, {
252
+ label: formatMessage('Custom'),
253
+ value: "custom"
254
+ }))), renderColorMixer(variant, choosersEnabled), renderColorPreset(variant, choosersEnabled));
255
+ };
256
+ return /*#__PURE__*/React.createElement(View, {
257
+ as: "div",
258
+ "data-testid": "color-picker"
259
+ }, /*#__PURE__*/React.createElement(View, {
260
+ as: "div",
261
+ padding: "small",
262
+ "data-mce-component": true
263
+ }, /*#__PURE__*/React.createElement(Tabs, {
264
+ onRequestTabChange: handleTabChange
265
+ }, !!tabs.foreground && /*#__PURE__*/React.createElement(Tabs.Panel, {
266
+ id: "foreground",
267
+ renderTitle: formatMessage('Color'),
268
+ isSelected: activeTab === 'foreground'
269
+ }, renderTab('foreground')), !!tabs.background && /*#__PURE__*/React.createElement(Tabs.Panel, {
270
+ id: "background",
271
+ renderTitle: formatMessage('Background'),
272
+ isSelected: activeTab === 'background'
273
+ }, renderTab('background')), !!tabs.border && /*#__PURE__*/React.createElement(Tabs.Panel, {
274
+ id: "border",
275
+ renderTitle: formatMessage('Border'),
276
+ isSelected: activeTab === 'border'
277
+ }, renderTab('border'))), renderColorContrast()), /*#__PURE__*/React.createElement(View, {
278
+ as: "div",
279
+ background: "secondary",
280
+ padding: "small",
281
+ textAlign: "end"
282
+ }, /*#__PURE__*/React.createElement(Button, {
283
+ onClick: handleCancel
284
+ }, formatMessage('Cancel')), /*#__PURE__*/React.createElement(Button, {
285
+ onClick: handleSubmit,
286
+ margin: "0 0 0 small",
287
+ color: "primary"
288
+ }, formatMessage('Apply'))));
289
+ };
290
+ ColorPicker.propTypes = {
291
+ colorsInUse: _pt.shape({
292
+ foreground: _pt.arrayOf(_pt.string).isRequired,
293
+ background: _pt.arrayOf(_pt.string).isRequired,
294
+ border: _pt.arrayOf(_pt.string).isRequired
295
+ }),
296
+ onCancel: _pt.func.isRequired,
297
+ onSave: _pt.func.isRequired
298
+ };
299
+ export { ColorPicker };
@@ -0,0 +1,68 @@
1
+ import _pt from "prop-types";
2
+ /*
3
+ * Copyright (C) 2024 - present Instructure, Inc.
4
+ *
5
+ * This file is part of Canvas.
6
+ *
7
+ * Canvas is free software: you can redistribute it and/or modify it under
8
+ * the terms of the GNU Affero General Public License as published by the Free
9
+ * Software Foundation, version 3 of the License.
10
+ *
11
+ * Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
12
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
13
+ * A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
14
+ * details.
15
+ *
16
+ * You should have received a copy of the GNU Affero General Public License along
17
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
18
+ */
19
+
20
+ import React, { useCallback, useState } from 'react';
21
+ import { Popover } from '@instructure/ui-popover';
22
+ import { ColorPicker } from './ColorPicker';
23
+ import formatMessage from '../../../../format-message';
24
+ const ColorPopup = _ref => {
25
+ let {
26
+ tabs,
27
+ open,
28
+ positionTarget,
29
+ onCancel,
30
+ onChange
31
+ } = _ref;
32
+ const [recreateKey, setRecreateKey] = useState(0);
33
+ const handleHideContent = useCallback(() => {
34
+ onCancel();
35
+ setRecreateKey(Date.now());
36
+ }, [onCancel]);
37
+ const handleSubmit = useCallback(newcolors => {
38
+ onChange(newcolors);
39
+ }, [onChange]);
40
+ const handleKey = useCallback(e => {
41
+ if (e.key === 'Escape') {
42
+ onCancel();
43
+ }
44
+ }, [onCancel]);
45
+ return /*#__PURE__*/React.createElement(Popover, {
46
+ key: recreateKey,
47
+ isShowingContent: open,
48
+ onHideContent: handleHideContent,
49
+ on: "click",
50
+ positionTarget: positionTarget,
51
+ screenReaderLabel: formatMessage('Color popup'),
52
+ shouldContainFocus: true,
53
+ shouldReturnFocus: true,
54
+ shouldCloseOnDocumentClick: true
55
+ }, /*#__PURE__*/React.createElement("div", {
56
+ onKeyDown: handleKey
57
+ }, /*#__PURE__*/React.createElement(ColorPicker, {
58
+ tabs: tabs,
59
+ onCancel: onCancel,
60
+ onSave: handleSubmit
61
+ })));
62
+ };
63
+ ColorPopup.propTypes = {
64
+ open: _pt.bool.isRequired,
65
+ onCancel: _pt.func.isRequired,
66
+ onChange: _pt.func.isRequired
67
+ };
68
+ export { ColorPopup };
@@ -0,0 +1,60 @@
1
+ /*
2
+ * Copyright (C) 2024 - present Instructure, Inc.
3
+ *
4
+ * This file is part of Canvas.
5
+ *
6
+ * Canvas is free software: you can redistribute it and/or modify it under
7
+ * the terms of the GNU Affero General Public License as published by the Free
8
+ * Software Foundation, version 3 of the License.
9
+ *
10
+ * Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
11
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12
+ * A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
13
+ * details.
14
+ *
15
+ * You should have received a copy of the GNU Affero General Public License along
16
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ import conversions, { contrast } from '@instructure/ui-color-utils';
20
+ import tinycolor from 'tinycolor2';
21
+ const isTransparent = color => {
22
+ if (!color) {
23
+ return true;
24
+ }
25
+ const c = tinycolor(color);
26
+ return c.isValid() && c.getAlpha() === 0;
27
+ };
28
+
29
+ // the following is copied from the INSTUI ColorContrast component
30
+ // a function to handle this will eventually be exported
31
+ // from @instructure/ui-color-utils
32
+ const INSTUIcalcBlendedColor = (c1, c2) => {
33
+ const alpha = 1 - (1 - c1.a) * (1 - c2.a);
34
+ return {
35
+ r: c2.r * c2.a / alpha + c1.r * c1.a * (1 - c2.a) / alpha,
36
+ g: c2.g * c2.a / alpha + c1.g * c1.a * (1 - c2.a) / alpha,
37
+ b: c2.b * c2.a / alpha + c1.b * c1.a * (1 - c2.a) / alpha,
38
+ a: 1
39
+ };
40
+ };
41
+ const INSTUIcalcContrast = (firstColor, secondColor) => {
42
+ const c1RGBA = conversions.colorToRGB(firstColor);
43
+ const c2RGBA = conversions.colorToRGB(secondColor);
44
+ const c1OnWhite = INSTUIcalcBlendedColor({
45
+ r: 255,
46
+ g: 255,
47
+ b: 255,
48
+ a: 1
49
+ }, c1RGBA);
50
+ const c2OnC1OnWhite = INSTUIcalcBlendedColor(c1OnWhite, c2RGBA);
51
+ return contrast(conversions.colorToHex8(c1OnWhite), conversions.colorToHex8(c2OnC1OnWhite), 2);
52
+ };
53
+ const getContrastStatus = (color1, color2) => {
54
+ return INSTUIcalcContrast(color1, color2) >= 4.5;
55
+ };
56
+ const getDefaultColors = () => {
57
+ const fontcolor = window.getComputedStyle(document.documentElement).getPropertyValue('--ic-brand-font-color-dark') || '#000000';
58
+ return [fontcolor.toLowerCase(), '#ffffff'];
59
+ };
60
+ export { getContrastStatus, isTransparent, getDefaultColors };
@@ -0,0 +1,40 @@
1
+ /*
2
+ * Copyright (C) 2024 - present Instructure, Inc.
3
+ *
4
+ * This file is part of Canvas.
5
+ *
6
+ * Canvas is free software: you can redistribute it and/or modify it under
7
+ * the terms of the GNU Affero General Public License as published by the Free
8
+ * Software Foundation, version 3 of the License.
9
+ *
10
+ * Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
11
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12
+ * A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
13
+ * details.
14
+ *
15
+ * You should have received a copy of the GNU Affero General Public License along
16
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ import tinymce from 'tinymce';
20
+ import formatMessage from '../../../format-message';
21
+ import clickCallback from './clickCallback';
22
+ tinymce.PluginManager.add('instructure_color', function (editor) {
23
+ editor.addCommand('launch_instructure_color', () => {
24
+ clickCallback(editor);
25
+ });
26
+ editor.ui.registry.addMenuItem('instructure_color', {
27
+ text: formatMessage('Color'),
28
+ icon: 'color',
29
+ onAction() {
30
+ editor.execCommand('launch_instructure_color');
31
+ }
32
+ });
33
+ editor.ui.registry.addButton('instructure_color', {
34
+ onAction() {
35
+ editor.execCommand('launch_instructure_color');
36
+ },
37
+ icon: 'color',
38
+ tooltip: formatMessage('Color')
39
+ });
40
+ });
@@ -4,13 +4,12 @@
4
4
  * For LGPL see License.txt in the project root for license information.
5
5
  * For commercial licenses see https://www.tiny.cloud/
6
6
  */
7
- const isChildOfBody = (editor, node) => !!editor.$.contains(editor.getBody(), node);
8
7
 
8
+ const isChildOfBody = (editor, node) => !!editor.$.contains(editor.getBody(), node);
9
9
  export const isTableCellNode = node => node && /^(TH|TD)$/.test(node.nodeName);
10
10
  export const isListNode = editor => node => node && /^(OL|UL|DL)$/.test(node.nodeName) && isChildOfBody(editor, node);
11
11
  export function listStyleForSelectionOfEditor(editor) {
12
12
  const listElm = editor.dom.getParent(editor.selection.getNode(), 'ol,ul');
13
-
14
13
  if (listElm) {
15
14
  return {
16
15
  // This is not type safe, but the above getParent selector enforces that this will be
@@ -21,4 +20,12 @@ export function listStyleForSelectionOfEditor(editor) {
21
20
  } else {
22
21
  return undefined;
23
22
  }
24
- }
23
+ }
24
+
25
+ /**
26
+ * Valid values of the "list-style-type" property.
27
+ *
28
+ * NOTE: Not all these types are supported by the RCE. For that, see `ListStyleTypeValue`
29
+ *
30
+ * From https://www.w3schools.com/cssref/pr_list-style-type.php
31
+ */
@@ -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 registerAlignmentButton from './ui/alignment-button';
19
20
  import registerIndentOutdentButton from './ui/indent-outdent-button';
20
21
  import registerListButton from './ui/list-button';
@@ -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 formatMessage from '../../../../format-message';
19
20
  import { toolbarIconHelperFor } from '../../../../util/tinymce-plugin-util';
20
21
  export default function (editor) {
@@ -47,14 +48,12 @@ export default function (editor) {
47
48
  }))),
48
49
  onSetup: api => {
49
50
  const iconHelper = toolbarIconHelperFor(editor, alignButtonLabel);
50
-
51
51
  function nodeChangeHandler() {
52
52
  const activeAlignment = alignToolbarButtons.find(b => editor.formatter.match(b.name));
53
53
  const icon = activeAlignment ? activeAlignment.icon : 'align-left';
54
54
  api.setActive(!!activeAlignment);
55
55
  iconHelper.updateIcon(icon);
56
56
  }
57
-
58
57
  nodeChangeHandler();
59
58
  editor.on('NodeChange', nodeChangeHandler);
60
59
  return () => editor.off('NodeChange', nodeChangeHandler);
@@ -15,12 +15,12 @@
15
15
  * You should have received a copy of the GNU Affero General Public License along
16
16
  * with this program. If not, see <http://www.gnu.org/licenses/>.
17
17
  */
18
+
18
19
  import formatMessage from '../../../../format-message';
19
20
  export default function (editor) {
20
21
  function defaultDirectionality() {
21
22
  return document.dir;
22
23
  }
23
-
24
24
  const directionalityMenuItems = [{
25
25
  name: 'ltr',
26
26
  text: formatMessage('Left-to-Right'),
@@ -32,8 +32,9 @@ export default function (editor) {
32
32
  cmd: 'mceDirectionRTL',
33
33
  icon: 'rtl'
34
34
  }];
35
- if (defaultDirectionality() === 'rtl') directionalityMenuItems.reverse(); // Register menu item
35
+ if (defaultDirectionality() === 'rtl') directionalityMenuItems.reverse();
36
36
 
37
+ // Register menu item
37
38
  editor.ui.registry.addNestedMenuItem('directionality', {
38
39
  text: formatMessage('Directionality'),
39
40
  getSubmenuItems: () => [directionalityMenuItems[0].name, directionalityMenuItems[1].name]
@@ -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 formatMessage from '../../../../format-message';
19
20
  export default function register(editor) {
20
21
  const indentButtons = [{