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